UNPKG

38.8 kBJavaScriptView Raw
1'use client';
2
3var _ClearIcon, _ArrowDropDownIcon;
4import * as React from 'react';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import integerPropType from '@mui/utils/integerPropType';
8import chainPropTypes from '@mui/utils/chainPropTypes';
9import composeClasses from '@mui/utils/composeClasses';
10import { alpha } from '@mui/system/colorManipulator';
11import useAutocomplete, { createFilterOptions } from "../useAutocomplete/index.js";
12import Popper from "../Popper/index.js";
13import ListSubheader from "../ListSubheader/index.js";
14import Paper from "../Paper/index.js";
15import IconButton from "../IconButton/index.js";
16import Chip from "../Chip/index.js";
17import inputClasses from "../Input/inputClasses.js";
18import inputBaseClasses from "../InputBase/inputBaseClasses.js";
19import outlinedInputClasses from "../OutlinedInput/outlinedInputClasses.js";
20import filledInputClasses from "../FilledInput/filledInputClasses.js";
21import ClearIcon from "../internal/svg-icons/Close.js";
22import ArrowDropDownIcon from "../internal/svg-icons/ArrowDropDown.js";
23import { styled } from "../zero-styled/index.js";
24import memoTheme from "../utils/memoTheme.js";
25import { useDefaultProps } from "../DefaultPropsProvider/index.js";
26import autocompleteClasses, { getAutocompleteUtilityClass } from "./autocompleteClasses.js";
27import capitalize from "../utils/capitalize.js";
28import useSlot from "../utils/useSlot.js";
29import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
30const useUtilityClasses = ownerState => {
31 const {
32 classes,
33 disablePortal,
34 expanded,
35 focused,
36 fullWidth,
37 hasClearIcon,
38 hasPopupIcon,
39 inputFocused,
40 popupOpen,
41 size
42 } = ownerState;
43 const slots = {
44 root: ['root', expanded && 'expanded', focused && 'focused', fullWidth && 'fullWidth', hasClearIcon && 'hasClearIcon', hasPopupIcon && 'hasPopupIcon'],
45 inputRoot: ['inputRoot'],
46 input: ['input', inputFocused && 'inputFocused'],
47 tag: ['tag', `tagSize${capitalize(size)}`],
48 endAdornment: ['endAdornment'],
49 clearIndicator: ['clearIndicator'],
50 popupIndicator: ['popupIndicator', popupOpen && 'popupIndicatorOpen'],
51 popper: ['popper', disablePortal && 'popperDisablePortal'],
52 paper: ['paper'],
53 listbox: ['listbox'],
54 loading: ['loading'],
55 noOptions: ['noOptions'],
56 option: ['option'],
57 groupLabel: ['groupLabel'],
58 groupUl: ['groupUl']
59 };
60 return composeClasses(slots, getAutocompleteUtilityClass, classes);
61};
62const AutocompleteRoot = styled('div', {
63 name: 'MuiAutocomplete',
64 slot: 'Root',
65 overridesResolver: (props, styles) => {
66 const {
67 ownerState
68 } = props;
69 const {
70 fullWidth,
71 hasClearIcon,
72 hasPopupIcon,
73 inputFocused,
74 size
75 } = ownerState;
76 return [{
77 [`& .${autocompleteClasses.tag}`]: styles.tag
78 }, {
79 [`& .${autocompleteClasses.tag}`]: styles[`tagSize${capitalize(size)}`]
80 }, {
81 [`& .${autocompleteClasses.inputRoot}`]: styles.inputRoot
82 }, {
83 [`& .${autocompleteClasses.input}`]: styles.input
84 }, {
85 [`& .${autocompleteClasses.input}`]: inputFocused && styles.inputFocused
86 }, styles.root, fullWidth && styles.fullWidth, hasPopupIcon && styles.hasPopupIcon, hasClearIcon && styles.hasClearIcon];
87 }
88})({
89 [`&.${autocompleteClasses.focused} .${autocompleteClasses.clearIndicator}`]: {
90 visibility: 'visible'
91 },
92 /* Avoid double tap issue on iOS */
93 '@media (pointer: fine)': {
94 [`&:hover .${autocompleteClasses.clearIndicator}`]: {
95 visibility: 'visible'
96 }
97 },
98 [`& .${autocompleteClasses.tag}`]: {
99 margin: 3,
100 maxWidth: 'calc(100% - 6px)'
101 },
102 [`& .${autocompleteClasses.inputRoot}`]: {
103 [`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {
104 paddingRight: 26 + 4
105 },
106 [`.${autocompleteClasses.hasPopupIcon}.${autocompleteClasses.hasClearIcon}&`]: {
107 paddingRight: 52 + 4
108 },
109 [`& .${autocompleteClasses.input}`]: {
110 width: 0,
111 minWidth: 30
112 }
113 },
114 [`& .${inputClasses.root}`]: {
115 paddingBottom: 1,
116 '& .MuiInput-input': {
117 padding: '4px 4px 4px 0px'
118 }
119 },
120 [`& .${inputClasses.root}.${inputBaseClasses.sizeSmall}`]: {
121 [`& .${inputClasses.input}`]: {
122 padding: '2px 4px 3px 0'
123 }
124 },
125 [`& .${outlinedInputClasses.root}`]: {
126 padding: 9,
127 [`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {
128 paddingRight: 26 + 4 + 9
129 },
130 [`.${autocompleteClasses.hasPopupIcon}.${autocompleteClasses.hasClearIcon}&`]: {
131 paddingRight: 52 + 4 + 9
132 },
133 [`& .${autocompleteClasses.input}`]: {
134 padding: '7.5px 4px 7.5px 5px'
135 },
136 [`& .${autocompleteClasses.endAdornment}`]: {
137 right: 9
138 }
139 },
140 [`& .${outlinedInputClasses.root}.${inputBaseClasses.sizeSmall}`]: {
141 // Don't specify paddingRight, as it overrides the default value set when there is only
142 // one of the popup or clear icon as the specificity is equal so the latter one wins
143 paddingTop: 6,
144 paddingBottom: 6,
145 paddingLeft: 6,
146 [`& .${autocompleteClasses.input}`]: {
147 padding: '2.5px 4px 2.5px 8px'
148 }
149 },
150 [`& .${filledInputClasses.root}`]: {
151 paddingTop: 19,
152 paddingLeft: 8,
153 [`.${autocompleteClasses.hasPopupIcon}&, .${autocompleteClasses.hasClearIcon}&`]: {
154 paddingRight: 26 + 4 + 9
155 },
156 [`.${autocompleteClasses.hasPopupIcon}.${autocompleteClasses.hasClearIcon}&`]: {
157 paddingRight: 52 + 4 + 9
158 },
159 [`& .${filledInputClasses.input}`]: {
160 padding: '7px 4px'
161 },
162 [`& .${autocompleteClasses.endAdornment}`]: {
163 right: 9
164 }
165 },
166 [`& .${filledInputClasses.root}.${inputBaseClasses.sizeSmall}`]: {
167 paddingBottom: 1,
168 [`& .${filledInputClasses.input}`]: {
169 padding: '2.5px 4px'
170 }
171 },
172 [`& .${inputBaseClasses.hiddenLabel}`]: {
173 paddingTop: 8
174 },
175 [`& .${filledInputClasses.root}.${inputBaseClasses.hiddenLabel}`]: {
176 paddingTop: 0,
177 paddingBottom: 0,
178 [`& .${autocompleteClasses.input}`]: {
179 paddingTop: 16,
180 paddingBottom: 17
181 }
182 },
183 [`& .${filledInputClasses.root}.${inputBaseClasses.hiddenLabel}.${inputBaseClasses.sizeSmall}`]: {
184 [`& .${autocompleteClasses.input}`]: {
185 paddingTop: 8,
186 paddingBottom: 9
187 }
188 },
189 [`& .${autocompleteClasses.input}`]: {
190 flexGrow: 1,
191 textOverflow: 'ellipsis',
192 opacity: 0
193 },
194 variants: [{
195 props: {
196 fullWidth: true
197 },
198 style: {
199 width: '100%'
200 }
201 }, {
202 props: {
203 size: 'small'
204 },
205 style: {
206 [`& .${autocompleteClasses.tag}`]: {
207 margin: 2,
208 maxWidth: 'calc(100% - 4px)'
209 }
210 }
211 }, {
212 props: {
213 inputFocused: true
214 },
215 style: {
216 [`& .${autocompleteClasses.input}`]: {
217 opacity: 1
218 }
219 }
220 }, {
221 props: {
222 multiple: true
223 },
224 style: {
225 [`& .${autocompleteClasses.inputRoot}`]: {
226 flexWrap: 'wrap'
227 }
228 }
229 }]
230});
231const AutocompleteEndAdornment = styled('div', {
232 name: 'MuiAutocomplete',
233 slot: 'EndAdornment',
234 overridesResolver: (props, styles) => styles.endAdornment
235})({
236 // We use a position absolute to support wrapping tags.
237 position: 'absolute',
238 right: 0,
239 top: '50%',
240 transform: 'translate(0, -50%)'
241});
242const AutocompleteClearIndicator = styled(IconButton, {
243 name: 'MuiAutocomplete',
244 slot: 'ClearIndicator',
245 overridesResolver: (props, styles) => styles.clearIndicator
246})({
247 marginRight: -2,
248 padding: 4,
249 visibility: 'hidden'
250});
251const AutocompletePopupIndicator = styled(IconButton, {
252 name: 'MuiAutocomplete',
253 slot: 'PopupIndicator',
254 overridesResolver: (props, styles) => {
255 const {
256 ownerState
257 } = props;
258 return [styles.popupIndicator, ownerState.popupOpen && styles.popupIndicatorOpen];
259 }
260})({
261 padding: 2,
262 marginRight: -2,
263 variants: [{
264 props: {
265 popupOpen: true
266 },
267 style: {
268 transform: 'rotate(180deg)'
269 }
270 }]
271});
272const AutocompletePopper = styled(Popper, {
273 name: 'MuiAutocomplete',
274 slot: 'Popper',
275 overridesResolver: (props, styles) => {
276 const {
277 ownerState
278 } = props;
279 return [{
280 [`& .${autocompleteClasses.option}`]: styles.option
281 }, styles.popper, ownerState.disablePortal && styles.popperDisablePortal];
282 }
283})(memoTheme(({
284 theme
285}) => ({
286 zIndex: (theme.vars || theme).zIndex.modal,
287 variants: [{
288 props: {
289 disablePortal: true
290 },
291 style: {
292 position: 'absolute'
293 }
294 }]
295})));
296const AutocompletePaper = styled(Paper, {
297 name: 'MuiAutocomplete',
298 slot: 'Paper',
299 overridesResolver: (props, styles) => styles.paper
300})(memoTheme(({
301 theme
302}) => ({
303 ...theme.typography.body1,
304 overflow: 'auto'
305})));
306const AutocompleteLoading = styled('div', {
307 name: 'MuiAutocomplete',
308 slot: 'Loading',
309 overridesResolver: (props, styles) => styles.loading
310})(memoTheme(({
311 theme
312}) => ({
313 color: (theme.vars || theme).palette.text.secondary,
314 padding: '14px 16px'
315})));
316const AutocompleteNoOptions = styled('div', {
317 name: 'MuiAutocomplete',
318 slot: 'NoOptions',
319 overridesResolver: (props, styles) => styles.noOptions
320})(memoTheme(({
321 theme
322}) => ({
323 color: (theme.vars || theme).palette.text.secondary,
324 padding: '14px 16px'
325})));
326const AutocompleteListbox = styled('ul', {
327 name: 'MuiAutocomplete',
328 slot: 'Listbox',
329 overridesResolver: (props, styles) => styles.listbox
330})(memoTheme(({
331 theme
332}) => ({
333 listStyle: 'none',
334 margin: 0,
335 padding: '8px 0',
336 maxHeight: '40vh',
337 overflow: 'auto',
338 position: 'relative',
339 [`& .${autocompleteClasses.option}`]: {
340 minHeight: 48,
341 display: 'flex',
342 overflow: 'hidden',
343 justifyContent: 'flex-start',
344 alignItems: 'center',
345 cursor: 'pointer',
346 paddingTop: 6,
347 boxSizing: 'border-box',
348 outline: '0',
349 WebkitTapHighlightColor: 'transparent',
350 paddingBottom: 6,
351 paddingLeft: 16,
352 paddingRight: 16,
353 [theme.breakpoints.up('sm')]: {
354 minHeight: 'auto'
355 },
356 [`&.${autocompleteClasses.focused}`]: {
357 backgroundColor: (theme.vars || theme).palette.action.hover,
358 // Reset on touch devices, it doesn't add specificity
359 '@media (hover: none)': {
360 backgroundColor: 'transparent'
361 }
362 },
363 '&[aria-disabled="true"]': {
364 opacity: (theme.vars || theme).palette.action.disabledOpacity,
365 pointerEvents: 'none'
366 },
367 [`&.${autocompleteClasses.focusVisible}`]: {
368 backgroundColor: (theme.vars || theme).palette.action.focus
369 },
370 '&[aria-selected="true"]': {
371 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
372 [`&.${autocompleteClasses.focused}`]: {
373 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
374 // Reset on touch devices, it doesn't add specificity
375 '@media (hover: none)': {
376 backgroundColor: (theme.vars || theme).palette.action.selected
377 }
378 },
379 [`&.${autocompleteClasses.focusVisible}`]: {
380 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity)
381 }
382 }
383 }
384})));
385const AutocompleteGroupLabel = styled(ListSubheader, {
386 name: 'MuiAutocomplete',
387 slot: 'GroupLabel',
388 overridesResolver: (props, styles) => styles.groupLabel
389})(memoTheme(({
390 theme
391}) => ({
392 backgroundColor: (theme.vars || theme).palette.background.paper,
393 top: -8
394})));
395const AutocompleteGroupUl = styled('ul', {
396 name: 'MuiAutocomplete',
397 slot: 'GroupUl',
398 overridesResolver: (props, styles) => styles.groupUl
399})({
400 padding: 0,
401 [`& .${autocompleteClasses.option}`]: {
402 paddingLeft: 24
403 }
404});
405export { createFilterOptions };
406const Autocomplete = /*#__PURE__*/React.forwardRef(function Autocomplete(inProps, ref) {
407 const props = useDefaultProps({
408 props: inProps,
409 name: 'MuiAutocomplete'
410 });
411
412 /* eslint-disable @typescript-eslint/no-unused-vars */
413 const {
414 autoComplete = false,
415 autoHighlight = false,
416 autoSelect = false,
417 blurOnSelect = false,
418 ChipProps: ChipPropsProp,
419 className,
420 clearIcon = _ClearIcon || (_ClearIcon = /*#__PURE__*/_jsx(ClearIcon, {
421 fontSize: "small"
422 })),
423 clearOnBlur = !props.freeSolo,
424 clearOnEscape = false,
425 clearText = 'Clear',
426 closeText = 'Close',
427 componentsProps,
428 defaultValue = props.multiple ? [] : null,
429 disableClearable = false,
430 disableCloseOnSelect = false,
431 disabled = false,
432 disabledItemsFocusable = false,
433 disableListWrap = false,
434 disablePortal = false,
435 filterOptions,
436 filterSelectedOptions = false,
437 forcePopupIcon = 'auto',
438 freeSolo = false,
439 fullWidth = false,
440 getLimitTagsText = more => `+${more}`,
441 getOptionDisabled,
442 getOptionKey,
443 getOptionLabel: getOptionLabelProp,
444 isOptionEqualToValue,
445 groupBy,
446 handleHomeEndKeys = !props.freeSolo,
447 id: idProp,
448 includeInputInList = false,
449 inputValue: inputValueProp,
450 limitTags = -1,
451 ListboxComponent: ListboxComponentProp,
452 ListboxProps: ListboxPropsProp,
453 loading = false,
454 loadingText = 'Loading…',
455 multiple = false,
456 noOptionsText = 'No options',
457 onChange,
458 onClose,
459 onHighlightChange,
460 onInputChange,
461 onOpen,
462 open,
463 openOnFocus = false,
464 openText = 'Open',
465 options,
466 PaperComponent: PaperComponentProp,
467 PopperComponent: PopperComponentProp,
468 popupIcon = _ArrowDropDownIcon || (_ArrowDropDownIcon = /*#__PURE__*/_jsx(ArrowDropDownIcon, {})),
469 readOnly = false,
470 renderGroup: renderGroupProp,
471 renderInput,
472 renderOption: renderOptionProp,
473 renderTags,
474 selectOnFocus = !props.freeSolo,
475 size = 'medium',
476 slots = {},
477 slotProps = {},
478 value: valueProp,
479 ...other
480 } = props;
481 /* eslint-enable @typescript-eslint/no-unused-vars */
482
483 const {
484 getRootProps,
485 getInputProps,
486 getInputLabelProps,
487 getPopupIndicatorProps,
488 getClearProps,
489 getTagProps,
490 getListboxProps,
491 getOptionProps,
492 value,
493 dirty,
494 expanded,
495 id,
496 popupOpen,
497 focused,
498 focusedTag,
499 anchorEl,
500 setAnchorEl,
501 inputValue,
502 groupedOptions
503 } = useAutocomplete({
504 ...props,
505 componentName: 'Autocomplete'
506 });
507 const hasClearIcon = !disableClearable && !disabled && dirty && !readOnly;
508 const hasPopupIcon = (!freeSolo || forcePopupIcon === true) && forcePopupIcon !== false;
509 const {
510 onMouseDown: handleInputMouseDown
511 } = getInputProps();
512 const {
513 ref: listboxRef,
514 ...otherListboxProps
515 } = getListboxProps();
516 const defaultGetOptionLabel = option => option.label ?? option;
517 const getOptionLabel = getOptionLabelProp || defaultGetOptionLabel;
518
519 // If you modify this, make sure to keep the `AutocompleteOwnerState` type in sync.
520 const ownerState = {
521 ...props,
522 disablePortal,
523 expanded,
524 focused,
525 fullWidth,
526 getOptionLabel,
527 hasClearIcon,
528 hasPopupIcon,
529 inputFocused: focusedTag === -1,
530 popupOpen,
531 size
532 };
533 const classes = useUtilityClasses(ownerState);
534 const externalForwardedProps = {
535 slots: {
536 paper: PaperComponentProp,
537 popper: PopperComponentProp,
538 ...slots
539 },
540 slotProps: {
541 chip: ChipPropsProp,
542 listbox: ListboxPropsProp,
543 ...componentsProps,
544 ...slotProps
545 }
546 };
547 const [ListboxSlot, listboxProps] = useSlot('listbox', {
548 elementType: AutocompleteListbox,
549 externalForwardedProps,
550 ownerState,
551 className: classes.listbox,
552 additionalProps: otherListboxProps,
553 ref: listboxRef
554 });
555 const [PaperSlot, paperProps] = useSlot('paper', {
556 elementType: Paper,
557 externalForwardedProps,
558 ownerState,
559 className: classes.paper
560 });
561 const [PopperSlot, popperProps] = useSlot('popper', {
562 elementType: Popper,
563 externalForwardedProps,
564 ownerState,
565 className: classes.popper,
566 additionalProps: {
567 disablePortal,
568 style: {
569 width: anchorEl ? anchorEl.clientWidth : null
570 },
571 role: 'presentation',
572 anchorEl,
573 open: popupOpen
574 }
575 });
576 let startAdornment;
577 if (multiple && value.length > 0) {
578 const getCustomizedTagProps = params => ({
579 className: classes.tag,
580 disabled,
581 ...getTagProps(params)
582 });
583 if (renderTags) {
584 startAdornment = renderTags(value, getCustomizedTagProps, ownerState);
585 } else {
586 startAdornment = value.map((option, index) => {
587 const {
588 key,
589 ...customTagProps
590 } = getCustomizedTagProps({
591 index
592 });
593 return /*#__PURE__*/_jsx(Chip, {
594 label: getOptionLabel(option),
595 size: size,
596 ...customTagProps,
597 ...externalForwardedProps.slotProps.chip
598 }, key);
599 });
600 }
601 }
602 if (limitTags > -1 && Array.isArray(startAdornment)) {
603 const more = startAdornment.length - limitTags;
604 if (!focused && more > 0) {
605 startAdornment = startAdornment.splice(0, limitTags);
606 startAdornment.push(/*#__PURE__*/_jsx("span", {
607 className: classes.tag,
608 children: getLimitTagsText(more)
609 }, startAdornment.length));
610 }
611 }
612 const defaultRenderGroup = params => /*#__PURE__*/_jsxs("li", {
613 children: [/*#__PURE__*/_jsx(AutocompleteGroupLabel, {
614 className: classes.groupLabel,
615 ownerState: ownerState,
616 component: "div",
617 children: params.group
618 }), /*#__PURE__*/_jsx(AutocompleteGroupUl, {
619 className: classes.groupUl,
620 ownerState: ownerState,
621 children: params.children
622 })]
623 }, params.key);
624 const renderGroup = renderGroupProp || defaultRenderGroup;
625 const defaultRenderOption = (props2, option) => {
626 // Need to clearly apply key because of https://github.com/vercel/next.js/issues/55642
627 const {
628 key,
629 ...otherProps
630 } = props2;
631 return /*#__PURE__*/_jsx("li", {
632 ...otherProps,
633 children: getOptionLabel(option)
634 }, key);
635 };
636 const renderOption = renderOptionProp || defaultRenderOption;
637 const renderListOption = (option, index) => {
638 const optionProps = getOptionProps({
639 option,
640 index
641 });
642 return renderOption({
643 ...optionProps,
644 className: classes.option
645 }, option, {
646 selected: optionProps['aria-selected'],
647 index,
648 inputValue
649 }, ownerState);
650 };
651 const clearIndicatorSlotProps = externalForwardedProps.slotProps.clearIndicator;
652 const popupIndicatorSlotProps = externalForwardedProps.slotProps.popupIndicator;
653 return /*#__PURE__*/_jsxs(React.Fragment, {
654 children: [/*#__PURE__*/_jsx(AutocompleteRoot, {
655 ref: ref,
656 className: clsx(classes.root, className),
657 ownerState: ownerState,
658 ...getRootProps(other),
659 children: renderInput({
660 id,
661 disabled,
662 fullWidth: true,
663 size: size === 'small' ? 'small' : undefined,
664 InputLabelProps: getInputLabelProps(),
665 InputProps: {
666 ref: setAnchorEl,
667 className: classes.inputRoot,
668 startAdornment,
669 onMouseDown: event => {
670 if (event.target === event.currentTarget) {
671 handleInputMouseDown(event);
672 }
673 },
674 ...((hasClearIcon || hasPopupIcon) && {
675 endAdornment: /*#__PURE__*/_jsxs(AutocompleteEndAdornment, {
676 className: classes.endAdornment,
677 ownerState: ownerState,
678 children: [hasClearIcon ? /*#__PURE__*/_jsx(AutocompleteClearIndicator, {
679 ...getClearProps(),
680 "aria-label": clearText,
681 title: clearText,
682 ownerState: ownerState,
683 ...clearIndicatorSlotProps,
684 className: clsx(classes.clearIndicator, clearIndicatorSlotProps?.className),
685 children: clearIcon
686 }) : null, hasPopupIcon ? /*#__PURE__*/_jsx(AutocompletePopupIndicator, {
687 ...getPopupIndicatorProps(),
688 disabled: disabled,
689 "aria-label": popupOpen ? closeText : openText,
690 title: popupOpen ? closeText : openText,
691 ownerState: ownerState,
692 ...popupIndicatorSlotProps,
693 className: clsx(classes.popupIndicator, popupIndicatorSlotProps?.className),
694 children: popupIcon
695 }) : null]
696 })
697 })
698 },
699 inputProps: {
700 className: classes.input,
701 disabled,
702 readOnly,
703 ...getInputProps()
704 }
705 })
706 }), anchorEl ? /*#__PURE__*/_jsx(AutocompletePopper, {
707 as: PopperSlot,
708 ...popperProps,
709 children: /*#__PURE__*/_jsxs(AutocompletePaper, {
710 as: PaperSlot,
711 ...paperProps,
712 children: [loading && groupedOptions.length === 0 ? /*#__PURE__*/_jsx(AutocompleteLoading, {
713 className: classes.loading,
714 ownerState: ownerState,
715 children: loadingText
716 }) : null, groupedOptions.length === 0 && !freeSolo && !loading ? /*#__PURE__*/_jsx(AutocompleteNoOptions, {
717 className: classes.noOptions,
718 ownerState: ownerState,
719 role: "presentation",
720 onMouseDown: event => {
721 // Prevent input blur when interacting with the "no options" content
722 event.preventDefault();
723 },
724 children: noOptionsText
725 }) : null, groupedOptions.length > 0 ? /*#__PURE__*/_jsx(ListboxSlot, {
726 as: ListboxComponentProp,
727 ...listboxProps,
728 children: groupedOptions.map((option, index) => {
729 if (groupBy) {
730 return renderGroup({
731 key: option.key,
732 group: option.group,
733 children: option.options.map((option2, index2) => renderListOption(option2, option.index + index2))
734 });
735 }
736 return renderListOption(option, index);
737 })
738 }) : null]
739 })
740 }) : null]
741 });
742});
743process.env.NODE_ENV !== "production" ? Autocomplete.propTypes /* remove-proptypes */ = {
744 // ┌────────────────────────────── Warning ──────────────────────────────┐
745 // │ These PropTypes are generated from the TypeScript type definitions. │
746 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
747 // └─────────────────────────────────────────────────────────────────────┘
748 /**
749 * If `true`, the portion of the selected suggestion that the user hasn't typed,
750 * known as the completion string, appears inline after the input cursor in the textbox.
751 * The inline completion string is visually highlighted and has a selected state.
752 * @default false
753 */
754 autoComplete: PropTypes.bool,
755 /**
756 * If `true`, the first option is automatically highlighted.
757 * @default false
758 */
759 autoHighlight: PropTypes.bool,
760 /**
761 * If `true`, the selected option becomes the value of the input
762 * when the Autocomplete loses focus unless the user chooses
763 * a different option or changes the character string in the input.
764 *
765 * When using the `freeSolo` mode, the typed value will be the input value
766 * if the Autocomplete loses focus without highlighting an option.
767 * @default false
768 */
769 autoSelect: PropTypes.bool,
770 /**
771 * Control if the input should be blurred when an option is selected:
772 *
773 * - `false` the input is not blurred.
774 * - `true` the input is always blurred.
775 * - `touch` the input is blurred after a touch event.
776 * - `mouse` the input is blurred after a mouse event.
777 * @default false
778 */
779 blurOnSelect: PropTypes.oneOfType([PropTypes.oneOf(['mouse', 'touch']), PropTypes.bool]),
780 /**
781 * Props applied to the [`Chip`](https://mui.com/material-ui/api/chip/) element.
782 * @deprecated Use `slotProps.chip` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](/material-ui/migration/migrating-from-deprecated-apis/) for more details.
783 */
784 ChipProps: PropTypes.object,
785 /**
786 * Override or extend the styles applied to the component.
787 */
788 classes: PropTypes.object,
789 /**
790 * @ignore
791 */
792 className: PropTypes.string,
793 /**
794 * The icon to display in place of the default clear icon.
795 * @default <ClearIcon fontSize="small" />
796 */
797 clearIcon: PropTypes.node,
798 /**
799 * If `true`, the input's text is cleared on blur if no value is selected.
800 *
801 * Set it to `true` if you want to help the user enter a new value.
802 * Set it to `false` if you want to help the user resume their search.
803 * @default !props.freeSolo
804 */
805 clearOnBlur: PropTypes.bool,
806 /**
807 * If `true`, clear all values when the user presses escape and the popup is closed.
808 * @default false
809 */
810 clearOnEscape: PropTypes.bool,
811 /**
812 * Override the default text for the *clear* icon button.
813 *
814 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
815 * @default 'Clear'
816 */
817 clearText: PropTypes.string,
818 /**
819 * Override the default text for the *close popup* icon button.
820 *
821 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
822 * @default 'Close'
823 */
824 closeText: PropTypes.string,
825 /**
826 * The props used for each slot inside.
827 * @deprecated Use the `slotProps` prop instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
828 */
829 componentsProps: PropTypes.shape({
830 clearIndicator: PropTypes.object,
831 paper: PropTypes.object,
832 popper: PropTypes.object,
833 popupIndicator: PropTypes.object
834 }),
835 /**
836 * The default value. Use when the component is not controlled.
837 * @default props.multiple ? [] : null
838 */
839 defaultValue: chainPropTypes(PropTypes.any, props => {
840 if (props.multiple && props.defaultValue !== undefined && !Array.isArray(props.defaultValue)) {
841 return new Error(['MUI: The Autocomplete expects the `defaultValue` prop to be an array when `multiple={true}` or undefined.', `However, ${props.defaultValue} was provided.`].join('\n'));
842 }
843 return null;
844 }),
845 /**
846 * If `true`, the input can't be cleared.
847 * @default false
848 */
849 disableClearable: PropTypes.bool,
850 /**
851 * If `true`, the popup won't close when a value is selected.
852 * @default false
853 */
854 disableCloseOnSelect: PropTypes.bool,
855 /**
856 * If `true`, the component is disabled.
857 * @default false
858 */
859 disabled: PropTypes.bool,
860 /**
861 * If `true`, will allow focus on disabled items.
862 * @default false
863 */
864 disabledItemsFocusable: PropTypes.bool,
865 /**
866 * If `true`, the list box in the popup will not wrap focus.
867 * @default false
868 */
869 disableListWrap: PropTypes.bool,
870 /**
871 * If `true`, the `Popper` content will be under the DOM hierarchy of the parent component.
872 * @default false
873 */
874 disablePortal: PropTypes.bool,
875 /**
876 * A function that determines the filtered options to be rendered on search.
877 *
878 * @default createFilterOptions()
879 * @param {Value[]} options The options to render.
880 * @param {object} state The state of the component.
881 * @returns {Value[]}
882 */
883 filterOptions: PropTypes.func,
884 /**
885 * If `true`, hide the selected options from the list box.
886 * @default false
887 */
888 filterSelectedOptions: PropTypes.bool,
889 /**
890 * Force the visibility display of the popup icon.
891 * @default 'auto'
892 */
893 forcePopupIcon: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.bool]),
894 /**
895 * If `true`, the Autocomplete is free solo, meaning that the user input is not bound to provided options.
896 * @default false
897 */
898 freeSolo: PropTypes.bool,
899 /**
900 * If `true`, the input will take up the full width of its container.
901 * @default false
902 */
903 fullWidth: PropTypes.bool,
904 /**
905 * The label to display when the tags are truncated (`limitTags`).
906 *
907 * @param {number} more The number of truncated tags.
908 * @returns {ReactNode}
909 * @default (more) => `+${more}`
910 */
911 getLimitTagsText: PropTypes.func,
912 /**
913 * Used to determine the disabled state for a given option.
914 *
915 * @param {Value} option The option to test.
916 * @returns {boolean}
917 */
918 getOptionDisabled: PropTypes.func,
919 /**
920 * Used to determine the key for a given option.
921 * This can be useful when the labels of options are not unique (since labels are used as keys by default).
922 *
923 * @param {Value} option The option to get the key for.
924 * @returns {string | number}
925 */
926 getOptionKey: PropTypes.func,
927 /**
928 * Used to determine the string value for a given option.
929 * It's used to fill the input (and the list box options if `renderOption` is not provided).
930 *
931 * If used in free solo mode, it must accept both the type of the options and a string.
932 *
933 * @param {Value} option
934 * @returns {string}
935 * @default (option) => option.label ?? option
936 */
937 getOptionLabel: PropTypes.func,
938 /**
939 * If provided, the options will be grouped under the returned string.
940 * The groupBy value is also used as the text for group headings when `renderGroup` is not provided.
941 *
942 * @param {Value} option The Autocomplete option.
943 * @returns {string}
944 */
945 groupBy: PropTypes.func,
946 /**
947 * If `true`, the component handles the "Home" and "End" keys when the popup is open.
948 * It should move focus to the first option and last option, respectively.
949 * @default !props.freeSolo
950 */
951 handleHomeEndKeys: PropTypes.bool,
952 /**
953 * This prop is used to help implement the accessibility logic.
954 * If you don't provide an id it will fall back to a randomly generated one.
955 */
956 id: PropTypes.string,
957 /**
958 * If `true`, the highlight can move to the input.
959 * @default false
960 */
961 includeInputInList: PropTypes.bool,
962 /**
963 * The input value.
964 */
965 inputValue: PropTypes.string,
966 /**
967 * Used to determine if the option represents the given value.
968 * Uses strict equality by default.
969 * ⚠️ Both arguments need to be handled, an option can only match with one value.
970 *
971 * @param {Value} option The option to test.
972 * @param {Value} value The value to test against.
973 * @returns {boolean}
974 */
975 isOptionEqualToValue: PropTypes.func,
976 /**
977 * The maximum number of tags that will be visible when not focused.
978 * Set `-1` to disable the limit.
979 * @default -1
980 */
981 limitTags: integerPropType,
982 /**
983 * The component used to render the listbox.
984 * @default 'ul'
985 * @deprecated Use `slotProps.listbox.component` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](/material-ui/migration/migrating-from-deprecated-apis/) for more details.
986 */
987 ListboxComponent: PropTypes.elementType,
988 /**
989 * Props applied to the Listbox element.
990 * @deprecated Use `slotProps.listbox` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](/material-ui/migration/migrating-from-deprecated-apis/) for more details.
991 */
992 ListboxProps: PropTypes.object,
993 /**
994 * If `true`, the component is in a loading state.
995 * This shows the `loadingText` in place of suggestions (only if there are no suggestions to show, for example `options` are empty).
996 * @default false
997 */
998 loading: PropTypes.bool,
999 /**
1000 * Text to display when in a loading state.
1001 *
1002 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
1003 * @default 'Loading…'
1004 */
1005 loadingText: PropTypes.node,
1006 /**
1007 * If `true`, `value` must be an array and the menu will support multiple selections.
1008 * @default false
1009 */
1010 multiple: PropTypes.bool,
1011 /**
1012 * Text to display when there are no options.
1013 *
1014 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
1015 * @default 'No options'
1016 */
1017 noOptionsText: PropTypes.node,
1018 /**
1019 * Callback fired when the value changes.
1020 *
1021 * @param {React.SyntheticEvent} event The event source of the callback.
1022 * @param {Value|Value[]} value The new value of the component.
1023 * @param {string} reason One of "createOption", "selectOption", "removeOption", "blur" or "clear".
1024 * @param {string} [details]
1025 */
1026 onChange: PropTypes.func,
1027 /**
1028 * Callback fired when the popup requests to be closed.
1029 * Use in controlled mode (see open).
1030 *
1031 * @param {React.SyntheticEvent} event The event source of the callback.
1032 * @param {string} reason Can be: `"toggleInput"`, `"escape"`, `"selectOption"`, `"removeOption"`, `"blur"`.
1033 */
1034 onClose: PropTypes.func,
1035 /**
1036 * Callback fired when the highlight option changes.
1037 *
1038 * @param {React.SyntheticEvent} event The event source of the callback.
1039 * @param {Value} option The highlighted option.
1040 * @param {string} reason Can be: `"keyboard"`, `"auto"`, `"mouse"`, `"touch"`.
1041 */
1042 onHighlightChange: PropTypes.func,
1043 /**
1044 * Callback fired when the input value changes.
1045 *
1046 * @param {React.SyntheticEvent} event The event source of the callback.
1047 * @param {string} value The new value of the text input.
1048 * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`, `"blur"`, `"selectOption"`, `"removeOption"`
1049 */
1050 onInputChange: PropTypes.func,
1051 /**
1052 * @ignore
1053 */
1054 onKeyDown: PropTypes.func,
1055 /**
1056 * Callback fired when the popup requests to be opened.
1057 * Use in controlled mode (see open).
1058 *
1059 * @param {React.SyntheticEvent} event The event source of the callback.
1060 */
1061 onOpen: PropTypes.func,
1062 /**
1063 * If `true`, the component is shown.
1064 */
1065 open: PropTypes.bool,
1066 /**
1067 * If `true`, the popup will open on input focus.
1068 * @default false
1069 */
1070 openOnFocus: PropTypes.bool,
1071 /**
1072 * Override the default text for the *open popup* icon button.
1073 *
1074 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
1075 * @default 'Open'
1076 */
1077 openText: PropTypes.string,
1078 /**
1079 * A list of options that will be shown in the Autocomplete.
1080 */
1081 options: PropTypes.array.isRequired,
1082 /**
1083 * The component used to render the body of the popup.
1084 * @default Paper
1085 * @deprecated Use `slots.paper` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1086 */
1087 PaperComponent: PropTypes.elementType,
1088 /**
1089 * The component used to position the popup.
1090 * @default Popper
1091 * @deprecated Use `slots.popper` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](/material-ui/migration/migrating-from-deprecated-apis/) for more details.
1092 */
1093 PopperComponent: PropTypes.elementType,
1094 /**
1095 * The icon to display in place of the default popup icon.
1096 * @default <ArrowDropDownIcon />
1097 */
1098 popupIcon: PropTypes.node,
1099 /**
1100 * If `true`, the component becomes readonly. It is also supported for multiple tags where the tag cannot be deleted.
1101 * @default false
1102 */
1103 readOnly: PropTypes.bool,
1104 /**
1105 * Render the group.
1106 *
1107 * @param {AutocompleteRenderGroupParams} params The group to render.
1108 * @returns {ReactNode}
1109 */
1110 renderGroup: PropTypes.func,
1111 /**
1112 * Render the input.
1113 *
1114 * @param {object} params
1115 * @returns {ReactNode}
1116 */
1117 renderInput: PropTypes.func.isRequired,
1118 /**
1119 * Render the option, use `getOptionLabel` by default.
1120 *
1121 * @param {object} props The props to apply on the li element.
1122 * @param {Value} option The option to render.
1123 * @param {object} state The state of each option.
1124 * @param {object} ownerState The state of the Autocomplete component.
1125 * @returns {ReactNode}
1126 */
1127 renderOption: PropTypes.func,
1128 /**
1129 * Render the selected value.
1130 *
1131 * @param {Value[]} value The `value` provided to the component.
1132 * @param {function} getTagProps A tag props getter.
1133 * @param {object} ownerState The state of the Autocomplete component.
1134 * @returns {ReactNode}
1135 */
1136 renderTags: PropTypes.func,
1137 /**
1138 * If `true`, the input's text is selected on focus.
1139 * It helps the user clear the selected value.
1140 * @default !props.freeSolo
1141 */
1142 selectOnFocus: PropTypes.bool,
1143 /**
1144 * The size of the component.
1145 * @default 'medium'
1146 */
1147 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['small', 'medium']), PropTypes.string]),
1148 /**
1149 * The props used for each slot inside.
1150 * @default {}
1151 */
1152 slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
1153 chip: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1154 clearIndicator: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1155 listbox: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1156 paper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1157 popper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1158 popupIndicator: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
1159 }),
1160 /**
1161 * The components used for each slot inside.
1162 * @default {}
1163 */
1164 slots: PropTypes.shape({
1165 listbox: PropTypes.elementType,
1166 paper: PropTypes.elementType,
1167 popper: PropTypes.elementType
1168 }),
1169 /**
1170 * The system prop that allows defining system overrides as well as additional CSS styles.
1171 */
1172 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1173 /**
1174 * The value of the autocomplete.
1175 *
1176 * The value must have reference equality with the option in order to be selected.
1177 * You can customize the equality behavior with the `isOptionEqualToValue` prop.
1178 */
1179 value: chainPropTypes(PropTypes.any, props => {
1180 if (props.multiple && props.value !== undefined && !Array.isArray(props.value)) {
1181 return new Error(['MUI: The Autocomplete expects the `value` prop to be an array when `multiple={true}` or undefined.', `However, ${props.value} was provided.`].join('\n'));
1182 }
1183 return null;
1184 })
1185} : void 0;
1186export default Autocomplete;
\No newline at end of file