text: "use strict";
  
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = void 0;
  
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
  
  var _utils = require("@mui/utils");
  
  var React = _interopRequireWildcard(require("react"));
  
  var _reactIs = require("react-is");
  
  var _propTypes = _interopRequireDefault(require("prop-types"));
  
  var _clsx = _interopRequireDefault(require("clsx"));
  
  var _base = require("@mui/base");
  
  var _ownerDocument = _interopRequireDefault(require("../utils/ownerDocument"));
  
  var _capitalize = _interopRequireDefault(require("../utils/capitalize"));
  
  var _Menu = _interopRequireDefault(require("../Menu/Menu"));
  
  var _NativeSelectInput = require("../NativeSelect/NativeSelectInput");
  
  var _utils2 = require("../InputBase/utils");
  
  var _styled = _interopRequireWildcard(require("../styles/styled"));
  
  var _useForkRef = _interopRequireDefault(require("../utils/useForkRef"));
  
  var _useControlled = _interopRequireDefault(require("../utils/useControlled"));
  
  var _selectClasses = _interopRequireWildcard(require("./selectClasses"));
  
  var _jsxRuntime = require("react/jsx-runtime");
  
  var _span;
  
  const _excluded = ["aria-describedby", "aria-label", "autoFocus", "autoWidth", "children", "className", "defaultOpen", "defaultValue", "disabled", "displayEmpty", "IconComponent", "inputRef", "labelId", "MenuProps", "multiple", "name", "onBlur", "onChange", "onClose", "onFocus", "onOpen", "open", "readOnly", "renderValue", "SelectDisplayProps", "tabIndex", "type", "value", "variant"];
  
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  
  const SelectSelect = (0, _styled.default)('div', {
    name: 'MuiSelect',
    slot: 'Select',
    overridesResolver: (props, styles) => {
      const {
        ownerState
      } = props;
      return [// Win specificity over the input base
      {
        [`&.${_selectClasses.default.select}`]: styles.select
      }, {
        [`&.${_selectClasses.default.select}`]: styles[ownerState.variant]
      }, {
        [`&.${_selectClasses.default.multiple}`]: styles.multiple
      }];
    }
  })(_NativeSelectInput.nativeSelectSelectStyles, {
    // Win specificity over the input base
    [`&.${_selectClasses.default.select}`]: {
      height: 'auto',
      // Resets for multiple select with chips
      minHeight: '1.4375em',
      // Required for select\text-field height consistency
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap',
      overflow: 'hidden'
    }
  });
  const SelectIcon = (0, _styled.default)('svg', {
    name: 'MuiSelect',
    slot: 'Icon',
    overridesResolver: (props, styles) => {
      const {
        ownerState
      } = props;
      return [styles.icon, ownerState.variant && styles[`icon${(0, _capitalize.default)(ownerState.variant)}`], ownerState.open && styles.iconOpen];
    }
  })(_NativeSelectInput.nativeSelectIconStyles);
  const SelectNativeInput = (0, _styled.default)('input', {
    shouldForwardProp: prop => (0, _styled.slotShouldForwardProp)(prop) && prop !== 'classes',
    name: 'MuiSelect',
    slot: 'NativeInput',
    overridesResolver: (props, styles) => styles.nativeInput
  })({
    bottom: 0,
    left: 0,
    position: 'absolute',
    opacity: 0,
    pointerEvents: 'none',
    width: '100%',
    boxSizing: 'border-box'
  });
  
  function areEqualValues(a, b) {
    if (typeof b === 'object' && b !== null) {
      return a === b;
    } // The value could be a number, the DOM will stringify it anyway.
  
  
    return String(a) === String(b);
  }
  
  function isEmpty(display) {
    return display == null || typeof display === 'string' && !display.trim();
  }
  
  const useUtilityClasses = ownerState => {
    const {
      classes,
      variant,
      disabled,
      multiple,
      open
    } = ownerState;
    const slots = {
      select: ['select', variant, disabled && 'disabled', multiple && 'multiple'],
      icon: ['icon', `icon${(0, _capitalize.default)(variant)}`, open && 'iconOpen', disabled && 'disabled'],
      nativeInput: ['nativeInput']
    };
    return (0, _base.unstable_composeClasses)(slots, _selectClasses.getSelectUtilityClasses, classes);
  };
  /**
   * @ignore - internal component.
   */
  
  
  const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, ref) {
    const {
      'aria-describedby': ariaDescribedby,
      'aria-label': ariaLabel,
      autoFocus,
      autoWidth,
      children,
      className,
      defaultOpen,
      defaultValue,
      disabled,
      displayEmpty,
      IconComponent,
      inputRef: inputRefProp,
      labelId,
      MenuProps = {},
      multiple,
      name,
      onBlur,
      onChange,
      onClose,
      onFocus,
      onOpen,
      open: openProp,
      readOnly,
      renderValue,
      SelectDisplayProps = {},
      tabIndex: tabIndexProp,
      value: valueProp,
      variant = 'standard'
    } = props,
          other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
    const [value, setValueState] = (0, _useControlled.default)({
      controlled: valueProp,
      default: defaultValue,
      name: 'Select'
    });
    const [openState, setOpenState] = (0, _useControlled.default)({
      controlled: openProp,
      default: defaultOpen,
      name: 'Select'
    });
    const inputRef = React.useRef(null);
    const displayRef = React.useRef(null);
    const [displayNode, setDisplayNode] = React.useState(null);
    const {
      current: isOpenControlled
    } = React.useRef(openProp != null);
    const [menuMinWidthState, setMenuMinWidthState] = React.useState();
    const handleRef = (0, _useForkRef.default)(ref, inputRefProp);
    const handleDisplayRef = React.useCallback(node => {
      displayRef.current = node;
  
      if (node) {
        setDisplayNode(node);
      }
    }, []);
    React.useImperativeHandle(handleRef, () => ({
      focus: () => {
        displayRef.current.focus();
      },
      node: inputRef.current,
      value
    }), [value]); // Resize menu on `defaultOpen` automatic toggle.
  
    React.useEffect(() => {
      if (defaultOpen && openState && displayNode && !isOpenControlled) {
        setMenuMinWidthState(autoWidth ? null : displayNode.clientWidth);
        displayRef.current.focus();
      } // eslint-disable-next-line react-hooks/exhaustive-deps
  
    }, [displayNode, autoWidth]); // `isOpenControlled` is ignored because the component should never switch between controlled and uncontrolled modes.
    // `defaultOpen` and `openState` are ignored to avoid unnecessary callbacks.
  
    React.useEffect(() => {
      if (autoFocus) {
        displayRef.current.focus();
      }
    }, [autoFocus]);
    React.useEffect(() => {
      if (!labelId) {
        return undefined;
      }
  
      const label = (0, _ownerDocument.default)(displayRef.current).getElementById(labelId);
  
      if (label) {
        const handler = () => {
          if (getSelection().isCollapsed) {
            displayRef.current.focus();
          }
        };
  
        label.addEventListener('click', handler);
        return () => {
          label.removeEventListener('click', handler);
        };
      }
  
      return undefined;
    }, [labelId]);
  
    const update = (open, event) => {
      if (open) {
        if (onOpen) {
          onOpen(event);
        }
      } else if (onClose) {
        onClose(event);
      }
  
      if (!isOpenControlled) {
        setMenuMinWidthState(autoWidth ? null : displayNode.clientWidth);
        setOpenState(open);
      }
    };
  
    const handleMouseDown = event => {
      // Ignore everything but left-click
      if (event.button !== 0) {
        return;
      } // Hijack the default focus behavior.
  
  
      event.preventDefault();
      displayRef.current.focus();
      update(true, event);
    };
  
    const handleClose = event => {
      update(false, event);
    };
  
    const childrenArray = React.Children.toArray(children); // Support autofill.
  
    const handleChange = event => {
      const index = childrenArray.map(child => child.props.value).indexOf(event.target.value);
  
      if (index === -1) {
        return;
      }
  
      const child = childrenArray[index];
      setValueState(child.props.value);
  
      if (onChange) {
        onChange(event, child);
      }
    };
  
    const handleItemClick = child => event => {
      let newValue; // We use the tabindex attribute to signal the available options.
  
      if (!event.currentTarget.hasAttribute('tabindex')) {
        return;
      }
  
      if (multiple) {
        newValue = Array.isArray(value) ? value.slice() : [];
        const itemIndex = value.indexOf(child.props.value);
  
        if (itemIndex === -1) {
          newValue.push(child.props.value);
        } else {
          newValue.splice(itemIndex, 1);
        }
      } else {
        newValue = child.props.value;
      }
  
      if (child.props.onClick) {
        child.props.onClick(event);
      }
  
      if (value !== newValue) {
        setValueState(newValue);
  
        if (onChange) {
          // Redefine target to allow name and value to be read.
          // This allows seamless integration with the most popular form libraries.
          // https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
          // Clone the event to not override `target` of the original event.
          const nativeEvent = event.nativeEvent || event;
          const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
          Object.defineProperty(clonedEvent, 'target', {
            writable: true,
            value: {
              value: newValue,
              name
            }
          });
          onChange(clonedEvent, child);
        }
      }
  
      if (!multiple) {
        update(false, event);
      }
    };
  
    const handleKeyDown = event => {
      if (!readOnly) {
        const validKeys = [' ', 'ArrowUp', 'ArrowDown', // The native select doesn't respond to enter on MacOS, but it's recommended by
        // https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html
        'Enter'];
  
        if (validKeys.indexOf(event.key) !== -1) {
          event.preventDefault();
          update(true, event);
        }
      }
    };
  
    const open = displayNode !== null && openState;
  
    const handleBlur = event => {
      // if open event.stopImmediatePropagation
      if (!open && onBlur) {
        // Preact support, target is read only property on a native event.
        Object.defineProperty(event, 'target', {
          writable: true,
          value: {
            value,
            name
          }
        });
        onBlur(event);
      }
    };
  
    delete other['aria-invalid'];
    let display;
    let displaySingle;
    const displayMultiple = [];
    let computeDisplay = false;
    let foundMatch = false; // No need to display any value if the field is empty.
  
    if ((0, _utils2.isFilled)({
      value
    }) || displayEmpty) {
      if (renderValue) {
        display = renderValue(value);
      } else {
        computeDisplay = true;
      }
    }
  
    const items = childrenArray.map(child => {
      if (! /*#__PURE__*/React.isValidElement(child)) {
        return null;
      }
  
      if (process.env.NODE_ENV !== 'production') {
        if ((0, _reactIs.isFragment)(child)) {
          console.error(["MUI: The Select component doesn't accept a Fragment as a child.", 'Consider providing an array instead.'].join('\n'));
        }
      }
  
      let selected;
  
      if (multiple) {
        if (!Array.isArray(value)) {
          throw new Error(process.env.NODE_ENV !== "production" ? `MUI: The \`value\` prop must be an array when using the \`Select\` component with \`multiple\`.` : (0, _utils.formatMuiErrorMessage)(2));
        }
  
        selected = value.some(v => areEqualValues(v, child.props.value));
  
        if (selected && computeDisplay) {
          displayMultiple.push(child.props.children);
        }
      } else {
        selected = areEqualValues(value, child.props.value);
  
        if (selected && computeDisplay) {
          displaySingle = child.props.children;
        }
      }
  
      if (selected) {
        foundMatch = true;
      }
  
      return /*#__PURE__*/React.cloneElement(child, {
        'aria-selected': selected ? 'true' : 'false',
        onClick: handleItemClick(child),
        onKeyUp: event => {
          if (event.key === ' ') {
            // otherwise our MenuItems dispatches a click event
            // it's not behavior of the native <option> and causes
            // the select to close immediately since we open on space keydown
            event.preventDefault();
          }
  
          if (child.props.onKeyUp) {
            child.props.onKeyUp(event);
          }
        },
        role: 'option',
        selected,
        value: undefined,
        // The value is most likely not a valid HTML attribute.
        'data-value': child.props.value // Instead, we provide it as a data attribute.
  
      });
    });
  
    if (process.env.NODE_ENV !== 'production') {
      // eslint-disable-next-line react-hooks/rules-of-hooks
      React.useEffect(() => {
        if (!foundMatch && !multiple && value !== '') {
          const values = childrenArray.map(child => child.props.value);
          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'));
        }
      }, [foundMatch, childrenArray, multiple, name, value]);
    }
  
    if (computeDisplay) {
      if (multiple) {
        if (displayMultiple.length === 0) {
          display = null;
        } else {
          display = displayMultiple.reduce((output, child, index) => {
            output.push(child);
  
            if (index < displayMultiple.length - 1) {
              output.push(', ');
            }
  
            return output;
          }, []);
        }
      } else {
        display = displaySingle;
      }
    } // Avoid performing a layout computation in the render method.
  
  
    let menuMinWidth = menuMinWidthState;
  
    if (!autoWidth && isOpenControlled && displayNode) {
      menuMinWidth = displayNode.clientWidth;
    }
  
    let tabIndex;
  
    if (typeof tabIndexProp !== 'undefined') {
      tabIndex = tabIndexProp;
    } else {
      tabIndex = disabled ? null : 0;
    }
  
    const buttonId = SelectDisplayProps.id || (name ? `mui-component-select-${name}` : undefined);
    const ownerState = (0, _extends2.default)({}, props, {
      variant,
      value,
      open
    });
    const classes = useUtilityClasses(ownerState);
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)(React.Fragment, {
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SelectSelect, (0, _extends2.default)({
        ref: handleDisplayRef,
        tabIndex: tabIndex,
        role: "button",
        "aria-disabled": disabled ? 'true' : undefined,
        "aria-expanded": open ? 'true' : 'false',
        "aria-haspopup": "listbox",
        "aria-label": ariaLabel,
        "aria-labelledby": [labelId, buttonId].filter(Boolean).join(' ') || undefined,
        "aria-describedby": ariaDescribedby,
        onKeyDown: handleKeyDown,
        onMouseDown: disabled || readOnly ? null : handleMouseDown,
        onBlur: handleBlur,
        onFocus: onFocus
      }, SelectDisplayProps, {
        ownerState: ownerState,
        className: (0, _clsx.default)(classes.select, className, SelectDisplayProps.className) // The id is required for proper a11y
        ,
        id: buttonId,
        children: isEmpty(display) ? // notranslate needed while Google Translate will not fix zero-width space issue
        _span || (_span = /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
          className: "notranslate",
          children: "\u200B"
        })) : display
      })), /*#__PURE__*/(0, _jsxRuntime.jsx)(SelectNativeInput, (0, _extends2.default)({
        value: Array.isArray(value) ? value.join(',') : value,
        name: name,
        ref: inputRef,
        "aria-hidden": true,
        onChange: handleChange,
        tabIndex: -1,
        disabled: disabled,
        className: classes.nativeInput,
        autoFocus: autoFocus,
        ownerState: ownerState
      }, other)), /*#__PURE__*/(0, _jsxRuntime.jsx)(SelectIcon, {
        as: IconComponent,
        className: classes.icon,
        ownerState: ownerState
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Menu.default, (0, _extends2.default)({
        id: `menu-${name || ''}`,
        anchorEl: displayNode,
        open: open,
        onClose: handleClose,
        anchorOrigin: {
          vertical: 'bottom',
          horizontal: 'center'
        },
        transformOrigin: {
          vertical: 'top',
          horizontal: 'center'
        }
      }, MenuProps, {
        MenuListProps: (0, _extends2.default)({
          'aria-labelledby': labelId,
          role: 'listbox',
          disableListWrap: true
        }, MenuProps.MenuListProps),
        PaperProps: (0, _extends2.default)({}, MenuProps.PaperProps, {
          style: (0, _extends2.default)({
            minWidth: menuMinWidth
          }, MenuProps.PaperProps != null ? MenuProps.PaperProps.style : null)
        }),
        children: items
      }))]
    });
  });
  process.env.NODE_ENV !== "production" ? SelectInput.propTypes = {
    /**
     * @ignore
     */
    'aria-describedby': _propTypes.default.string,
  
    /**
     * @ignore
     */
    'aria-label': _propTypes.default.string,
  
    /**
     * @ignore
     */
    autoFocus: _propTypes.default.bool,
  
    /**
     * If `true`, the width of the popover will automatically be set according to the items inside the
     * menu, otherwise it will be at least the width of the select input.
     */
    autoWidth: _propTypes.default.bool,
  
    /**
     * The option elements to populate the select with.
     * Can be some `<MenuItem>` elements.
     */
    children: _propTypes.default.node,
  
    /**
     * Override or extend the styles applied to the component.
     * See [CSS API](#css) below for more details.
     */
    classes: _propTypes.default.object,
  
    /**
     * The CSS class name of the select element.
     */
    className: _propTypes.default.string,
  
    /**
     * If `true`, the component is toggled on mount. Use when the component open state is not controlled.
     * You can only use it when the `native` prop is `false` (default).
     */
    defaultOpen: _propTypes.default.bool,
  
    /**
     * The default value. Use when the component is not controlled.
     */
    defaultValue: _propTypes.default.any,
  
    /**
     * If `true`, the select is disabled.
     */
    disabled: _propTypes.default.bool,
  
    /**
     * If `true`, the selected item is displayed even if its value is empty.
     */
    displayEmpty: _propTypes.default.bool,
  
    /**
     * The icon that displays the arrow.
     */
    IconComponent: _propTypes.default.elementType.isRequired,
  
    /**
     * Imperative handle implementing `{ value: T, node: HTMLElement, focus(): void }`
     * Equivalent to `ref`
     */
    inputRef: _utils.refType,
  
    /**
     * The ID of an element that acts as an additional label. The Select will
     * be labelled by the additional label and the selected value.
     */
    labelId: _propTypes.default.string,
  
    /**
     * Props applied to the [`Menu`](/api/menu/) element.
     */
    MenuProps: _propTypes.default.object,
  
    /**
     * If `true`, `value` must be an array and the menu will support multiple selections.
     */
    multiple: _propTypes.default.bool,
  
    /**
     * Name attribute of the `select` or hidden `input` element.
     */
    name: _propTypes.default.string,
  
    /**
     * @ignore
     */
    onBlur: _propTypes.default.func,
  
    /**
     * Callback fired when a menu item is selected.
     *
     * @param {object} event The event source of the callback.
     * You can pull out the new value by accessing `event.target.value` (any).
     * @param {object} [child] The react element that was selected.
     */
    onChange: _propTypes.default.func,
  
    /**
     * Callback fired when the component requests to be closed.
     * Use in controlled mode (see open).
     *
     * @param {object} event The event source of the callback.
     */
    onClose: _propTypes.default.func,
  
    /**
     * @ignore
     */
    onFocus: _propTypes.default.func,
  
    /**
     * Callback fired when the component requests to be opened.
     * Use in controlled mode (see open).
     *
     * @param {object} event The event source of the callback.
     */
    onOpen: _propTypes.default.func,
  
    /**
     * If `true`, the component is shown.
     */
    open: _propTypes.default.bool,
  
    /**
     * @ignore
     */
    readOnly: _propTypes.default.bool,
  
    /**
     * Render the selected value.
     *
     * @param {any} value The `value` provided to the component.
     * @returns {ReactNode}
     */
    renderValue: _propTypes.default.func,
  
    /**
     * Props applied to the clickable div element.
     */
    SelectDisplayProps: _propTypes.default.object,
  
    /**
     * @ignore
     */
    tabIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
  
    /**
     * @ignore
     */
    type: _propTypes.default.any,
  
    /**
     * The input value.
     */
    value: _propTypes.default.any,
  
    /**
     * The variant to use.
     */
    variant: _propTypes.default.oneOf(['standard', 'outlined', 'filled'])
  } : void 0;
  var _default = SelectInput;
  exports.default = _default;