hongluan-ui
Version:
Hongluan Component Library for Vue 3
325 lines (322 loc) • 12.5 kB
JavaScript
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