UNPKG

6.01 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import NativeSelectInput from './NativeSelectInput';
6import withStyles from '../styles/withStyles';
7import formControlState from '../FormControl/formControlState';
8import useFormControl from '../FormControl/useFormControl';
9import ArrowDropDownIcon from '../internal/svg-icons/ArrowDropDown';
10import Input from '../Input';
11export const styles = theme => ({
12 /* Styles applied to the select component `root` class. */
13 root: {},
14
15 /* Styles applied to the select component `select` class. */
16 select: {
17 '-moz-appearance': 'none',
18 // Reset
19 '-webkit-appearance': 'none',
20 // Reset
21 // When interacting quickly, the text can end up selected.
22 // Native select can't be selected either.
23 userSelect: 'none',
24 borderRadius: 0,
25 // Reset
26 minWidth: 16,
27 // So it doesn't collapse.
28 cursor: 'pointer',
29 '&:focus': {
30 // Show that it's not an text input
31 backgroundColor: theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.05)' : 'rgba(255, 255, 255, 0.05)',
32 borderRadius: 0 // Reset Chrome style
33
34 },
35 // Remove IE 11 arrow
36 '&::-ms-expand': {
37 display: 'none'
38 },
39 '&$disabled': {
40 cursor: 'default'
41 },
42 '&[multiple]': {
43 height: 'auto'
44 },
45 '&:not([multiple]) option, &:not([multiple]) optgroup': {
46 backgroundColor: theme.palette.background.paper
47 },
48 '&&': {
49 paddingRight: 24
50 }
51 },
52
53 /* Styles applied to the select component if `variant="filled"`. */
54 filled: {
55 '&&': {
56 paddingRight: 32
57 }
58 },
59
60 /* Styles applied to the select component if `variant="outlined"`. */
61 outlined: {
62 borderRadius: theme.shape.borderRadius,
63 '&&': {
64 paddingRight: 32
65 }
66 },
67
68 /* Styles applied to the select component `selectMenu` class. */
69 selectMenu: {
70 height: 'auto',
71 // Resets for multpile select with chips
72 minHeight: '1.1876em',
73 // Required for select\text-field height consistency
74 textOverflow: 'ellipsis',
75 whiteSpace: 'nowrap',
76 overflow: 'hidden'
77 },
78
79 /* Pseudo-class applied to the select component `disabled` class. */
80 disabled: {},
81
82 /* Styles applied to the icon component. */
83 icon: {
84 // We use a position absolute over a flexbox in order to forward the pointer events
85 // to the input and to support wrapping tags..
86 position: 'absolute',
87 right: 0,
88 top: 'calc(50% - 12px)',
89 // Center vertically
90 pointerEvents: 'none',
91 // Don't block pointer events on the select under the icon.
92 color: theme.palette.action.active,
93 '&$disabled': {
94 color: theme.palette.action.disabled
95 }
96 },
97
98 /* Styles applied to the icon component if the popup is open. */
99 iconOpen: {
100 transform: 'rotate(180deg)'
101 },
102
103 /* Styles applied to the icon component if `variant="filled"`. */
104 iconFilled: {
105 right: 7
106 },
107
108 /* Styles applied to the icon component if `variant="outlined"`. */
109 iconOutlined: {
110 right: 7
111 },
112
113 /* Styles applied to the underlying native input component. */
114 nativeInput: {
115 bottom: 0,
116 left: 0,
117 position: 'absolute',
118 opacity: 0,
119 pointerEvents: 'none',
120 width: '100%'
121 }
122});
123const defaultInput = /*#__PURE__*/React.createElement(Input, null);
124/**
125 * An alternative to `<Select native />` with a much smaller bundle size footprint.
126 */
127
128const NativeSelect = /*#__PURE__*/React.forwardRef(function NativeSelect(props, ref) {
129 const {
130 children,
131 classes,
132 IconComponent = ArrowDropDownIcon,
133 input = defaultInput,
134 inputProps
135 } = props,
136 other = _objectWithoutPropertiesLoose(props, ["children", "classes", "IconComponent", "input", "inputProps", "variant"]);
137
138 const muiFormControl = useFormControl();
139 const fcs = formControlState({
140 props,
141 muiFormControl,
142 states: ['variant']
143 });
144 return /*#__PURE__*/React.cloneElement(input, _extends({
145 // Most of the logic is implemented in `NativeSelectInput`.
146 // The `Select` component is a simple API wrapper to expose something better to play with.
147 inputComponent: NativeSelectInput,
148 inputProps: _extends({
149 children,
150 classes,
151 IconComponent,
152 variant: fcs.variant,
153 type: undefined
154 }, inputProps, input ? input.props.inputProps : {}),
155 ref
156 }, other));
157});
158process.env.NODE_ENV !== "production" ? NativeSelect.propTypes = {
159 // ----------------------------- Warning --------------------------------
160 // | These PropTypes are generated from the TypeScript type definitions |
161 // | To update them edit the d.ts file and run "yarn proptypes" |
162 // ----------------------------------------------------------------------
163
164 /**
165 * The option elements to populate the select with.
166 * Can be some `<option>` elements.
167 */
168 children: PropTypes.node,
169
170 /**
171 * Override or extend the styles applied to the component.
172 * See [CSS API](#css) below for more details.
173 */
174 classes: PropTypes.object,
175
176 /**
177 * The icon that displays the arrow.
178 */
179 IconComponent: PropTypes.elementType,
180
181 /**
182 * An `Input` element; does not have to be a material-ui specific `Input`.
183 */
184 input: PropTypes.element,
185
186 /**
187 * Attributes applied to the `select` element.
188 */
189 inputProps: PropTypes.object,
190
191 /**
192 * Callback function fired when a menu item is selected.
193 *
194 * @param {object} event The event source of the callback.
195 * You can pull out the new value by accessing `event.target.value` (string).
196 */
197 onChange: PropTypes.func,
198
199 /**
200 * The input value. The DOM API casts this to a string.
201 */
202 value: PropTypes.any,
203
204 /**
205 * The variant to use.
206 */
207 variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
208} : void 0;
209NativeSelect.muiName = 'Select';
210export default withStyles(styles, {
211 name: 'MuiNativeSelect'
212})(NativeSelect);
\No newline at end of file