UNPKG

hongluan-ui

Version:
325 lines (322 loc) 12.5 kB
import { defineComponent, ref, computed, watch, resolveComponent, openBlock, createBlock, withCtx, withDirectives, createVNode, vShow, normalizeClass, createElementBlock, Fragment, renderList, createElementVNode, toDisplayString, createCommentVNode, renderSlot, createTextVNode } from 'vue'; import { cloneDeep, debounce } from 'lodash-unified'; import { isPromise } from '@vue/shared'; import { HlCascaderPanel } from '../../cascader-panel/index.mjs'; import { HlScrollbar } from '../../scrollbar/index.mjs'; import { HlSelector } from '../../selector/index.mjs'; import '../../../utils/index.mjs'; import '../../../constants/index.mjs'; import '../../../hooks/index.mjs'; import '../../../tokens/index.mjs'; import { cascaderProps } from './cascader.mjs'; import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs'; import { UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../../../constants/event.mjs'; import { useNamespace } from '../../../hooks/use-namespace/index.mjs'; import { useLocale } from '../../../hooks/use-locale/index.mjs'; import { useFormItem } from '../../../hooks/use-form-item/index.mjs'; import { useEmptyValues } from '../../../hooks/use-empty-values/index.mjs'; import { useConsistentProp } from '../../../hooks/use-consistent-prop/index.mjs'; import { FormItemEvents } from '../../../tokens/form.mjs'; import { debugWarn } from '../../../utils/error.mjs'; import { EVENT_CODE } from '../../../constants/aria.mjs'; import { focusNode, getSibling } from '../../../utils/dom/aria.mjs'; const _sfc_main = defineComponent({ name: "Cascader", components: { HlCascaderPanel, HlScrollbar, HlSelector }, props: cascaderProps, emits: [ UPDATE_MODEL_EVENT, CHANGE_EVENT, "focus", "blur", "clear", "visible-change", "expand-change", "remove-tag" ], setup(props, { emit }) { const { namespace } = useNamespace("cascader"); const { t } = useLocale(); const { formItem } = useFormItem(); const { valueOnClear } = useEmptyValues(props); const hlSelector = ref(null); const panel = ref(null); const suggestionPanel = ref(null); const filtering = ref(false); const searchKeyword = ref(""); const suggestions = ref([]); const multiple = computed(() => !!props.props.multiple); const checkedNodes = computed(() => { var _a; return ((_a = panel.value) == null ? void 0 : _a.checkedNodes) || []; }); const { size: cascaderSize, disabled: isDisabled, fill: cascaderFill } = useConsistentProp(); const checkedValue = computed({ get() { return cloneDeep(props.modelValue); }, set(val) { var _a; const value = val != null ? val : valueOnClear.value; emit(UPDATE_MODEL_EVENT, value); emit(CHANGE_EVENT, value); if (props.validateEvent) { (_a = formItem == null ? void 0 : formItem.validate) == null ? void 0 : _a.call(formItem, FormItemEvents.change).catch((err) => debugWarn(err)); } } }); const popperPaneRef = computed(() => { var _a; return (_a = hlSelector.value) == null ? void 0 : _a.popperPaneRef; }); const togglePopperVisible = (visible) => { hlSelector.value.togglePopperVisible(visible); }; const updatePopperPosition = () => { hlSelector.value.updatePopperPosition(); }; const hideSuggestionPanel = () => { filtering.value = false; }; const deleteTag = (tag) => { var _a; const node = tag.text; node.doCheck(false); (_a = panel.value) == null ? void 0 : _a.calculateCheckedValue(); emit("remove-tag", node.valueByOption); }; const calculateSuggestions = () => { const { filterMethod, showAllLevels, separator } = props; const res = panel.value.getFlattedNodes(!props.props.checkStrictly).filter((node) => { if (node.isDisabled) return false; node.calcText(showAllLevels, separator); return filterMethod(node, searchKeyword.value); }); if (multiple.value) { hlSelector.value.updateTags((tag) => { tag.hitState = false; }); } filtering.value = true; suggestions.value = res; updatePopperPosition(); }; const handleSuggestionKeyDown = (e) => { const target = e.target; const { code } = e; switch (code) { case EVENT_CODE.up: case EVENT_CODE.down: { const distance = code === EVENT_CODE.up ? -1 : 1; focusNode(getSibling(target, distance, '.cascader-suggestion-item[tabindex="-1"]')); break; } case EVENT_CODE.enter: target.click(); break; } }; const focusFirstNode = () => { var _a; let firstNode = null; if (filtering.value && suggestionPanel.value) { firstNode = suggestionPanel.value.$el.querySelector(".cascader-suggestion-item"); } else { firstNode = (_a = panel.value) == null ? void 0 : _a.$el.querySelector('.cascader-node[tabindex="-1"]'); } if (firstNode) { firstNode.focus(); !filtering.value && firstNode.click(); } }; const resizePanel = (inputInner) => { var _a; const suggestionPanelEl = (_a = suggestionPanel.value) == null ? void 0 : _a.$el; if (suggestionPanelEl) { const suggestionList = suggestionPanelEl.querySelector(".cascader-suggestion-list"); suggestionList.style.minWidth = inputInner.offsetWidth + "px"; } }; const getCheckedNodes = (leafOnly) => { var _a; return (_a = panel.value) == null ? void 0 : _a.getCheckedNodes(leafOnly); }; const handleExpandChange = (value) => { updatePopperPosition(); emit("expand-change", value); }; const handleClear = () => { var _a; (_a = panel.value) == null ? void 0 : _a.clearCheckedNodes(); emit("clear"); }; const handleSuggestionClick = (node) => { var _a, _b; const { checked } = node; if (multiple.value) { (_a = panel.value) == null ? void 0 : _a.handleCheckChange(node, !checked, false); } else { !checked && ((_b = panel.value) == null ? void 0 : _b.handleCheckChange(node, true, false)); togglePopperVisible(false); } }; const handleFilter = debounce(() => { const { value } = searchKeyword; if (!value) return; const passed = props.beforeFilter(value); if (isPromise(passed)) { passed.then(calculateSuggestions).catch(() => { }); } else if (passed !== false) { calculateSuggestions(); } else { hideSuggestionPanel(); } }, props.debounce); const handleInput = (val) => { searchKeyword.value = val; val ? handleFilter() : hideSuggestionPanel(); }; watch(filtering, updatePopperPosition); watch(checkedNodes, (nodes) => { if (multiple.value) { hlSelector.value.setValue(nodes || []); } else { const { showAllLevels, separator } = props; hlSelector.value.setValue(nodes.length ? nodes[0].calcText(showAllLevels, separator) : ""); } }); return { namespace, hlSelector, popperPaneRef, panel, suggestionPanel, filtering, checkedValue, suggestions, isDisabled, cascaderSize, cascaderFill, multiple, t, togglePopperVisible, hideSuggestionPanel, resizePanel, deleteTag, focusFirstNode, getCheckedNodes, handleExpandChange, handleClear, handleSuggestionClick, handleSuggestionKeyDown, handleInput }; } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_hl_cascader_panel = resolveComponent("hl-cascader-panel"); const _component_hl_scrollbar = resolveComponent("hl-scrollbar"); const _component_hl_selector = resolveComponent("hl-selector"); return openBlock(), createBlock(_component_hl_selector, { ref: "hlSelector", size: _ctx.cascaderSize, fill: _ctx.cascaderFill, placeholder: _ctx.placeholder, disabled: _ctx.isDisabled, clearable: !_ctx.filtering && _ctx.clearable, filterable: _ctx.filterable, "collapse-tags": _ctx.collapseTags, "max-collapse-tags": _ctx.maxCollapseTags, "collapse-tags-tooltip": _ctx.collapseTagsTooltip, "tag-type": _ctx.tagType, "tag-effect": _ctx.tagEffect, "popper-class": _ctx.popperClass + " " + _ctx.namespace + "-popper", block: _ctx.block, multiple: _ctx.props.multiple, "fallback-placements": _ctx.fallbackPlacements, placement: _ctx.placement, "popper-append-to-body": _ctx.popperAppendToBody, teleported: _ctx.teleported, "popper-offset": _ctx.popperOffset, persistent: _ctx.persistent, onFocus: (e) => _ctx.$emit("focus", e), onBlur: (e) => _ctx.$emit("blur", e), onResize: _ctx.resizePanel, onKeyboardDown: _ctx.focusFirstNode, onInput: _ctx.handleInput, onClear: _ctx.handleClear, onRemoveTag: _ctx.deleteTag, onVisibleChange: (e) => _ctx.$emit("visible-change", e), onAfterLeave: _ctx.hideSuggestionPanel }, { default: withCtx(() => [ withDirectives(createVNode(_component_hl_cascader_panel, { ref: "panel", modelValue: _ctx.checkedValue, "onUpdate:modelValue": ($event) => _ctx.checkedValue = $event, options: _ctx.options, props: _ctx.props, border: false, "render-label": _ctx.$slots.default, onExpandChange: _ctx.handleExpandChange, onClose: ($event) => _ctx.togglePopperVisible(false) }, null, 8, ["modelValue", "onUpdate:modelValue", "options", "props", "render-label", "onExpandChange", "onClose"]), [ [vShow, !_ctx.filtering] ]), _ctx.filterable ? withDirectives((openBlock(), createBlock(_component_hl_scrollbar, { key: 0, ref: "suggestionPanel", tag: "ul", class: normalizeClass([_ctx.namespace + "-suggestion-panel"]), "view-class": "cascader-suggestion-list", onKeydown: _ctx.handleSuggestionKeyDown }, { default: withCtx(() => [ _ctx.suggestions.length ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(_ctx.suggestions, (item) => { return openBlock(), createElementBlock("li", { key: item.uid, class: normalizeClass([ "cascader-suggestion-item", item.checked && "is-active" ]), tabindex: -1, onClick: ($event) => _ctx.handleSuggestionClick(item) }, [ createElementVNode("span", null, toDisplayString(item.text), 1), item.checked ? (openBlock(), createElementBlock("i", { key: 0, class: normalizeClass(["system-icon checked cascader-item-prefix"]) })) : createCommentVNode("v-if", true) ], 10, ["onClick"]); }), 128)) : renderSlot(_ctx.$slots, "empty", { key: 1 }, () => [ createElementVNode("li", { class: "cascader-empty-text" }, toDisplayString(_ctx.t("hl.cascader.noMatch")), 1) ]) ]), _: 3 }, 8, ["class", "onKeydown"])), [ [vShow, _ctx.filtering] ]) : createCommentVNode("v-if", true) ]), tag: withCtx(({ tag }) => [ tag.key === "-1" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ createTextVNode(toDisplayString(tag.text), 1) ], 2112)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [ createTextVNode(toDisplayString(tag.text.calcText(_ctx.showAllLevels, _ctx.separator)), 1) ], 2112)) ]), "collapse-tag": withCtx(({ tag }) => [ createTextVNode(toDisplayString(tag.text.calcText(_ctx.showAllLevels, _ctx.separator)), 1) ]), _: 3 }, 8, ["size", "fill", "placeholder", "disabled", "clearable", "filterable", "collapse-tags", "max-collapse-tags", "collapse-tags-tooltip", "tag-type", "tag-effect", "popper-class", "block", "multiple", "fallback-placements", "placement", "popper-append-to-body", "teleported", "popper-offset", "persistent", "onFocus", "onBlur", "onResize", "onKeyboardDown", "onInput", "onClear", "onRemoveTag", "onVisibleChange", "onAfterLeave"]); } var Cascader = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { Cascader as default }; //# sourceMappingURL=cascader2.mjs.map