ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
1,115 lines (949 loc) • 45.3 kB
JavaScript
import { isVNode as _isVNode, createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue";
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; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
/**
* 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
*/
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
}
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
import KeyCode from '../_util/KeyCode';
import classNames from '../_util/classNames';
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 { getSeparatedContent } from './utils/valueUtil';
import useSelectTriggerControl from './hooks/useSelectTriggerControl';
import useCacheDisplayValue from './hooks/useCacheDisplayValue';
import useCacheOptions from './hooks/useCacheOptions';
import { computed, defineComponent, onBeforeUnmount, onMounted, provide, ref, watch, watchEffect } from 'vue';
import createRef from '../_util/createRef';
import PropTypes, { withUndefined } from '../_util/vue-types';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import warning from '../_util/warning';
function _isSlot(s) {
return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !_isVNode(s);
}
var DEFAULT_OMIT_PROPS = ['children', 'removeIcon', 'placeholder', 'autofocus', 'maxTagCount', 'maxTagTextLength', 'maxTagPlaceholder', 'choiceTransitionName', 'onInputKeyDown'];
export var BaseProps = function BaseProps() {
return {
prefixCls: PropTypes.string,
id: PropTypes.string,
class: PropTypes.string,
style: PropTypes.any,
// Options
options: PropTypes.array,
mode: PropTypes.string,
// Value
value: PropTypes.any,
defaultValue: PropTypes.any,
labelInValue: PropTypes.looseBool,
// Search
inputValue: PropTypes.string,
searchValue: PropTypes.string,
optionFilterProp: PropTypes.string,
/**
* In Select, `false` means do nothing.
* In TreeSelect, `false` will highlight match item.
* It's by design.
*/
filterOption: PropTypes.any,
showSearch: PropTypes.looseBool,
autoClearSearchValue: PropTypes.looseBool,
onSearch: PropTypes.func,
onClear: PropTypes.func,
// Icons
allowClear: PropTypes.looseBool,
clearIcon: PropTypes.VNodeChild,
showArrow: PropTypes.looseBool,
inputIcon: PropTypes.VNodeChild,
removeIcon: PropTypes.VNodeChild,
menuItemSelectedIcon: PropTypes.VNodeChild,
// Dropdown
open: PropTypes.looseBool,
defaultOpen: PropTypes.looseBool,
listHeight: PropTypes.number,
listItemHeight: PropTypes.number,
dropdownStyle: PropTypes.object,
dropdownClassName: PropTypes.string,
dropdownMatchSelectWidth: withUndefined(PropTypes.oneOfType([Boolean, Number])),
virtual: PropTypes.looseBool,
dropdownRender: PropTypes.func,
dropdownAlign: PropTypes.any,
animation: PropTypes.string,
transitionName: PropTypes.string,
getPopupContainer: PropTypes.func,
direction: PropTypes.string,
// Others
disabled: PropTypes.looseBool,
loading: PropTypes.looseBool,
autofocus: PropTypes.looseBool,
defaultActiveFirstOption: PropTypes.looseBool,
notFoundContent: PropTypes.VNodeChild,
placeholder: PropTypes.VNodeChild,
backfill: PropTypes.looseBool,
getInputElement: PropTypes.func,
optionLabelProp: PropTypes.string,
maxTagTextLength: PropTypes.number,
maxTagCount: PropTypes.number,
maxTagPlaceholder: PropTypes.any,
tokenSeparators: PropTypes.array,
tagRender: PropTypes.func,
showAction: PropTypes.array,
tabindex: PropTypes.number,
// Events
onKeyup: PropTypes.func,
onKeydown: PropTypes.func,
onPopupScroll: PropTypes.func,
onDropdownVisibleChange: PropTypes.func,
onSelect: PropTypes.func,
onDeselect: PropTypes.func,
onInputKeyDown: PropTypes.func,
onClick: PropTypes.func,
onChange: PropTypes.func,
onBlur: PropTypes.func,
onFocus: PropTypes.func,
onMousedown: PropTypes.func,
onMouseenter: PropTypes.func,
onMouseleave: PropTypes.func,
// Motion
choiceTransitionName: PropTypes.string,
// Internal props
/**
* Only used in current version for internal event process.
* Do not use in production environment.
*/
internalProps: PropTypes.object,
children: PropTypes.array
};
};
/**
* 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;
var Select = defineComponent({
name: 'Select',
setup: function setup(props) {
var useInternalProps = computed(function () {
return props.internalProps && props.internalProps.mark === INTERNAL_PROPS_MARK;
});
warning(props.optionFilterProp !== 'children', 'Select', 'optionFilterProp not support children, please use label instead');
var containerRef = ref(null);
var triggerRef = ref(null);
var selectorRef = ref(null);
var listRef = ref(null);
var tokenWithEnter = computed(function () {
return (props.tokenSeparators || []).some(function (tokenSeparator) {
return ['\n', '\r\n'].includes(tokenSeparator);
});
});
/** Used for component focused management */
var _useDelayReset = useDelayReset(),
_useDelayReset2 = _slicedToArray(_useDelayReset, 3),
mockFocused = _useDelayReset2[0],
setMockFocused = _useDelayReset2[1],
cancelSetMockFocused = _useDelayReset2[2];
var mergedId = computed(function () {
return props.id || "rc_select_".concat(getUUID());
}); // optionLabelProp
var mergedOptionLabelProp = computed(function () {
var mergedOptionLabelProp = props.optionLabelProp;
if (mergedOptionLabelProp === undefined) {
mergedOptionLabelProp = props.options ? 'label' : 'children';
}
return mergedOptionLabelProp;
}); // labelInValue
var mergedLabelInValue = computed(function () {
return props.mode === 'combobox' ? false : props.labelInValue;
});
var isMultiple = computed(function () {
return props.mode === 'tags' || props.mode === 'multiple';
});
var mergedShowSearch = computed(function () {
return props.showSearch !== undefined ? props.showSearch : isMultiple.value || props.mode === 'combobox';
}); // ============================== Ref ===============================
var selectorDomRef = createRef();
var mergedValue = ref(undefined);
watch(computed(function () {
return [props.value, props.defaultValue];
}), function () {
mergedValue.value = props.value !== undefined ? props.value : props.defaultValue;
}, {
immediate: true
}); // ============================= Value ==============================
/** Unique raw values */
var mergedRawValue = computed(function () {
return toInnerValue(mergedValue.value, {
labelInValue: mergedLabelInValue.value,
combobox: props.mode === 'combobox'
});
});
/** We cache a set of raw values to speed up check */
var rawValues = computed(function () {
return new Set(mergedRawValue.value);
}); // ============================= Option =============================
// Set by option list active, it will merge into search input when mode is `combobox`
var activeValue = ref(null);
var setActiveValue = function setActiveValue(val) {
activeValue.value = val;
};
var innerSearchValue = ref('');
var setInnerSearchValue = function setInnerSearchValue(val) {
innerSearchValue.value = val;
};
var mergedSearchValue = computed(function () {
var mergedSearchValue = innerSearchValue.value;
if (props.mode === 'combobox' && mergedValue.value !== undefined) {
mergedSearchValue = mergedValue.value;
} else if (props.searchValue !== undefined) {
mergedSearchValue = props.searchValue;
} else if (props.inputValue) {
mergedSearchValue = props.inputValue;
}
return mergedSearchValue;
});
var mergedOptions = computed(function () {
var newOptions = props.options;
if (newOptions === undefined) {
newOptions = convertChildrenToData(props.children);
}
/**
* `tags` should fill un-list item.
* This is not cool here since TreeSelect do not need this
*/
if (props.mode === 'tags' && fillOptionsWithMissingValue) {
newOptions = fillOptionsWithMissingValue(newOptions, mergedValue.value, mergedOptionLabelProp.value, props.labelInValue);
}
return newOptions || [];
});
var mergedFlattenOptions = computed(function () {
return flattenOptions(mergedOptions.value, props);
});
var getValueOption = useCacheOptions(mergedRawValue.value, mergedFlattenOptions); // Display options for OptionList
var displayOptions = computed(function () {
if (!mergedSearchValue.value || !mergedShowSearch.value) {
return _toConsumableArray(mergedOptions.value);
}
var _props$optionFilterPr = props.optionFilterProp,
optionFilterProp = _props$optionFilterPr === void 0 ? 'value' : _props$optionFilterPr,
mode = props.mode,
filterOption = props.filterOption;
var filteredOptions = filterOptions(mergedSearchValue.value, mergedOptions.value, {
optionFilterProp: optionFilterProp,
filterOption: mode === 'combobox' && filterOption === undefined ? function () {
return true;
} : filterOption
});
if (mode === 'tags' && filteredOptions.every(function (opt) {
return opt[optionFilterProp] !== mergedSearchValue.value;
})) {
filteredOptions.unshift({
value: mergedSearchValue.value,
label: mergedSearchValue.value,
key: '__RC_SELECT_TAG_PLACEHOLDER__'
});
}
return filteredOptions;
});
var displayFlattenOptions = computed(function () {
return flattenOptions(displayOptions.value, props);
});
onMounted(function () {
watch(mergedSearchValue, function () {
if (listRef.value && listRef.value.scrollTo) {
listRef.value.scrollTo(0);
}
}, {
flush: 'post',
immediate: true
});
}); // ============================ Selector ============================
var displayValues = computed(function () {
var tmpValues = mergedRawValue.value.map(function (val) {
var valueOptions = getValueOption([val]);
var displayValue = getLabeledValue(val, {
options: valueOptions,
prevValue: mergedValue.value,
labelInValue: mergedLabelInValue.value,
optionLabelProp: mergedOptionLabelProp.value
});
return _extends(_extends({}, displayValue), {
disabled: isValueDisabled(val, valueOptions)
});
});
if (!props.mode && tmpValues.length === 1 && tmpValues[0].value === null && tmpValues[0].label === null) {
return [];
}
return tmpValues;
}); // Polyfill with cache label
displayValues = useCacheDisplayValue(displayValues);
var triggerSelect = function triggerSelect(newValue, isSelect, source) {
var newValueOption = getValueOption([newValue]);
var outOption = findValueOption([newValue], newValueOption)[0];
var _props$internalProps = props.internalProps,
internalProps = _props$internalProps === void 0 ? {} : _props$internalProps;
if (!internalProps.skipTriggerSelect) {
// Skip trigger `onSelect` or `onDeselect` if configured
var selectValue = mergedLabelInValue.value ? getLabeledValue(newValue, {
options: newValueOption,
prevValue: mergedValue.value,
labelInValue: mergedLabelInValue.value,
optionLabelProp: mergedOptionLabelProp.value
}) : newValue;
if (isSelect && props.onSelect) {
props.onSelect(selectValue, outOption);
} else if (!isSelect && props.onDeselect) {
props.onDeselect(selectValue, outOption);
}
} // Trigger internal event
if (useInternalProps.value) {
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 prevValueOptions = ref([]);
var setPrevValueOptions = function setPrevValueOptions(val) {
prevValueOptions.value = val;
};
var triggerChange = function triggerChange(newRawValues) {
if (useInternalProps.value && props.internalProps && props.internalProps.skipTriggerChange) {
return;
}
var newRawValuesOptions = getValueOption(newRawValues);
var outValues = toOuterValues(Array.from(newRawValues), {
labelInValue: mergedLabelInValue.value,
options: newRawValuesOptions,
getLabeledValue: getLabeledValue,
prevValue: mergedValue.value,
optionLabelProp: mergedOptionLabelProp.value
});
var outValue = isMultiple.value ? outValues : outValues[0]; // Skip trigger if prev & current value is both empty
if (props.onChange && (mergedRawValue.value.length !== 0 || outValues.length !== 0)) {
var outOptions = findValueOption(newRawValues, newRawValuesOptions, {
prevValueOptions: prevValueOptions.value
}); // We will cache option in case it removed by ajax
setPrevValueOptions(outOptions.map(function (option, index) {
var clone = _extends({}, option);
Object.defineProperty(clone, '_INTERNAL_OPTION_VALUE_', {
get: function get() {
return newRawValues[index];
}
});
return clone;
}));
props.onChange(outValue, isMultiple.value ? outOptions : outOptions[0]);
}
mergedValue.value = outValue;
};
var onInternalSelect = function onInternalSelect(newValue, _ref) {
var selected = _ref.selected,
source = _ref.source;
var _props$autoClearSearc = props.autoClearSearchValue,
autoClearSearchValue = _props$autoClearSearc === void 0 ? true : _props$autoClearSearc;
if (props.disabled) {
return;
}
var newRawValue;
if (isMultiple.value) {
newRawValue = new Set(mergedRawValue.value);
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.value || !isMultiple.value && Array.from(mergedRawValue.value)[0] !== newValue) {
triggerChange(Array.from(newRawValue));
} // Trigger `onSelect`. Single mode always trigger select
triggerSelect(newValue, !isMultiple.value || selected, source); // Clean search value if single or configured
if (props.mode === 'combobox') {
setInnerSearchValue(String(newValue));
setActiveValue('');
} else if (!isMultiple.value || autoClearSearchValue) {
setInnerSearchValue('');
setActiveValue('');
}
};
var onInternalOptionSelect = function onInternalOptionSelect(newValue, info) {
onInternalSelect(newValue, _extends(_extends({}, info), {
source: 'option'
}));
};
var onInternalSelectionSelect = function onInternalSelectionSelect(newValue, info) {
onInternalSelect(newValue, _extends(_extends({}, info), {
source: 'selection'
}));
}; // ============================== Open ==============================
var initOpen = props.open !== undefined ? props.open : props.defaultOpen;
var innerOpen = ref(initOpen);
var mergedOpen = ref(initOpen);
var setInnerOpen = function setInnerOpen(val) {
innerOpen.value = props.open !== undefined ? props.open : val;
mergedOpen.value = innerOpen.value;
};
watch(function () {
return props.open;
}, function () {
setInnerOpen(props.open);
}); // Not trigger `open` in `combobox` when `notFoundContent` is empty
var emptyListContent = computed(function () {
return !props.notFoundContent && !displayOptions.value.length;
});
watchEffect(function () {
mergedOpen.value = innerOpen.value;
if (props.disabled || emptyListContent.value && mergedOpen.value && props.mode === 'combobox') {
mergedOpen.value = false;
}
});
var triggerOpen = computed(function () {
return emptyListContent.value ? false : mergedOpen.value;
});
var onToggleOpen = function onToggleOpen(newOpen) {
var nextOpen = newOpen !== undefined ? newOpen : !mergedOpen.value;
if (innerOpen.value !== nextOpen && !props.disabled) {
setInnerOpen(nextOpen);
if (props.onDropdownVisibleChange) {
props.onDropdownVisibleChange(nextOpen);
}
}
};
useSelectTriggerControl([containerRef, triggerRef], triggerOpen, onToggleOpen); // ============================= Search =============================
var triggerSearch = function triggerSearch(searchText, fromTyping, isCompositing) {
var ret = true;
var newSearchText = searchText;
var preSearchValue = mergedSearchValue.value;
setActiveValue(null); // Check if match the `tokenSeparators`
var patchLabels = isCompositing ? null : getSeparatedContent(searchText, props.tokenSeparators);
var patchRawValues = patchLabels;
if (props.mode === 'combobox') {
// Only typing will trigger onChange
if (fromTyping) {
triggerChange([newSearchText]);
}
} else if (patchLabels) {
newSearchText = '';
if (props.mode !== 'tags') {
patchRawValues = patchLabels.map(function (label) {
var item = mergedFlattenOptions.value.find(function (_ref2) {
var data = _ref2.data;
return data[mergedOptionLabelProp.value] === label;
});
return item ? item.data.value : null;
}).filter(function (val) {
return val !== null;
});
}
var newRawValues = Array.from(new Set([].concat(_toConsumableArray(mergedRawValue.value), _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 (props.onSearch && preSearchValue !== newSearchText) {
props.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.value), [searchText])));
triggerChange(newRawValues);
newRawValues.forEach(function (newRawValue) {
triggerSelect(newRawValue, true, 'input');
});
setInnerSearchValue('');
}; // Close dropdown when disabled change
watch(computed(function () {
return props.disabled;
}), function () {
if (innerOpen.value && !!props.disabled) {
setInnerOpen(false);
}
}, {
immediate: true
}); // Close will clean up single mode search text
watch(mergedOpen, function () {
if (!mergedOpen.value && !isMultiple.value && props.mode !== 'combobox') {
triggerSearch('', false, false);
}
}, {
immediate: true
}); // ============================ 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.value && which === KeyCode.ENTER) {
onToggleOpen(true);
}
setClearLock(!!mergedSearchValue.value); // Remove value by `backspace`
if (which === KeyCode.BACKSPACE && !clearLock && isMultiple.value && !mergedSearchValue.value && mergedRawValue.value.length) {
var removeInfo = removeLastEnabledValue(displayValues.value, mergedRawValue.value);
if (removeInfo.removedValue !== null) {
triggerChange(removeInfo.values);
triggerSelect(removeInfo.removedValue, false, 'input');
}
}
if (mergedOpen.value && listRef.value) {
listRef.value.onKeydown(event);
}
if (props.onKeydown) {
props.onKeydown(event);
}
}; // KeyUp
var onInternalKeyUp = function onInternalKeyUp(event) {
if (mergedOpen.value && listRef.value) {
listRef.value.onKeyup(event);
}
if (props.onKeyup) {
props.onKeyup(event);
}
}; // ========================== Focus / Blur ==========================
/** Record real focus status */
var focusRef = ref(false);
var onContainerFocus = function onContainerFocus() {
setMockFocused(true);
if (!props.disabled) {
if (props.onFocus && !focusRef.value) {
props.onFocus(arguments.length <= 0 ? undefined : arguments[0]);
} // `showAction` should handle `focus` if set
if (props.showAction && props.showAction.includes('focus')) {
onToggleOpen(true);
}
}
focusRef.value = true;
};
var onContainerBlur = function onContainerBlur() {
setMockFocused(false, function () {
focusRef.value = false;
onToggleOpen(false);
});
if (props.disabled) {
return;
}
var serachVal = mergedSearchValue.value;
if (serachVal) {
// `tags` mode should move `searchValue` into values
if (props.mode === 'tags') {
triggerSearch('', false, false);
triggerChange(Array.from(new Set([].concat(_toConsumableArray(mergedRawValue.value), [serachVal]))));
} else if (props.mode === 'multiple') {
// `multiple` mode only clean the search value but not trigger event
setInnerSearchValue('');
}
}
if (props.onBlur) {
props.onBlur(arguments.length <= 0 ? undefined : arguments[0]);
}
};
provide('VCSelectContainerEvent', {
focus: onContainerFocus,
blur: onContainerBlur
});
var activeTimeoutIds = [];
onMounted(function () {
activeTimeoutIds.forEach(function (timeoutId) {
return clearTimeout(timeoutId);
});
activeTimeoutIds.splice(0, activeTimeoutIds.length);
});
onBeforeUnmount(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.value && triggerRef.value.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.value.focus();
}
});
activeTimeoutIds.push(timeoutId);
}
if (props.onMousedown) {
props.onMousedown(event);
}
}; // ========================= Accessibility ==========================
var accessibilityIndex = ref(0);
var mergedDefaultActiveFirstOption = computed(function () {
return props.defaultActiveFirstOption !== undefined ? props.defaultActiveFirstOption : props.mode !== 'combobox';
});
var onActiveValue = function onActiveValue(active, index) {
var _ref3 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
_ref3$source = _ref3.source,
source = _ref3$source === void 0 ? 'keyboard' : _ref3$source;
accessibilityIndex.value = index;
if (props.backfill && props.mode === 'combobox' && active !== null && source === 'keyboard') {
setActiveValue(String(active));
}
}; // ============================= Popup ==============================
var containerWidth = ref(null);
onMounted(function () {
watch(triggerOpen, function () {
if (triggerOpen.value) {
var newWidth = Math.ceil(containerRef.value.offsetWidth);
if (containerWidth.value !== newWidth) {
containerWidth.value = newWidth;
}
}
}, {
immediate: true
});
});
var focus = function focus() {
selectorRef.value.focus();
};
var blur = function blur() {
selectorRef.value.blur();
};
return {
focus: focus,
blur: blur,
tokenWithEnter: tokenWithEnter,
mockFocused: mockFocused,
mergedId: mergedId,
containerWidth: containerWidth,
onActiveValue: onActiveValue,
accessibilityIndex: accessibilityIndex,
mergedDefaultActiveFirstOption: mergedDefaultActiveFirstOption,
onInternalMouseDown: onInternalMouseDown,
onContainerFocus: onContainerFocus,
onContainerBlur: onContainerBlur,
onInternalKeyDown: onInternalKeyDown,
isMultiple: isMultiple,
mergedOpen: mergedOpen,
displayOptions: displayOptions,
displayFlattenOptions: displayFlattenOptions,
rawValues: rawValues,
onInternalOptionSelect: onInternalOptionSelect,
onToggleOpen: onToggleOpen,
mergedSearchValue: mergedSearchValue,
useInternalProps: useInternalProps,
triggerChange: triggerChange,
triggerSearch: triggerSearch,
mergedRawValue: mergedRawValue,
mergedShowSearch: mergedShowSearch,
onInternalKeyUp: onInternalKeyUp,
triggerOpen: triggerOpen,
mergedOptions: mergedOptions,
onInternalSelectionSelect: onInternalSelectionSelect,
selectorDomRef: selectorDomRef,
displayValues: displayValues,
activeValue: activeValue,
onSearchSubmit: onSearchSubmit,
containerRef: containerRef,
listRef: listRef,
triggerRef: triggerRef,
selectorRef: selectorRef
};
},
methods: {
// We need force update here since popup dom is render async
onPopupMouseEnter: function onPopupMouseEnter() {
this.$forceUpdate();
}
},
render: function render() {
var _slot;
var _classNames2;
var tokenWithEnter = this.tokenWithEnter,
mockFocused = this.mockFocused,
mergedId = this.mergedId,
containerWidth = this.containerWidth,
onActiveValue = this.onActiveValue,
accessibilityIndex = this.accessibilityIndex,
mergedDefaultActiveFirstOption = this.mergedDefaultActiveFirstOption,
onInternalMouseDown = this.onInternalMouseDown,
onInternalKeyDown = this.onInternalKeyDown,
isMultiple = this.isMultiple,
mergedOpen = this.mergedOpen,
displayOptions = this.displayOptions,
displayFlattenOptions = this.displayFlattenOptions,
rawValues = this.rawValues,
onInternalOptionSelect = this.onInternalOptionSelect,
onToggleOpen = this.onToggleOpen,
mergedSearchValue = this.mergedSearchValue,
onPopupMouseEnter = this.onPopupMouseEnter,
useInternalProps = this.useInternalProps,
triggerChange = this.triggerChange,
triggerSearch = this.triggerSearch,
mergedRawValue = this.mergedRawValue,
mergedShowSearch = this.mergedShowSearch,
onInternalKeyUp = this.onInternalKeyUp,
triggerOpen = this.triggerOpen,
mergedOptions = this.mergedOptions,
onInternalSelectionSelect = this.onInternalSelectionSelect,
selectorDomRef = this.selectorDomRef,
displayValues = this.displayValues,
activeValue = this.activeValue,
onSearchSubmit = this.onSearchSubmit;
var _a = this.$props,
_a$prefixCls = _a.prefixCls,
prefixCls = _a$prefixCls === void 0 ? defaultPrefixCls : _a$prefixCls,
className = _a.class,
id = _a.id,
open = _a.open,
defaultOpen = _a.defaultOpen,
options = _a.options,
children = _a.children,
mode = _a.mode,
value = _a.value,
defaultValue = _a.defaultValue,
labelInValue = _a.labelInValue,
showSearch = _a.showSearch,
inputValue = _a.inputValue,
searchValue = _a.searchValue,
filterOption = _a.filterOption,
optionFilterProp = _a.optionFilterProp,
autoClearSearchValue = _a.autoClearSearchValue,
onSearch = _a.onSearch,
allowClear = _a.allowClear,
clearIcon = _a.clearIcon,
showArrow = _a.showArrow,
inputIcon = _a.inputIcon,
menuItemSelectedIcon = _a.menuItemSelectedIcon,
disabled = _a.disabled,
loading = _a.loading,
defaultActiveFirstOption = _a.defaultActiveFirstOption,
_a$notFoundContent = _a.notFoundContent,
notFoundContent = _a$notFoundContent === void 0 ? 'Not Found' : _a$notFoundContent,
optionLabelProp = _a.optionLabelProp,
backfill = _a.backfill,
getInputElement = _a.getInputElement,
getPopupContainer = _a.getPopupContainer,
_a$listHeight = _a.listHeight,
listHeight = _a$listHeight === void 0 ? 200 : _a$listHeight,
_a$listItemHeight = _a.listItemHeight,
listItemHeight = _a$listItemHeight === void 0 ? 20 : _a$listItemHeight,
animation = _a.animation,
transitionName = _a.transitionName,
virtual = _a.virtual,
dropdownStyle = _a.dropdownStyle,
dropdownClassName = _a.dropdownClassName,
dropdownMatchSelectWidth = _a.dropdownMatchSelectWidth,
dropdownRender = _a.dropdownRender,
dropdownAlign = _a.dropdownAlign,
showAction = _a.showAction,
direction = _a.direction,
tokenSeparators = _a.tokenSeparators,
tagRender = _a.tagRender,
onPopupScroll = _a.onPopupScroll,
onDropdownVisibleChange = _a.onDropdownVisibleChange,
onFocus = _a.onFocus,
onBlur = _a.onBlur,
onKeyup = _a.onKeyup,
onKeydown = _a.onKeydown,
onMousedown = _a.onMousedown,
onChange = _a.onChange,
onSelect = _a.onSelect,
onDeselect = _a.onDeselect,
onClear = _a.onClear,
_a$internalProps = _a.internalProps,
internalProps = _a$internalProps === void 0 ? {} : _a$internalProps,
restProps = __rest(_a, ["prefixCls", "class", "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", "onClear", "internalProps"]); // ============================= Input ==============================
// Only works in `combobox`
var customizeInputElement = mode === 'combobox' && getInputElement && getInputElement() || null;
var domProps = omitDOMProps ? omitDOMProps(restProps) : restProps;
DEFAULT_OMIT_PROPS.forEach(function (prop) {
delete domProps[prop];
});
var popupNode = _createVNode(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
}, null); // ============================= Clear ==============================
var clearNode;
var onClearMouseDown = function onClearMouseDown() {
// Trigger internal `onClear` event
if (useInternalProps && internalProps.onClear) {
internalProps.onClear();
}
if (onClear) {
onClear();
}
triggerChange([]);
triggerSearch('', false, false);
};
if (!disabled && allowClear && (mergedRawValue.length || mergedSearchValue)) {
clearNode = _createVNode(TransBtn, {
"class": "".concat(prefixCls, "-clear"),
"onMousedown": onClearMouseDown,
"customizeIcon": clearIcon
}, {
default: function _default() {
return [_createTextVNode("\xD7")];
}
});
} // ============================= Arrow ==============================
var mergedShowArrow = showArrow !== undefined ? showArrow : loading || !isMultiple && mode !== 'combobox';
var arrowNode;
if (mergedShowArrow) {
arrowNode = _createVNode(TransBtn, {
"class": classNames("".concat(prefixCls, "-arrow"), _defineProperty({}, "".concat(prefixCls, "-arrow-loading"), loading)),
"customizeIcon": inputIcon,
"customizeIconProps": {
loading: loading,
searchValue: mergedSearchValue,
open: mergedOpen,
focused: mockFocused,
showSearch: mergedShowSearch
}
}, null);
} // ============================ Warning =============================
if (process.env.NODE_ENV !== 'production' && warningProps) {
warningProps(this.$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 _createVNode("div", _objectSpread(_objectSpread({
"class": mergedClassName
}, domProps), {}, {
"ref": "containerRef",
"onMousedown": onInternalMouseDown,
"onKeydown": onInternalKeyDown,
"onKeyup": onInternalKeyUp
}), [mockFocused && !mergedOpen && _createVNode("span", {
"style": {
width: 0,
height: 0,
display: 'flex',
overflow: 'hidden',
opacity: 0
},
"aria-live": "polite"
}, ["".concat(mergedRawValue.join(', '))]), _createVNode(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;
}
}, _isSlot(_slot = _createVNode(Selector, _objectSpread(_objectSpread({}, this.$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
}), null)) ? _slot : {
default: function _default() {
return [_slot];
}
}), arrowNode, clearNode]);
}
});
Select.inheritAttrs = false;
Select.props = initDefaultProps(BaseProps(), {});
return Select;
}