UNPKG

element-plus

Version:

A Component Library for Vue3.0

1,260 lines (1,242 loc) 55.6 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var ElInput = require('../el-input'); var util = require('../utils/util'); var resizeEvent = require('../utils/resize-event'); var ElTag = require('../el-tag'); var ElPopper = require('../el-popper'); var ElScrollbar = require('../el-scrollbar'); var directives = require('../directives'); var locale = require('../locale'); var constants = require('../utils/constants'); var validators = require('../utils/validators'); var mitt = require('mitt'); var aria = require('../utils/aria'); var isServer = require('../utils/isServer'); var scrollIntoView = require('../utils/scroll-into-view'); var lodashDebounce = require('lodash/debounce'); var isDef = require('../utils/isDef'); var form = require('../el-form'); var isEqual = require('lodash/isEqual'); var hooks = require('../hooks'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var ElInput__default = /*#__PURE__*/_interopDefaultLegacy(ElInput); var ElTag__default = /*#__PURE__*/_interopDefaultLegacy(ElTag); var ElPopper__default = /*#__PURE__*/_interopDefaultLegacy(ElPopper); var ElScrollbar__default = /*#__PURE__*/_interopDefaultLegacy(ElScrollbar); var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt); var isServer__default = /*#__PURE__*/_interopDefaultLegacy(isServer); var scrollIntoView__default = /*#__PURE__*/_interopDefaultLegacy(scrollIntoView); var lodashDebounce__default = /*#__PURE__*/_interopDefaultLegacy(lodashDebounce); var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual); const selectGroupKey = 'ElSelectGroup'; const selectKey = 'ElSelect'; const selectEvents = { queryChange: 'elOptionQueryChange', groupQueryChange: 'elOptionGroupQueryChange', }; function useOption(props, states) { const select = vue.inject(selectKey); const selectGroup = vue.inject(selectGroupKey, { disabled: false }); const isObject = vue.computed(() => { return Object.prototype.toString.call(props.value).toLowerCase() === '[object object]'; }); const itemSelected = vue.computed(() => { if (!select.props.multiple) { return isEqual(props.value, select.props.modelValue); } else { return contains(select.props.modelValue, props.value); } }); const limitReached = vue.computed(() => { if (select.props.multiple) { const modelValue = (select.props.modelValue || []); return !itemSelected.value && modelValue.length >= select.props.multipleLimit && select.props.multipleLimit > 0; } else { return false; } }); const currentLabel = vue.computed(() => { return props.label || (isObject.value ? '' : props.value); }); const currentValue = vue.computed(() => { return props.value || props.label || ''; }); const isDisabled = vue.computed(() => { return props.disabled || states.groupDisabled || limitReached.value; }); const instance = vue.getCurrentInstance(); const contains = (arr = [], target) => { if (!isObject.value) { return arr && arr.indexOf(target) > -1; } else { const valueKey = select.props.valueKey; return arr && arr.some(item => { return util.getValueByPath(item, valueKey) === util.getValueByPath(target, valueKey); }); } }; const isEqual = (a, b) => { if (!isObject.value) { return a === b; } else { const { valueKey } = select.props; return util.getValueByPath(a, valueKey) === util.getValueByPath(b, valueKey); } }; const hoverItem = () => { if (!props.disabled && !selectGroup.disabled) { select.hoverIndex = select.options.indexOf(instance); } }; const queryChange = (query) => { const regexp = new RegExp(util.escapeRegexpString(query), 'i'); states.visible = regexp.test(currentLabel.value) || props.created; if (!states.visible) { select.filteredOptionsCount--; } }; vue.watch(() => currentLabel.value, () => { if (!props.created && !select.props.remote) select.setSelected(); }); vue.watch(() => props.value, (val, oldVal) => { const { remote, valueKey } = select.props; if (!props.created && !remote) { if (valueKey && typeof val === 'object' && typeof oldVal === 'object' && val[valueKey] === oldVal[valueKey]) { return; } select.setSelected(); } }); select.selectEmitter.on(selectEvents.queryChange, queryChange); return { select, currentLabel, currentValue, itemSelected, isDisabled, hoverItem, }; } var script = vue.defineComponent({ name: 'ElOption', componentName: 'ElOption', props: { value: { required: true, type: [String, Number, Object], }, label: [String, Number], created: Boolean, disabled: { type: Boolean, default: false, }, }, setup(props) { const states = vue.reactive({ index: -1, groupDisabled: false, visible: true, hitState: false, hover: false, }); const { currentLabel, itemSelected, isDisabled, select, hoverItem, } = useOption(props, states); const { visible, hover, } = vue.toRefs(states); const vm = vue.getCurrentInstance().proxy; select.onOptionCreate(vm); vue.onBeforeUnmount(() => { const { selected } = select; let selectedOptions = select.props.multiple ? selected : [selected]; let index = select.cachedOptions.indexOf(vm); let selectedIndex = selectedOptions.findIndex(item => { return item.value === vm.value; }); if (index > -1 && selectedIndex < 0) { select.cachedOptions.splice(index, 1); } select.onOptionDestroy(select.options.map(item => item.value).indexOf(props.value)); }); function selectOptionClick() { if (props.disabled !== true && states.groupDisabled !== true) { select.handleOptionSelect(vm, true); } } return { currentLabel, itemSelected, isDisabled, select, hoverItem, visible, hover, selectOptionClick, }; }, }); function render(_ctx, _cache, $props, $setup, $data, $options) { return vue.withDirectives((vue.openBlock(), vue.createBlock("li", { class: ["el-select-dropdown__item", { 'selected': _ctx.itemSelected, 'is-disabled': _ctx.isDisabled, 'hover': _ctx.hover}], onMouseenter: _cache[1] || (_cache[1] = (...args) => (_ctx.hoverItem && _ctx.hoverItem(...args))), onClick: _cache[2] || (_cache[2] = vue.withModifiers((...args) => (_ctx.selectOptionClick && _ctx.selectOptionClick(...args)), ["stop"])) }, [ vue.renderSlot(_ctx.$slots, "default", {}, () => [ vue.createVNode("span", null, vue.toDisplayString(_ctx.currentLabel), 1 /* TEXT */) ]) ], 34 /* CLASS, HYDRATE_EVENTS */)), [ [vue.vShow, _ctx.visible] ]) } script.render = render; script.__file = "packages/select/src/option.vue"; var script$1 = vue.defineComponent({ name: 'ElSelectDropdown', componentName: 'ElSelectDropdown', setup() { const select = vue.inject(selectKey); const popperClass = vue.computed(() => select.props.popperClass); const isMultiple = vue.computed(() => select.props.multiple); const minWidth = vue.ref(''); function updateMinWidth() { var _a; minWidth.value = ((_a = select.selectWrapper) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) + 'px'; } vue.onMounted(() => { resizeEvent.addResizeListener(select.selectWrapper, updateMinWidth); }); vue.onBeforeUnmount(() => { resizeEvent.removeResizeListener(select.selectWrapper, updateMinWidth); }); return { minWidth, popperClass, isMultiple, }; }, }); function render$1(_ctx, _cache, $props, $setup, $data, $options) { return (vue.openBlock(), vue.createBlock("div", { class: ["el-select-dropdown", [{ 'is-multiple': _ctx.isMultiple }, _ctx.popperClass]], style: { minWidth: _ctx.minWidth } }, [ vue.renderSlot(_ctx.$slots, "default") ], 6 /* CLASS, STYLE */)) } script$1.render = render$1; script$1.__file = "packages/select/src/select-dropdown.vue"; /** * Make a map and return a function for checking if a key * is in that map. * IMPORTANT: all calls of this function must be prefixed with * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ const EMPTY_OBJ = (process.env.NODE_ENV !== 'production') ? Object.freeze({}) : {}; const EMPTY_ARR = (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : []; const isObject = (val) => val !== null && typeof val === 'object'; const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const toRawType = (value) => { // extract "RawType" from strings like "[object RawType]" return toTypeString(value).slice(8, -1); }; function useSelectStates(props) { const selectEmitter = mitt__default['default'](); return vue.reactive({ options: [], cachedOptions: [], createdLabel: null, createdSelected: false, selected: props.multiple ? [] : {}, inputLength: 20, inputWidth: 0, initialInputHeight: 0, optionsCount: 0, filteredOptionsCount: 0, visible: false, softFocus: false, selectedLabel: '', hoverIndex: -1, query: '', previousQuery: null, inputHovering: false, cachedPlaceHolder: '', currentPlaceholder: locale.t('el.select.placeholder'), menuVisibleOnFocus: false, isOnComposition: false, isSilentBlur: false, selectEmitter, }); } const useSelect = (props, states, ctx) => { const ELEMENT = util.useGlobalConfig(); const reference = vue.ref(null); const input = vue.ref(null); const popper = vue.ref(null); const tags = vue.ref(null); const selectWrapper = vue.ref(null); const scrollbar = vue.ref(null); const hoverOption = vue.ref(-1); const elForm = vue.inject(form.elFormKey, {}); const elFormItem = vue.inject(form.elFormItemKey, {}); const readonly = vue.computed(() => !props.filterable || props.multiple || (!util.isIE() && !util.isEdge() && !states.visible)); const selectDisabled = vue.computed(() => props.disabled || elForm.disabled); const showClose = vue.computed(() => { const hasValue = props.multiple ? Array.isArray(props.modelValue) && props.modelValue.length > 0 : props.modelValue !== undefined && props.modelValue !== null && props.modelValue !== ''; const criteria = props.clearable && !selectDisabled.value && states.inputHovering && hasValue; return criteria; }); const iconClass = vue.computed(() => props.remote && props.filterable ? '' : (states.visible ? 'arrow-up is-reverse' : 'arrow-up')); const debounce = vue.computed(() => props.remote ? 300 : 0); const emptyText = vue.computed(() => { if (props.loading) { return props.loadingText || locale.t('el.select.loading'); } else { if (props.remote && states.query === '' && states.options.length === 0) return false; if (props.filterable && states.query && states.options.length > 0 && states.filteredOptionsCount === 0) { return props.noMatchText || locale.t('el.select.noMatch'); } if (states.options.length === 0) { return props.noDataText || locale.t('el.select.noData'); } } return null; }); const showNewOption = vue.computed(() => { const hasExistingOption = states.options.filter(option => { return !option.created; }).some(option => { return option.currentLabel === states.query; }); return props.filterable && props.allowCreate && states.query !== '' && !hasExistingOption; }); const selectSize = vue.computed(() => props.size || elFormItem.size || ELEMENT.size); const collapseTagSize = vue.computed(() => ['small', 'mini'].indexOf(selectSize.value) > -1 ? 'mini' : 'small'); const dropMenuVisible = vue.computed(() => states.visible && emptyText.value !== false); vue.watch(() => selectDisabled.value, () => { vue.nextTick(() => { resetInputHeight(); }); }); vue.watch(() => props.placeholder, val => { states.cachedPlaceHolder = states.currentPlaceholder = val; }); vue.watch(() => props.modelValue, (val, oldVal) => { var _a; if (props.multiple) { resetInputHeight(); if ((val && val.length > 0) || (input.value && states.query !== '')) { states.currentPlaceholder = ''; } else { states.currentPlaceholder = states.cachedPlaceHolder; } if (props.filterable && !props.reserveKeyword) { states.query = ''; handleQueryChange(states.query); } } setSelected(); if (props.filterable && !props.multiple) { states.inputLength = 20; } if (!isEqual__default['default'](val, oldVal)) { (_a = elFormItem.formItemMitt) === null || _a === void 0 ? void 0 : _a.emit('el.form.change', val); } }, { flush: 'post', }); vue.watch(() => states.visible, val => { var _a, _b; if (!val) { input.value && input.value.blur(); states.query = ''; states.previousQuery = null; states.selectedLabel = ''; states.inputLength = 20; states.menuVisibleOnFocus = false; resetHoverIndex(); vue.nextTick(() => { if (input.value && input.value.value === '' && states.selected.length === 0) { states.currentPlaceholder = states.cachedPlaceHolder; } }); if (!props.multiple) { if (states.selected) { if (props.filterable && props.allowCreate && states.createdSelected && states.createdLabel) { states.selectedLabel = states.createdLabel; } else { states.selectedLabel = states.selected.currentLabel; } if (props.filterable) states.query = states.selectedLabel; } if (props.filterable) { states.currentPlaceholder = states.cachedPlaceHolder; } } } else { (_b = (_a = popper.value) === null || _a === void 0 ? void 0 : _a.update) === null || _b === void 0 ? void 0 : _b.call(_a); if (props.filterable) { states.query = props.remote ? '' : states.selectedLabel; if (props.multiple) { input.value.focus(); } else { if (states.selectedLabel) { states.currentPlaceholder = states.selectedLabel; states.selectedLabel = ''; } } if (!props.multiple && !props.remote) { states.selectEmitter.emit('elOptionQueryChange', ''); states.selectEmitter.emit('elOptionGroupQueryChange'); } else { handleQueryChange(states.query); } } } ctx.emit('visible-change', val); }); vue.watch(() => ([...states.options]), () => { var _a, _b, _c; if (isServer__default['default']) return; (_b = (_a = popper.value) === null || _a === void 0 ? void 0 : _a.update) === null || _b === void 0 ? void 0 : _b.call(_a); if (props.multiple) { resetInputHeight(); } const inputs = ((_c = selectWrapper.value) === null || _c === void 0 ? void 0 : _c.querySelectorAll('input')) || []; if ([].indexOf.call(inputs, document.activeElement) === -1) { setSelected(); } if (props.defaultFirstOption && (props.filterable || props.remote) && states.filteredOptionsCount) { checkDefaultFirstOption(); } }); vue.watch(() => states.hoverIndex, val => { if (typeof val === 'number' && val > -1) { hoverOption.value = states.options[val] || {}; } states.options.forEach(option => { option.hover = hoverOption.value === option; }); }); const resetInputHeight = () => { if (props.collapseTags && !props.filterable) return; vue.nextTick(() => { var _a, _b; if (!reference.value) return; const inputChildNodes = reference.value.$el.childNodes; const input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0]; const _tags = tags.value; const sizeInMap = states.initialInputHeight || 40; input.style.height = states.selected.length === 0 ? sizeInMap + 'px' : Math.max(_tags ? (_tags.clientHeight + (_tags.clientHeight > sizeInMap ? 6 : 0)) : 0, sizeInMap) + 'px'; if (states.visible && emptyText.value !== false) { (_b = (_a = popper.value) === null || _a === void 0 ? void 0 : _a.update) === null || _b === void 0 ? void 0 : _b.call(_a); } }); }; const handleQueryChange = val => { if (states.previousQuery === val || states.isOnComposition) return; if (states.previousQuery === null && (typeof props.filterMethod === 'function' || typeof props.remoteMethod === 'function')) { states.previousQuery = val; return; } states.previousQuery = val; vue.nextTick(() => { var _a, _b; if (states.visible) (_b = (_a = popper.value) === null || _a === void 0 ? void 0 : _a.update) === null || _b === void 0 ? void 0 : _b.call(_a); }); states.hoverIndex = -1; if (props.multiple && props.filterable) { vue.nextTick(() => { const length = input.value.length * 15 + 20; states.inputLength = props.collapseTags ? Math.min(50, length) : length; managePlaceholder(); resetInputHeight(); }); } if (props.remote && typeof props.remoteMethod === 'function') { states.hoverIndex = -1; props.remoteMethod(val); } else if (typeof props.filterMethod === 'function') { props.filterMethod(val); states.selectEmitter.emit('elOptionGroupQueryChange'); } else { states.filteredOptionsCount = states.optionsCount; states.selectEmitter.emit('elOptionQueryChange', val); states.selectEmitter.emit('elOptionGroupQueryChange'); } if (props.defaultFirstOption && (props.filterable || props.remote) && states.filteredOptionsCount) { checkDefaultFirstOption(); } }; const managePlaceholder = () => { if (states.currentPlaceholder !== '') { states.currentPlaceholder = input.value ? '' : states.cachedPlaceHolder; } }; const checkDefaultFirstOption = () => { states.hoverIndex = -1; let hasCreated = false; for (let i = states.options.length - 1; i >= 0; i--) { if (states.options[i].created) { hasCreated = true; states.hoverIndex = i; break; } } if (hasCreated) return; for (let i = 0; i !== states.options.length; ++i) { const option = states.options[i]; if (states.query) { if (!option.disabled && !option.groupDisabled && option.visible) { states.hoverIndex = i; break; } } else { if (option.itemSelected) { states.hoverIndex = i; break; } } } }; const setSelected = () => { var _a; if (!props.multiple) { const option = getOption(props.modelValue); if ((_a = option.props) === null || _a === void 0 ? void 0 : _a.created) { states.createdLabel = option.props.value; states.createdSelected = true; } else { states.createdSelected = false; } states.selectedLabel = option.currentLabel; states.selected = option; if (props.filterable) states.query = states.selectedLabel; return; } const result = []; if (Array.isArray(props.modelValue)) { props.modelValue.forEach(value => { result.push(getOption(value)); }); } states.selected = result; vue.nextTick(() => { resetInputHeight(); }); }; const getOption = value => { let option; const isObjectValue = toRawType(value).toLowerCase() === 'object'; const isNull = toRawType(value).toLowerCase() === 'null'; const isUndefined = toRawType(value).toLowerCase() === 'undefined'; for (let i = states.cachedOptions.length - 1; i >= 0; i--) { const cachedOption = states.cachedOptions[i]; const isEqualValue = isObjectValue ? util.getValueByPath(cachedOption.value, props.valueKey) === util.getValueByPath(value, props.valueKey) : cachedOption.value === value; if (isEqualValue) { option = { value, currentLabel: cachedOption.currentLabel, }; break; } } if (option) return option; const label = (!isObjectValue && !isNull && !isUndefined) ? value : ''; const newOption = { value, currentLabel: label, }; if (props.multiple) { newOption.hitState = false; } return newOption; }; const resetHoverIndex = () => { setTimeout(() => { if (!props.multiple) { states.hoverIndex = states.options.indexOf(states.selected); } else { if (states.selected.length > 0) { states.hoverIndex = Math.min.apply(null, states.selected.map(item => states.options.indexOf(item))); } else { states.hoverIndex = -1; } } }, 300); }; const handleResize = () => { var _a, _b; resetInputWidth(); (_b = (_a = popper.value) === null || _a === void 0 ? void 0 : _a.update) === null || _b === void 0 ? void 0 : _b.call(_a); if (props.multiple) resetInputHeight(); }; const resetInputWidth = () => { var _a; states.inputWidth = (_a = reference.value) === null || _a === void 0 ? void 0 : _a.$el.getBoundingClientRect().width; }; const onInputChange = () => { if (props.filterable && states.query !== states.selectedLabel) { states.query = states.selectedLabel; handleQueryChange(states.query); } }; const debouncedOnInputChange = lodashDebounce__default['default'](() => { onInputChange(); }, debounce.value); const debouncedQueryChange = lodashDebounce__default['default'](e => { handleQueryChange(e.target.value); }, debounce.value); const emitChange = val => { if (!isEqual__default['default'](props.modelValue, val)) { ctx.emit(constants.CHANGE_EVENT, val); } }; const deletePrevTag = e => { if (e.target.value.length <= 0 && !toggleLastOptionHitState()) { const value = props.modelValue.slice(); value.pop(); ctx.emit(constants.UPDATE_MODEL_EVENT, value); emitChange(value); } }; const deleteTag = (event, tag) => { const index = states.selected.indexOf(tag); if (index > -1 && !selectDisabled.value) { const value = props.modelValue.slice(); value.splice(index, 1); ctx.emit(constants.UPDATE_MODEL_EVENT, value); emitChange(value); ctx.emit('remove-tag', tag.value); } event.stopPropagation(); }; const deleteSelected = event => { event.stopPropagation(); const value = props.multiple ? [] : ''; ctx.emit(constants.UPDATE_MODEL_EVENT, value); emitChange(value); states.visible = false; ctx.emit('clear'); }; const handleOptionSelect = (option, byClick) => { if (props.multiple) { const value = (props.modelValue || []).slice(); const optionIndex = getValueIndex(value, option.value); if (optionIndex > -1) { value.splice(optionIndex, 1); } else if (props.multipleLimit <= 0 || value.length < props.multipleLimit) { value.push(option.value); } ctx.emit(constants.UPDATE_MODEL_EVENT, value); emitChange(value); if (option.created) { states.query = ''; handleQueryChange(''); states.inputLength = 20; } if (props.filterable) input.value.focus(); } else { ctx.emit(constants.UPDATE_MODEL_EVENT, option.value); emitChange(option.value); states.visible = false; } states.isSilentBlur = byClick; setSoftFocus(); if (states.visible) return; vue.nextTick(() => { scrollToOption(option); }); }; const getValueIndex = (arr = [], value) => { if (!isObject(value)) return arr.indexOf(value); const valueKey = props.valueKey; let index = -1; arr.some((item, i) => { if (util.getValueByPath(item, valueKey) === util.getValueByPath(value, valueKey)) { index = i; return true; } return false; }); return index; }; const setSoftFocus = () => { states.softFocus = true; const _input = input.value || reference.value; if (_input) { _input.focus(); } }; const getEl = option => { const options = states.options.filter(item => item.value === option.value); if (options.length > 0) { return options[0].$el; } }; const scrollToOption = option => { var _a, _b, _c, _d; const target = Array.isArray(option) ? getEl(option[0]) : getEl(option); if (popper.value && target) { const menu = (_c = (_b = (_a = popper.value) === null || _a === void 0 ? void 0 : _a.popperRef) === null || _b === void 0 ? void 0 : _b.querySelector) === null || _c === void 0 ? void 0 : _c.call(_b, '.el-select-dropdown__wrap'); if (menu) { scrollIntoView__default['default'](menu, target); } } (_d = scrollbar.value) === null || _d === void 0 ? void 0 : _d.handleScroll(); }; const onOptionCreate = (vm) => { states.optionsCount++; states.filteredOptionsCount++; states.options.push(vm); states.cachedOptions.push(vm); }; const onOptionDestroy = (index) => { if (index > -1) { states.optionsCount--; states.filteredOptionsCount--; states.options.splice(index, 1); } }; const resetInputState = (e) => { if (e.code !== aria.EVENT_CODE.backspace) toggleLastOptionHitState(false); states.inputLength = input.value.length * 15 + 20; resetInputHeight(); }; const toggleLastOptionHitState = (hit) => { if (!Array.isArray(states.selected)) return; const option = states.selected[states.selected.length - 1]; if (!option) return; if (hit === true || hit === false) { option.hitState = hit; return hit; } option.hitState = !option.hitState; return option.hitState; }; const handleComposition = event => { const text = event.target.value; if (event.type === 'compositionend') { states.isOnComposition = false; vue.nextTick(() => handleQueryChange(text)); } else { const lastCharacter = text[text.length - 1] || ''; states.isOnComposition = !isDef.isKorean(lastCharacter); } }; const handleMenuEnter = () => { vue.nextTick(() => scrollToOption(states.selected)); }; const handleFocus = event => { if (!states.softFocus) { if (props.automaticDropdown || props.filterable) { states.visible = true; if (props.filterable) { states.menuVisibleOnFocus = true; } } ctx.emit('focus', event); } else { states.softFocus = false; } }; const blur = () => { states.visible = false; reference.value.blur(); }; const handleBlur = (event) => { vue.nextTick(() => { if (states.isSilentBlur) { states.isSilentBlur = false; } else { ctx.emit('blur', event); } }); states.softFocus = false; }; const handleClearClick = (event) => { deleteSelected(event); }; const handleClose = () => { states.visible = false; }; const toggleMenu = () => { if (props.automaticDropdown) return; if (!selectDisabled.value) { if (states.menuVisibleOnFocus) { states.menuVisibleOnFocus = false; } else { states.visible = !states.visible; } if (states.visible) { (input.value || reference.value).focus(); } } }; const selectOption = () => { if (!states.visible) { toggleMenu(); } else { if (states.options[states.hoverIndex]) { handleOptionSelect(states.options[states.hoverIndex], undefined); } } }; const getValueKey = item => { return isObject(item.value) ? util.getValueByPath(item.value, props.valueKey) : item.value; }; const optionsAllDisabled = vue.computed(() => states.options.filter(option => option.visible).every(option => option.disabled)); const navigateOptions = direction => { if (!states.visible) { states.visible = true; return; } if (states.options.length === 0 || states.filteredOptionsCount === 0) return; if (!optionsAllDisabled.value) { if (direction === 'next') { states.hoverIndex++; if (states.hoverIndex === states.options.length) { states.hoverIndex = 0; } } else if (direction === 'prev') { states.hoverIndex--; if (states.hoverIndex < 0) { states.hoverIndex = states.options.length - 1; } } const option = states.options[states.hoverIndex]; if (option.disabled === true || option.groupDisabled === true || !option.visible) { navigateOptions(direction); } vue.nextTick(() => scrollToOption(hoverOption.value)); } }; return { selectSize, handleResize, debouncedOnInputChange, debouncedQueryChange, deletePrevTag, deleteTag, deleteSelected, handleOptionSelect, scrollToOption, readonly, resetInputHeight, showClose, iconClass, showNewOption, collapseTagSize, setSelected, managePlaceholder, selectDisabled, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, onOptionCreate, onOptionDestroy, handleMenuEnter, handleFocus, blur, handleBlur, handleClearClick, handleClose, toggleMenu, selectOption, getValueKey, navigateOptions, dropMenuVisible, reference, input, popper, tags, selectWrapper, scrollbar, }; }; var script$2 = vue.defineComponent({ name: 'ElSelect', componentName: 'ElSelect', components: { ElInput: ElInput__default['default'], ElSelectMenu: script$1, ElOption: script, ElTag: ElTag__default['default'], ElScrollbar: ElScrollbar__default['default'], ElPopper: ElPopper__default['default'], }, directives: { ClickOutside: directives.ClickOutside }, props: { name: String, id: String, modelValue: [Array, String, Number, Boolean, Object], autocomplete: { type: String, default: 'off', }, automaticDropdown: Boolean, size: { type: String, validator: validators.isValidComponentSize, }, disabled: Boolean, clearable: Boolean, filterable: Boolean, allowCreate: Boolean, loading: Boolean, popperClass: { type: String, default: '', }, remote: Boolean, loadingText: String, noMatchText: String, noDataText: String, remoteMethod: Function, filterMethod: Function, multiple: Boolean, multipleLimit: { type: Number, default: 0, }, placeholder: { type: String, }, defaultFirstOption: Boolean, reserveKeyword: Boolean, valueKey: { type: String, default: 'value', }, collapseTags: Boolean, popperAppendToBody: { type: Boolean, default: true, }, clearIcon: { type: String, default: 'el-icon-circle-close', }, }, emits: [constants.UPDATE_MODEL_EVENT, constants.CHANGE_EVENT, 'remove-tag', 'clear', 'visible-change', 'focus', 'blur'], setup(props, ctx) { const states = useSelectStates(props); const { selectSize, readonly, handleResize, collapseTagSize, debouncedOnInputChange, debouncedQueryChange, deletePrevTag, deleteTag, deleteSelected, handleOptionSelect, scrollToOption, setSelected, resetInputHeight, managePlaceholder, showClose, selectDisabled, iconClass, showNewOption, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, onOptionCreate, onOptionDestroy, handleMenuEnter, handleFocus, blur, handleBlur, handleClearClick, handleClose, toggleMenu, selectOption, getValueKey, navigateOptions, dropMenuVisible, reference, input, popper, tags, selectWrapper, scrollbar, } = useSelect(props, states, ctx); const { focus } = hooks.useFocus(reference); const { inputWidth, selected, inputLength, filteredOptionsCount, visible, softFocus, selectedLabel, hoverIndex, query, inputHovering, currentPlaceholder, menuVisibleOnFocus, isOnComposition, isSilentBlur, options, cachedOptions, optionsCount, } = vue.toRefs(states); vue.provide(selectKey, vue.reactive({ props, options, cachedOptions, optionsCount, filteredOptionsCount, hoverIndex, handleOptionSelect, selectEmitter: states.selectEmitter, onOptionCreate, onOptionDestroy, selectWrapper, selected, setSelected, })); vue.onMounted(() => { states.cachedPlaceHolder = currentPlaceholder.value = (props.placeholder || locale.t('el.select.placeholder')); if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) { currentPlaceholder.value = ''; } resizeEvent.addResizeListener(selectWrapper.value, handleResize); if (reference.value && reference.value.$el) { const sizeMap = { medium: 36, small: 32, mini: 28, }; const input = reference.value.input; states.initialInputHeight = input.getBoundingClientRect().height || sizeMap[selectSize.value]; } if (props.remote && props.multiple) { resetInputHeight(); } vue.nextTick(() => { if (reference.value.$el) { inputWidth.value = reference.value.$el.getBoundingClientRect().width; } }); setSelected(); }); vue.onBeforeUnmount(() => { resizeEvent.removeResizeListener(selectWrapper.value, handleResize); }); if (props.multiple && !Array.isArray(props.modelValue)) { ctx.emit(constants.UPDATE_MODEL_EVENT, []); } if (!props.multiple && Array.isArray(props.modelValue)) { ctx.emit(constants.UPDATE_MODEL_EVENT, ''); } const popperPaneRef = vue.computed(() => { var _a; return (_a = popper.value) === null || _a === void 0 ? void 0 : _a.popperRef; }); return { selectSize, readonly, handleResize, collapseTagSize, debouncedOnInputChange, debouncedQueryChange, deletePrevTag, deleteTag, deleteSelected, handleOptionSelect, scrollToOption, inputWidth, selected, inputLength, filteredOptionsCount, visible, softFocus, selectedLabel, hoverIndex, query, inputHovering, currentPlaceholder, menuVisibleOnFocus, isOnComposition, isSilentBlur, options, resetInputHeight, managePlaceholder, showClose, selectDisabled, iconClass, showNewOption, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, handleMenuEnter, handleFocus, blur, handleBlur, handleClearClick, handleClose, toggleMenu, selectOption, getValueKey, navigateOptions, dropMenuVisible, focus, reference, input, popper, popperPaneRef, tags, selectWrapper, scrollbar, }; }, }); const _hoisted_1 = { class: "select-trigger" }; const _hoisted_2 = { key: 0 }; const _hoisted_3 = { class: "el-select__tags-text" }; const _hoisted_4 = { key: 1, class: "el-select-dropdown__empty" }; function render$2(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_tag = vue.resolveComponent("el-tag"); const _component_el_input = vue.resolveComponent("el-input"); const _component_el_option = vue.resolveComponent("el-option"); const _component_el_scrollbar = vue.resolveComponent("el-scrollbar"); const _component_el_select_menu = vue.resolveComponent("el-select-menu"); const _component_el_popper = vue.resolveComponent("el-popper"); const _directive_click_outside = vue.resolveDirective("click-outside"); return vue.withDirectives((vue.openBlock(), vue.createBlock("div", { ref: "selectWrapper", class: ["el-select", [_ctx.selectSize ? 'el-select--' + _ctx.selectSize : '']], onClick: _cache[26] || (_cache[26] = vue.withModifiers((...args) => (_ctx.toggleMenu && _ctx.toggleMenu(...args)), ["stop"])) }, [ vue.createVNode(_component_el_popper, { ref: "popper", visible: _ctx.dropMenuVisible, "onUpdate:visible": _cache[25] || (_cache[25] = $event => (_ctx.dropMenuVisible = $event)), placement: "bottom-start", "append-to-body": _ctx.popperAppendToBody, "popper-class": `el-select__popper ${_ctx.popperClass}`, "manual-mode": "", effect: "light", pure: "", trigger: "click", transition: "el-zoom-in-top", "stop-popper-mouse-event": false, "gpu-acceleration": false, onBeforeEnter: _ctx.handleMenuEnter }, { trigger: vue.withCtx(() => [ vue.createVNode("div", _hoisted_1, [ (_ctx.multiple) ? (vue.openBlock(), vue.createBlock("div", { key: 0, ref: "tags", class: "el-select__tags", style: { 'max-width': _ctx.inputWidth - 32 + 'px', width: '100%' } }, [ (_ctx.collapseTags && _ctx.selected.length) ? (vue.openBlock(), vue.createBlock("span", _hoisted_2, [ vue.createVNode(_component_el_tag, { closable: !_ctx.selectDisabled, size: _ctx.collapseTagSize, hit: _ctx.selected[0].hitState, type: "info", "disable-transitions": "", onClose: _cache[1] || (_cache[1] = $event => (_ctx.deleteTag($event, _ctx.selected[0]))) }, { default: vue.withCtx(() => [ vue.createVNode("span", { class: "el-select__tags-text", style: { 'max-width': _ctx.inputWidth - 123 + 'px' } }, vue.toDisplayString(_ctx.selected[0].currentLabel), 5 /* TEXT, STYLE */) ]), _: 1 /* STABLE */ }, 8 /* PROPS */, ["closable", "size", "hit"]), (_ctx.selected.length > 1) ? (vue.openBlock(), vue.createBlock(_component_el_tag, { key: 0, closable: false, size: _ctx.collapseTagSize, type: "info", "disable-transitions": "" }, { default: vue.withCtx(() => [ vue.createVNode("span", _hoisted_3, "+ " + vue.toDisplayString(_ctx.selected.length - 1), 1 /* TEXT */) ]), _: 1 /* STABLE */ }, 8 /* PROPS */, ["size"])) : vue.createCommentVNode("v-if", true) ])) : vue.createCommentVNode("v-if", true), vue.createCommentVNode(" <div> "), (!_ctx.collapseTags) ? (vue.openBlock(), vue.createBlock(vue.Transition, { key: 1, onAfterLeave: _ctx.resetInputHeight }, { default: vue.withCtx(() => [ vue.createVNode("span", null, [ (vue.openBlock(true), vue.createBlock(vue.Fragment, null, vue.renderList(_ctx.selected, (item) => { return (vue.openBlock(), vue.createBlock(_component_el_tag, { key: _ctx.getValueKey(item), closable: !_ctx.selectDisabled, size: _ctx.collapseTagSize, hit: item.hitState, type: "info", "disable-transitions": "", onClose: $event => (_ctx.deleteTag($event, item)) }, { default: vue.withCtx(() => [ vue.createVNode("span", { class: "el-select__tags-text", style: { 'max-width': _ctx.inputWidth - 75 + 'px' } }, vue.toDisplayString(item.currentLabel), 5 /* TEXT, STYLE */) ]), _: 2 /* DYNAMIC */ }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["closable", "size", "hit", "onClose"])) }), 128 /* KEYED_FRAGMENT */)) ]) ]), _: 1 /* STABLE */ }, 8 /* PROPS */, ["onAfterLeave"])) : vue.createCommentVNode("v-if", true), vue.createCommentVNode(" </div> "), (_ctx.filterable) ? vue.withDirectives((vue.openBlock(), vue.createBlock("input", { key: 2, ref: "input", "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => (_ctx.query = $event)), type: "text", class: ["el-select__input", [_ctx.selectSize ? `is-${ _ctx.selectSize }` : '']], disabled: _ctx.selectDisabled, autocomplete: _ctx.autocomplete, style: { 'flex-grow': '1', width: _ctx.inputLength / (_ctx.inputWidth - 32) + '%', 'max-width': _ctx.inputWidth - 42 + 'px' }, onFocus: _cache[3] || (_cache[3] = (...args) => (_ctx.handleFocus && _ctx.handleFocus(...args))), onBlur: _cache[4] || (_cache[4] = $event => (_ctx.softFocus = false)), onKeyup: _cache[5] || (_cache[5] = (...args) => (_ctx.managePlaceholder && _ctx.managePlaceholder(...args))), onKeydown: [ _cache[6] || (_cache[6] = (...args) => (_ctx.resetInputState && _ctx.resetInputState(...args))), _cache[7] || (_cache[7] = vue.withKeys(vue.withModifiers($event => (_ctx.navigateOptions('next')), ["prevent"]), ["down"])), _cache[8] || (_cache[8] = vue.withKeys(vue.withModifiers($event => (_ctx.navigateOptions('prev')), ["prevent"]), ["up"])), _cache[9] || (_cache[9] = vue.withKeys(vue.withModifiers($event => (_ctx.visible = false), ["stop","prevent"]), ["esc"])), _cache[10] || (_cache[10] = vue.withKeys(vue.withModifiers((...args) => (_ctx.selectOption && _ctx.selectOption(...args)), ["stop","prevent"]), ["enter"])), _cache[11] || (_cache[11] = vue.withKeys((...args) => (_ctx.deletePrevTag && _ctx.deletePrevTag(...args)), ["delete"])), _cache[12] || (_cache[12] = vue.withKeys($event => (_ctx.visible = false), ["tab"])) ], onCompositionstart: _cache[13] || (_cache[13] = (...args) => (_ctx.handleComposition && _ctx.handleComposition(...args))), onCompositionupdate: _cache[14] || (_cache[14] = (...args) => (_ctx.handleComposition && _ctx.handleComposition(...args))), onCompositionend: _cache[15] || (_cache[15] = (...args) => (_ctx.handleComposition && _ctx.handleComposit