UNPKG

11.3 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import { unstable_useForkRef as useForkRef } from '@mui/utils';
6import useSelect from '../useSelect';
7import { useSlotProps } from '../utils';
8import Popper from '../Popper';
9import composeClasses from '../composeClasses';
10import { getSelectUtilityClass } from './selectClasses';
11import defaultOptionStringifier from '../useSelect/defaultOptionStringifier';
12import { useClassNamesOverride } from '../utils/ClassNameConfigurator';
13import SelectProvider from '../useSelect/SelectProvider';
14import { jsx as _jsx } from "react/jsx-runtime";
15import { jsxs as _jsxs } from "react/jsx-runtime";
16function defaultRenderValue(selectedOptions) {
17 var _selectedOptions$labe;
18 if (Array.isArray(selectedOptions)) {
19 return /*#__PURE__*/_jsx(React.Fragment, {
20 children: selectedOptions.map(function (o) {
21 return o.label;
22 }).join(', ')
23 });
24 }
25 return (_selectedOptions$labe = selectedOptions == null ? void 0 : selectedOptions.label) != null ? _selectedOptions$labe : '';
26}
27function defaultFormValueProvider(selectedOption) {
28 if (Array.isArray(selectedOption)) {
29 if (selectedOption.length === 0) {
30 return '';
31 }
32 if (selectedOption.every(function (o) {
33 return typeof o.value === 'string' || typeof o.value === 'number' || typeof o.value === 'boolean';
34 })) {
35 return selectedOption.map(function (o) {
36 return String(o.value);
37 });
38 }
39 return JSON.stringify(selectedOption.map(function (o) {
40 return o.value;
41 }));
42 }
43 if ((selectedOption == null ? void 0 : selectedOption.value) == null) {
44 return '';
45 }
46 if (typeof selectedOption.value === 'string' || typeof selectedOption.value === 'number') {
47 return selectedOption.value;
48 }
49 return JSON.stringify(selectedOption.value);
50}
51function useUtilityClasses(ownerState) {
52 var active = ownerState.active,
53 disabled = ownerState.disabled,
54 open = ownerState.open,
55 focusVisible = ownerState.focusVisible;
56 var slots = {
57 root: ['root', disabled && 'disabled', focusVisible && 'focusVisible', active && 'active', open && 'expanded'],
58 listbox: ['listbox', disabled && 'disabled'],
59 popper: ['popper']
60 };
61 return composeClasses(slots, useClassNamesOverride(getSelectUtilityClass));
62}
63
64/**
65 * The foundation for building custom-styled select components.
66 *
67 * Demos:
68 *
69 * - [Select](https://mui.com/base/react-select/)
70 *
71 * API:
72 *
73 * - [Select API](https://mui.com/base/react-select/components-api/#select)
74 */
75var Select = /*#__PURE__*/React.forwardRef(function Select(props, forwardedRef) {
76 var _slots$root, _slots$listbox, _slots$popper;
77 var autoFocus = props.autoFocus,
78 children = props.children,
79 defaultValue = props.defaultValue,
80 _props$defaultListbox = props.defaultListboxOpen,
81 defaultListboxOpen = _props$defaultListbox === void 0 ? false : _props$defaultListbox,
82 disabledProp = props.disabled,
83 _props$getSerializedV = props.getSerializedValue,
84 getSerializedValue = _props$getSerializedV === void 0 ? defaultFormValueProvider : _props$getSerializedV,
85 listboxId = props.listboxId,
86 listboxOpenProp = props.listboxOpen,
87 _props$multiple = props.multiple,
88 multiple = _props$multiple === void 0 ? false : _props$multiple,
89 name = props.name,
90 onChange = props.onChange,
91 onListboxOpenChange = props.onListboxOpenChange,
92 _props$getOptionAsStr = props.getOptionAsString,
93 getOptionAsString = _props$getOptionAsStr === void 0 ? defaultOptionStringifier : _props$getOptionAsStr,
94 renderValueProp = props.renderValue,
95 _props$slotProps = props.slotProps,
96 slotProps = _props$slotProps === void 0 ? {} : _props$slotProps,
97 _props$slots = props.slots,
98 slots = _props$slots === void 0 ? {} : _props$slots,
99 valueProp = props.value,
100 other = _objectWithoutProperties(props, ["autoFocus", "children", "defaultValue", "defaultListboxOpen", "disabled", "getSerializedValue", "listboxId", "listboxOpen", "multiple", "name", "onChange", "onListboxOpenChange", "getOptionAsString", "renderValue", "slotProps", "slots", "value"]);
101 var renderValue = renderValueProp != null ? renderValueProp : defaultRenderValue;
102 var _React$useState = React.useState(false),
103 buttonDefined = _React$useState[0],
104 setButtonDefined = _React$useState[1];
105 var buttonRef = React.useRef(null);
106 var listboxRef = React.useRef(null);
107 var Button = (_slots$root = slots.root) != null ? _slots$root : 'button';
108 var ListboxRoot = (_slots$listbox = slots.listbox) != null ? _slots$listbox : 'ul';
109 var PopperComponent = (_slots$popper = slots.popper) != null ? _slots$popper : Popper;
110 var handleButtonRefChange = React.useCallback(function (element) {
111 setButtonDefined(element != null);
112 }, []);
113 var handleButtonRef = useForkRef(forwardedRef, buttonRef, handleButtonRefChange);
114 React.useEffect(function () {
115 if (autoFocus) {
116 buttonRef.current.focus();
117 }
118 }, [autoFocus]);
119 var _useSelect = useSelect({
120 buttonRef: handleButtonRef,
121 defaultOpen: defaultListboxOpen,
122 defaultValue: defaultValue,
123 disabled: disabledProp,
124 listboxId: listboxId,
125 multiple: multiple,
126 open: listboxOpenProp,
127 onChange: onChange,
128 onOpenChange: onListboxOpenChange,
129 getOptionAsString: getOptionAsString,
130 value: valueProp
131 }),
132 buttonActive = _useSelect.buttonActive,
133 buttonFocusVisible = _useSelect.buttonFocusVisible,
134 contextValue = _useSelect.contextValue,
135 disabled = _useSelect.disabled,
136 getButtonProps = _useSelect.getButtonProps,
137 getListboxProps = _useSelect.getListboxProps,
138 getOptionMetadata = _useSelect.getOptionMetadata,
139 value = _useSelect.value,
140 open = _useSelect.open;
141 var ownerState = _extends({}, props, {
142 active: buttonActive,
143 defaultListboxOpen: defaultListboxOpen,
144 disabled: disabled,
145 focusVisible: buttonFocusVisible,
146 open: open,
147 multiple: multiple,
148 renderValue: renderValue,
149 value: value
150 });
151 var classes = useUtilityClasses(ownerState);
152 var buttonProps = useSlotProps({
153 elementType: Button,
154 getSlotProps: getButtonProps,
155 externalSlotProps: slotProps.root,
156 externalForwardedProps: other,
157 ownerState: ownerState,
158 className: classes.root
159 });
160 var listboxProps = useSlotProps({
161 elementType: ListboxRoot,
162 getSlotProps: getListboxProps,
163 externalSlotProps: slotProps.listbox,
164 additionalProps: {
165 ref: listboxRef
166 },
167 ownerState: ownerState,
168 className: classes.listbox
169 });
170 var popperProps = useSlotProps({
171 elementType: PopperComponent,
172 externalSlotProps: slotProps.popper,
173 additionalProps: {
174 anchorEl: buttonRef.current,
175 keepMounted: true,
176 open: open,
177 placement: 'bottom-start',
178 role: undefined
179 },
180 ownerState: ownerState,
181 className: classes.popper
182 });
183 var selectedOptionsMetadata;
184 if (multiple) {
185 selectedOptionsMetadata = value.map(function (v) {
186 return getOptionMetadata(v);
187 }).filter(function (o) {
188 return o !== undefined;
189 });
190 } else {
191 var _getOptionMetadata;
192 selectedOptionsMetadata = (_getOptionMetadata = getOptionMetadata(value)) != null ? _getOptionMetadata : null;
193 }
194 return /*#__PURE__*/_jsxs(React.Fragment, {
195 children: [/*#__PURE__*/_jsx(Button, _extends({}, buttonProps, {
196 children: renderValue(selectedOptionsMetadata)
197 })), buttonDefined && /*#__PURE__*/_jsx(PopperComponent, _extends({}, popperProps, {
198 children: /*#__PURE__*/_jsx(ListboxRoot, _extends({}, listboxProps, {
199 children: /*#__PURE__*/_jsx(SelectProvider, {
200 value: contextValue,
201 children: children
202 })
203 }))
204 })), name && /*#__PURE__*/_jsx("input", {
205 type: "hidden",
206 name: name,
207 value: getSerializedValue(selectedOptionsMetadata)
208 })]
209 });
210});
211process.env.NODE_ENV !== "production" ? Select.propTypes /* remove-proptypes */ = {
212 // ----------------------------- Warning --------------------------------
213 // | These PropTypes are generated from the TypeScript type definitions |
214 // | To update them edit TypeScript types and run "yarn proptypes" |
215 // ----------------------------------------------------------------------
216 /**
217 * If `true`, the select element is focused during the first mount
218 * @default false
219 */
220 autoFocus: PropTypes.bool,
221 /**
222 * @ignore
223 */
224 children: PropTypes.node,
225 /**
226 * If `true`, the select will be initially open.
227 * @default false
228 */
229 defaultListboxOpen: PropTypes.bool,
230 /**
231 * The default selected value. Use when the component is not controlled.
232 */
233 defaultValue: PropTypes.any,
234 /**
235 * If `true`, the select is disabled.
236 * @default false
237 */
238 disabled: PropTypes.bool,
239 /**
240 * A function used to convert the option label to a string.
241 * It's useful when labels are elements and need to be converted to plain text
242 * to enable navigation using character keys on a keyboard.
243 *
244 * @default defaultOptionStringifier
245 */
246 getOptionAsString: PropTypes.func,
247 /**
248 * A function to convert the currently selected value to a string.
249 * Used to set a value of a hidden input associated with the select,
250 * so that the selected value can be posted with a form.
251 */
252 getSerializedValue: PropTypes.func,
253 /**
254 * `id` attribute of the listbox element.
255 */
256 listboxId: PropTypes.string,
257 /**
258 * Controls the open state of the select's listbox.
259 * @default undefined
260 */
261 listboxOpen: PropTypes.bool,
262 /**
263 * If `true`, selecting multiple values is allowed.
264 * This affects the type of the `value`, `defaultValue`, and `onChange` props.
265 *
266 * @default false
267 */
268 multiple: PropTypes.bool,
269 /**
270 * Name of the element. For example used by the server to identify the fields in form submits.
271 * If the name is provided, the component will render a hidden input element that can be submitted to a server.
272 */
273 name: PropTypes.string,
274 /**
275 * Callback fired when an option is selected.
276 */
277 onChange: PropTypes.func,
278 /**
279 * Callback fired when the component requests to be opened.
280 * Use in controlled mode (see listboxOpen).
281 */
282 onListboxOpenChange: PropTypes.func,
283 /**
284 * Function that customizes the rendering of the selected value.
285 */
286 renderValue: PropTypes.func,
287 /**
288 * The props used for each slot inside the Input.
289 * @default {}
290 */
291 slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
292 listbox: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
293 popper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
294 root: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
295 }),
296 /**
297 * The components used for each slot inside the Select.
298 * Either a string to use a HTML element or a component.
299 * @default {}
300 */
301 slots: PropTypes /* @typescript-to-proptypes-ignore */.shape({
302 listbox: PropTypes.elementType,
303 popper: PropTypes.elementType,
304 root: PropTypes.elementType
305 }),
306 /**
307 * The selected value.
308 * Set to `null` to deselect all options.
309 */
310 value: PropTypes.any
311} : void 0;
312export default Select;
\No newline at end of file