UNPKG

hongluan-ui

Version:
681 lines (678 loc) 26.2 kB
import { defineComponent, toRefs, provide, reactive, onMounted, nextTick, computed, resolveComponent, resolveDirective, withDirectives, openBlock, createElementBlock, normalizeClass, withModifiers, createVNode, withCtx, createElementVNode, withKeys, createSlots, renderSlot, Fragment, renderList, createBlock, createTextVNode, toDisplayString, createCommentVNode, vModelText, vShow } from 'vue'; import { HlInput } from '../../input/index.mjs'; import { placements } from '@popperjs/core'; import { useResizeObserver } from '@vueuse/core'; import { HlTag } from '../../tag/index.mjs'; import { HlTooltip } from '../../tooltip/index.mjs'; import { HlScrollbar } from '../../scrollbar/index.mjs'; import { HlIcon } from '../../icon/index.mjs'; import '../../system-icon/index.mjs'; import '../../popper/index.mjs'; import '../../../directives/index.mjs'; import '../../../utils/index.mjs'; import '../../../hooks/index.mjs'; import '../../../constants/index.mjs'; import { useSelectStates, useSelect } from './useSelect.mjs'; import { selectKey } from './token.mjs'; import HlOption from './option.mjs'; import HlOptions from './options.mjs'; import HlSelectMenu from './select-dropdown.mjs'; import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs'; import SystemSelectArrow from '../../system-icon/src/select-arrow.mjs'; import SystemClose from '../../system-icon/src/close.mjs'; import ClickOutside from '../../../directives/click-outside/index.mjs'; import { isValidComponentSize } from '../../../utils/vue/validator.mjs'; import { useTooltipContentProps } from '../../tooltip/src/content2.mjs'; import { useAriaProps } from '../../../hooks/use-aria/index.mjs'; import { useEmptyValuesProps } from '../../../hooks/use-empty-values/index.mjs'; import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../../../constants/event.mjs'; import { useLocale } from '../../../hooks/use-locale/index.mjs'; import { useNamespace } from '../../../hooks/use-namespace/index.mjs'; import { useId } from '../../../hooks/use-id/index.mjs'; import { useDeprecateAppendToBody } from '../../popper/src/deprecation.mjs'; const _sfc_main = defineComponent({ name: "Select", componentName: "Select", components: { HlInput, HlSelectMenu, HlOption, HlOptions, HlTag, HlScrollbar, HlTooltip, HlIcon, SystemSelectArrow, SystemClose }, directives: { ClickOutside }, 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: isValidComponentSize }, effect: { type: String, default: "" }, disabled: Boolean, clearable: Boolean, filterable: Boolean, allowCreate: Boolean, block: Boolean, loading: Boolean, popperClass: { type: String, default: "" }, popperOptions: { type: Object, 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: Boolean, maxCollapseTags: { type: Number, default: 1 }, popperAppendToBody: { type: Boolean, default: void 0 }, teleported: useTooltipContentProps.teleported, persistent: { type: Boolean, default: true }, fill: Boolean, thin: Boolean, round: Boolean, tagType: { type: String, default: "" }, popperOffset: { type: Number, default: 4 }, validateEvent: { type: Boolean, default: true }, remoteShowSuffix: Boolean, suffixTransition: { type: Boolean, default: true }, placement: { type: String, values: placements, default: "bottom-start" }, ...useAriaProps(["ariaLabel"]), ...useEmptyValuesProps }, emits: [UPDATE_MODEL_EVENT, CHANGE_EVENT, "remove-tag", "clear", "visible-change", "focus", "blur"], setup(props, ctx) { const { t } = useLocale(); const { namespace } = useNamespace(); const states = useSelectStates(props); const contentId = useId(); const { optionList, optionsArray, hoverOption, selectSize, readonly, handleResize, debouncedOnInputChange, debouncedQueryChange, deletePrevTag, deleteTag, deleteSelected, handleOptionSelect, scrollToOption, setSelected, managePlaceholder, showClose, selectDisabled, selectFill, iconClass, showIcon, showNewOption, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, onOptionCreate, onOptionDestroy, handleMenuEnter, handleFocus, blur, focus, handleBlur, handleClearClick, handleClose, handleKeydownEscape, toggleMenu, selectOption, getValueKey, navigateOptions, handleDeleteTooltipTag, dropMenuVisible, queryChange, groupQueryChange, reference, input, tooltipRef, tagTooltipRef, tags, selectWrapper, scrollbar, handleMouseEnter, handleMouseLeave, showTagList, collapseTagList } = useSelect(props, states, ctx); const { selected, filteredOptionsCount, visible, selectedLabel, hoverIndex, query, inputHovering, currentPlaceholder, menuVisibleOnFocus, isOnComposition, options, cachedOptions, optionsCount } = toRefs(states); provide(selectKey, reactive({ props, options, optionsArray, cachedOptions, optionsCount, filteredOptionsCount, hoverIndex, handleOptionSelect, onOptionCreate, onOptionDestroy, selectWrapper, selected, setSelected, queryChange, groupQueryChange })); onMounted(() => { var _a; states.cachedPlaceHolder = currentPlaceholder.value = props.placeholder || (() => t("hl.select.placeholder")); if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) { currentPlaceholder.value = ""; } useResizeObserver(selectWrapper, handleResize); if ((_a = reference.value) == null ? void 0 : _a.$el) { } if (props.remote && props.multiple) { } nextTick(() => { var _a2; if ((_a2 = reference.value) == null ? void 0 : _a2.$el) { } if (ctx.slots.prefix) { } }); setSelected(); }); if (props.multiple && !Array.isArray(props.modelValue)) { ctx.emit(UPDATE_MODEL_EVENT, []); } if (!props.multiple && Array.isArray(props.modelValue)) { ctx.emit(UPDATE_MODEL_EVENT, ""); } const popperPaneRef = computed(() => { var _a, _b; return (_b = (_a = tooltipRef.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.contentRef; }); const { compatTeleported } = useDeprecateAppendToBody("Select", "popperAppendToBody"); const onOptionsRendered = (v) => { optionList.value = v; }; return { namespace, onOptionsRendered, compatTeleported, selectSize, readonly, handleResize, debouncedOnInputChange, debouncedQueryChange, deletePrevTag, deleteTag, handleDeleteTooltipTag, deleteSelected, handleOptionSelect, scrollToOption, selected, filteredOptionsCount, visible, selectedLabel, hoverIndex, query, inputHovering, currentPlaceholder, menuVisibleOnFocus, isOnComposition, options, managePlaceholder, showClose, selectDisabled, selectFill, iconClass, showIcon, showNewOption, emptyText, toggleLastOptionHitState, resetInputState, handleComposition, handleMenuEnter, handleFocus, handleKeydownEscape, blur, handleBlur, handleClearClick, handleClose, toggleMenu, selectOption, getValueKey, navigateOptions, dropMenuVisible, focus, reference, input, tooltipRef, popperPaneRef, tags, selectWrapper, scrollbar, handleMouseEnter, handleMouseLeave, showTagList, collapseTagList, tagTooltipRef, contentId, hoverOption }; } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_hl_tag = resolveComponent("hl-tag"); const _component_hl_tooltip = resolveComponent("hl-tooltip"); const _component_system_select_arrow = resolveComponent("system-select-arrow"); const _component_hl_icon = resolveComponent("hl-icon"); const _component_system_close = resolveComponent("system-close"); const _component_hl_input = resolveComponent("hl-input"); const _component_hl_option = resolveComponent("hl-option"); const _component_hl_options = resolveComponent("hl-options"); const _component_hl_scrollbar = resolveComponent("hl-scrollbar"); const _component_hl_select_menu = resolveComponent("hl-select-menu"); const _directive_click_outside = resolveDirective("click-outside"); return withDirectives((openBlock(), createElementBlock("div", { ref: "selectWrapper", class: normalizeClass([ _ctx.namespace + "-input-select", _ctx.selectSize, _ctx.block ? "block" : "" ]), onMouseenter: _ctx.handleMouseEnter, onMouseleave: _ctx.handleMouseLeave, onClick: withModifiers(_ctx.toggleMenu, ["stop"]) }, [ createVNode(_component_hl_tooltip, { ref: "tooltipRef", visible: _ctx.dropMenuVisible, placement: _ctx.placement, teleported: _ctx.compatTeleported, offset: _ctx.popperOffset, "popper-class": `${_ctx.namespace}-select-popper ${_ctx.popperClass}`, "popper-options": _ctx.popperOptions, "fallback-placements": ["bottom-start", "top-start", "right", "left"], effect: _ctx.effect, trigger: "click", transition: "dropdown", persistent: _ctx.persistent, "show-arrow": false, "stop-popper-mouse-event": false, "gpu-acceleration": false, onShow: _ctx.handleMenuEnter }, { default: withCtx(() => { var _a; return [ createElementVNode("div", { class: "select-trigger", onMouseenter: ($event) => _ctx.inputHovering = true, onMouseleave: ($event) => _ctx.inputHovering = false }, [ createVNode(_component_hl_input, { id: _ctx.id, ref: "reference", modelValue: _ctx.selectedLabel, "onUpdate:modelValue": ($event) => _ctx.selectedLabel = $event, "native-type": "text", placeholder: typeof _ctx.currentPlaceholder === "function" ? _ctx.currentPlaceholder() : _ctx.currentPlaceholder, name: _ctx.name, autocomplete: _ctx.autocomplete, size: _ctx.selectSize, fill: _ctx.selectFill, thin: _ctx.thin, round: _ctx.round, disabled: _ctx.selectDisabled, readonly: _ctx.readonly, "validate-event": false, label: _ctx.ariaLabel, "aria-autocomplete": "none", "aria-haspopup": "listbox", class: normalizeClass({ "is-focus": _ctx.visible, "is-tags": _ctx.selected.length, "is-remote": !_ctx.showIcon }), tabindex: _ctx.multiple && _ctx.filterable ? "-1" : null, role: "combobox", "aria-activedescendant": ((_a = _ctx.hoverOption) == null ? void 0 : _a.id) || "", "aria-controls": _ctx.contentId, "aria-expanded": _ctx.dropMenuVisible, onFocus: _ctx.handleFocus, onBlur: _ctx.handleBlur, onInput: _ctx.debouncedOnInputChange, onPaste: _ctx.debouncedOnInputChange, onCompositionstart: _ctx.handleComposition, onCompositionupdate: _ctx.handleComposition, onCompositionend: _ctx.handleComposition, onKeydown: [ withKeys(withModifiers(($event) => _ctx.navigateOptions("next"), ["stop", "prevent"]), ["down"]), withKeys(withModifiers(($event) => _ctx.navigateOptions("prev"), ["stop", "prevent"]), ["up"]), withKeys(withModifiers(_ctx.selectOption, ["stop", "prevent"]), ["enter"]), withKeys(_ctx.handleKeydownEscape, ["esc"]), withKeys(($event) => _ctx.visible = false, ["tab"]) ] }, createSlots({ suffix: withCtx(() => [ renderSlot(_ctx.$slots, "suffix", { className: `${_ctx.iconClass} ${!_ctx.showClose && _ctx.showIcon ? "visible" : ""}` }, () => [ createVNode(_component_hl_icon, { class: normalizeClass([_ctx.iconClass, !_ctx.showClose && _ctx.showIcon ? "visible" : ""]) }, { default: withCtx(() => [ createVNode(_component_system_select_arrow) ]), _: 1 }, 8, ["class"]) ]), renderSlot(_ctx.$slots, "clear", {}, () => [ createVNode(_component_hl_icon, { class: normalizeClass(["select-close", _ctx.showClose && "visible"]), onClick: _ctx.handleClearClick }, { default: withCtx(() => [ createVNode(_component_system_close) ]), _: 1 }, 8, ["class", "onClick"]) ]) ]), _: 2 }, [ _ctx.multiple ? { name: "tags", fn: withCtx(() => [ withDirectives(createElementVNode("div", { ref: "tags", tabindex: "-1", class: normalizeClass(["input-tags", _ctx.selectDisabled ? "is-disabled" : ""]), onClick: _ctx.focus }, [ _ctx.collapseTags && _ctx.selected.length ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.showTagList, (item) => { return openBlock(), createBlock(_component_hl_tag, { key: _ctx.getValueKey(item), closable: !_ctx.selectDisabled && !item.isDisabled, active: item.hitState, "disable-transitions": "", size: _ctx.selectSize, type: _ctx.tagType, onClose: ($event) => _ctx.deleteTag($event, item) }, { default: withCtx(() => [ createTextVNode(toDisplayString(item.currentLabel), 1) ]), _: 2 }, 1032, ["closable", "active", "size", "type", "onClose"]); }), 128)), _ctx.selected.length > _ctx.maxCollapseTags ? (openBlock(), createBlock(_component_hl_tag, { key: 0, closable: false, "disable-transitions": "", size: _ctx.selectSize, type: _ctx.tagType }, { default: withCtx(() => [ _ctx.collapseTagsTooltip ? (openBlock(), createBlock(_component_hl_tooltip, { key: 0, ref: "tagTooltipRef", disabled: _ctx.dropMenuVisible, "fallback-placements": ["bottom", "top", "right", "left"], effect: _ctx.effect, placement: "bottom", teleported: false, "popper-class": `collapse-tags-popper` }, { default: withCtx(() => [ createTextVNode(" + " + toDisplayString(_ctx.selected.length - _ctx.maxCollapseTags), 1) ]), content: withCtx(() => [ createElementVNode("div", { class: "collapse-tags" }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.collapseTagList, (item) => { return openBlock(), createElementBlock("div", { key: _ctx.getValueKey(item), class: "collapse-tag" }, [ (openBlock(), createBlock(_component_hl_tag, { key: _ctx.getValueKey(item), class: "in-tooltip", closable: !_ctx.selectDisabled && !item.isDisabled, size: _ctx.selectSize, hit: item.hitState, type: _ctx.tagType, "disable-transitions": "", onClose: ($event) => _ctx.handleDeleteTooltipTag($event, item) }, { default: withCtx(() => [ createTextVNode(toDisplayString(item.currentLabel), 1) ]), _: 2 }, 1032, ["closable", "size", "hit", "type", "onClose"])) ]); }), 128)) ]) ]), _: 1 }, 8, ["disabled", "effect"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [ createTextVNode(" + " + toDisplayString(_ctx.selected.length - _ctx.maxCollapseTags), 1) ], 2112)) ]), _: 1 }, 8, ["size", "type"])) : createCommentVNode("v-if", true) ], 64)) : createCommentVNode("v-if", true), !_ctx.collapseTags ? renderSlot(_ctx.$slots, "tag", { key: 1, items: _ctx.selected }, () => [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.selected, (item) => { return openBlock(), createBlock(_component_hl_tag, { key: _ctx.getValueKey(item), closable: !_ctx.selectDisabled && !item.isDisabled, active: item.hitState, "disable-transitions": "", size: _ctx.selectSize, type: _ctx.tagType, onClose: ($event) => _ctx.deleteTag($event, item) }, { default: withCtx(() => [ createTextVNode(toDisplayString(item.currentLabel), 1) ]), _: 2 }, 1032, ["closable", "active", "size", "type", "onClose"]); }), 128)) ]) : createCommentVNode("v-if", true), _ctx.filterable ? withDirectives((openBlock(), createElementBlock("input", { key: 2, ref: "input", "onUpdate:modelValue": ($event) => _ctx.query = $event, type: "text", class: normalizeClass([ "select-input", _ctx.selectSize ? `is-${_ctx.selectSize}` : "", _ctx.selectDisabled ? "is-disabled" : "" ]), "aria-label": _ctx.ariaLabel, disabled: _ctx.selectDisabled, autocomplete: _ctx.autocomplete, onFocus: _ctx.handleFocus, onBlur: _ctx.handleBlur, onKeyup: _ctx.managePlaceholder, onKeydown: [ _ctx.resetInputState, withKeys(withModifiers(($event) => _ctx.navigateOptions("next"), ["prevent"]), ["down"]), withKeys(withModifiers(($event) => _ctx.navigateOptions("prev"), ["prevent"]), ["up"]), withKeys(_ctx.handleKeydownEscape, ["esc"]), withKeys(withModifiers(_ctx.selectOption, ["stop", "prevent"]), ["enter"]), withKeys(_ctx.deletePrevTag, ["delete"]), withKeys(($event) => _ctx.visible = false, ["tab"]) ], onCompositionstart: _ctx.handleComposition, onCompositionupdate: _ctx.handleComposition, onCompositionend: _ctx.handleComposition, onInput: _ctx.debouncedQueryChange }, null, 42, ["onUpdate:modelValue", "aria-label", "disabled", "autocomplete", "onFocus", "onBlur", "onKeyup", "onKeydown", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onInput"])), [ [vModelText, _ctx.query] ]) : createCommentVNode("v-if", true) ], 10, ["onClick"]), [ [vShow, _ctx.selected.length] ]) ]) } : void 0, _ctx.$slots.prefix ? { name: "prefix", fn: withCtx(() => [ createElementVNode("div", null, [ renderSlot(_ctx.$slots, "prefix") ]) ]) } : void 0 ]), 1032, ["id", "modelValue", "onUpdate:modelValue", "placeholder", "name", "autocomplete", "size", "fill", "thin", "round", "disabled", "readonly", "label", "class", "tabindex", "aria-activedescendant", "aria-controls", "aria-expanded", "onFocus", "onBlur", "onInput", "onPaste", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onKeydown"]) ], 40, ["onMouseenter", "onMouseleave"]) ]; }), content: withCtx(() => [ createVNode(_component_hl_select_menu, null, createSlots({ default: withCtx(() => [ withDirectives(createVNode(_component_hl_scrollbar, { id: _ctx.contentId, ref: "scrollbar", tag: "ul", "wrap-class": "select-dropdown-wrap", "view-class": "select-dropdown-list", class: normalizeClass({ "is-empty": !_ctx.allowCreate && Boolean(_ctx.query) && _ctx.filteredOptionsCount === 0 }), role: "listbox", "aria-label": _ctx.ariaLabel, "aria-orientation": "vertical", onAtEnd: ($event) => _ctx.$emit("at-end") }, { default: withCtx(() => [ _ctx.showNewOption ? (openBlock(), createBlock(_component_hl_option, { key: 0, value: _ctx.query, created: true }, null, 8, ["value"])) : createCommentVNode("v-if", true), createVNode(_component_hl_options, { onUpdateOptions: _ctx.onOptionsRendered }, { default: withCtx(() => [ renderSlot(_ctx.$slots, "default") ]), _: 3 }, 8, ["onUpdateOptions"]) ]), _: 3 }, 8, ["id", "class", "aria-label", "onAtEnd"]), [ [vShow, _ctx.options.size > 0 && !_ctx.loading] ]), _ctx.emptyText && (!_ctx.allowCreate || _ctx.loading || _ctx.allowCreate && _ctx.options.size === 0) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ _ctx.$slots.empty ? renderSlot(_ctx.$slots, "empty", { key: 0 }) : (openBlock(), createElementBlock("p", { key: 1, class: "select-dropdown-empty" }, toDisplayString(_ctx.emptyText), 1)) ], 2112)) : createCommentVNode("v-if", true) ]), _: 2 }, [ _ctx.$slots.header ? { name: "header", fn: withCtx(() => [ renderSlot(_ctx.$slots, "header") ]) } : void 0, _ctx.$slots.footer ? { name: "footer", fn: withCtx(() => [ renderSlot(_ctx.$slots, "footer") ]) } : void 0 ]), 1024) ]), _: 3 }, 8, ["visible", "placement", "teleported", "offset", "popper-class", "popper-options", "effect", "persistent", "onShow"]) ], 42, ["onMouseenter", "onMouseleave", "onClick"])), [ [_directive_click_outside, _ctx.handleClose, _ctx.popperPaneRef] ]); } var Select = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { Select as default }; //# sourceMappingURL=select.mjs.map