UNPKG

element-plus

Version:

A Component Library for Vue 3

657 lines (652 loc) 26.7 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); require('../../../directives/index.js'); require('../../../hooks/index.js'); var index = require('../../input/index.js'); var index$3 = require('../../tooltip/index.js'); var index$2 = require('../../scrollbar/index.js'); var index$1 = require('../../tag/index.js'); var index$4 = require('../../icon/index.js'); require('../../popper/index.js'); require('../../../constants/index.js'); require('../../../utils/index.js'); var iconsVue = require('@element-plus/icons-vue'); var option = require('./option.js'); var selectDropdown = require('./select-dropdown.js'); var useSelect = require('./useSelect.js'); var token = require('./token.js'); var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js'); var index$5 = require('../../../directives/click-outside/index.js'); var validator = require('../../../utils/vue/validator.js'); var tooltip = require('../../tooltip/src/tooltip.js'); var tag = require('../../tag/src/tag.js'); var event = require('../../../constants/event.js'); var index$6 = require('../../../hooks/use-namespace/index.js'); var index$7 = require('../../../hooks/use-locale/index.js'); var index$8 = require('../../../hooks/use-focus/index.js'); var resizeEvent = require('../../../utils/dom/resize-event.js'); var size = require('../../../utils/vue/size.js'); var deprecation = require('../../popper/src/deprecation.js'); const COMPONENT_NAME = "ElSelect"; const _sfc_main = vue.defineComponent({ name: COMPONENT_NAME, componentName: COMPONENT_NAME, components: { ElInput: index.ElInput, ElSelectMenu: selectDropdown["default"], ElOption: option["default"], ElTag: index$1.ElTag, ElScrollbar: index$2.ElScrollbar, ElTooltip: index$3.ElTooltip, ElIcon: index$4.ElIcon }, directives: { ClickOutside: index$5["default"] }, props: { name: String, id: String, modelValue: { type: [Array, String, Number, Boolean, Object], default: void 0 }, autocomplete: { type: String, default: "off" }, automaticDropdown: Boolean, size: { type: String, validator: validator.isValidComponentSize }, effect: { type: String, default: "light" }, 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: { type: Boolean, default: true }, valueKey: { type: String, default: "value" }, collapseTags: Boolean, collapseTagsTooltip: { type: Boolean, default: false }, popperAppendToBody: { type: Boolean, default: void 0 }, teleported: tooltip.useTooltipContentProps.teleported, persistent: { type: Boolean, default: true }, clearIcon: { type: [String, Object], default: iconsVue.CircleClose }, fitInputWidth: { type: Boolean, default: false }, suffixIcon: { type: [String, Object], default: iconsVue.ArrowUp }, tagType: { ...tag.tagProps.type, default: "info" } }, emits: [ event.UPDATE_MODEL_EVENT, event.CHANGE_EVENT, "remove-tag", "clear", "visible-change", "focus", "blur" ], setup(props, ctx) { const nsSelect = index$6.useNamespace("select"); const nsInput = index$6.useNamespace("input"); const { t } = index$7.useLocale(); const states = useSelect.useSelectStates(props); const { optionsArray, selectSize, readonly, handleResize, collapseTagSize, debouncedOnInputChange, debouncedQueryChange, deletePrevTag, deleteTag, deleteSelected, handleOptionSelect, scrollToOption, setSelected, resetInputHeight, managePlaceholder, showClose, selectDisabled, iconComponent, iconReverse, showNewOption, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, onOptionCreate, onOptionDestroy, handleMenuEnter, handleFocus, blur, handleBlur, handleClearClick, handleClose, toggleMenu, selectOption, getValueKey, navigateOptions, dropMenuVisible, reference, input, tooltipRef, tags, selectWrapper, scrollbar, queryChange, groupQueryChange } = useSelect.useSelect(props, states, ctx); const { focus } = index$8.useFocus(reference); const { inputWidth, selected, inputLength, filteredOptionsCount, visible, softFocus, selectedLabel, hoverIndex, query, inputHovering, currentPlaceholder, menuVisibleOnFocus, isOnComposition, isSilentBlur, options, cachedOptions, optionsCount, prefixWidth, tagInMultiLine } = vue.toRefs(states); const wrapperKls = vue.computed(() => { const classList = [nsSelect.b()]; const _selectSize = vue.unref(selectSize); if (_selectSize) { classList.push(nsSelect.m(_selectSize)); } if (props.disabled) { classList.push(nsSelect.m("disabled")); } return classList; }); const selectTagsStyle = vue.computed(() => ({ maxWidth: `${vue.unref(inputWidth) - 32}px`, width: "100%" })); vue.provide(token.selectKey, vue.reactive({ props, options, optionsArray, cachedOptions, optionsCount, filteredOptionsCount, hoverIndex, handleOptionSelect, onOptionCreate, onOptionDestroy, selectWrapper, selected, setSelected, queryChange, groupQueryChange })); vue.onMounted(() => { states.cachedPlaceHolder = currentPlaceholder.value = props.placeholder || 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 input2 = reference.value.input; states.initialInputHeight = input2.getBoundingClientRect().height || size.getComponentSize(selectSize.value); } if (props.remote && props.multiple) { resetInputHeight(); } vue.nextTick(() => { const refEl = reference.value && reference.value.$el; if (!refEl) return; inputWidth.value = refEl.getBoundingClientRect().width; if (ctx.slots.prefix) { const prefix = refEl.querySelector(`.${nsInput.e("prefix")}`); prefixWidth.value = Math.max(prefix.getBoundingClientRect().width + 5, 30); } }); setSelected(); }); vue.onBeforeUnmount(() => { resizeEvent.removeResizeListener(selectWrapper.value, handleResize); }); if (props.multiple && !Array.isArray(props.modelValue)) { ctx.emit(event.UPDATE_MODEL_EVENT, []); } if (!props.multiple && Array.isArray(props.modelValue)) { ctx.emit(event.UPDATE_MODEL_EVENT, ""); } const popperPaneRef = vue.computed(() => { var _a, _b; return (_b = (_a = tooltipRef.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.contentRef; }); const { compatTeleported } = deprecation.useDeprecateAppendToBody(COMPONENT_NAME, "popperAppendToBody"); return { tagInMultiLine, prefixWidth, 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, iconComponent, iconReverse, showNewOption, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, handleMenuEnter, handleFocus, blur, handleBlur, handleClearClick, handleClose, toggleMenu, selectOption, getValueKey, navigateOptions, dropMenuVisible, focus, reference, input, tooltipRef, popperPaneRef, tags, selectWrapper, scrollbar, wrapperKls, selectTagsStyle, compatTeleported, nsSelect }; } }); const _hoisted_1 = { class: "select-trigger" }; const _hoisted_2 = ["disabled", "autocomplete"]; const _hoisted_3 = { style: { "height": "100%", "display": "flex", "justify-content": "center", "align-items": "center" } }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_tag = vue.resolveComponent("el-tag"); const _component_el_tooltip = vue.resolveComponent("el-tooltip"); const _component_el_icon = vue.resolveComponent("el-icon"); 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 _directive_click_outside = vue.resolveDirective("click-outside"); return vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", { ref: "selectWrapper", class: vue.normalizeClass(_ctx.wrapperKls), onClick: _cache[24] || (_cache[24] = vue.withModifiers((...args) => _ctx.toggleMenu && _ctx.toggleMenu(...args), ["stop"])) }, [ vue.createVNode(_component_el_tooltip, { ref: "tooltipRef", visible: _ctx.dropMenuVisible, "onUpdate:visible": _cache[23] || (_cache[23] = ($event) => _ctx.dropMenuVisible = $event), placement: "bottom-start", teleported: _ctx.compatTeleported, "popper-class": [_ctx.nsSelect.e("popper"), _ctx.popperClass], "fallback-placements": ["bottom-start", "top-start", "right", "left"], effect: _ctx.effect, pure: "", trigger: "click", transition: `${_ctx.nsSelect.namespace.value}-zoom-in-top`, "stop-popper-mouse-event": false, "gpu-acceleration": false, persistent: _ctx.persistent, onShow: _ctx.handleMenuEnter }, { default: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_1, [ _ctx.multiple ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, ref: "tags", class: vue.normalizeClass(_ctx.nsSelect.e("tags")), style: vue.normalizeStyle(_ctx.selectTagsStyle) }, [ _ctx.collapseTags && _ctx.selected.length ? (vue.openBlock(), vue.createElementBlock("span", { key: 0, class: vue.normalizeClass([ _ctx.nsSelect.b("tags-wrapper"), { "has-prefix": _ctx.prefixWidth && _ctx.selected.length } ]) }, [ vue.createVNode(_component_el_tag, { closable: !_ctx.selectDisabled && !_ctx.selected[0].isDisabled, size: _ctx.collapseTagSize, hit: _ctx.selected[0].hitState, type: _ctx.tagType, "disable-transitions": "", onClose: _cache[0] || (_cache[0] = ($event) => _ctx.deleteTag($event, _ctx.selected[0])) }, { default: vue.withCtx(() => [ vue.createElementVNode("span", { class: vue.normalizeClass(_ctx.nsSelect.e("tags-text")), style: vue.normalizeStyle({ maxWidth: _ctx.inputWidth - 123 + "px" }) }, vue.toDisplayString(_ctx.selected[0].currentLabel), 7) ]), _: 1 }, 8, ["closable", "size", "hit", "type"]), _ctx.selected.length > 1 ? (vue.openBlock(), vue.createBlock(_component_el_tag, { key: 0, closable: false, size: _ctx.collapseTagSize, type: _ctx.tagType, "disable-transitions": "" }, { default: vue.withCtx(() => [ _ctx.collapseTagsTooltip ? (vue.openBlock(), vue.createBlock(_component_el_tooltip, { key: 0, disabled: _ctx.dropMenuVisible, "fallback-placements": ["bottom", "top", "right", "left"], effect: _ctx.effect, placement: "bottom", teleported: false }, { default: vue.withCtx(() => [ vue.createElementVNode("span", { class: vue.normalizeClass(_ctx.nsSelect.e("tags-text")) }, "+ " + vue.toDisplayString(_ctx.selected.length - 1), 3) ]), content: vue.withCtx(() => [ vue.createElementVNode("div", { class: vue.normalizeClass(_ctx.nsSelect.e("collapse-tags")) }, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.selected, (item, idx) => { return vue.openBlock(), vue.createElementBlock("div", { key: idx, class: vue.normalizeClass(_ctx.nsSelect.e("collapse-tag")) }, [ (vue.openBlock(), vue.createBlock(_component_el_tag, { key: _ctx.getValueKey(item), class: "in-tooltip", closable: !_ctx.selectDisabled && !item.isDisabled, size: _ctx.collapseTagSize, hit: item.hitState, type: _ctx.tagType, "disable-transitions": "", style: { margin: "2px" }, onClose: ($event) => _ctx.deleteTag($event, item) }, { default: vue.withCtx(() => [ vue.createElementVNode("span", { class: vue.normalizeClass(_ctx.nsSelect.e("tags-text")), style: vue.normalizeStyle({ maxWidth: _ctx.inputWidth - 75 + "px" }) }, vue.toDisplayString(item.currentLabel), 7) ]), _: 2 }, 1032, ["closable", "size", "hit", "type", "onClose"])) ], 2); }), 128)) ], 2) ]), _: 1 }, 8, ["disabled", "effect"])) : (vue.openBlock(), vue.createElementBlock("span", { key: 1, class: vue.normalizeClass(_ctx.nsSelect.e("tags-text")) }, "+ " + vue.toDisplayString(_ctx.selected.length - 1), 3)) ]), _: 1 }, 8, ["size", "type"])) : vue.createCommentVNode("v-if", true) ], 2)) : 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.createElementVNode("span", { class: vue.normalizeClass([ _ctx.nsSelect.b("tags-wrapper"), { "has-prefix": _ctx.prefixWidth && _ctx.selected.length } ]) }, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.selected, (item) => { return vue.openBlock(), vue.createBlock(_component_el_tag, { key: _ctx.getValueKey(item), closable: !_ctx.selectDisabled && !item.isDisabled, size: _ctx.collapseTagSize, hit: item.hitState, type: _ctx.tagType, "disable-transitions": "", onClose: ($event) => _ctx.deleteTag($event, item) }, { default: vue.withCtx(() => [ vue.createElementVNode("span", { class: vue.normalizeClass(_ctx.nsSelect.e("tags-text")), style: vue.normalizeStyle({ maxWidth: _ctx.inputWidth - 75 + "px" }) }, vue.toDisplayString(item.currentLabel), 7) ]), _: 2 }, 1032, ["closable", "size", "hit", "type", "onClose"]); }), 128)) ], 2) ]), _: 1 }, 8, ["onAfterLeave"])) : vue.createCommentVNode("v-if", true), vue.createCommentVNode(" </div> "), _ctx.filterable ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", { key: 2, ref: "input", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.query = $event), type: "text", class: vue.normalizeClass([_ctx.nsSelect.e("input"), _ctx.nsSelect.is(_ctx.selectSize)]), disabled: _ctx.selectDisabled, autocomplete: _ctx.autocomplete, style: vue.normalizeStyle({ marginLeft: _ctx.prefixWidth && !_ctx.selected.length || _ctx.tagInMultiLine ? `${_ctx.prefixWidth}px` : "", flexGrow: 1, width: `${_ctx.inputLength / (_ctx.inputWidth - 32)}%`, maxWidth: `${_ctx.inputWidth - 42}px` }), onFocus: _cache[2] || (_cache[2] = (...args) => _ctx.handleFocus && _ctx.handleFocus(...args)), onBlur: _cache[3] || (_cache[3] = (...args) => _ctx.handleBlur && _ctx.handleBlur(...args)), onKeyup: _cache[4] || (_cache[4] = (...args) => _ctx.managePlaceholder && _ctx.managePlaceholder(...args)), onKeydown: [ _cache[5] || (_cache[5] = (...args) => _ctx.resetInputState && _ctx.resetInputState(...args)), _cache[6] || (_cache[6] = vue.withKeys(vue.withModifiers(($event) => _ctx.navigateOptions("next"), ["prevent"]), ["down"])), _cache[7] || (_cache[7] = vue.withKeys(vue.withModifiers(($event) => _ctx.navigateOptions("prev"), ["prevent"]), ["up"])), _cache[8] || (_cache[8] = vue.withKeys(vue.withModifiers(($event) => _ctx.visible = false, ["stop", "prevent"]), ["esc"])), _cache[9] || (_cache[9] = vue.withKeys(vue.withModifiers((...args) => _ctx.selectOption && _ctx.selectOption(...args), ["stop", "prevent"]), ["enter"])), _cache[10] || (_cache[10] = vue.withKeys((...args) => _ctx.deletePrevTag && _ctx.deletePrevTag(...args), ["delete"])), _cache[11] || (_cache[11] = vue.withKeys(($event) => _ctx.visible = false, ["tab"])) ], onCompositionstart: _cache[12] || (_cache[12] = (...args) => _ctx.handleComposition && _ctx.handleComposition(...args)), onCompositionupdate: _cache[13] || (_cache[13] = (...args) => _ctx.handleComposition && _ctx.handleComposition(...args)), onCompositionend: _cache[14] || (_cache[14] = (...args) => _ctx.handleComposition && _ctx.handleComposition(...args)), onInput: _cache[15] || (_cache[15] = (...args) => _ctx.debouncedQueryChange && _ctx.debouncedQueryChange(...args)) }, null, 46, _hoisted_2)), [ [vue.vModelText, _ctx.query] ]) : vue.createCommentVNode("v-if", true) ], 6)) : vue.createCommentVNode("v-if", true), vue.createVNode(_component_el_input, { id: _ctx.id, ref: "reference", modelValue: _ctx.selectedLabel, "onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => _ctx.selectedLabel = $event), type: "text", placeholder: _ctx.currentPlaceholder, name: _ctx.name, autocomplete: _ctx.autocomplete, size: _ctx.selectSize, disabled: _ctx.selectDisabled, readonly: _ctx.readonly, "validate-event": false, class: vue.normalizeClass([_ctx.nsSelect.is("focus", _ctx.visible)]), tabindex: _ctx.multiple && _ctx.filterable ? -1 : void 0, onFocus: _ctx.handleFocus, onBlur: _ctx.handleBlur, onInput: _ctx.debouncedOnInputChange, onPaste: _ctx.debouncedOnInputChange, onCompositionstart: _ctx.handleComposition, onCompositionupdate: _ctx.handleComposition, onCompositionend: _ctx.handleComposition, onKeydown: [ _cache[17] || (_cache[17] = vue.withKeys(vue.withModifiers(($event) => _ctx.navigateOptions("next"), ["stop", "prevent"]), ["down"])), _cache[18] || (_cache[18] = vue.withKeys(vue.withModifiers(($event) => _ctx.navigateOptions("prev"), ["stop", "prevent"]), ["up"])), vue.withKeys(vue.withModifiers(_ctx.selectOption, ["stop", "prevent"]), ["enter"]), _cache[19] || (_cache[19] = vue.withKeys(vue.withModifiers(($event) => _ctx.visible = false, ["stop", "prevent"]), ["esc"])), _cache[20] || (_cache[20] = vue.withKeys(($event) => _ctx.visible = false, ["tab"])) ], onMouseenter: _cache[21] || (_cache[21] = ($event) => _ctx.inputHovering = true), onMouseleave: _cache[22] || (_cache[22] = ($event) => _ctx.inputHovering = false) }, vue.createSlots({ suffix: vue.withCtx(() => [ _ctx.iconComponent && !_ctx.showClose ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 0, class: vue.normalizeClass([_ctx.nsSelect.e("caret"), _ctx.nsSelect.e("icon"), _ctx.iconReverse]) }, { default: vue.withCtx(() => [ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.iconComponent))) ]), _: 1 }, 8, ["class"])) : vue.createCommentVNode("v-if", true), _ctx.showClose && _ctx.clearIcon ? (vue.openBlock(), vue.createBlock(_component_el_icon, { key: 1, class: vue.normalizeClass([_ctx.nsSelect.e("caret"), _ctx.nsSelect.e("icon")]), onClick: _ctx.handleClearClick }, { default: vue.withCtx(() => [ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.clearIcon))) ]), _: 1 }, 8, ["class", "onClick"])) : vue.createCommentVNode("v-if", true) ]), _: 2 }, [ _ctx.$slots.prefix ? { name: "prefix", fn: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_3, [ vue.renderSlot(_ctx.$slots, "prefix") ]) ]) } : void 0 ]), 1032, ["id", "modelValue", "placeholder", "name", "autocomplete", "size", "disabled", "readonly", "class", "tabindex", "onFocus", "onBlur", "onInput", "onPaste", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onKeydown"]) ]) ]), content: vue.withCtx(() => [ vue.createVNode(_component_el_select_menu, null, { default: vue.withCtx(() => [ vue.withDirectives(vue.createVNode(_component_el_scrollbar, { ref: "scrollbar", tag: "ul", "wrap-class": _ctx.nsSelect.be("dropdown", "wrap"), "view-class": _ctx.nsSelect.be("dropdown", "list"), class: vue.normalizeClass([ _ctx.nsSelect.is("empty", !_ctx.allowCreate && Boolean(_ctx.query) && _ctx.filteredOptionsCount === 0) ]) }, { default: vue.withCtx(() => [ _ctx.showNewOption ? (vue.openBlock(), vue.createBlock(_component_el_option, { key: 0, value: _ctx.query, created: true }, null, 8, ["value"])) : vue.createCommentVNode("v-if", true), vue.renderSlot(_ctx.$slots, "default") ]), _: 3 }, 8, ["wrap-class", "view-class", "class"]), [ [vue.vShow, _ctx.options.size > 0 && !_ctx.loading] ]), _ctx.emptyText && (!_ctx.allowCreate || _ctx.loading || _ctx.allowCreate && _ctx.options.size === 0) ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [ _ctx.$slots.empty ? vue.renderSlot(_ctx.$slots, "empty", { key: 0 }) : (vue.openBlock(), vue.createElementBlock("p", { key: 1, class: vue.normalizeClass(_ctx.nsSelect.be("dropdown", "empty")) }, vue.toDisplayString(_ctx.emptyText), 3)) ], 2112)) : vue.createCommentVNode("v-if", true) ]), _: 3 }) ]), _: 3 }, 8, ["visible", "teleported", "popper-class", "effect", "transition", "persistent", "onShow"]) ], 2)), [ [_directive_click_outside, _ctx.handleClose, _ctx.popperPaneRef] ]); } var Select = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["render", _sfc_render], ["__file", "/home/runner/work/element-plus/element-plus/packages/components/select/src/select.vue"]]); exports["default"] = Select; //# sourceMappingURL=select.js.map