UNPKG

38.2 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: ({
255 ownerState
256 }, styles) => ({
257 ...styles.popupIndicator,
258 ...(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('div', {
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 const renderAutocompletePopperChildren = children => /*#__PURE__*/_jsx(AutocompletePopper, {
654 as: PopperSlot,
655 ...popperProps,
656 children: /*#__PURE__*/_jsx(AutocompletePaper, {
657 as: PaperSlot,
658 ...paperProps,
659 children: children
660 })
661 });
662 let autocompletePopper = null;
663 if (groupedOptions.length > 0) {
664 autocompletePopper = renderAutocompletePopperChildren(
665 /*#__PURE__*/
666 // TODO v7: remove `as` prop and move ListboxComponentProp to externalForwardedProps or remove ListboxComponentProp entirely
667 // https://github.com/mui/material-ui/pull/43994#issuecomment-2401945800
668 _jsx(ListboxSlot, {
669 as: ListboxComponentProp,
670 ...listboxProps,
671 children: groupedOptions.map((option, index) => {
672 if (groupBy) {
673 return renderGroup({
674 key: option.key,
675 group: option.group,
676 children: option.options.map((option2, index2) => renderListOption(option2, option.index + index2))
677 });
678 }
679 return renderListOption(option, index);
680 })
681 }));
682 } else if (loading && groupedOptions.length === 0) {
683 autocompletePopper = renderAutocompletePopperChildren(/*#__PURE__*/_jsx(AutocompleteLoading, {
684 className: classes.loading,
685 ownerState: ownerState,
686 children: loadingText
687 }));
688 } else if (groupedOptions.length === 0 && !freeSolo && !loading) {
689 autocompletePopper = renderAutocompletePopperChildren(/*#__PURE__*/_jsx(AutocompleteNoOptions, {
690 className: classes.noOptions,
691 ownerState: ownerState,
692 role: "presentation",
693 onMouseDown: event => {
694 // Prevent input blur when interacting with the "no options" content
695 event.preventDefault();
696 },
697 children: noOptionsText
698 }));
699 }
700 return /*#__PURE__*/_jsxs(React.Fragment, {
701 children: [/*#__PURE__*/_jsx(AutocompleteRoot, {
702 ref: ref,
703 className: clsx(classes.root, className),
704 ownerState: ownerState,
705 ...getRootProps(other),
706 children: renderInput({
707 id,
708 disabled,
709 fullWidth: true,
710 size: size === 'small' ? 'small' : undefined,
711 InputLabelProps: getInputLabelProps(),
712 InputProps: {
713 ref: setAnchorEl,
714 className: classes.inputRoot,
715 startAdornment,
716 onMouseDown: event => {
717 if (event.target === event.currentTarget) {
718 handleInputMouseDown(event);
719 }
720 },
721 ...((hasClearIcon || hasPopupIcon) && {
722 endAdornment: /*#__PURE__*/_jsxs(AutocompleteEndAdornment, {
723 className: classes.endAdornment,
724 ownerState: ownerState,
725 children: [hasClearIcon ? /*#__PURE__*/_jsx(AutocompleteClearIndicator, {
726 ...getClearProps(),
727 "aria-label": clearText,
728 title: clearText,
729 ownerState: ownerState,
730 ...clearIndicatorSlotProps,
731 className: clsx(classes.clearIndicator, clearIndicatorSlotProps?.className),
732 children: clearIcon
733 }) : null, hasPopupIcon ? /*#__PURE__*/_jsx(AutocompletePopupIndicator, {
734 ...getPopupIndicatorProps(),
735 disabled: disabled,
736 "aria-label": popupOpen ? closeText : openText,
737 title: popupOpen ? closeText : openText,
738 ownerState: ownerState,
739 ...popupIndicatorSlotProps,
740 className: clsx(classes.popupIndicator, popupIndicatorSlotProps?.className),
741 children: popupIcon
742 }) : null]
743 })
744 })
745 },
746 inputProps: {
747 className: classes.input,
748 disabled,
749 readOnly,
750 ...getInputProps()
751 }
752 })
753 }), anchorEl ? autocompletePopper : null]
754 });
755});
756process.env.NODE_ENV !== "production" ? Autocomplete.propTypes /* remove-proptypes */ = {
757 // ┌────────────────────────────── Warning ──────────────────────────────┐
758 // │ These PropTypes are generated from the TypeScript type definitions. │
759 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
760 // └─────────────────────────────────────────────────────────────────────┘
761 /**
762 * If `true`, the portion of the selected suggestion that the user hasn't typed,
763 * known as the completion string, appears inline after the input cursor in the textbox.
764 * The inline completion string is visually highlighted and has a selected state.
765 * @default false
766 */
767 autoComplete: PropTypes.bool,
768 /**
769 * If `true`, the first option is automatically highlighted.
770 * @default false
771 */
772 autoHighlight: PropTypes.bool,
773 /**
774 * If `true`, the selected option becomes the value of the input
775 * when the Autocomplete loses focus unless the user chooses
776 * a different option or changes the character string in the input.
777 *
778 * When using the `freeSolo` mode, the typed value will be the input value
779 * if the Autocomplete loses focus without highlighting an option.
780 * @default false
781 */
782 autoSelect: PropTypes.bool,
783 /**
784 * Control if the input should be blurred when an option is selected:
785 *
786 * - `false` the input is not blurred.
787 * - `true` the input is always blurred.
788 * - `touch` the input is blurred after a touch event.
789 * - `mouse` the input is blurred after a mouse event.
790 * @default false
791 */
792 blurOnSelect: PropTypes.oneOfType([PropTypes.oneOf(['mouse', 'touch']), PropTypes.bool]),
793 /**
794 * Props applied to the [`Chip`](https://mui.com/material-ui/api/chip/) element.
795 */
796 ChipProps: PropTypes.object,
797 /**
798 * Override or extend the styles applied to the component.
799 */
800 classes: PropTypes.object,
801 /**
802 * @ignore
803 */
804 className: PropTypes.string,
805 /**
806 * The icon to display in place of the default clear icon.
807 * @default <ClearIcon fontSize="small" />
808 */
809 clearIcon: PropTypes.node,
810 /**
811 * If `true`, the input's text is cleared on blur if no value is selected.
812 *
813 * Set it to `true` if you want to help the user enter a new value.
814 * Set it to `false` if you want to help the user resume their search.
815 * @default !props.freeSolo
816 */
817 clearOnBlur: PropTypes.bool,
818 /**
819 * If `true`, clear all values when the user presses escape and the popup is closed.
820 * @default false
821 */
822 clearOnEscape: PropTypes.bool,
823 /**
824 * Override the default text for the *clear* icon button.
825 *
826 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
827 * @default 'Clear'
828 */
829 clearText: PropTypes.string,
830 /**
831 * Override the default text for the *close popup* icon button.
832 *
833 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
834 * @default 'Close'
835 */
836 closeText: PropTypes.string,
837 /**
838 * The props used for each slot inside.
839 * @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.
840 */
841 componentsProps: PropTypes.shape({
842 clearIndicator: PropTypes.object,
843 paper: PropTypes.object,
844 popper: PropTypes.object,
845 popupIndicator: PropTypes.object
846 }),
847 /**
848 * The default value. Use when the component is not controlled.
849 * @default props.multiple ? [] : null
850 */
851 defaultValue: chainPropTypes(PropTypes.any, props => {
852 if (props.multiple && props.defaultValue !== undefined && !Array.isArray(props.defaultValue)) {
853 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'));
854 }
855 return null;
856 }),
857 /**
858 * If `true`, the input can't be cleared.
859 * @default false
860 */
861 disableClearable: PropTypes.bool,
862 /**
863 * If `true`, the popup won't close when a value is selected.
864 * @default false
865 */
866 disableCloseOnSelect: PropTypes.bool,
867 /**
868 * If `true`, the component is disabled.
869 * @default false
870 */
871 disabled: PropTypes.bool,
872 /**
873 * If `true`, will allow focus on disabled items.
874 * @default false
875 */
876 disabledItemsFocusable: PropTypes.bool,
877 /**
878 * If `true`, the list box in the popup will not wrap focus.
879 * @default false
880 */
881 disableListWrap: PropTypes.bool,
882 /**
883 * If `true`, the `Popper` content will be under the DOM hierarchy of the parent component.
884 * @default false
885 */
886 disablePortal: PropTypes.bool,
887 /**
888 * A function that determines the filtered options to be rendered on search.
889 *
890 * @default createFilterOptions()
891 * @param {Value[]} options The options to render.
892 * @param {object} state The state of the component.
893 * @returns {Value[]}
894 */
895 filterOptions: PropTypes.func,
896 /**
897 * If `true`, hide the selected options from the list box.
898 * @default false
899 */
900 filterSelectedOptions: PropTypes.bool,
901 /**
902 * Force the visibility display of the popup icon.
903 * @default 'auto'
904 */
905 forcePopupIcon: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.bool]),
906 /**
907 * If `true`, the Autocomplete is free solo, meaning that the user input is not bound to provided options.
908 * @default false
909 */
910 freeSolo: PropTypes.bool,
911 /**
912 * If `true`, the input will take up the full width of its container.
913 * @default false
914 */
915 fullWidth: PropTypes.bool,
916 /**
917 * The label to display when the tags are truncated (`limitTags`).
918 *
919 * @param {number} more The number of truncated tags.
920 * @returns {ReactNode}
921 * @default (more) => `+${more}`
922 */
923 getLimitTagsText: PropTypes.func,
924 /**
925 * Used to determine the disabled state for a given option.
926 *
927 * @param {Value} option The option to test.
928 * @returns {boolean}
929 */
930 getOptionDisabled: PropTypes.func,
931 /**
932 * Used to determine the key for a given option.
933 * This can be useful when the labels of options are not unique (since labels are used as keys by default).
934 *
935 * @param {Value} option The option to get the key for.
936 * @returns {string | number}
937 */
938 getOptionKey: PropTypes.func,
939 /**
940 * Used to determine the string value for a given option.
941 * It's used to fill the input (and the list box options if `renderOption` is not provided).
942 *
943 * If used in free solo mode, it must accept both the type of the options and a string.
944 *
945 * @param {Value} option
946 * @returns {string}
947 * @default (option) => option.label ?? option
948 */
949 getOptionLabel: PropTypes.func,
950 /**
951 * If provided, the options will be grouped under the returned string.
952 * The groupBy value is also used as the text for group headings when `renderGroup` is not provided.
953 *
954 * @param {Value} options The options to group.
955 * @returns {string}
956 */
957 groupBy: PropTypes.func,
958 /**
959 * If `true`, the component handles the "Home" and "End" keys when the popup is open.
960 * It should move focus to the first option and last option, respectively.
961 * @default !props.freeSolo
962 */
963 handleHomeEndKeys: PropTypes.bool,
964 /**
965 * This prop is used to help implement the accessibility logic.
966 * If you don't provide an id it will fall back to a randomly generated one.
967 */
968 id: PropTypes.string,
969 /**
970 * If `true`, the highlight can move to the input.
971 * @default false
972 */
973 includeInputInList: PropTypes.bool,
974 /**
975 * The input value.
976 */
977 inputValue: PropTypes.string,
978 /**
979 * Used to determine if the option represents the given value.
980 * Uses strict equality by default.
981 * ⚠️ Both arguments need to be handled, an option can only match with one value.
982 *
983 * @param {Value} option The option to test.
984 * @param {Value} value The value to test against.
985 * @returns {boolean}
986 */
987 isOptionEqualToValue: PropTypes.func,
988 /**
989 * The maximum number of tags that will be visible when not focused.
990 * Set `-1` to disable the limit.
991 * @default -1
992 */
993 limitTags: integerPropType,
994 /**
995 * The component used to render the listbox.
996 * @default 'ul'
997 */
998 ListboxComponent: PropTypes.elementType,
999 /**
1000 * Props applied to the Listbox element.
1001 */
1002 ListboxProps: PropTypes.object,
1003 /**
1004 * If `true`, the component is in a loading state.
1005 * This shows the `loadingText` in place of suggestions (only if there are no suggestions to show, for example `options` are empty).
1006 * @default false
1007 */
1008 loading: PropTypes.bool,
1009 /**
1010 * Text to display when in a loading state.
1011 *
1012 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
1013 * @default 'Loading…'
1014 */
1015 loadingText: PropTypes.node,
1016 /**
1017 * If `true`, `value` must be an array and the menu will support multiple selections.
1018 * @default false
1019 */
1020 multiple: PropTypes.bool,
1021 /**
1022 * Text to display when there are no options.
1023 *
1024 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
1025 * @default 'No options'
1026 */
1027 noOptionsText: PropTypes.node,
1028 /**
1029 * Callback fired when the value changes.
1030 *
1031 * @param {React.SyntheticEvent} event The event source of the callback.
1032 * @param {Value|Value[]} value The new value of the component.
1033 * @param {string} reason One of "createOption", "selectOption", "removeOption", "blur" or "clear".
1034 * @param {string} [details]
1035 */
1036 onChange: PropTypes.func,
1037 /**
1038 * Callback fired when the popup requests to be closed.
1039 * Use in controlled mode (see open).
1040 *
1041 * @param {React.SyntheticEvent} event The event source of the callback.
1042 * @param {string} reason Can be: `"toggleInput"`, `"escape"`, `"selectOption"`, `"removeOption"`, `"blur"`.
1043 */
1044 onClose: PropTypes.func,
1045 /**
1046 * Callback fired when the highlight option changes.
1047 *
1048 * @param {React.SyntheticEvent} event The event source of the callback.
1049 * @param {Value} option The highlighted option.
1050 * @param {string} reason Can be: `"keyboard"`, `"auto"`, `"mouse"`, `"touch"`.
1051 */
1052 onHighlightChange: PropTypes.func,
1053 /**
1054 * Callback fired when the input value changes.
1055 *
1056 * @param {React.SyntheticEvent} event The event source of the callback.
1057 * @param {string} value The new value of the text input.
1058 * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`, `"blur"`, `"selectOption"`, `"removeOption"`
1059 */
1060 onInputChange: PropTypes.func,
1061 /**
1062 * @ignore
1063 */
1064 onKeyDown: PropTypes.func,
1065 /**
1066 * Callback fired when the popup requests to be opened.
1067 * Use in controlled mode (see open).
1068 *
1069 * @param {React.SyntheticEvent} event The event source of the callback.
1070 */
1071 onOpen: PropTypes.func,
1072 /**
1073 * If `true`, the component is shown.
1074 */
1075 open: PropTypes.bool,
1076 /**
1077 * If `true`, the popup will open on input focus.
1078 * @default false
1079 */
1080 openOnFocus: PropTypes.bool,
1081 /**
1082 * Override the default text for the *open popup* icon button.
1083 *
1084 * For localization purposes, you can use the provided [translations](https://mui.com/material-ui/guides/localization/).
1085 * @default 'Open'
1086 */
1087 openText: PropTypes.string,
1088 /**
1089 * A list of options that will be shown in the Autocomplete.
1090 */
1091 options: PropTypes.array.isRequired,
1092 /**
1093 * The component used to render the body of the popup.
1094 * @default Paper
1095 */
1096 PaperComponent: PropTypes.elementType,
1097 /**
1098 * The component used to position the popup.
1099 * @default Popper
1100 */
1101 PopperComponent: PropTypes.elementType,
1102 /**
1103 * The icon to display in place of the default popup icon.
1104 * @default <ArrowDropDownIcon />
1105 */
1106 popupIcon: PropTypes.node,
1107 /**
1108 * If `true`, the component becomes readonly. It is also supported for multiple tags where the tag cannot be deleted.
1109 * @default false
1110 */
1111 readOnly: PropTypes.bool,
1112 /**
1113 * Render the group.
1114 *
1115 * @param {AutocompleteRenderGroupParams} params The group to render.
1116 * @returns {ReactNode}
1117 */
1118 renderGroup: PropTypes.func,
1119 /**
1120 * Render the input.
1121 *
1122 * @param {object} params
1123 * @returns {ReactNode}
1124 */
1125 renderInput: PropTypes.func.isRequired,
1126 /**
1127 * Render the option, use `getOptionLabel` by default.
1128 *
1129 * @param {object} props The props to apply on the li element.
1130 * @param {Value} option The option to render.
1131 * @param {object} state The state of each option.
1132 * @param {object} ownerState The state of the Autocomplete component.
1133 * @returns {ReactNode}
1134 */
1135 renderOption: PropTypes.func,
1136 /**
1137 * Render the selected value.
1138 *
1139 * @param {Value[]} value The `value` provided to the component.
1140 * @param {function} getTagProps A tag props getter.
1141 * @param {object} ownerState The state of the Autocomplete component.
1142 * @returns {ReactNode}
1143 */
1144 renderTags: PropTypes.func,
1145 /**
1146 * If `true`, the input's text is selected on focus.
1147 * It helps the user clear the selected value.
1148 * @default !props.freeSolo
1149 */
1150 selectOnFocus: PropTypes.bool,
1151 /**
1152 * The size of the component.
1153 * @default 'medium'
1154 */
1155 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['small', 'medium']), PropTypes.string]),
1156 /**
1157 * The props used for each slot inside.
1158 * @default {}
1159 */
1160 slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
1161 chip: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1162 clearIndicator: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1163 listbox: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1164 paper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1165 popper: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
1166 popupIndicator: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
1167 }),
1168 /**
1169 * The components used for each slot inside.
1170 * @default {}
1171 */
1172 slots: PropTypes.shape({
1173 listbox: PropTypes.elementType,
1174 paper: PropTypes.elementType,
1175 popper: PropTypes.elementType
1176 }),
1177 /**
1178 * The system prop that allows defining system overrides as well as additional CSS styles.
1179 */
1180 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
1181 /**
1182 * The value of the autocomplete.
1183 *
1184 * The value must have reference equality with the option in order to be selected.
1185 * You can customize the equality behavior with the `isOptionEqualToValue` prop.
1186 */
1187 value: chainPropTypes(PropTypes.any, props => {
1188 if (props.multiple && props.value !== undefined && !Array.isArray(props.value)) {
1189 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'));
1190 }
1191 return null;
1192 })
1193} : void 0;
1194export default Autocomplete;
\No newline at end of file