UNPKG

hongluan-ui

Version:
555 lines (550 loc) 20.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var core = require('@vueuse/core'); var index = require('../../input/index.js'); var index$1 = require('../../tooltip/index.js'); var index$3 = require('../../icon/index.js'); require('../../system-icon/index.js'); var index$2 = require('../../tag/index.js'); require('../../../directives/index.js'); require('../../popper/index.js'); require('../../../hooks/index.js'); require('../../../constants/index.js'); require('../../../utils/index.js'); var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js'); var selectArrow = require('../../system-icon/src/select-arrow.js'); var close = require('../../system-icon/src/close.js'); var index$4 = require('../../../directives/click-outside/index.js'); var validator = require('../../../utils/vue/validator.js'); var content = require('../../tooltip/src/content2.js'); var tag = require('../../tag/src/tag2.js'); var index$5 = require('../../../hooks/use-namespace/index.js'); var index$6 = require('../../../hooks/use-locale/index.js'); var deprecation = require('../../popper/src/deprecation.js'); var index$7 = require('../../../hooks/use-composition/index.js'); var index$8 = require('../../../hooks/use-consistent-prop/index.js'); var aria = require('../../../constants/aria.js'); const _sfc_main = vue.defineComponent({ name: "Selector", components: { HlInput: index.HlInput, HlTooltip: index$1.HlTooltip, HlTag: index$2.HlTag, HlIcon: index$3.HlIcon, SystemSelectArrow: selectArrow["default"], SystemClose: close["default"] }, directives: { Clickoutside: index$4["default"] }, props: { size: { type: String, validator: validator.isValidComponentSize }, placeholder: { type: String }, disabled: Boolean, clearable: Boolean, filterable: Boolean, collapseTags: Boolean, maxCollapseTags: { type: Number, default: 1 }, collapseTagsTooltip: { type: Boolean, default: false }, placement: { type: String, default: "bottom-start" }, fallbackPlacements: { type: Array, default: () => [] }, popperClass: { type: String, default: "" }, block: { type: Boolean, default: false }, inputStyle: { type: Object, default: () => ({}) }, multiple: { type: Boolean, default: false }, popperAppendToBody: { type: Boolean, default: void 0 }, teleported: content.useTooltipContentProps.teleported, fill: Boolean, round: Boolean, thin: Boolean, popperOffset: { type: Number, default: 4 }, persistent: { type: Boolean, default: true }, tagType: { ...tag.tagProps.type, default: "" }, tagEffect: { type: String, default: "" } }, emits: [ "focus", "blur", "input", "resize", "after-leave", "keyboard-down", "visible-change", "popper-visible", "remove-tag", "clear" ], setup(props, { emit }) { const { namespace } = index$5.useNamespace("selector"); const { t } = index$6.useLocale(); const { compatTeleported } = deprecation.useDeprecateAppendToBody("Selector", "popperAppendToBody"); const { isComposing, handleComposition } = index$7.useComposition({ afterComposition(event) { var _a; const text = (_a = event.target) == null ? void 0 : _a.value; handleInput(text); } }); let pressDeleteCount = 0; const popper = vue.ref(null); const input = vue.ref(null); const tagWrapper = vue.ref(null); const panel = vue.ref(null); const popperVisible = vue.ref(false); const inputHover = vue.ref(false); const inputValue = vue.ref(""); const searchInputValue = vue.ref(""); const presentTags = vue.ref([]); const allPresentTags = vue.ref([]); const presentText = vue.ref(""); const checkedNodes = vue.ref([]); const { size: realSize, disabled: isDisabled, fill: realFill } = index$8.useConsistentProp(); const readonly = vue.computed(() => !props.filterable); const inputPlaceholder = vue.computed(() => props.placeholder || t("hl.cascader.placeholder")); const clearBtnVisible = vue.computed(() => { if (!props.clearable || isDisabled.value || !inputHover.value) return false; return props.multiple ? !!checkedNodes.value.length : !!presentText.value; }); const currentPlaceholder = vue.computed(() => searchInputValue.value || presentTags.value.length > 0 ? "" : inputPlaceholder.value); const popperPaneRef = vue.computed(() => { var _a, _b; return (_b = (_a = popper.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.contentRef; }); const setValue = (val) => { if (Array.isArray(val)) { checkedNodes.value = [...val]; } else { presentText.value = val; } }; const afterLeave = () => { emit("after-leave"); }; const togglePopperVisible = (visible) => { var _a, _b; if (isDisabled.value) return; visible = visible != null ? visible : !popperVisible.value; if (visible !== popperVisible.value) { popperVisible.value = visible; (_b = (_a = input.value) == null ? void 0 : _a.input) == null ? void 0 : _b.setAttribute("aria-expanded", `${visible}`); if (visible) { updatePopperPosition(); vue.nextTick(() => { emit("popper-visible"); }); } else if (props.filterable) { if (props.multiple) { searchInputValue.value = ""; } else { const { value } = presentText; inputValue.value = value; } emit("input", ""); } emit("visible-change", visible); } }; const updatePopperPosition = () => { var _a; vue.nextTick((_a = popper.value) == null ? void 0 : _a.updatePopper); }; const genTag = (node) => { return { key: String(Math.random()), text: node, hitState: false, closable: !isDisabled.value, isCollapseTag: false }; }; const deleteTag = (tag) => { checkedNodes.value = checkedNodes.value.filter((cn) => cn !== tag.text); !checkedNodes.value.length && resetInput(); emit("remove-tag", tag); }; const calculatePresentTags = () => { if (!props.multiple) return; const nodes = checkedNodes.value; const tags = []; const allTags = []; nodes.forEach((node) => allTags.push(genTag(node))); allPresentTags.value = allTags; if (nodes.length) { nodes.slice(0, props.maxCollapseTags).forEach((node) => tags.push(genTag(node))); const rest = nodes.slice(props.maxCollapseTags); const restCount = rest.length; if (restCount) { if (props.collapseTags) { tags.push({ key: "-1", text: `+ ${restCount}`, closable: false, isCollapseTag: true }); } else { rest.forEach((node) => tags.push(genTag(node))); } } } presentTags.value = tags; }; const updateTags = (cb) => { presentTags.value.forEach(cb); allPresentTags.value.forEach(cb); }; const focusFirstNode = () => { emit("keyboard-down"); }; const updateStyle = () => { var _a; const inputInner = (_a = input.value) == null ? void 0 : _a.input; const tagWrapperEl = tagWrapper.value; if (!core.isClient || !inputInner) return; emit("resize", input.value.$el); if (tagWrapperEl) { updatePopperPosition(); } }; const handleKeyDown = (e) => { if (isComposing.value) return; switch (e.code) { case aria.EVENT_CODE.enter: togglePopperVisible(); break; case aria.EVENT_CODE.down: togglePopperVisible(true); vue.nextTick(focusFirstNode); e.preventDefault(); break; case aria.EVENT_CODE.esc: if (popperVisible.value === true) { e.preventDefault(); e.stopPropagation(); togglePopperVisible(false); } break; case aria.EVENT_CODE.tab: togglePopperVisible(false); break; } }; const handleClear = () => { togglePopperVisible(false); emit("clear"); resetInput(); }; const resetInput = () => { checkedNodes.value = []; presentText.value = ""; inputValue.value = ""; searchInputValue.value = ""; }; const handleDelete = () => { const tags = presentTags.value; const lastTag = tags[tags.length - 1]; pressDeleteCount = searchInputValue.value ? 0 : pressDeleteCount + 1; if (!lastTag || !pressDeleteCount || props.collapseTags && tags.length > 1) return; if (lastTag.hitState) { deleteTag(lastTag); } else { lastTag.hitState = true; } }; const handleInput = (val, e) => { !popperVisible.value && togglePopperVisible(true); if (e == null ? void 0 : e.isComposing) return; emit("input", val); }; vue.watch([checkedNodes, isDisabled, () => props.collapseTags], calculatePresentTags); vue.watch(presentTags, () => { vue.nextTick(() => updateStyle()); }); vue.watch(presentText, (val) => inputValue.value = val, { immediate: true }); vue.onMounted(() => { var _a; const inputEl = (_a = input.value) == null ? void 0 : _a.$el; core.useResizeObserver(inputEl, updateStyle); }); return { namespace, compatTeleported, popper, popperPaneRef, input, tagWrapper, panel, popperVisible, inputHover, presentText, checkedNodes, inputValue, inputPlaceholder, searchInputValue, currentPlaceholder, presentTags, allPresentTags, isDisabled, realSize, realFill, readonly, clearBtnVisible, setValue, afterLeave, t, togglePopperVisible, updatePopperPosition, deleteTag, updateTags, focusFirstNode, handleKeyDown, handleComposition, handleClear, handleDelete, handleInput }; } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_hl_tag = vue.resolveComponent("hl-tag"); const _component_hl_tooltip = vue.resolveComponent("hl-tooltip"); const _component_system_select_arrow = vue.resolveComponent("system-select-arrow"); const _component_hl_icon = vue.resolveComponent("hl-icon"); const _component_system_close = vue.resolveComponent("system-close"); const _component_hl_input = vue.resolveComponent("hl-input"); const _directive_clickoutside = vue.resolveDirective("clickoutside"); return vue.openBlock(), vue.createBlock(_component_hl_tooltip, { ref: "popper", visible: _ctx.popperVisible, teleported: _ctx.compatTeleported, offset: _ctx.popperOffset, placement: _ctx.placement, "popper-class": `${_ctx.namespace}-popper ${_ctx.popperClass}`, "fallback-placements": _ctx.fallbackPlacements, "stop-popper-mouse-event": false, "show-arrow": false, transition: "dropdown", "gpu-acceleration": false, persistent: _ctx.persistent, onHide: _ctx.afterLeave }, { content: vue.withCtx(() => [ vue.createElementVNode("div", { class: "selector-dropdown" }, [ vue.renderSlot(_ctx.$slots, "default") ]) ]), default: vue.withCtx(() => [ vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass([ _ctx.namespace, _ctx.realSize && `cascader-${_ctx.realSize}`, { "is-disabled": _ctx.isDisabled, "block": _ctx.block }, _ctx.$attrs.class ]), style: vue.normalizeStyle(_ctx.$attrs.style), onClick: [ () => _ctx.togglePopperVisible(_ctx.readonly ? void 0 : true), vue.withModifiers(() => { }, ["stop"]) ], onKeydown: _ctx.handleKeyDown, onMouseenter: ($event) => _ctx.inputHover = true, onMouseleave: ($event) => _ctx.inputHover = false }, [ vue.createVNode(_component_hl_input, { ref: "input", modelValue: _ctx.inputValue, "onUpdate:modelValue": ($event) => _ctx.inputValue = $event, placeholder: _ctx.currentPlaceholder, readonly: _ctx.readonly, disabled: _ctx.isDisabled, "validate-event": false, fill: _ctx.realFill, thin: _ctx.thin, round: _ctx.round, size: _ctx.realSize, class: vue.normalizeClass({ "is-focus": _ctx.popperVisible, "is-tags": _ctx.presentTags.length }), "input-style": _ctx.inputStyle, onCompositionstart: _ctx.handleComposition, onCompositionupdate: _ctx.handleComposition, onCompositionend: _ctx.handleComposition, onFocus: (e) => _ctx.$emit("focus", e), onBlur: (e) => _ctx.$emit("blur", e), onInput: _ctx.handleInput }, vue.createSlots({ suffix: vue.withCtx(() => [ vue.createVNode(_component_hl_icon, { class: vue.normalizeClass(["select-caret", _ctx.popperVisible ? "is-open" : "", !_ctx.clearBtnVisible ? "visible" : ""]), onClick: vue.withModifiers(($event) => _ctx.togglePopperVisible(), ["stop"]) }, { default: vue.withCtx(() => [ vue.createVNode(_component_system_select_arrow) ]), _: 1 }, 8, ["class", "onClick"]), vue.createVNode(_component_hl_icon, { key: "clear", class: vue.normalizeClass(["select-close", _ctx.clearBtnVisible ? "visible" : ""]), onClick: vue.withModifiers(_ctx.handleClear, ["stop"]) }, { default: vue.withCtx(() => [ vue.createVNode(_component_system_close) ]), _: 1 }, 8, ["class", "onClick"]) ]), _: 2 }, [ _ctx.multiple ? { name: "tags", fn: vue.withCtx(() => [ _ctx.presentTags.length ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, ref: "tagWrapper", class: "input-tags" }, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.presentTags, (tag) => { return vue.openBlock(), vue.createBlock(_component_hl_tag, { key: tag.key, type: _ctx.tagType, effect: _ctx.tagEffect, active: tag.hitState, closable: tag.closable, size: _ctx.realSize, "disable-transitions": "", onClose: ($event) => _ctx.deleteTag(tag) }, { default: vue.withCtx(() => [ tag.isCollapseTag === false ? vue.renderSlot(_ctx.$slots, "tag", { key: 0, tag }, () => [ vue.createTextVNode(vue.toDisplayString(tag.text), 1) ]) : (vue.openBlock(), vue.createBlock(_component_hl_tooltip, { key: 1, disabled: _ctx.popperVisible || !_ctx.collapseTagsTooltip, "fallback-placements": ["bottom", "top", "right", "left"], placement: "bottom", "show-arrow": false, "popper-class": `collapse-tags-popper` }, { default: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, "tag", { tag }, () => [ vue.createTextVNode(vue.toDisplayString(tag.text), 1) ]) ]), content: vue.withCtx(() => [ vue.createElementVNode("div", { class: "collapse-tags" }, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.allPresentTags.slice(_ctx.maxCollapseTags), (tag2) => { return vue.openBlock(), vue.createBlock(_component_hl_tag, { key: tag2.key, class: "in-tooltip collapse-tag", type: _ctx.tagType, effect: _ctx.tagEffect, size: _ctx.realSize, hit: tag2.hitState, closable: tag2.closable, "disable-transitions": "", onClose: ($event) => _ctx.deleteTag(tag2) }, { default: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, "collapse-tag", { tag: tag2 }, () => [ vue.createTextVNode(vue.toDisplayString(tag2.text), 1) ]) ]), _: 2 }, 1032, ["type", "effect", "size", "hit", "closable", "onClose"]); }), 128)) ]) ]), _: 2 }, 1032, ["disabled"])) ]), _: 2 }, 1032, ["type", "effect", "active", "closable", "size", "onClose"]); }), 128)), _ctx.filterable && !_ctx.isDisabled ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", { key: 0, "onUpdate:modelValue": ($event) => _ctx.searchInputValue = $event, type: "text", class: "selector-input", onInput: (e) => _ctx.handleInput(_ctx.searchInputValue, e), onClick: vue.withModifiers(($event) => _ctx.togglePopperVisible(true), ["stop"]), onKeydown: vue.withKeys(_ctx.handleDelete, ["delete"]), onCompositionstart: _ctx.handleComposition, onCompositionupdate: _ctx.handleComposition, onCompositionend: _ctx.handleComposition }, null, 40, ["onUpdate:modelValue", "onInput", "onClick", "onKeydown", "onCompositionstart", "onCompositionupdate", "onCompositionend"])), [ [vue.vModelText, _ctx.searchInputValue] ]) : vue.createCommentVNode("v-if", true) ], 512)) : vue.createCommentVNode("v-if", true) ]) } : void 0, _ctx.$slots.prefix ? { name: "prefix", fn: vue.withCtx(() => [ vue.renderSlot(_ctx.$slots, "prefix") ]) } : void 0 ]), 1032, ["modelValue", "onUpdate:modelValue", "placeholder", "readonly", "disabled", "fill", "thin", "round", "size", "class", "input-style", "onCompositionstart", "onCompositionupdate", "onCompositionend", "onFocus", "onBlur", "onInput"]) ], 46, ["onClick", "onKeydown", "onMouseenter", "onMouseleave"])), [ [_directive_clickoutside, () => _ctx.togglePopperVisible(false), _ctx.popperPaneRef] ]) ]), _: 3 }, 8, ["visible", "teleported", "offset", "placement", "popper-class", "fallback-placements", "persistent", "onHide"]); } var Selector = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["render", _sfc_render]]); exports["default"] = Selector; //# sourceMappingURL=index.js.map