1 | "use strict";
|
2 | 'use client';
|
3 |
|
4 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
5 | var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
6 | Object.defineProperty(exports, "__esModule", {
|
7 | value: true
|
8 | });
|
9 | exports.default = void 0;
|
10 | var _formatMuiErrorMessage2 = _interopRequireDefault(require("@mui/utils/formatMuiErrorMessage"));
|
11 | var React = _interopRequireWildcard(require("react"));
|
12 | var _reactIs = require("react-is");
|
13 | var _propTypes = _interopRequireDefault(require("prop-types"));
|
14 | var _clsx = _interopRequireDefault(require("clsx"));
|
15 | var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
|
16 | var _useId = _interopRequireDefault(require("@mui/utils/useId"));
|
17 | var _refType = _interopRequireDefault(require("@mui/utils/refType"));
|
18 | var _ownerDocument = _interopRequireDefault(require("../utils/ownerDocument"));
|
19 | var _capitalize = _interopRequireDefault(require("../utils/capitalize"));
|
20 | var _Menu = _interopRequireDefault(require("../Menu/Menu"));
|
21 | var _NativeSelectInput = require("../NativeSelect/NativeSelectInput");
|
22 | var _utils = require("../InputBase/utils");
|
23 | var _zeroStyled = require("../zero-styled");
|
24 | var _slotShouldForwardProp = _interopRequireDefault(require("../styles/slotShouldForwardProp"));
|
25 | var _useForkRef = _interopRequireDefault(require("../utils/useForkRef"));
|
26 | var _useControlled = _interopRequireDefault(require("../utils/useControlled"));
|
27 | var _selectClasses = _interopRequireWildcard(require("./selectClasses"));
|
28 | var _jsxRuntime = require("react/jsx-runtime");
|
29 | var _span;
|
30 | const SelectSelect = (0, _zeroStyled.styled)(_NativeSelectInput.StyledSelectSelect, {
|
31 | name: 'MuiSelect',
|
32 | slot: 'Select',
|
33 | overridesResolver: (props, styles) => {
|
34 | const {
|
35 | ownerState
|
36 | } = props;
|
37 | return [
|
38 |
|
39 | {
|
40 | [`&.${_selectClasses.default.select}`]: styles.select
|
41 | }, {
|
42 | [`&.${_selectClasses.default.select}`]: styles[ownerState.variant]
|
43 | }, {
|
44 | [`&.${_selectClasses.default.error}`]: styles.error
|
45 | }, {
|
46 | [`&.${_selectClasses.default.multiple}`]: styles.multiple
|
47 | }];
|
48 | }
|
49 | })({
|
50 |
|
51 | [`&.${_selectClasses.default.select}`]: {
|
52 | height: 'auto',
|
53 |
|
54 | minHeight: '1.4375em',
|
55 |
|
56 | textOverflow: 'ellipsis',
|
57 | whiteSpace: 'nowrap',
|
58 | overflow: 'hidden'
|
59 | }
|
60 | });
|
61 | const SelectIcon = (0, _zeroStyled.styled)(_NativeSelectInput.StyledSelectIcon, {
|
62 | name: 'MuiSelect',
|
63 | slot: 'Icon',
|
64 | overridesResolver: (props, styles) => {
|
65 | const {
|
66 | ownerState
|
67 | } = props;
|
68 | return [styles.icon, ownerState.variant && styles[`icon${(0, _capitalize.default)(ownerState.variant)}`], ownerState.open && styles.iconOpen];
|
69 | }
|
70 | })({});
|
71 | const SelectNativeInput = (0, _zeroStyled.styled)('input', {
|
72 | shouldForwardProp: prop => (0, _slotShouldForwardProp.default)(prop) && prop !== 'classes',
|
73 | name: 'MuiSelect',
|
74 | slot: 'NativeInput',
|
75 | overridesResolver: (props, styles) => styles.nativeInput
|
76 | })({
|
77 | bottom: 0,
|
78 | left: 0,
|
79 | position: 'absolute',
|
80 | opacity: 0,
|
81 | pointerEvents: 'none',
|
82 | width: '100%',
|
83 | boxSizing: 'border-box'
|
84 | });
|
85 | function areEqualValues(a, b) {
|
86 | if (typeof b === 'object' && b !== null) {
|
87 | return a === b;
|
88 | }
|
89 |
|
90 |
|
91 | return String(a) === String(b);
|
92 | }
|
93 | function isEmpty(display) {
|
94 | return display == null || typeof display === 'string' && !display.trim();
|
95 | }
|
96 | const useUtilityClasses = ownerState => {
|
97 | const {
|
98 | classes,
|
99 | variant,
|
100 | disabled,
|
101 | multiple,
|
102 | open,
|
103 | error
|
104 | } = ownerState;
|
105 | const slots = {
|
106 | select: ['select', variant, disabled && 'disabled', multiple && 'multiple', error && 'error'],
|
107 | icon: ['icon', `icon${(0, _capitalize.default)(variant)}`, open && 'iconOpen', disabled && 'disabled'],
|
108 | nativeInput: ['nativeInput']
|
109 | };
|
110 | return (0, _composeClasses.default)(slots, _selectClasses.getSelectUtilityClasses, classes);
|
111 | };
|
112 |
|
113 |
|
114 |
|
115 |
|
116 | const SelectInput = React.forwardRef(function SelectInput(props, ref) {
|
117 | const {
|
118 | 'aria-describedby': ariaDescribedby,
|
119 | 'aria-label': ariaLabel,
|
120 | autoFocus,
|
121 | autoWidth,
|
122 | children,
|
123 | className,
|
124 | defaultOpen,
|
125 | defaultValue,
|
126 | disabled,
|
127 | displayEmpty,
|
128 | error = false,
|
129 | IconComponent,
|
130 | inputRef: inputRefProp,
|
131 | labelId,
|
132 | MenuProps = {},
|
133 | multiple,
|
134 | name,
|
135 | onBlur,
|
136 | onChange,
|
137 | onClose,
|
138 | onFocus,
|
139 | onOpen,
|
140 | open: openProp,
|
141 | readOnly,
|
142 | renderValue,
|
143 | SelectDisplayProps = {},
|
144 | tabIndex: tabIndexProp,
|
145 |
|
146 | type,
|
147 | value: valueProp,
|
148 | variant = 'standard',
|
149 | ...other
|
150 | } = props;
|
151 | const [value, setValueState] = (0, _useControlled.default)({
|
152 | controlled: valueProp,
|
153 | default: defaultValue,
|
154 | name: 'Select'
|
155 | });
|
156 | const [openState, setOpenState] = (0, _useControlled.default)({
|
157 | controlled: openProp,
|
158 | default: defaultOpen,
|
159 | name: 'Select'
|
160 | });
|
161 | const inputRef = React.useRef(null);
|
162 | const displayRef = React.useRef(null);
|
163 | const [displayNode, setDisplayNode] = React.useState(null);
|
164 | const {
|
165 | current: isOpenControlled
|
166 | } = React.useRef(openProp != null);
|
167 | const [menuMinWidthState, setMenuMinWidthState] = React.useState();
|
168 | const handleRef = (0, _useForkRef.default)(ref, inputRefProp);
|
169 | const handleDisplayRef = React.useCallback(node => {
|
170 | displayRef.current = node;
|
171 | if (node) {
|
172 | setDisplayNode(node);
|
173 | }
|
174 | }, []);
|
175 | const anchorElement = displayNode?.parentNode;
|
176 | React.useImperativeHandle(handleRef, () => ({
|
177 | focus: () => {
|
178 | displayRef.current.focus();
|
179 | },
|
180 | node: inputRef.current,
|
181 | value
|
182 | }), [value]);
|
183 |
|
184 |
|
185 | React.useEffect(() => {
|
186 | if (defaultOpen && openState && displayNode && !isOpenControlled) {
|
187 | setMenuMinWidthState(autoWidth ? null : anchorElement.clientWidth);
|
188 | displayRef.current.focus();
|
189 | }
|
190 |
|
191 |
|
192 | }, [displayNode, autoWidth]);
|
193 |
|
194 |
|
195 | React.useEffect(() => {
|
196 | if (autoFocus) {
|
197 | displayRef.current.focus();
|
198 | }
|
199 | }, [autoFocus]);
|
200 | React.useEffect(() => {
|
201 | if (!labelId) {
|
202 | return undefined;
|
203 | }
|
204 | const label = (0, _ownerDocument.default)(displayRef.current).getElementById(labelId);
|
205 | if (label) {
|
206 | const handler = () => {
|
207 | if (getSelection().isCollapsed) {
|
208 | displayRef.current.focus();
|
209 | }
|
210 | };
|
211 | label.addEventListener('click', handler);
|
212 | return () => {
|
213 | label.removeEventListener('click', handler);
|
214 | };
|
215 | }
|
216 | return undefined;
|
217 | }, [labelId]);
|
218 | const update = (open, event) => {
|
219 | if (open) {
|
220 | if (onOpen) {
|
221 | onOpen(event);
|
222 | }
|
223 | } else if (onClose) {
|
224 | onClose(event);
|
225 | }
|
226 | if (!isOpenControlled) {
|
227 | setMenuMinWidthState(autoWidth ? null : anchorElement.clientWidth);
|
228 | setOpenState(open);
|
229 | }
|
230 | };
|
231 | const handleMouseDown = event => {
|
232 |
|
233 | if (event.button !== 0) {
|
234 | return;
|
235 | }
|
236 |
|
237 | event.preventDefault();
|
238 | displayRef.current.focus();
|
239 | update(true, event);
|
240 | };
|
241 | const handleClose = event => {
|
242 | update(false, event);
|
243 | };
|
244 | const childrenArray = React.Children.toArray(children);
|
245 |
|
246 |
|
247 | const handleChange = event => {
|
248 | const child = childrenArray.find(childItem => childItem.props.value === event.target.value);
|
249 | if (child === undefined) {
|
250 | return;
|
251 | }
|
252 | setValueState(child.props.value);
|
253 | if (onChange) {
|
254 | onChange(event, child);
|
255 | }
|
256 | };
|
257 | const handleItemClick = child => event => {
|
258 | let newValue;
|
259 |
|
260 |
|
261 | if (!event.currentTarget.hasAttribute('tabindex')) {
|
262 | return;
|
263 | }
|
264 | if (multiple) {
|
265 | newValue = Array.isArray(value) ? value.slice() : [];
|
266 | const itemIndex = value.indexOf(child.props.value);
|
267 | if (itemIndex === -1) {
|
268 | newValue.push(child.props.value);
|
269 | } else {
|
270 | newValue.splice(itemIndex, 1);
|
271 | }
|
272 | } else {
|
273 | newValue = child.props.value;
|
274 | }
|
275 | if (child.props.onClick) {
|
276 | child.props.onClick(event);
|
277 | }
|
278 | if (value !== newValue) {
|
279 | setValueState(newValue);
|
280 | if (onChange) {
|
281 |
|
282 |
|
283 |
|
284 |
|
285 | const nativeEvent = event.nativeEvent || event;
|
286 | const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
287 | Object.defineProperty(clonedEvent, 'target', {
|
288 | writable: true,
|
289 | value: {
|
290 | value: newValue,
|
291 | name
|
292 | }
|
293 | });
|
294 | onChange(clonedEvent, child);
|
295 | }
|
296 | }
|
297 | if (!multiple) {
|
298 | update(false, event);
|
299 | }
|
300 | };
|
301 | const handleKeyDown = event => {
|
302 | if (!readOnly) {
|
303 | const validKeys = [' ', 'ArrowUp', 'ArrowDown',
|
304 |
|
305 |
|
306 | 'Enter'];
|
307 | if (validKeys.includes(event.key)) {
|
308 | event.preventDefault();
|
309 | update(true, event);
|
310 | }
|
311 | }
|
312 | };
|
313 | const open = displayNode !== null && openState;
|
314 | const handleBlur = event => {
|
315 |
|
316 | if (!open && onBlur) {
|
317 |
|
318 | Object.defineProperty(event, 'target', {
|
319 | writable: true,
|
320 | value: {
|
321 | value,
|
322 | name
|
323 | }
|
324 | });
|
325 | onBlur(event);
|
326 | }
|
327 | };
|
328 | delete other['aria-invalid'];
|
329 | let display;
|
330 | let displaySingle;
|
331 | const displayMultiple = [];
|
332 | let computeDisplay = false;
|
333 | let foundMatch = false;
|
334 |
|
335 |
|
336 | if ((0, _utils.isFilled)({
|
337 | value
|
338 | }) || displayEmpty) {
|
339 | if (renderValue) {
|
340 | display = renderValue(value);
|
341 | } else {
|
342 | computeDisplay = true;
|
343 | }
|
344 | }
|
345 | const items = childrenArray.map(child => {
|
346 | if (! React.isValidElement(child)) {
|
347 | return null;
|
348 | }
|
349 | if (process.env.NODE_ENV !== 'production') {
|
350 | if ((0, _reactIs.isFragment)(child)) {
|
351 | console.error(["MUI: The Select component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
|
352 | }
|
353 | }
|
354 | let selected;
|
355 | if (multiple) {
|
356 | if (!Array.isArray(value)) {
|
357 | throw new Error(process.env.NODE_ENV !== "production" ? 'MUI: The `value` prop must be an array ' + 'when using the `Select` component with `multiple`.' : (0, _formatMuiErrorMessage2.default)(2));
|
358 | }
|
359 | selected = value.some(v => areEqualValues(v, child.props.value));
|
360 | if (selected && computeDisplay) {
|
361 | displayMultiple.push(child.props.children);
|
362 | }
|
363 | } else {
|
364 | selected = areEqualValues(value, child.props.value);
|
365 | if (selected && computeDisplay) {
|
366 | displaySingle = child.props.children;
|
367 | }
|
368 | }
|
369 | if (selected) {
|
370 | foundMatch = true;
|
371 | }
|
372 | return React.cloneElement(child, {
|
373 | 'aria-selected': selected ? 'true' : 'false',
|
374 | onClick: handleItemClick(child),
|
375 | onKeyUp: event => {
|
376 | if (event.key === ' ') {
|
377 |
|
378 |
|
379 |
|
380 | event.preventDefault();
|
381 | }
|
382 | if (child.props.onKeyUp) {
|
383 | child.props.onKeyUp(event);
|
384 | }
|
385 | },
|
386 | role: 'option',
|
387 | selected,
|
388 | value: undefined,
|
389 |
|
390 | 'data-value': child.props.value
|
391 | });
|
392 | });
|
393 | if (process.env.NODE_ENV !== 'production') {
|
394 |
|
395 |
|
396 | React.useEffect(() => {
|
397 | if (!foundMatch && !multiple && value !== '') {
|
398 | const values = childrenArray.map(child => child.props.value);
|
399 | console.warn([`MUI: You have provided an out-of-range value \`${value}\` for the select ${name ? `(name="${name}") ` : ''}component.`, "Consider providing a value that matches one of the available options or ''.", `The available values are ${values.filter(x => x != null).map(x => `\`${x}\``).join(', ') || '""'}.`].join('\n'));
|
400 | }
|
401 | }, [foundMatch, childrenArray, multiple, name, value]);
|
402 | }
|
403 | if (computeDisplay) {
|
404 | if (multiple) {
|
405 | if (displayMultiple.length === 0) {
|
406 | display = null;
|
407 | } else {
|
408 | display = displayMultiple.reduce((output, child, index) => {
|
409 | output.push(child);
|
410 | if (index < displayMultiple.length - 1) {
|
411 | output.push(', ');
|
412 | }
|
413 | return output;
|
414 | }, []);
|
415 | }
|
416 | } else {
|
417 | display = displaySingle;
|
418 | }
|
419 | }
|
420 |
|
421 |
|
422 | let menuMinWidth = menuMinWidthState;
|
423 | if (!autoWidth && isOpenControlled && displayNode) {
|
424 | menuMinWidth = anchorElement.clientWidth;
|
425 | }
|
426 | let tabIndex;
|
427 | if (typeof tabIndexProp !== 'undefined') {
|
428 | tabIndex = tabIndexProp;
|
429 | } else {
|
430 | tabIndex = disabled ? null : 0;
|
431 | }
|
432 | const buttonId = SelectDisplayProps.id || (name ? `mui-component-select-${name}` : undefined);
|
433 | const ownerState = {
|
434 | ...props,
|
435 | variant,
|
436 | value,
|
437 | open,
|
438 | error
|
439 | };
|
440 | const classes = useUtilityClasses(ownerState);
|
441 | const paperProps = {
|
442 | ...MenuProps.PaperProps,
|
443 | ...MenuProps.slotProps?.paper
|
444 | };
|
445 | const listboxId = (0, _useId.default)();
|
446 | return (0, _jsxRuntime.jsxs)(React.Fragment, {
|
447 | children: [(0, _jsxRuntime.jsx)(SelectSelect, {
|
448 | as: "div",
|
449 | ref: handleDisplayRef,
|
450 | tabIndex: tabIndex,
|
451 | role: "combobox",
|
452 | "aria-controls": listboxId,
|
453 | "aria-disabled": disabled ? 'true' : undefined,
|
454 | "aria-expanded": open ? 'true' : 'false',
|
455 | "aria-haspopup": "listbox",
|
456 | "aria-label": ariaLabel,
|
457 | "aria-labelledby": [labelId, buttonId].filter(Boolean).join(' ') || undefined,
|
458 | "aria-describedby": ariaDescribedby,
|
459 | onKeyDown: handleKeyDown,
|
460 | onMouseDown: disabled || readOnly ? null : handleMouseDown,
|
461 | onBlur: handleBlur,
|
462 | onFocus: onFocus,
|
463 | ...SelectDisplayProps,
|
464 | ownerState: ownerState,
|
465 | className: (0, _clsx.default)(SelectDisplayProps.className, classes.select, className)
|
466 |
|
467 | ,
|
468 | id: buttonId,
|
469 | children: isEmpty(display) ?
|
470 | _span || (_span = (0, _jsxRuntime.jsx)("span", {
|
471 | className: "notranslate",
|
472 | children: "\u200B"
|
473 | })) : display
|
474 | }), (0, _jsxRuntime.jsx)(SelectNativeInput, {
|
475 | "aria-invalid": error,
|
476 | value: Array.isArray(value) ? value.join(',') : value,
|
477 | name: name,
|
478 | ref: inputRef,
|
479 | "aria-hidden": true,
|
480 | onChange: handleChange,
|
481 | tabIndex: -1,
|
482 | disabled: disabled,
|
483 | className: classes.nativeInput,
|
484 | autoFocus: autoFocus,
|
485 | ...other,
|
486 | ownerState: ownerState
|
487 | }), (0, _jsxRuntime.jsx)(SelectIcon, {
|
488 | as: IconComponent,
|
489 | className: classes.icon,
|
490 | ownerState: ownerState
|
491 | }), (0, _jsxRuntime.jsx)(_Menu.default, {
|
492 | id: `menu-${name || ''}`,
|
493 | anchorEl: anchorElement,
|
494 | open: open,
|
495 | onClose: handleClose,
|
496 | anchorOrigin: {
|
497 | vertical: 'bottom',
|
498 | horizontal: 'center'
|
499 | },
|
500 | transformOrigin: {
|
501 | vertical: 'top',
|
502 | horizontal: 'center'
|
503 | },
|
504 | ...MenuProps,
|
505 | MenuListProps: {
|
506 | 'aria-labelledby': labelId,
|
507 | role: 'listbox',
|
508 | 'aria-multiselectable': multiple ? 'true' : undefined,
|
509 | disableListWrap: true,
|
510 | id: listboxId,
|
511 | ...MenuProps.MenuListProps
|
512 | },
|
513 | slotProps: {
|
514 | ...MenuProps.slotProps,
|
515 | paper: {
|
516 | ...paperProps,
|
517 | style: {
|
518 | minWidth: menuMinWidth,
|
519 | ...(paperProps != null ? paperProps.style : null)
|
520 | }
|
521 | }
|
522 | },
|
523 | children: items
|
524 | })]
|
525 | });
|
526 | });
|
527 | process.env.NODE_ENV !== "production" ? SelectInput.propTypes = {
|
528 | |
529 |
|
530 |
|
531 | 'aria-describedby': _propTypes.default.string,
|
532 | |
533 |
|
534 |
|
535 | 'aria-label': _propTypes.default.string,
|
536 | |
537 |
|
538 |
|
539 | autoFocus: _propTypes.default.bool,
|
540 | |
541 |
|
542 |
|
543 |
|
544 | autoWidth: _propTypes.default.bool,
|
545 | |
546 |
|
547 |
|
548 |
|
549 | children: _propTypes.default.node,
|
550 | |
551 |
|
552 |
|
553 | classes: _propTypes.default.object,
|
554 | |
555 |
|
556 |
|
557 | className: _propTypes.default.string,
|
558 | |
559 |
|
560 |
|
561 |
|
562 | defaultOpen: _propTypes.default.bool,
|
563 | |
564 |
|
565 |
|
566 | defaultValue: _propTypes.default.any,
|
567 | |
568 |
|
569 |
|
570 | disabled: _propTypes.default.bool,
|
571 | |
572 |
|
573 |
|
574 | displayEmpty: _propTypes.default.bool,
|
575 | |
576 |
|
577 |
|
578 | error: _propTypes.default.bool,
|
579 | |
580 |
|
581 |
|
582 | IconComponent: _propTypes.default.elementType.isRequired,
|
583 | |
584 |
|
585 |
|
586 |
|
587 | inputRef: _refType.default,
|
588 | |
589 |
|
590 |
|
591 |
|
592 | labelId: _propTypes.default.string,
|
593 | |
594 |
|
595 |
|
596 | MenuProps: _propTypes.default.object,
|
597 | |
598 |
|
599 |
|
600 | multiple: _propTypes.default.bool,
|
601 | |
602 |
|
603 |
|
604 | name: _propTypes.default.string,
|
605 | |
606 |
|
607 |
|
608 | onBlur: _propTypes.default.func,
|
609 | |
610 |
|
611 |
|
612 |
|
613 |
|
614 |
|
615 |
|
616 | onChange: _propTypes.default.func,
|
617 | |
618 |
|
619 |
|
620 |
|
621 |
|
622 |
|
623 | onClose: _propTypes.default.func,
|
624 | |
625 |
|
626 |
|
627 | onFocus: _propTypes.default.func,
|
628 | |
629 |
|
630 |
|
631 |
|
632 |
|
633 |
|
634 | onOpen: _propTypes.default.func,
|
635 | |
636 |
|
637 |
|
638 | open: _propTypes.default.bool,
|
639 | |
640 |
|
641 |
|
642 | readOnly: _propTypes.default.bool,
|
643 | |
644 |
|
645 |
|
646 |
|
647 |
|
648 |
|
649 | renderValue: _propTypes.default.func,
|
650 | |
651 |
|
652 |
|
653 | SelectDisplayProps: _propTypes.default.object,
|
654 | |
655 |
|
656 |
|
657 | tabIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
|
658 | |
659 |
|
660 |
|
661 | type: _propTypes.default.any,
|
662 | |
663 |
|
664 |
|
665 | value: _propTypes.default.any,
|
666 | |
667 |
|
668 |
|
669 | variant: _propTypes.default.oneOf(['standard', 'outlined', 'filled'])
|
670 | } : void 0;
|
671 | var _default = exports.default = SelectInput; |
\ | No newline at end of file |