import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * To match accessibility requirement, we always provide an input in the component. * Other element will not set `tabIndex` to avoid `onBlur` sequence problem. * For focused select, we set `aria-live="polite"` to update the accessibility content. * * ref: * - keyboard: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role#Keyboard_interactions */ import * as React from 'react'; import { useState, useRef, useEffect, useMemo } from 'react'; import KeyCode from "rc-util/es/KeyCode"; import classNames from 'classnames'; import useMergedState from "rc-util/es/hooks/useMergedState"; import Selector from './Selector'; import SelectTrigger from './SelectTrigger'; import { INTERNAL_PROPS_MARK } from './interface/generator'; import { toInnerValue, toOuterValues, removeLastEnabledValue, getUUID } from './utils/commonUtil'; import TransBtn from './TransBtn'; import useLock from './hooks/useLock'; import useDelayReset from './hooks/useDelayReset'; import useLayoutEffect from './hooks/useLayoutEffect'; import { getSeparatedContent } from './utils/valueUtil'; import useSelectTriggerControl from './hooks/useSelectTriggerControl'; import useCacheDisplayValue from './hooks/useCacheDisplayValue'; import useCacheOptions from './hooks/useCacheOptions'; var DEFAULT_OMIT_PROPS = ['removeIcon', 'placeholder', 'autoFocus', 'maxTagCount', 'maxTagTextLength', 'maxTagPlaceholder', 'choiceTransitionName', 'onInputKeyDown']; /** * This function is in internal usage. * Do not use it in your prod env since we may refactor this. */ export default function generateSelector(config) { var defaultPrefixCls = config.prefixCls, OptionList = config.components.optionList, convertChildrenToData = config.convertChildrenToData, flattenOptions = config.flattenOptions, getLabeledValue = config.getLabeledValue, filterOptions = config.filterOptions, isValueDisabled = config.isValueDisabled, findValueOption = config.findValueOption, warningProps = config.warningProps, fillOptionsWithMissingValue = config.fillOptionsWithMissingValue, omitDOMProps = config.omitDOMProps; // Use raw define since `React.FC` not support generic function Select(props, ref) { var _classNames2; var _props$prefixCls = props.prefixCls, prefixCls = _props$prefixCls === void 0 ? defaultPrefixCls : _props$prefixCls, className = props.className, id = props.id, open = props.open, defaultOpen = props.defaultOpen, options = props.options, children = props.children, mode = props.mode, value = props.value, defaultValue = props.defaultValue, labelInValue = props.labelInValue, showSearch = props.showSearch, inputValue = props.inputValue, searchValue = props.searchValue, filterOption = props.filterOption, _props$optionFilterPr = props.optionFilterProp, optionFilterProp = _props$optionFilterPr === void 0 ? 'value' : _props$optionFilterPr, _props$autoClearSearc = props.autoClearSearchValue, autoClearSearchValue = _props$autoClearSearc === void 0 ? true : _props$autoClearSearc, onSearch = props.onSearch, allowClear = props.allowClear, clearIcon = props.clearIcon, showArrow = props.showArrow, inputIcon = props.inputIcon, menuItemSelectedIcon = props.menuItemSelectedIcon, disabled = props.disabled, loading = props.loading, defaultActiveFirstOption = props.defaultActiveFirstOption, _props$notFoundConten = props.notFoundContent, notFoundContent = _props$notFoundConten === void 0 ? 'Not Found' : _props$notFoundConten, optionLabelProp = props.optionLabelProp, backfill = props.backfill, getInputElement = props.getInputElement, getPopupContainer = props.getPopupContainer, _props$listHeight = props.listHeight, listHeight = _props$listHeight === void 0 ? 200 : _props$listHeight, _props$listItemHeight = props.listItemHeight, listItemHeight = _props$listItemHeight === void 0 ? 20 : _props$listItemHeight, animation = props.animation, transitionName = props.transitionName, virtual = props.virtual, dropdownStyle = props.dropdownStyle, dropdownClassName = props.dropdownClassName, dropdownMatchSelectWidth = props.dropdownMatchSelectWidth, dropdownRender = props.dropdownRender, dropdownAlign = props.dropdownAlign, _props$showAction = props.showAction, showAction = _props$showAction === void 0 ? [] : _props$showAction, direction = props.direction, tokenSeparators = props.tokenSeparators, tagRender = props.tagRender, onPopupScroll = props.onPopupScroll, onDropdownVisibleChange = props.onDropdownVisibleChange, onFocus = props.onFocus, onBlur = props.onBlur, onKeyUp = props.onKeyUp, onKeyDown = props.onKeyDown, onMouseDown = props.onMouseDown, onChange = props.onChange, onSelect = props.onSelect, onDeselect = props.onDeselect, _props$internalProps = props.internalProps, internalProps = _props$internalProps === void 0 ? {} : _props$internalProps, restProps = _objectWithoutProperties(props, ["prefixCls", "className", "id", "open", "defaultOpen", "options", "children", "mode", "value", "defaultValue", "labelInValue", "showSearch", "inputValue", "searchValue", "filterOption", "optionFilterProp", "autoClearSearchValue", "onSearch", "allowClear", "clearIcon", "showArrow", "inputIcon", "menuItemSelectedIcon", "disabled", "loading", "defaultActiveFirstOption", "notFoundContent", "optionLabelProp", "backfill", "getInputElement", "getPopupContainer", "listHeight", "listItemHeight", "animation", "transitionName", "virtual", "dropdownStyle", "dropdownClassName", "dropdownMatchSelectWidth", "dropdownRender", "dropdownAlign", "showAction", "direction", "tokenSeparators", "tagRender", "onPopupScroll", "onDropdownVisibleChange", "onFocus", "onBlur", "onKeyUp", "onKeyDown", "onMouseDown", "onChange", "onSelect", "onDeselect", "internalProps"]); var useInternalProps = internalProps.mark === INTERNAL_PROPS_MARK; var domProps = omitDOMProps ? omitDOMProps(restProps) : restProps; DEFAULT_OMIT_PROPS.forEach(function (prop) { delete domProps[prop]; }); var containerRef = useRef(null); var triggerRef = useRef(null); var selectorRef = useRef(null); var listRef = useRef(null); var tokenWithEnter = useMemo(function () { return (tokenSeparators || []).some(function (tokenSeparator) { return ['\n', '\r\n'].includes(tokenSeparator); }); }, [tokenSeparators]); /** Used for component focused management */ var _useDelayReset = useDelayReset(), _useDelayReset2 = _slicedToArray(_useDelayReset, 3), mockFocused = _useDelayReset2[0], setMockFocused = _useDelayReset2[1], cancelSetMockFocused = _useDelayReset2[2]; // Inner id for accessibility usage. Only work in client side var _useState = useState(), _useState2 = _slicedToArray(_useState, 2), innerId = _useState2[0], setInnerId = _useState2[1]; useEffect(function () { setInnerId("rc_select_".concat(getUUID())); }, []); var mergedId = id || innerId; // optionLabelProp var mergedOptionLabelProp = optionLabelProp; if (mergedOptionLabelProp === undefined) { mergedOptionLabelProp = options ? 'label' : 'children'; } // labelInValue var mergedLabelInValue = mode === 'combobox' ? false : labelInValue; var isMultiple = mode === 'tags' || mode === 'multiple'; var mergedShowSearch = showSearch !== undefined ? showSearch : isMultiple || mode === 'combobox'; // ============================== Ref =============================== var selectorDomRef = useRef(null); React.useImperativeHandle(ref, function () { return { focus: selectorRef.current.focus, blur: selectorRef.current.blur }; }); // ============================= Value ============================== var _useMergedState = useMergedState(defaultValue, { value: value }), _useMergedState2 = _slicedToArray(_useMergedState, 2), mergedValue = _useMergedState2[0], setMergedValue = _useMergedState2[1]; /** Unique raw values */ var mergedRawValue = useMemo(function () { return toInnerValue(mergedValue, { labelInValue: mergedLabelInValue, combobox: mode === 'combobox' }); }, [mergedValue, mergedLabelInValue]); /** We cache a set of raw values to speed up check */ var rawValues = useMemo(function () { return new Set(mergedRawValue); }, [mergedRawValue]); // ============================= Option ============================= // Set by option list active, it will merge into search input when mode is `combobox` var _useState3 = useState(null), _useState4 = _slicedToArray(_useState3, 2), activeValue = _useState4[0], setActiveValue = _useState4[1]; var _useState5 = useState(''), _useState6 = _slicedToArray(_useState5, 2), innerSearchValue = _useState6[0], setInnerSearchValue = _useState6[1]; var mergedSearchValue = innerSearchValue; if (mode === 'combobox' && mergedValue !== undefined) { mergedSearchValue = mergedValue; } else if (searchValue !== undefined) { mergedSearchValue = searchValue; } else if (inputValue) { mergedSearchValue = inputValue; } var mergedOptions = useMemo(function () { var newOptions = options; if (newOptions === undefined) { newOptions = convertChildrenToData(children); } /** * `tags` should fill un-list item. * This is not cool here since TreeSelect do not need this */ if (mode === 'tags' && fillOptionsWithMissingValue) { newOptions = fillOptionsWithMissingValue(newOptions, mergedValue, mergedOptionLabelProp, labelInValue); } return newOptions || []; }, [options, children, mode, mergedValue]); var mergedFlattenOptions = useMemo(function () { return flattenOptions(mergedOptions, props); }, [mergedOptions]); var getValueOption = useCacheOptions(mergedRawValue, mergedFlattenOptions); // Display options for OptionList var displayOptions = useMemo(function () { if (!mergedSearchValue || !mergedShowSearch) { return _toConsumableArray(mergedOptions); } var filteredOptions = filterOptions(mergedSearchValue, mergedOptions, { optionFilterProp: optionFilterProp, filterOption: mode === 'combobox' && filterOption === undefined ? function () { return true; } : filterOption }); if (mode === 'tags' && filteredOptions.every(function (opt) { return opt.value !== mergedSearchValue; })) { filteredOptions.unshift({ value: mergedSearchValue, label: mergedSearchValue, key: '__RC_SELECT_TAG_PLACEHOLDER__' }); } return filteredOptions; }, [mergedOptions, mergedSearchValue, mode, mergedShowSearch]); var displayFlattenOptions = useMemo(function () { return flattenOptions(displayOptions, props); }, [displayOptions]); useEffect(function () { if (listRef.current && listRef.current.scrollTo) { listRef.current.scrollTo(0); } }, [mergedSearchValue]); // ============================ Selector ============================ var displayValues = useMemo(function () { var tmpValues = mergedRawValue.map(function (val) { var valueOptions = getValueOption([val]); var displayValue = getLabeledValue(val, { options: valueOptions, prevValue: mergedValue, labelInValue: mergedLabelInValue, optionLabelProp: mergedOptionLabelProp }); return _objectSpread(_objectSpread({}, displayValue), {}, { disabled: isValueDisabled(val, valueOptions) }); }); if (!mode && tmpValues.length === 1 && tmpValues[0].value === null && tmpValues[0].label === null) { return []; } return tmpValues; }, [mergedValue, mergedOptions, mode]); // Polyfill with cache label displayValues = useCacheDisplayValue(displayValues); var triggerSelect = function triggerSelect(newValue, isSelect, source) { var newValueOption = getValueOption([newValue]); var outOption = findValueOption([newValue], newValueOption)[0]; if (!internalProps.skipTriggerSelect) { // Skip trigger `onSelect` or `onDeselect` if configured var selectValue = mergedLabelInValue ? getLabeledValue(newValue, { options: newValueOption, prevValue: mergedValue, labelInValue: mergedLabelInValue, optionLabelProp: mergedOptionLabelProp }) : newValue; if (isSelect && onSelect) { onSelect(selectValue, outOption); } else if (!isSelect && onDeselect) { onDeselect(selectValue, outOption); } } // Trigger internal event if (useInternalProps) { if (isSelect && internalProps.onRawSelect) { internalProps.onRawSelect(newValue, outOption, source); } else if (!isSelect && internalProps.onRawDeselect) { internalProps.onRawDeselect(newValue, outOption, source); } } }; // We need cache options here in case user update the option list var _useState7 = useState([]), _useState8 = _slicedToArray(_useState7, 2), prevValueOptions = _useState8[0], setPrevValueOptions = _useState8[1]; var triggerChange = function triggerChange(newRawValues) { if (useInternalProps && internalProps.skipTriggerChange) { return; } var newRawValuesOptions = getValueOption(newRawValues); var outValues = toOuterValues(Array.from(newRawValues), { labelInValue: mergedLabelInValue, options: newRawValuesOptions, getLabeledValue: getLabeledValue, prevValue: mergedValue, optionLabelProp: mergedOptionLabelProp }); var outValue = isMultiple ? outValues : outValues[0]; // Skip trigger if prev & current value is both empty if (onChange && (mergedRawValue.length !== 0 || outValues.length !== 0)) { var outOptions = findValueOption(newRawValues, newRawValuesOptions, { prevValueOptions: prevValueOptions }); // We will cache option in case it removed by ajax setPrevValueOptions(outOptions.map(function (option, index) { var clone = _objectSpread({}, option); Object.defineProperty(clone, '_INTERNAL_OPTION_VALUE_', { get: function get() { return newRawValues[index]; } }); return clone; })); onChange(outValue, isMultiple ? outOptions : outOptions[0]); } setMergedValue(outValue); }; var onInternalSelect = function onInternalSelect(newValue, _ref) { var selected = _ref.selected, source = _ref.source; if (disabled) { return; } var newRawValue; if (isMultiple) { newRawValue = new Set(mergedRawValue); if (selected) { newRawValue.add(newValue); } else { newRawValue.delete(newValue); } } else { newRawValue = new Set(); newRawValue.add(newValue); } // Multiple always trigger change and single should change if value changed if (isMultiple || !isMultiple && Array.from(mergedRawValue)[0] !== newValue) { triggerChange(Array.from(newRawValue)); } // Trigger `onSelect`. Single mode always trigger select triggerSelect(newValue, !isMultiple || selected, source); // Clean search value if single or configured if (mode === 'combobox') { setInnerSearchValue(String(newValue)); setActiveValue(''); } else if (!isMultiple || autoClearSearchValue) { setInnerSearchValue(''); setActiveValue(''); } }; var onInternalOptionSelect = function onInternalOptionSelect(newValue, info) { onInternalSelect(newValue, _objectSpread(_objectSpread({}, info), {}, { source: 'option' })); }; var onInternalSelectionSelect = function onInternalSelectionSelect(newValue, info) { onInternalSelect(newValue, _objectSpread(_objectSpread({}, info), {}, { source: 'selection' })); }; // ============================= Input ============================== // Only works in `combobox` var customizeInputElement = mode === 'combobox' && getInputElement && getInputElement() || null; // ============================== Open ============================== var _useMergedState3 = useMergedState(undefined, { defaultValue: defaultOpen, value: open }), _useMergedState4 = _slicedToArray(_useMergedState3, 2), innerOpen = _useMergedState4[0], setInnerOpen = _useMergedState4[1]; var mergedOpen = innerOpen; // Not trigger `open` in `combobox` when `notFoundContent` is empty var emptyListContent = !notFoundContent && !displayOptions.length; if (disabled || emptyListContent && mergedOpen && mode === 'combobox') { mergedOpen = false; } var triggerOpen = emptyListContent ? false : mergedOpen; var onToggleOpen = function onToggleOpen(newOpen) { var nextOpen = newOpen !== undefined ? newOpen : !mergedOpen; if (innerOpen !== nextOpen && !disabled) { setInnerOpen(nextOpen); if (onDropdownVisibleChange) { onDropdownVisibleChange(nextOpen); } } }; useSelectTriggerControl([containerRef.current, triggerRef.current && triggerRef.current.getPopupElement()], triggerOpen, onToggleOpen); // ============================= Search ============================= var triggerSearch = function triggerSearch(searchText, fromTyping, isCompositing) { var ret = true; var newSearchText = searchText; setActiveValue(null); // Check if match the `tokenSeparators` var patchLabels = isCompositing ? null : getSeparatedContent(searchText, tokenSeparators); var patchRawValues = patchLabels; if (mode === 'combobox') { // Only typing will trigger onChange if (fromTyping) { triggerChange([newSearchText]); } } else if (patchLabels) { newSearchText = ''; if (mode !== 'tags') { patchRawValues = patchLabels.map(function (label) { var item = mergedFlattenOptions.find(function (_ref2) { var data = _ref2.data; return data[mergedOptionLabelProp] === label; }); return item ? item.data.value : null; }).filter(function (val) { return val !== null; }); } var newRawValues = Array.from(new Set([].concat(_toConsumableArray(mergedRawValue), _toConsumableArray(patchRawValues)))); triggerChange(newRawValues); newRawValues.forEach(function (newRawValue) { triggerSelect(newRawValue, true, 'input'); }); // Should close when paste finish onToggleOpen(false); // Tell Selector that break next actions ret = false; } setInnerSearchValue(newSearchText); if (onSearch && mergedSearchValue !== newSearchText) { onSearch(newSearchText); } return ret; }; // Only triggered when menu is closed & mode is tags // If menu is open, OptionList will take charge // If mode isn't tags, press enter is not meaningful when you can't see any option var onSearchSubmit = function onSearchSubmit(searchText) { var newRawValues = Array.from(new Set([].concat(_toConsumableArray(mergedRawValue), [searchText]))); triggerChange(newRawValues); newRawValues.forEach(function (newRawValue) { triggerSelect(newRawValue, true, 'input'); }); setInnerSearchValue(''); }; // Close dropdown when disabled change useEffect(function () { if (innerOpen && !!disabled) { setInnerOpen(false); } }, [disabled]); // Close will clean up single mode search text useEffect(function () { if (!mergedOpen && !isMultiple && mode !== 'combobox') { triggerSearch('', false, false); } }, [mergedOpen]); // ============================ Keyboard ============================ /** * We record input value here to check if can press to clean up by backspace * - null: Key is not down, this is reset by key up * - true: Search text is empty when first time backspace down * - false: Search text is not empty when first time backspace down */ var _useLock = useLock(), _useLock2 = _slicedToArray(_useLock, 2), getClearLock = _useLock2[0], setClearLock = _useLock2[1]; // KeyDown var onInternalKeyDown = function onInternalKeyDown(event) { var clearLock = getClearLock(); var which = event.which; // We only manage open state here, close logic should handle by list component if (!mergedOpen && which === KeyCode.ENTER) { onToggleOpen(true); } setClearLock(!!mergedSearchValue); // Remove value by `backspace` if (which === KeyCode.BACKSPACE && !clearLock && isMultiple && !mergedSearchValue && mergedRawValue.length) { var removeInfo = removeLastEnabledValue(displayValues, mergedRawValue); if (removeInfo.removedValue !== null) { triggerChange(removeInfo.values); triggerSelect(removeInfo.removedValue, false, 'input'); } } for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { rest[_key - 1] = arguments[_key]; } if (mergedOpen && listRef.current) { var _listRef$current; (_listRef$current = listRef.current).onKeyDown.apply(_listRef$current, [event].concat(rest)); } if (onKeyDown) { onKeyDown.apply(void 0, [event].concat(rest)); } }; // KeyUp var onInternalKeyUp = function onInternalKeyUp(event) { for (var _len2 = arguments.length, rest = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { rest[_key2 - 1] = arguments[_key2]; } if (mergedOpen && listRef.current) { var _listRef$current2; (_listRef$current2 = listRef.current).onKeyUp.apply(_listRef$current2, [event].concat(rest)); } if (onKeyUp) { onKeyUp.apply(void 0, [event].concat(rest)); } }; // ========================== Focus / Blur ========================== /** Record real focus status */ var focusRef = useRef(false); var onContainerFocus = function onContainerFocus() { setMockFocused(true); if (!disabled) { if (onFocus && !focusRef.current) { onFocus.apply(void 0, arguments); } // `showAction` should handle `focus` if set if (showAction.includes('focus')) { onToggleOpen(true); } } focusRef.current = true; }; var onContainerBlur = function onContainerBlur() { setMockFocused(false, function () { focusRef.current = false; onToggleOpen(false); }); if (disabled) { return; } if (mergedSearchValue) { // `tags` mode should move `searchValue` into values if (mode === 'tags') { triggerSearch('', false, false); triggerChange(Array.from(new Set([].concat(_toConsumableArray(mergedRawValue), [mergedSearchValue])))); } else if (mode === 'multiple') { // `multiple` mode only clean the search value but not trigger event setInnerSearchValue(''); } } if (onBlur) { onBlur.apply(void 0, arguments); } }; var activeTimeoutIds = []; useEffect(function () { return function () { activeTimeoutIds.forEach(function (timeoutId) { return clearTimeout(timeoutId); }); activeTimeoutIds.splice(0, activeTimeoutIds.length); }; }, []); var onInternalMouseDown = function onInternalMouseDown(event) { var target = event.target; var popupElement = triggerRef.current && triggerRef.current.getPopupElement(); // We should give focus back to selector if clicked item is not focusable if (popupElement && popupElement.contains(target)) { var timeoutId = setTimeout(function () { var index = activeTimeoutIds.indexOf(timeoutId); if (index !== -1) { activeTimeoutIds.splice(index, 1); } cancelSetMockFocused(); if (!popupElement.contains(document.activeElement)) { selectorRef.current.focus(); } }); activeTimeoutIds.push(timeoutId); } if (onMouseDown) { for (var _len3 = arguments.length, restArgs = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { restArgs[_key3 - 1] = arguments[_key3]; } onMouseDown.apply(void 0, [event].concat(restArgs)); } }; // ========================= Accessibility ========================== var _useState9 = useState(0), _useState10 = _slicedToArray(_useState9, 2), accessibilityIndex = _useState10[0], setAccessibilityIndex = _useState10[1]; var mergedDefaultActiveFirstOption = defaultActiveFirstOption !== undefined ? defaultActiveFirstOption : mode !== 'combobox'; var onActiveValue = function onActiveValue(active, index) { setAccessibilityIndex(index); if (backfill && mode === 'combobox' && active !== null) { setActiveValue(String(active)); } }; // ============================= Popup ============================== var _useState11 = useState(null), _useState12 = _slicedToArray(_useState11, 2), containerWidth = _useState12[0], setContainerWidth = _useState12[1]; var _useState13 = useState({}), _useState14 = _slicedToArray(_useState13, 2), forceUpdate = _useState14[1]; // We need force update here since popup dom is render async function onPopupMouseEnter() { forceUpdate({}); } useLayoutEffect(function () { if (triggerOpen) { var newWidth = Math.ceil(containerRef.current.offsetWidth); if (containerWidth !== newWidth) { setContainerWidth(newWidth); } } }, [triggerOpen]); var popupNode = React.createElement(OptionList, { ref: listRef, prefixCls: prefixCls, id: mergedId, open: mergedOpen, childrenAsData: !options, options: displayOptions, flattenOptions: displayFlattenOptions, multiple: isMultiple, values: rawValues, height: listHeight, itemHeight: listItemHeight, onSelect: onInternalOptionSelect, onToggleOpen: onToggleOpen, onActiveValue: onActiveValue, defaultActiveFirstOption: mergedDefaultActiveFirstOption, notFoundContent: notFoundContent, onScroll: onPopupScroll, searchValue: mergedSearchValue, menuItemSelectedIcon: menuItemSelectedIcon, virtual: virtual !== false && dropdownMatchSelectWidth !== false, onMouseEnter: onPopupMouseEnter }); // ============================= Clear ============================== var clearNode; var onClearMouseDown = function onClearMouseDown() { // Trigger internal `onClear` event if (useInternalProps && internalProps.onClear) { internalProps.onClear(); } triggerChange([]); triggerSearch('', false, false); }; if (!disabled && allowClear && (mergedRawValue.length || mergedSearchValue)) { clearNode = React.createElement(TransBtn, { className: "".concat(prefixCls, "-clear"), onMouseDown: onClearMouseDown, customizeIcon: clearIcon }, "\xD7"); } // ============================= Arrow ============================== var mergedShowArrow = showArrow !== undefined ? showArrow : loading || !isMultiple && mode !== 'combobox'; var arrowNode; if (mergedShowArrow) { arrowNode = React.createElement(TransBtn, { className: classNames("".concat(prefixCls, "-arrow"), _defineProperty({}, "".concat(prefixCls, "-arrow-loading"), loading)), customizeIcon: inputIcon, customizeIconProps: { loading: loading, searchValue: mergedSearchValue, open: mergedOpen, focused: mockFocused, showSearch: mergedShowSearch } }); } // ============================ Warning ============================= if (process.env.NODE_ENV !== 'production' && warningProps) { warningProps(props); } // ============================= Render ============================= var mergedClassName = classNames(prefixCls, className, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls, "-focused"), mockFocused), _defineProperty(_classNames2, "".concat(prefixCls, "-multiple"), isMultiple), _defineProperty(_classNames2, "".concat(prefixCls, "-single"), !isMultiple), _defineProperty(_classNames2, "".concat(prefixCls, "-allow-clear"), allowClear), _defineProperty(_classNames2, "".concat(prefixCls, "-show-arrow"), mergedShowArrow), _defineProperty(_classNames2, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames2, "".concat(prefixCls, "-loading"), loading), _defineProperty(_classNames2, "".concat(prefixCls, "-open"), mergedOpen), _defineProperty(_classNames2, "".concat(prefixCls, "-customize-input"), customizeInputElement), _defineProperty(_classNames2, "".concat(prefixCls, "-show-search"), mergedShowSearch), _classNames2)); return React.createElement("div", Object.assign({ className: mergedClassName }, domProps, { ref: containerRef, onMouseDown: onInternalMouseDown, onKeyDown: onInternalKeyDown, onKeyUp: onInternalKeyUp, onFocus: onContainerFocus, onBlur: onContainerBlur }), mockFocused && !mergedOpen && React.createElement("span", { style: { width: 0, height: 0, display: 'flex', overflow: 'hidden', opacity: 0 }, "aria-live": "polite" }, "".concat(mergedRawValue.join(', '))), React.createElement(SelectTrigger, { ref: triggerRef, disabled: disabled, prefixCls: prefixCls, visible: triggerOpen, popupElement: popupNode, containerWidth: containerWidth, animation: animation, transitionName: transitionName, dropdownStyle: dropdownStyle, dropdownClassName: dropdownClassName, direction: direction, dropdownMatchSelectWidth: dropdownMatchSelectWidth, dropdownRender: dropdownRender, dropdownAlign: dropdownAlign, getPopupContainer: getPopupContainer, empty: !mergedOptions.length, getTriggerDOMNode: function getTriggerDOMNode() { return selectorDomRef.current; } }, React.createElement(Selector, Object.assign({}, props, { domRef: selectorDomRef, prefixCls: prefixCls, inputElement: customizeInputElement, ref: selectorRef, id: mergedId, showSearch: mergedShowSearch, mode: mode, accessibilityIndex: accessibilityIndex, multiple: isMultiple, tagRender: tagRender, values: displayValues, open: mergedOpen, onToggleOpen: onToggleOpen, searchValue: mergedSearchValue, activeValue: activeValue, onSearch: triggerSearch, onSearchSubmit: onSearchSubmit, onSelect: onInternalSelectionSelect, tokenWithEnter: tokenWithEnter }))), arrowNode, clearNode); } var RefSelect = React.forwardRef(Select); return RefSelect; }