UNPKG

6.13 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import refType from '@mui/utils/refType';
7import composeClasses from '@mui/utils/composeClasses';
8import capitalize from "../utils/capitalize.js";
9import nativeSelectClasses, { getNativeSelectUtilityClasses } from "./nativeSelectClasses.js";
10import { styled } from "../zero-styled/index.js";
11import rootShouldForwardProp from "../styles/rootShouldForwardProp.js";
12import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13const useUtilityClasses = ownerState => {
14 const {
15 classes,
16 variant,
17 disabled,
18 multiple,
19 open,
20 error
21 } = ownerState;
22 const slots = {
23 select: ['select', variant, disabled && 'disabled', multiple && 'multiple', error && 'error'],
24 icon: ['icon', `icon${capitalize(variant)}`, open && 'iconOpen', disabled && 'disabled']
25 };
26 return composeClasses(slots, getNativeSelectUtilityClasses, classes);
27};
28export const StyledSelectSelect = styled('select')(({
29 theme
30}) => ({
31 // Reset
32 MozAppearance: 'none',
33 // Reset
34 WebkitAppearance: 'none',
35 // When interacting quickly, the text can end up selected.
36 // Native select can't be selected either.
37 userSelect: 'none',
38 // Reset
39 borderRadius: 0,
40 cursor: 'pointer',
41 '&:focus': {
42 // Reset Chrome style
43 borderRadius: 0
44 },
45 [`&.${nativeSelectClasses.disabled}`]: {
46 cursor: 'default'
47 },
48 '&[multiple]': {
49 height: 'auto'
50 },
51 '&:not([multiple]) option, &:not([multiple]) optgroup': {
52 backgroundColor: (theme.vars || theme).palette.background.paper
53 },
54 variants: [{
55 props: ({
56 ownerState
57 }) => ownerState.variant !== 'filled' && ownerState.variant !== 'outlined',
58 style: {
59 // Bump specificity to allow extending custom inputs
60 '&&&': {
61 paddingRight: 24,
62 minWidth: 16 // So it doesn't collapse.
63 }
64 }
65 }, {
66 props: {
67 variant: 'filled'
68 },
69 style: {
70 '&&&': {
71 paddingRight: 32
72 }
73 }
74 }, {
75 props: {
76 variant: 'outlined'
77 },
78 style: {
79 borderRadius: (theme.vars || theme).shape.borderRadius,
80 '&:focus': {
81 borderRadius: (theme.vars || theme).shape.borderRadius // Reset the reset for Chrome style
82 },
83 '&&&': {
84 paddingRight: 32
85 }
86 }
87 }]
88}));
89const NativeSelectSelect = styled(StyledSelectSelect, {
90 name: 'MuiNativeSelect',
91 slot: 'Select',
92 shouldForwardProp: rootShouldForwardProp,
93 overridesResolver: (props, styles) => {
94 const {
95 ownerState
96 } = props;
97 return [styles.select, styles[ownerState.variant], ownerState.error && styles.error, {
98 [`&.${nativeSelectClasses.multiple}`]: styles.multiple
99 }];
100 }
101})({});
102export const StyledSelectIcon = styled('svg')(({
103 theme
104}) => ({
105 // We use a position absolute over a flexbox in order to forward the pointer events
106 // to the input and to support wrapping tags..
107 position: 'absolute',
108 right: 0,
109 // Center vertically, height is 1em
110 top: 'calc(50% - .5em)',
111 // Don't block pointer events on the select under the icon.
112 pointerEvents: 'none',
113 color: (theme.vars || theme).palette.action.active,
114 [`&.${nativeSelectClasses.disabled}`]: {
115 color: (theme.vars || theme).palette.action.disabled
116 },
117 variants: [{
118 props: ({
119 ownerState
120 }) => ownerState.open,
121 style: {
122 transform: 'rotate(180deg)'
123 }
124 }, {
125 props: {
126 variant: 'filled'
127 },
128 style: {
129 right: 7
130 }
131 }, {
132 props: {
133 variant: 'outlined'
134 },
135 style: {
136 right: 7
137 }
138 }]
139}));
140const NativeSelectIcon = styled(StyledSelectIcon, {
141 name: 'MuiNativeSelect',
142 slot: 'Icon',
143 overridesResolver: (props, styles) => {
144 const {
145 ownerState
146 } = props;
147 return [styles.icon, ownerState.variant && styles[`icon${capitalize(ownerState.variant)}`], ownerState.open && styles.iconOpen];
148 }
149})({});
150
151/**
152 * @ignore - internal component.
153 */
154const NativeSelectInput = /*#__PURE__*/React.forwardRef(function NativeSelectInput(props, ref) {
155 const {
156 className,
157 disabled,
158 error,
159 IconComponent,
160 inputRef,
161 variant = 'standard',
162 ...other
163 } = props;
164 const ownerState = {
165 ...props,
166 disabled,
167 variant,
168 error
169 };
170 const classes = useUtilityClasses(ownerState);
171 return /*#__PURE__*/_jsxs(React.Fragment, {
172 children: [/*#__PURE__*/_jsx(NativeSelectSelect, {
173 ownerState: ownerState,
174 className: clsx(classes.select, className),
175 disabled: disabled,
176 ref: inputRef || ref,
177 ...other
178 }), props.multiple ? null : /*#__PURE__*/_jsx(NativeSelectIcon, {
179 as: IconComponent,
180 ownerState: ownerState,
181 className: classes.icon
182 })]
183 });
184});
185process.env.NODE_ENV !== "production" ? NativeSelectInput.propTypes = {
186 /**
187 * The option elements to populate the select with.
188 * Can be some `<option>` elements.
189 */
190 children: PropTypes.node,
191 /**
192 * Override or extend the styles applied to the component.
193 */
194 classes: PropTypes.object,
195 /**
196 * The CSS class name of the select element.
197 */
198 className: PropTypes.string,
199 /**
200 * If `true`, the select is disabled.
201 */
202 disabled: PropTypes.bool,
203 /**
204 * If `true`, the `select input` will indicate an error.
205 */
206 error: PropTypes.bool,
207 /**
208 * The icon that displays the arrow.
209 */
210 IconComponent: PropTypes.elementType.isRequired,
211 /**
212 * Use that prop to pass a ref to the native select element.
213 * @deprecated
214 */
215 inputRef: refType,
216 /**
217 * @ignore
218 */
219 multiple: PropTypes.bool,
220 /**
221 * Name attribute of the `select` or hidden `input` element.
222 */
223 name: PropTypes.string,
224 /**
225 * Callback fired when a menu item is selected.
226 *
227 * @param {object} event The event source of the callback.
228 * You can pull out the new value by accessing `event.target.value` (string).
229 */
230 onChange: PropTypes.func,
231 /**
232 * The input value.
233 */
234 value: PropTypes.any,
235 /**
236 * The variant to use.
237 */
238 variant: PropTypes.oneOf(['standard', 'outlined', 'filled'])
239} : void 0;
240export default NativeSelectInput;
\No newline at end of file