@veltra/desktop 1.7.19 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/batch-edit/batch-edit-form.js +40 -26
- package/dist/components/batch-edit/batch-edit-form.js.map +1 -1
- package/dist/components/batch-edit/use-handlers.js +3 -3
- package/dist/components/batch-edit/use-handlers.js.map +1 -1
- package/dist/components/batch-edit/use-shortcut-key.js +4 -2
- package/dist/components/batch-edit/use-shortcut-key.js.map +1 -1
- package/dist/components/card/style2.css +0 -2
- package/dist/components/condition-editor/condition-editor.js +8 -2
- package/dist/components/condition-editor/condition-editor.js.map +1 -1
- package/dist/components/dropdown/dropdown.js +5 -3
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/expression-editor/components/path-preview.js +3 -6
- package/dist/components/expression-editor/components/path-preview.js.map +1 -1
- package/dist/components/expression-editor/components/variable-picker.js +49 -12
- package/dist/components/expression-editor/components/variable-picker.js.map +1 -1
- package/dist/components/expression-editor/core/editor.js +42 -0
- package/dist/components/expression-editor/core/editor.js.map +1 -1
- package/dist/components/expression-editor/expression-editor.js +68 -22
- package/dist/components/expression-editor/expression-editor.js.map +1 -1
- package/dist/components/expression-editor/style2.css +135 -73
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js +0 -1
- package/dist/components/form/form.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form/style2.css +8 -3
- package/dist/components/form-item/style2.css +14 -0
- package/dist/components/index.d.ts +27 -26
- package/dist/components/index.js +54 -52
- package/dist/components/index.js.map +1 -1
- package/dist/components/kanban/di.js +7 -0
- package/dist/components/kanban/di.js.map +1 -0
- package/dist/components/kanban/kanban-column.js +67 -0
- package/dist/components/kanban/kanban-column.js.map +1 -0
- package/dist/components/kanban/kanban.js +89 -0
- package/dist/components/kanban/kanban.js.map +1 -0
- package/dist/components/kanban/style.d.ts +1 -0
- package/dist/components/kanban/style.js +1 -0
- package/dist/components/kanban/style2.css +128 -0
- package/dist/components/multi-select/multi-select.js +16 -12
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/style2.css +7 -0
- package/dist/components/multi-tree-select/multi-tree-select.js +82 -56
- package/dist/components/multi-tree-select/multi-tree-select.js.map +1 -1
- package/dist/components/multi-tree-select/style2.css +7 -0
- package/dist/components/rich-text-editor/image-node.js +154 -0
- package/dist/components/rich-text-editor/image-node.js.map +1 -0
- package/dist/components/rich-text-editor/rich-text-editor.js +80 -22
- package/dist/components/rich-text-editor/rich-text-editor.js.map +1 -1
- package/dist/components/rich-text-editor/style2.css +6 -0
- package/dist/components/rich-text-editor/toolbar.js +22 -2
- package/dist/components/rich-text-editor/toolbar.js.map +1 -1
- package/dist/components/select/select.js +7 -3
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/style2.css +7 -0
- package/dist/components/select/use-options.js +14 -3
- package/dist/components/select/use-options.js.map +1 -1
- package/dist/components/tree-select/style2.css +7 -0
- package/dist/components/tree-select/tree-select.js +49 -17
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/index.d.ts +48 -46
- package/dist/index.js +47 -46
- package/dist/types/dropdown.d.ts +10 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/kanban.d.ts +69 -0
- package/dist/types/multi-tree-select.d.ts +7 -1
- package/dist/types/rich-text-editor.d.ts +13 -2
- package/dist/types/tree-select.d.ts +7 -1
- package/package.json +1 -1
- package/src/components/batch-edit/__test__/batch-edit.test.ts +112 -1
- package/src/components/batch-edit/batch-edit-form.vue +21 -2
- package/src/components/batch-edit/use-handlers.ts +6 -5
- package/src/components/batch-edit/use-shortcut-key.ts +5 -2
- package/src/components/card/style.scss +0 -2
- package/src/components/condition-editor/__test__/condition-editor.test.ts +61 -0
- package/src/components/condition-editor/condition-editor.vue +6 -1
- package/src/components/dropdown/dropdown.vue +9 -4
- package/src/components/expression-editor/__test__/editor.test.ts +66 -0
- package/src/components/expression-editor/__test__/expression-editor.test.ts +124 -0
- package/src/components/expression-editor/components/path-preview.vue +1 -2
- package/src/components/expression-editor/components/variable-picker.vue +54 -13
- package/src/components/expression-editor/core/editor.ts +61 -0
- package/src/components/expression-editor/expression-editor.vue +58 -20
- package/src/components/expression-editor/style.scss +160 -76
- package/src/components/form/form.vue +0 -1
- package/src/components/form/style.scss +11 -4
- package/src/components/form-item/style.scss +16 -1
- package/src/components/index.ts +2 -0
- package/src/components/kanban/__test__/kanban.test.ts +212 -0
- package/src/components/kanban/di.ts +19 -0
- package/src/components/kanban/index.ts +1 -0
- package/src/components/kanban/kanban-column.vue +77 -0
- package/src/components/kanban/kanban.vue +81 -0
- package/src/components/kanban/style.scss +124 -0
- package/src/components/kanban/style.ts +1 -0
- package/src/components/multi-select/multi-select.vue +11 -2
- package/src/components/multi-select/style.scss +6 -0
- package/src/components/multi-tree-select/multi-tree-select.vue +58 -9
- package/src/components/multi-tree-select/style.scss +6 -0
- package/src/components/rich-text-editor/image-node.ts +193 -0
- package/src/components/rich-text-editor/rich-text-editor.vue +131 -29
- package/src/components/rich-text-editor/style.scss +7 -0
- package/src/components/rich-text-editor/toolbar.vue +21 -1
- package/src/components/select/__test__/select.test.ts +78 -0
- package/src/components/select/select.vue +13 -3
- package/src/components/select/style.scss +6 -0
- package/src/components/select/use-options.ts +25 -4
- package/src/components/tree-select/__test__/tree-select.test.ts +116 -0
- package/src/components/tree-select/style.scss +6 -0
- package/src/components/tree-select/tree-select.vue +63 -13
- package/src/types/dropdown.ts +10 -0
- package/src/types/index.ts +1 -0
- package/src/types/kanban.ts +63 -0
- package/src/types/multi-tree-select.ts +12 -1
- package/src/types/rich-text-editor.ts +14 -1
- package/src/types/tree-select.ts +12 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select.js","names":["$attrs"],"sources":["../../../src/components/multi-select/multi-select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n trigger=\"click\"\n ref=\"dropdownRef\"\n :class=\"[cls.b, cls.m(size), bem.is('disabled', disabled), bem.is('focus', dropdownVisible)]\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n :disabled=\"disabled\"\n @update:visible=\"handleDropdownVisible\"\n >\n <!-- 触发 -->\n <template #trigger>\n <span :class=\"cls.e('placeholder')\" v-if=\"!filterable && !model?.length\">\n {{ placeholder }}\n </span>\n\n <div v-if=\"model?.length || filterable\" :class=\"cls.e('tags')\">\n <u-tag\n v-for=\"option of tags\"\n :key=\"option[valueKey]\"\n :closable=\"!disabled\"\n size=\"small\"\n @close=\"handleClose(option)\"\n >\n {{ option[labelKey] }}\n </u-tag>\n <u-tag v-if=\"restTag\" size=\"small\"> {{ restTag }}+ </u-tag>\n\n <!-- 内嵌查询输入框:承载过滤与回车创建 -->\n <input\n v-if=\"filterable\"\n ref=\"inputRef\"\n :class=\"cls.e('input')\"\n v-model=\"queryString\"\n :placeholder=\"model?.length ? '' : placeholder\"\n :disabled=\"disabled\"\n @click.stop=\"handleInputClick\"\n @focus=\"handleInputFocus\"\n @keydown.enter.prevent=\"handleCreateByEnter\"\n />\n </div>\n\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"clearable && model?.length && hovered && !disabled\"\n :class=\"cls.e('clear')\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n\n <u-icon :class=\"cls.e('arrow')\" v-else><ArrowDown /></u-icon>\n </transition>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <!-- 多选栏 -->\n <div :class=\"cls.e('content-header')\">\n <u-checkbox\n :model-value=\"allChecked\"\n :indeterminate=\"indeterminate\"\n @update:model-value=\"handleCheckAll\"\n :disabled=\"max !== undefined\"\n >\n 全选\n </u-checkbox>\n\n <span> 已选 {{ model?.length }}/{{ max ?? options?.length ?? 0 }} </span>\n </div>\n\n <!-- 多选列表 -->\n <!--\n 虚拟化启用时内容容器 height 由 useVirtualizer 命令式写入;\n 模板不再绑定 totalSize,避免尺寸变化引起重渲染。\n -->\n <u-scroll\n tag=\"ul\"\n :class=\"[cls.e('options')]\"\n ref=\"scrollRef\"\n v-if=\"options.length\"\n :content-class=\"[cls.e('options-wrap'), bem.is('virtual', virtualEnabled)]\"\n >\n <template v-if=\"virtualEnabled\">\n <u-multi-select-option\n v-for=\"{ option, index, key, label, offset } of virtualOptions\"\n :option=\"option\"\n :disabled=\"isDisabled(option)\"\n :key=\"key\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n @check=\"handleCheck(option, $event)\"\n :checked=\"checkedSet.has(option)\"\n :index=\"index\"\n :measure-element=\"measureElement\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ label }}\n </slot>\n </u-multi-select-option>\n </template>\n\n <template v-else>\n <u-multi-select-option\n v-for=\"(option, index) of options\"\n :option=\"option\"\n :disabled=\"isDisabled(option)\"\n :key=\"chainObj(option).get(valueKey)\"\n @check=\"handleCheck(option, $event)\"\n :checked=\"checkedSet.has(option)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ chainObj(option).get(labelKey) }}\n </slot>\n </u-multi-select-option>\n </template>\n </u-scroll>\n\n <div v-else :class=\"cls.e('empty')\">\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <div v-else-if=\"model?.length\" :class=\"[cls.m(size), cls.e('readonly-tags')]\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"option of tags\" :key=\"option[valueKey]\" size=\"small\">\n {{ option[labelKey] }}\n </u-tag>\n </div>\n </div>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o as chainObj } from '@cat-kit/core'\nimport { useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { ArrowDown, Close } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n computed,\n nextTick,\n shallowRef,\n shallowReactive,\n watch,\n provide,\n useTemplateRef\n} from 'vue'\n\nimport type {\n MultiSelectEmits,\n MultiSelectProps,\n ScrollExposed,\n DropdownExposed\n} from '../../types'\nimport { UCheckbox } from '../checkbox'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { UScroll } from '../scroll'\nimport { useOptions } from '../select/use-options'\nimport { UTag } from '../tag'\nimport { MultiSelectDIKey } from './di'\nimport UMultiSelectOption from './multi-select-option.vue'\n\ndefineOptions({ name: 'UMultiSelect', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<MultiSelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n clearable: true,\n visibilityLimit: 3,\n disabled: undefined,\n readonly: undefined,\n minWidth: '220px'\n})\n\nconst emit = defineEmits<MultiSelectEmits>()\n\nconst cls = bem('multi-select')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst hovered = shallowRef(false)\n\nconst { options: rawOptions, queryString, allOptions: rawAllOptions } = useOptions({ props })\n\nconst createdOptions = shallowRef<Record<string, any>[]>([])\n\nconst options = computed(() => {\n const base = rawOptions.value\n if (!props.creatable || !createdOptions.value.length) return base\n\n const createdValues = new Set(createdOptions.value.map((o) => chainObj(o).get(valueKey.value)))\n const deduped = base.filter(\n (o) => !(o.__isTemp && createdValues.has(chainObj(o).get(valueKey.value)))\n )\n const dedupedValues = new Set(deduped.map((o) => chainObj(o).get(valueKey.value)))\n const toAdd = createdOptions.value.filter(\n (o) => !dedupedValues.has(chainObj(o).get(valueKey.value))\n )\n return [...toAdd, ...deduped]\n})\n\nconst allOptions = computed(() => {\n if (!props.creatable || !createdOptions.value.length) return rawAllOptions.value\n return [...createdOptions.value, ...rawAllOptions.value]\n})\n\nconst virtualEnabled = computed(() => options.value.length > 80)\n\nconst { virtualizer, items } = useVirtualizer({\n estimateSize: () => 40,\n count: computed(() => options.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null)\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n return items.value.map((v) => {\n const option = _options[v.index]!\n const val = chainObj(option).get(valueKey.value)\n return {\n option,\n index: v.index,\n val,\n key: v.index,\n offset: v.start,\n label: chainObj(option).get(labelKey.value)\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nconst filterable = computed(() => {\n return props.filterable || props.creatable || typeof props.options === 'function'\n})\n\nconst model = defineModel<Array<string | number>>()\n\nconst checkedSet = shallowReactive<Set<Record<string, any>>>(new Set())\nconst allChecked = computed(() => {\n return checkedSet.size === options.value.length\n})\nconst indeterminate = computed(() => {\n return checkedSet.size > 0 && !allChecked.value\n})\n\nconst optionsMap = computed(() => {\n return new Map<string | number, Record<string, any>>(\n allOptions.value.map((option) => [option[valueKey.value], option])\n )\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nlet internalChange = false\n\nwatch(\n [model, optionsMap],\n ([model, optionsMap]) => {\n if (internalChange) {\n internalChange = false\n return\n }\n checkedSet.clear()\n if (optionsMap.size && model?.length) {\n model.forEach((v) => {\n const option = optionsMap.get(v)\n option && checkedSet.add(option)\n })\n }\n },\n { immediate: true }\n)\n\nconst emitChange = () => {\n emit('change', Array.from(checkedSet))\n}\n\nconst tags = computed(() => {\n let tags: Record<string, any>[] = []\n let { visibilityLimit } = props\n if (visibilityLimit < 0) {\n visibilityLimit = 0\n }\n\n // 禁用时,显示全部\n if (disabled.value || readonly.value) {\n visibilityLimit = model.value?.length ?? 0\n }\n\n model.value?.slice(0, visibilityLimit).forEach((k) => {\n const option = optionsMap.value.get(k)\n option && tags.push(option)\n })\n\n return tags\n})\n\nconst restTag = computed(() => {\n return (model.value?.length ?? 0) - tags.value.length\n})\n\nconst dropdownVisible = shallowRef(false)\n\nconst inputRef = useTemplateRef<HTMLInputElement>('inputRef')\n\nconst handleDropdownVisible = (visible: boolean) => {\n dropdownVisible.value = visible\n if (!visible) {\n queryString.value = ''\n }\n}\n\n/**\n * 拦截输入区域的点击(@click.stop):阻止 dropdown 的 trigger 开合切换,\n * 保持面板展开以不中断输入。\n */\nconst handleInputClick = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\nconst handleInputFocus = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\n/** 勾选后把焦点还给输入框,便于连续输入过滤 */\nconst refocusInput = () => {\n if (!filterable.value) return\n nextTick(() => inputRef.value?.focus())\n}\n\nconst handleCheck = (option: Record<string, any>, checked: boolean) => {\n if (checked) {\n if (option.__isTemp && props.creatable) {\n const created: Record<string, any> = {\n [labelKey.value]: chainObj(option).get(labelKey.value),\n [valueKey.value]: chainObj(option).get(valueKey.value)\n }\n createdOptions.value = [...createdOptions.value, created]\n checkedSet.add(created)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(created).get(valueKey.value)!]\n queryString.value = ''\n } else if (!checkedSet.has(option)) {\n checkedSet.add(option)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(option).get(valueKey.value)!]\n }\n } else {\n checkedSet.delete(option)\n const val = chainObj(option).get(valueKey.value)\n internalChange = true\n model.value = (model.value ?? []).filter((v) => v !== val)\n removeCreatedOption(option)\n }\n\n emitChange()\n dropdownRef.value?.updateDropdown()\n refocusInput()\n}\n\n/** 全选 */\nconst handleCheckAll = (checked: boolean) => {\n if (checked) {\n options.value.forEach((option) => {\n if (!option.__isTemp) checkedSet.add(option)\n })\n internalChange = true\n model.value = Array.from(checkedSet).map((o) => chainObj(o).get(valueKey.value)!)\n } else {\n checkedSet.clear()\n internalChange = true\n model.value = []\n if (props.creatable) {\n createdOptions.value = []\n }\n }\n\n emitChange()\n dropdownRef.value?.updateDropdown()\n}\n\n/** 清除选项 */\nconst handleClear = () => {\n checkedSet.clear()\n internalChange = true\n model.value = []\n if (props.creatable) {\n createdOptions.value = []\n }\n emit('change', [])\n}\n\nconst handleClose = (option: Record<string, any>) => {\n checkedSet.delete(option)\n const val = chainObj(option).get(valueKey.value)\n internalChange = true\n model.value = (model.value ?? []).filter((v) => v !== val)\n removeCreatedOption(option)\n emitChange()\n}\n\nconst removeCreatedOption = (option: Record<string, any>) => {\n if (!props.creatable || !createdOptions.value.length) return\n const val = chainObj(option).get(valueKey.value)\n createdOptions.value = createdOptions.value.filter((o) => chainObj(o).get(valueKey.value) !== val)\n}\n\nconst handleCreateByEnter = () => {\n if (!props.creatable) return\n const qs = queryString.value?.trim()\n if (!qs) return\n\n const existingCreated = createdOptions.value.find((o) => chainObj(o).get(valueKey.value) === qs)\n if (existingCreated) {\n if (!checkedSet.has(existingCreated)) {\n checkedSet.add(existingCreated)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(existingCreated).get(valueKey.value)!]\n }\n queryString.value = ''\n emitChange()\n dropdownRef.value?.updateDropdown()\n return\n }\n\n const exactMatch = rawOptions.value.find(\n (o) => !o.__isTemp && chainObj(o).get(labelKey.value) === qs\n )\n if (exactMatch) {\n if (!checkedSet.has(exactMatch)) {\n checkedSet.add(exactMatch)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(exactMatch).get(valueKey.value)!]\n }\n queryString.value = ''\n emitChange()\n dropdownRef.value?.updateDropdown()\n return\n }\n\n const created: Record<string, any> = { [labelKey.value]: qs, [valueKey.value]: qs }\n createdOptions.value = [...createdOptions.value, created]\n checkedSet.add(created)\n internalChange = true\n model.value = [...(model.value ?? []), qs]\n queryString.value = ''\n emitChange()\n dropdownRef.value?.updateDropdown()\n}\n\nconst isDisabled = (option: Record<string, any>) => {\n const { max } = props\n return max !== undefined && checkedSet.size >= max && !checkedSet.has(option)\n}\n\nconst optionClass = cls.e('option')\nconst rippleClass = cls.e('ripple')\nconst checkboxClass = cls.e('checkbox')\n\nprovide(MultiSelectDIKey, { optionClass, rippleClass, checkboxClass })\n</script>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"multi-select.js","names":["$attrs"],"sources":["../../../src/components/multi-select/multi-select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n trigger=\"click\"\n ref=\"dropdownRef\"\n :class=\"[cls.b, cls.m(size), bem.is('disabled', disabled), bem.is('focus', dropdownVisible)]\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n :disabled=\"disabled\"\n @update:visible=\"handleDropdownVisible\"\n >\n <!-- 触发 -->\n <template #trigger>\n <span :class=\"cls.e('placeholder')\" v-if=\"!filterable && !model?.length\">\n {{ placeholder }}\n </span>\n\n <div v-if=\"model?.length || filterable\" :class=\"cls.e('tags')\">\n <u-tag\n v-for=\"option of tags\"\n :key=\"option[valueKey]\"\n :closable=\"!disabled\"\n size=\"small\"\n @close=\"handleClose(option)\"\n >\n {{ option[labelKey] }}\n </u-tag>\n <u-tag v-if=\"restTag\" size=\"small\"> {{ restTag }}+ </u-tag>\n\n <!-- 内嵌查询输入框:承载过滤与回车创建 -->\n <input\n v-if=\"filterable\"\n ref=\"inputRef\"\n :class=\"cls.e('input')\"\n v-model=\"queryString\"\n :placeholder=\"model?.length ? '' : placeholder\"\n :disabled=\"disabled\"\n @click.stop=\"handleInputClick\"\n @focus=\"handleInputFocus\"\n @keydown.enter.prevent=\"handleCreateByEnter\"\n />\n </div>\n\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon\n v-if=\"clearable && model?.length && hovered && !disabled\"\n :class=\"cls.e('clear')\"\n @click.stop=\"handleClear\"\n >\n <Close />\n </u-icon>\n\n <u-icon :class=\"cls.e('arrow')\" v-else><ArrowDown /></u-icon>\n </transition>\n </template>\n\n <!-- 下拉内容 -->\n <template #content>\n <!-- 多选栏 -->\n <div :class=\"cls.e('content-header')\">\n <u-checkbox\n :model-value=\"allChecked\"\n :indeterminate=\"indeterminate\"\n @update:model-value=\"handleCheckAll\"\n :disabled=\"max !== undefined\"\n >\n 全选\n </u-checkbox>\n\n <span> 已选 {{ model?.length }}/{{ max ?? options?.length ?? 0 }} </span>\n </div>\n\n <!-- 多选列表 -->\n <!--\n 虚拟化启用时内容容器 height 由 useVirtualizer 命令式写入;\n 模板不再绑定 totalSize,避免尺寸变化引起重渲染。\n -->\n <div v-if=\"loading\" :class=\"cls.e('loading')\">\n <ULoading type=\"dual-ring\" />\n </div>\n <u-scroll\n tag=\"ul\"\n :class=\"[cls.e('options')]\"\n ref=\"scrollRef\"\n v-else-if=\"options.length\"\n :content-class=\"[cls.e('options-wrap'), bem.is('virtual', virtualEnabled)]\"\n >\n <template v-if=\"virtualEnabled\">\n <u-multi-select-option\n v-for=\"{ option, index, key, label, offset } of virtualOptions\"\n :option=\"option\"\n :disabled=\"isDisabled(option)\"\n :key=\"key\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n @check=\"handleCheck(option, $event)\"\n :checked=\"checkedSet.has(option)\"\n :index=\"index\"\n :measure-element=\"measureElement\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ label }}\n </slot>\n </u-multi-select-option>\n </template>\n\n <template v-else>\n <u-multi-select-option\n v-for=\"(option, index) of options\"\n :option=\"option\"\n :disabled=\"isDisabled(option)\"\n :key=\"chainObj(option).get(valueKey)\"\n @check=\"handleCheck(option, $event)\"\n :checked=\"checkedSet.has(option)\"\n >\n <slot v-bind=\"{ option, index }\">\n {{ chainObj(option).get(labelKey) }}\n </slot>\n </u-multi-select-option>\n </template>\n </u-scroll>\n\n <div v-else :class=\"cls.e('empty')\">\n <UEmpty />\n </div>\n </template>\n </u-dropdown>\n\n <div v-else-if=\"model?.length\" :class=\"[cls.m(size), cls.e('readonly-tags')]\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"option of tags\" :key=\"option[valueKey]\" size=\"small\">\n {{ option[labelKey] }}\n </u-tag>\n </div>\n </div>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { o as chainObj } from '@cat-kit/core'\nimport { useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { ArrowDown, Close } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport {\n computed,\n nextTick,\n shallowRef,\n shallowReactive,\n watch,\n provide,\n useTemplateRef\n} from 'vue'\n\nimport type {\n MultiSelectEmits,\n MultiSelectProps,\n ScrollExposed,\n DropdownExposed\n} from '../../types'\nimport { UCheckbox } from '../checkbox'\nimport { UDropdown } from '../dropdown'\nimport { UEmpty } from '../empty'\nimport { UIcon } from '../icon'\nimport { ULoading } from '../loading'\nimport { UScroll } from '../scroll'\nimport { useOptions } from '../select/use-options'\nimport { UTag } from '../tag'\nimport { MultiSelectDIKey } from './di'\nimport UMultiSelectOption from './multi-select-option.vue'\n\ndefineOptions({ name: 'UMultiSelect', inheritAttrs: false })\n\nconst props = withDefaults(defineProps<MultiSelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n clearable: true,\n visibilityLimit: 3,\n disabled: undefined,\n readonly: undefined,\n minWidth: '220px'\n})\n\nconst emit = defineEmits<MultiSelectEmits>()\n\nconst cls = bem('multi-select')\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default',\n disabled: false,\n readonly: false\n})\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst hovered = shallowRef(false)\n\nconst {\n options: rawOptions,\n queryString,\n loading,\n allOptions: rawAllOptions\n} = useOptions({ props })\n\nconst createdOptions = shallowRef<Record<string, any>[]>([])\n\nconst options = computed(() => {\n const base = rawOptions.value\n if (!props.creatable || !createdOptions.value.length) return base\n\n const createdValues = new Set(createdOptions.value.map((o) => chainObj(o).get(valueKey.value)))\n const deduped = base.filter(\n (o) => !(o.__isTemp && createdValues.has(chainObj(o).get(valueKey.value)))\n )\n const dedupedValues = new Set(deduped.map((o) => chainObj(o).get(valueKey.value)))\n const toAdd = createdOptions.value.filter(\n (o) => !dedupedValues.has(chainObj(o).get(valueKey.value))\n )\n return [...toAdd, ...deduped]\n})\n\nconst allOptions = computed(() => {\n if (!props.creatable || !createdOptions.value.length) return rawAllOptions.value\n return [...createdOptions.value, ...rawAllOptions.value]\n})\n\nconst virtualEnabled = computed(() => options.value.length > 80)\n\nconst { virtualizer, items } = useVirtualizer({\n estimateSize: () => 40,\n count: computed(() => options.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null)\n})\n\nconst virtualOptions = computed(() => {\n const _options = options.value\n return items.value.map((v) => {\n const option = _options[v.index]!\n const val = chainObj(option).get(valueKey.value)\n return {\n option,\n index: v.index,\n val,\n key: v.index,\n offset: v.start,\n label: chainObj(option).get(labelKey.value)\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nconst filterable = computed(() => {\n return props.filterable || props.creatable || typeof props.options === 'function'\n})\n\nconst model = defineModel<Array<string | number>>()\n\nconst checkedSet = shallowReactive<Set<Record<string, any>>>(new Set())\nconst allChecked = computed(() => {\n return checkedSet.size === options.value.length\n})\nconst indeterminate = computed(() => {\n return checkedSet.size > 0 && !allChecked.value\n})\n\nconst optionsMap = computed(() => {\n return new Map<string | number, Record<string, any>>(\n allOptions.value.map((option) => [option[valueKey.value], option])\n )\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nlet internalChange = false\n\nwatch(\n [model, optionsMap],\n ([model, optionsMap]) => {\n if (internalChange) {\n internalChange = false\n return\n }\n checkedSet.clear()\n if (optionsMap.size && model?.length) {\n model.forEach((v) => {\n const option = optionsMap.get(v)\n option && checkedSet.add(option)\n })\n }\n },\n { immediate: true }\n)\n\nconst emitChange = () => {\n emit('change', Array.from(checkedSet))\n}\n\nconst tags = computed(() => {\n let tags: Record<string, any>[] = []\n let { visibilityLimit } = props\n if (visibilityLimit < 0) {\n visibilityLimit = 0\n }\n\n // 禁用时,显示全部\n if (disabled.value || readonly.value) {\n visibilityLimit = model.value?.length ?? 0\n }\n\n model.value?.slice(0, visibilityLimit).forEach((k) => {\n const option = optionsMap.value.get(k)\n option && tags.push(option)\n })\n\n return tags\n})\n\nconst restTag = computed(() => {\n return (model.value?.length ?? 0) - tags.value.length\n})\n\nconst dropdownVisible = shallowRef(false)\n\nconst inputRef = useTemplateRef<HTMLInputElement>('inputRef')\n\nconst handleDropdownVisible = (visible: boolean) => {\n dropdownVisible.value = visible\n if (!visible) {\n queryString.value = ''\n }\n}\n\n/**\n * 拦截输入区域的点击(@click.stop):阻止 dropdown 的 trigger 开合切换,\n * 保持面板展开以不中断输入。\n */\nconst handleInputClick = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\nconst handleInputFocus = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\n/** 勾选后把焦点还给输入框,便于连续输入过滤 */\nconst refocusInput = () => {\n if (!filterable.value) return\n nextTick(() => inputRef.value?.focus())\n}\n\nconst handleCheck = (option: Record<string, any>, checked: boolean) => {\n if (checked) {\n if (option.__isTemp && props.creatable) {\n const created: Record<string, any> = {\n [labelKey.value]: chainObj(option).get(labelKey.value),\n [valueKey.value]: chainObj(option).get(valueKey.value)\n }\n createdOptions.value = [...createdOptions.value, created]\n checkedSet.add(created)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(created).get(valueKey.value)!]\n queryString.value = ''\n } else if (!checkedSet.has(option)) {\n checkedSet.add(option)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(option).get(valueKey.value)!]\n }\n } else {\n checkedSet.delete(option)\n const val = chainObj(option).get(valueKey.value)\n internalChange = true\n model.value = (model.value ?? []).filter((v) => v !== val)\n removeCreatedOption(option)\n }\n\n emitChange()\n dropdownRef.value?.updateDropdown()\n refocusInput()\n}\n\n/** 全选 */\nconst handleCheckAll = (checked: boolean) => {\n if (checked) {\n options.value.forEach((option) => {\n if (!option.__isTemp) checkedSet.add(option)\n })\n internalChange = true\n model.value = Array.from(checkedSet).map((o) => chainObj(o).get(valueKey.value)!)\n } else {\n checkedSet.clear()\n internalChange = true\n model.value = []\n if (props.creatable) {\n createdOptions.value = []\n }\n }\n\n emitChange()\n dropdownRef.value?.updateDropdown()\n}\n\n/** 清除选项 */\nconst handleClear = () => {\n checkedSet.clear()\n internalChange = true\n model.value = []\n if (props.creatable) {\n createdOptions.value = []\n }\n emit('change', [])\n}\n\nconst handleClose = (option: Record<string, any>) => {\n checkedSet.delete(option)\n const val = chainObj(option).get(valueKey.value)\n internalChange = true\n model.value = (model.value ?? []).filter((v) => v !== val)\n removeCreatedOption(option)\n emitChange()\n}\n\nconst removeCreatedOption = (option: Record<string, any>) => {\n if (!props.creatable || !createdOptions.value.length) return\n const val = chainObj(option).get(valueKey.value)\n createdOptions.value = createdOptions.value.filter((o) => chainObj(o).get(valueKey.value) !== val)\n}\n\nconst handleCreateByEnter = () => {\n if (!props.creatable) return\n const qs = queryString.value?.trim()\n if (!qs) return\n\n const existingCreated = createdOptions.value.find((o) => chainObj(o).get(valueKey.value) === qs)\n if (existingCreated) {\n if (!checkedSet.has(existingCreated)) {\n checkedSet.add(existingCreated)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(existingCreated).get(valueKey.value)!]\n }\n queryString.value = ''\n emitChange()\n dropdownRef.value?.updateDropdown()\n return\n }\n\n const exactMatch = rawOptions.value.find(\n (o) => !o.__isTemp && chainObj(o).get(labelKey.value) === qs\n )\n if (exactMatch) {\n if (!checkedSet.has(exactMatch)) {\n checkedSet.add(exactMatch)\n internalChange = true\n model.value = [...(model.value ?? []), chainObj(exactMatch).get(valueKey.value)!]\n }\n queryString.value = ''\n emitChange()\n dropdownRef.value?.updateDropdown()\n return\n }\n\n const created: Record<string, any> = { [labelKey.value]: qs, [valueKey.value]: qs }\n createdOptions.value = [...createdOptions.value, created]\n checkedSet.add(created)\n internalChange = true\n model.value = [...(model.value ?? []), qs]\n queryString.value = ''\n emitChange()\n dropdownRef.value?.updateDropdown()\n}\n\nconst isDisabled = (option: Record<string, any>) => {\n const { max } = props\n return max !== undefined && checkedSet.size >= max && !checkedSet.has(option)\n}\n\nconst optionClass = cls.e('option')\nconst rippleClass = cls.e('ripple')\nconst checkboxClass = cls.e('checkbox')\n\nprovide(MultiSelectDIKey, { optionClass, rippleClass, checkboxClass })\n</script>\n"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import _sfc_main$1 from "../icon/icon.js";
|
|
2
2
|
import _sfc_main$2 from "../dropdown/dropdown.js";
|
|
3
|
-
import _sfc_main$3 from "../
|
|
4
|
-
import _sfc_main$4 from "../
|
|
5
|
-
import _sfc_main$5 from "../
|
|
6
|
-
import _sfc_main$6 from "../
|
|
3
|
+
import _sfc_main$3 from "../loading/loading.js";
|
|
4
|
+
import _sfc_main$4 from "../checkbox/checkbox.js";
|
|
5
|
+
import _sfc_main$5 from "../tree/tree.js";
|
|
6
|
+
import _sfc_main$6 from "../button/button.js";
|
|
7
|
+
import _sfc_main$7 from "../tag/tag.js";
|
|
7
8
|
import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, openBlock, renderList, shallowRef, toDisplayString, unref, useModel, useSlots, useTemplateRef, vModelText, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
8
9
|
import { useFormFallbackProps } from "@veltra/compositions";
|
|
9
10
|
import { FORM_EMPTY_CONTENT, bem, fieldKey, injectFormContext } from "@veltra/utils";
|
|
10
11
|
import { ArrowDown, Close } from "@veltra/icons/normal";
|
|
11
|
-
import { dfs, o } from "@cat-kit/core";
|
|
12
|
+
import { debounce, dfs, o } from "@cat-kit/core";
|
|
12
13
|
//#region src/components/multi-tree-select/multi-tree-select.vue
|
|
13
14
|
const _hoisted_1 = ["placeholder", "disabled"];
|
|
14
15
|
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
@@ -17,6 +18,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
17
18
|
__name: "multi-tree-select",
|
|
18
19
|
props: /*@__PURE__*/ mergeModels({
|
|
19
20
|
modelValue: {},
|
|
21
|
+
data: {},
|
|
20
22
|
placeholder: { default: "请选择" },
|
|
21
23
|
clearable: {
|
|
22
24
|
type: Boolean,
|
|
@@ -53,7 +55,6 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
53
55
|
labelKey: { default: "label" },
|
|
54
56
|
valueKey: { default: "value" },
|
|
55
57
|
childrenKey: {},
|
|
56
|
-
data: {},
|
|
57
58
|
disabledNode: {},
|
|
58
59
|
checkOnClickNode: {
|
|
59
60
|
type: Boolean,
|
|
@@ -88,6 +89,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
88
89
|
"label",
|
|
89
90
|
"readonly",
|
|
90
91
|
"modelValue",
|
|
92
|
+
"data",
|
|
91
93
|
"contentClass",
|
|
92
94
|
"contentStyle",
|
|
93
95
|
"minWidth",
|
|
@@ -96,11 +98,37 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
96
98
|
});
|
|
97
99
|
const emit = __emit;
|
|
98
100
|
const slots = useSlots();
|
|
99
|
-
|
|
101
|
+
/** 是否可搜索:显式声明或数据源为远程函数 */
|
|
102
|
+
const filterable = computed(() => props.filterable || typeof props.data === "function");
|
|
103
|
+
/** 过滤 */
|
|
100
104
|
const qs = shallowRef("");
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
const treeRef = shallowRef();
|
|
106
|
+
/** 远程搜索返回的树数据 */
|
|
107
|
+
const remoteData = shallowRef();
|
|
108
|
+
/** 面板渲染的树数据:data 为函数时来自远程搜索,否则为静态数据 */
|
|
109
|
+
const treeData = computed(() => typeof props.data === "function" ? remoteData.value : props.data);
|
|
110
|
+
const remoteLoading = shallowRef(false);
|
|
111
|
+
/** 远程请求序号;响应返回时序号不一致说明已有更新的请求,结果作废 */
|
|
112
|
+
let remoteSeq = 0;
|
|
113
|
+
const debouncedRemoteSearch = debounce(async (query, dataFn) => {
|
|
114
|
+
const seq = ++remoteSeq;
|
|
115
|
+
remoteLoading.value = true;
|
|
116
|
+
try {
|
|
117
|
+
const data = await dataFn(query);
|
|
118
|
+
if (seq !== remoteSeq || query !== qs.value) return;
|
|
119
|
+
remoteData.value = data ?? [];
|
|
120
|
+
if (query) nextTick(() => treeRef.value?.expandAll());
|
|
121
|
+
} finally {
|
|
122
|
+
if (seq === remoteSeq) remoteLoading.value = false;
|
|
123
|
+
}
|
|
124
|
+
}, 200);
|
|
125
|
+
watch([qs, () => props.data], ([query, data]) => {
|
|
126
|
+
if (typeof data === "function") {
|
|
127
|
+
debouncedRemoteSearch(query, data);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
treeRef.value?.filter(query);
|
|
131
|
+
}, { immediate: true });
|
|
104
132
|
const model = useModel(__props, "modelValue");
|
|
105
133
|
const hovered = shallowRef(false);
|
|
106
134
|
const tags = shallowRef([]);
|
|
@@ -109,7 +137,6 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
109
137
|
const showClear = computed(() => {
|
|
110
138
|
return props.clearable && model.value?.length && hovered.value && !disabled.value;
|
|
111
139
|
});
|
|
112
|
-
const treeRef = shallowRef();
|
|
113
140
|
const dropdownRef = shallowRef();
|
|
114
141
|
let changedByEvent = false;
|
|
115
142
|
function markEvent() {
|
|
@@ -153,7 +180,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
153
180
|
emit("clear");
|
|
154
181
|
};
|
|
155
182
|
const keyDicts = shallowRef(/* @__PURE__ */ new Map());
|
|
156
|
-
watch(
|
|
183
|
+
watch(treeData, (data) => {
|
|
157
184
|
if (!data?.length) keyDicts.value = /* @__PURE__ */ new Map();
|
|
158
185
|
else {
|
|
159
186
|
const newDict = /* @__PURE__ */ new Map();
|
|
@@ -237,17 +264,17 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
237
264
|
}), {
|
|
238
265
|
trigger: withCtx(() => [
|
|
239
266
|
createCommentVNode(" 默认展示 "),
|
|
240
|
-
!
|
|
267
|
+
!filterable.value && !tags.value.length ? (openBlock(), createElementBlock("span", {
|
|
241
268
|
key: 0,
|
|
242
269
|
class: normalizeClass(unref(cls).e("placeholder"))
|
|
243
270
|
}, toDisplayString(__props.placeholder), 3)) : createCommentVNode("v-if", true),
|
|
244
271
|
createCommentVNode(" 选择的数据项 "),
|
|
245
|
-
tags.value.length ||
|
|
272
|
+
tags.value.length || filterable.value ? (openBlock(), createElementBlock("div", {
|
|
246
273
|
key: 1,
|
|
247
274
|
class: normalizeClass(unref(cls).e("tags"))
|
|
248
275
|
}, [
|
|
249
276
|
(openBlock(true), createElementBlock(Fragment, null, renderList(visibleTags.value, (tag, index) => {
|
|
250
|
-
return openBlock(), createBlock(unref(_sfc_main$
|
|
277
|
+
return openBlock(), createBlock(unref(_sfc_main$7), {
|
|
251
278
|
key: tag[valueKey.value],
|
|
252
279
|
closable: !unref(disabled),
|
|
253
280
|
onClose: ($event) => handleRemove(index)
|
|
@@ -256,12 +283,12 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
256
283
|
_: 2
|
|
257
284
|
}, 1032, ["closable", "onClose"]);
|
|
258
285
|
}), 128)),
|
|
259
|
-
hiddenCount.value > 0 ? (openBlock(), createBlock(unref(_sfc_main$
|
|
286
|
+
hiddenCount.value > 0 ? (openBlock(), createBlock(unref(_sfc_main$7), { key: 0 }, {
|
|
260
287
|
default: withCtx(() => [createTextVNode("+" + toDisplayString(hiddenCount.value), 1)]),
|
|
261
288
|
_: 1
|
|
262
289
|
})) : createCommentVNode("v-if", true),
|
|
263
290
|
createCommentVNode(" 内嵌查询输入框:承载过滤 "),
|
|
264
|
-
|
|
291
|
+
filterable.value ? withDirectives((openBlock(), createElementBlock("input", {
|
|
265
292
|
key: 1,
|
|
266
293
|
ref_key: "inputRef",
|
|
267
294
|
ref: inputRef,
|
|
@@ -295,44 +322,43 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
295
322
|
_: 1
|
|
296
323
|
})
|
|
297
324
|
]),
|
|
298
|
-
content: withCtx(() => [
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
]),
|
|
325
|
+
content: withCtx(() => [createElementVNode("div", { class: normalizeClass([unref(cls).e("content-header"), unref(cls).m(unref(size))]) }, [
|
|
326
|
+
createCommentVNode(" 全选 "),
|
|
327
|
+
createVNode(unref(_sfc_main$4), {
|
|
328
|
+
"model-value": allChecked.value,
|
|
329
|
+
indeterminate: indeterminate.value,
|
|
330
|
+
"onUpdate:modelValue": handleCheckAll
|
|
331
|
+
}, {
|
|
332
|
+
default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode(" 全选 ", -1)])]),
|
|
333
|
+
_: 1
|
|
334
|
+
}, 8, ["model-value", "indeterminate"]),
|
|
335
|
+
createVNode(unref(_sfc_main$6), {
|
|
336
|
+
size: "small",
|
|
337
|
+
text: "",
|
|
338
|
+
type: "primary",
|
|
339
|
+
onClick: handleToggleExpandAll
|
|
340
|
+
}, {
|
|
341
|
+
default: withCtx(() => [createTextVNode(toDisplayString(allExpanded.value ? "收起全部" : "展开全部"), 1)]),
|
|
342
|
+
_: 1
|
|
343
|
+
})
|
|
344
|
+
], 2), remoteLoading.value ? (openBlock(), createElementBlock("div", {
|
|
345
|
+
key: 0,
|
|
346
|
+
class: normalizeClass(unref(cls).e("loading"))
|
|
347
|
+
}, [createVNode(unref(_sfc_main$3), { type: "dual-ring" })], 2)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" 菜单列表 "), createVNode(unref(_sfc_main$5), mergeProps(treeProps.value, {
|
|
348
|
+
checked: model.value,
|
|
349
|
+
"onUpdate:checked": [_cache[1] || (_cache[1] = ($event) => model.value = $event), handleCheck],
|
|
350
|
+
ref_key: "treeRef",
|
|
351
|
+
ref: treeRef,
|
|
352
|
+
class: unref(cls).e("content-tree"),
|
|
353
|
+
checkable: "",
|
|
354
|
+
data: treeData.value,
|
|
355
|
+
slots,
|
|
356
|
+
"scroll-to-view": ""
|
|
357
|
+
}), null, 16, [
|
|
358
|
+
"checked",
|
|
359
|
+
"class",
|
|
360
|
+
"data"
|
|
361
|
+
])], 2112))]),
|
|
336
362
|
_: 1
|
|
337
363
|
}, 16, [
|
|
338
364
|
"class",
|
|
@@ -345,7 +371,7 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
345
371
|
key: 1,
|
|
346
372
|
class: normalizeClass([unref(cls).m(unref(size)), unref(cls).e("readonly-tags")])
|
|
347
373
|
}, [createElementVNode("div", { class: normalizeClass(unref(cls).e("tags")) }, [(openBlock(true), createElementBlock(Fragment, null, renderList(tags.value, (option) => {
|
|
348
|
-
return openBlock(), createBlock(unref(_sfc_main$
|
|
374
|
+
return openBlock(), createBlock(unref(_sfc_main$7), { key: option[valueKey.value] }, {
|
|
349
375
|
default: withCtx(() => [createTextVNode(toDisplayString(option[labelKey.value]), 1)]),
|
|
350
376
|
_: 2
|
|
351
377
|
}, 1024);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-tree-select.js","names":["$attrs"],"sources":["../../../src/components/multi-tree-select/multi-tree-select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n :class=\"[cls.b, cls.m(size), bem.is('disabled', disabled), bem.is('focus', dropdownVisible)]\"\n trigger=\"click\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :disabled=\"disabled\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n ref=\"dropdownRef\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @update:visible=\"handleDropdownVisible\"\n >\n <template #trigger>\n <!-- 默认展示 -->\n <span :class=\"cls.e('placeholder')\" v-if=\"!filterable && !tags.length\">\n {{ placeholder }}\n </span>\n\n <!-- 选择的数据项 -->\n <div v-if=\"tags.length || filterable\" :class=\"cls.e('tags')\">\n <u-tag\n v-for=\"(tag, index) in visibleTags\"\n :key=\"tag[valueKey]\"\n :closable=\"!disabled\"\n @close=\"handleRemove(index)\"\n >\n {{ tag[labelKey] }}\n </u-tag>\n <u-tag v-if=\"hiddenCount > 0\">+{{ hiddenCount }}</u-tag>\n\n <!-- 内嵌查询输入框:承载过滤 -->\n <input\n v-if=\"filterable\"\n ref=\"inputRef\"\n :class=\"cls.e('input')\"\n v-model=\"qs\"\n :placeholder=\"tags.length ? '' : placeholder\"\n :disabled=\"disabled\"\n @click.stop=\"handleInputClick\"\n @focus=\"handleInputFocus\"\n />\n </div>\n <!-- 清空 icon -->\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon v-if=\"showClear\" :class=\"cls.e('clear')\" @click.stop=\"handleClear\">\n <Close />\n </u-icon>\n\n <!-- 下拉 icon -->\n <u-icon :class=\"cls.e(`arrow`)\" v-else-if=\"!readonly\">\n <ArrowDown />\n </u-icon>\n </transition>\n </template>\n <template #content>\n <div :class=\"[cls.e('content-header'), cls.m(size)]\">\n <!-- 全选 -->\n <u-checkbox\n :model-value=\"allChecked\"\n :indeterminate=\"indeterminate\"\n @update:model-value=\"handleCheckAll\"\n >\n 全选\n </u-checkbox>\n\n <u-button size=\"small\" text type=\"primary\" @click=\"handleToggleExpandAll\">\n {{ allExpanded ? '收起全部' : '展开全部' }}\n </u-button>\n </div>\n <!-- 菜单列表 -->\n <u-tree\n v-bind=\"treeProps\"\n v-model:checked=\"model\"\n @update:checked=\"handleCheck\"\n ref=\"treeRef\"\n :class=\"cls.e('content-tree')\"\n checkable\n :data=\"data\"\n :slots=\"slots\"\n scroll-to-view\n ></u-tree>\n </template>\n </u-dropdown>\n\n <div v-else-if=\"model.length\" :class=\"[cls.m(size), cls.e('readonly-tags')]\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"option of tags\" :key=\"option[valueKey]\">\n {{ option[labelKey] }}\n </u-tag>\n </div>\n </div>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { dfs, o } from '@cat-kit/core'\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { ArrowDown, Close } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { MultiTreeSelectProps, MultiTreeSelectEmits, TreeExposed } from '../../types'\nimport type { DropdownExposed } from '../../types'\nimport { UButton } from '../button'\nimport { UCheckbox } from '../checkbox'\nimport { UDropdown } from '../dropdown'\nimport { UIcon } from '../icon'\nimport { UTag } from '../tag'\nimport { UTree } from '../tree'\nimport type { TreeSlotsScope } from '../tree/di'\n\ndefineOptions({ name: 'UMultiTreeSelect', inheritAttrs: false })\n\nconst cls = bem('multi-tree-select')\n\nconst props = withDefaults(defineProps<MultiTreeSelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n expandAll: false,\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n filterable: false,\n visibilityLimit: 3,\n minWidth: '280px',\n checkStrictly: false,\n checkOnClickNode: true\n})\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst treeProps = computed(() => {\n return o(props as Record<string, any>).omit([\n 'tips',\n 'field',\n 'placeholder',\n 'disabled',\n 'label',\n 'readonly',\n 'modelValue',\n 'contentClass',\n 'contentStyle',\n 'minWidth',\n 'width'\n ])\n})\n\nconst emit = defineEmits<MultiTreeSelectEmits>()\n\nconst slots = defineSlots<{ default?: (props: TreeSlotsScope) => any }>()\n\n/**过滤 */\nconst qs = shallowRef('')\nwatch(qs, (qs) => {\n treeRef.value?.filter(qs)\n})\n\nconst model = defineModel<(string | number)[]>({ default: () => [] })\n\nconst hovered = shallowRef(false)\n\nconst tags = shallowRef<Record<string, any>[]>([])\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst showClear = computed(() => {\n return props.clearable && model.value?.length && hovered.value && !disabled.value\n})\n\nconst treeRef = shallowRef<TreeExposed>()\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nlet changedByEvent = false\n\nfunction markEvent() {\n changedByEvent = true\n nextTick(() => {\n changedByEvent = false\n })\n}\n\n/**是否全选 */\nconst allChecked = computed(() => {\n return model.value?.length === treeRef.value?.forest.size\n})\n\n/**部分 */\nconst indeterminate = computed(() => {\n return model.value.length! > 0 && !allChecked.value\n})\n\n/** 全选*/\nconst handleCheckAll = (checked: boolean) => {\n treeRef.value?.checkAll(checked)\n\n dropdownRef.value?.updateDropdown()\n}\n\n/**选中 */\nconst handleCheck = (checked: (string | number)[], checkedData: Record<string, any>[]) => {\n markEvent()\n tags.value = checkedData\n emit('change', checkedData!)\n\n dropdownRef.value?.updateDropdown()\n}\n\n/**删除 */\nconst handleRemove = (index: number) => {\n markEvent()\n tags.value = tags.value.filter((_, i) => i !== index)\n model.value = model.value.filter((_, i) => i !== index)\n emit('change', tags.value)\n}\n\n/**清空 */\nconst handleClear = () => {\n markEvent()\n tags.value = []\n model.value = []\n emit('clear')\n}\n\nconst keyDicts = shallowRef(new Map<string | number, Record<string, any>>())\n\nwatch(\n () => props.data,\n (data) => {\n if (!data?.length) {\n keyDicts.value = new Map()\n } else {\n const newDict = new Map()\n data.forEach((item) => {\n dfs(\n item,\n (v) => {\n newDict.set(v[valueKey.value], v)\n },\n props.childrenKey\n )\n })\n keyDicts.value = newDict\n }\n },\n { immediate: true }\n)\n\nwatch(\n [keyDicts, model],\n ([keyDicts, model]) => {\n if (changedByEvent) return\n\n if (!keyDicts.size || !model?.length) {\n tags.value = []\n return\n }\n\n tags.value = model.filter((v) => keyDicts.has(v)).map((v) => keyDicts.get(v)!)\n },\n { immediate: true }\n)\n\nconst allExpanded = shallowRef(props.expandAll)\nfunction handleToggleExpandAll() {\n allExpanded.value = !allExpanded.value\n allExpanded.value ? treeRef.value?.expandAll() : treeRef.value?.collapseAll()\n}\n\nwatch(treeRef, (treeRef) => {\n if (!treeRef) {\n allExpanded.value = props.expandAll\n }\n})\n\nconst limit = () => {\n let { visibilityLimit } = props\n\n if (visibilityLimit < 0) {\n visibilityLimit = 0\n }\n if (disabled.value || readonly.value) {\n visibilityLimit = model.value?.length ?? 0\n }\n return visibilityLimit\n}\n\nconst visibleTags = computed(() => {\n if (tags.value.length > limit()) {\n return tags.value.slice(0, limit())\n }\n return tags.value\n})\n\nconst hiddenCount = computed(() => {\n if (tags.value.length > limit()) {\n return tags.value.length - limit()\n }\n return 0\n})\n\nconst dropdownVisible = shallowRef(false)\n\nconst inputRef = useTemplateRef<HTMLInputElement>('inputRef')\n\nconst handleDropdownVisible = (visible: boolean) => {\n dropdownVisible.value = visible\n if (!visible) {\n qs.value = ''\n }\n}\n\n/**\n * 拦截输入区域的点击(@click.stop):阻止 dropdown 的 trigger 开合切换,\n * 保持面板展开以不中断输入。\n */\nconst handleInputClick = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\nconst handleInputFocus = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyHA,MAAM,MAAM,IAAI,mBAAmB;EAEnC,MAAM,QAAQ;EAed,MAAM,WAAW,eAAe,SAAS,MAAM,UAAU,OAAO,CAAC;EACjE,MAAM,WAAW,eAAe,SAAS,MAAM,UAAU,OAAO,CAAC;EAEjE,MAAM,YAAY,eAAe;GAC/B,OAAO,EAAE,KAA4B,CAAC,CAAC,KAAK;IAC1C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;EACH,CAAC;EAED,MAAM,OAAO;EAEb,MAAM,QAAQ,SAAA;;EAGd,MAAM,KAAK,WAAW,EAAE;EACxB,MAAM,KAAK,OAAO;GAChB,QAAQ,OAAO,OAAO,EAAE;EAC1B,CAAC;EAED,MAAM,QAAQ,SAAgC,SAAA,YAAsB;EAEpE,MAAM,UAAU,WAAW,KAAK;EAEhC,MAAM,OAAO,WAAkC,CAAC,CAAC;EAEjD,MAAM,EAAE,cAAc,kBAAkB;EAExC,MAAM,EAAE,MAAM,UAAU,aAAa,qBAAqB,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;EAElF,MAAM,YAAY,eAAe;GAC/B,OAAO,MAAM,aAAa,MAAM,OAAO,UAAU,QAAQ,SAAS,CAAC,SAAS;EAC9E,CAAC;EAED,MAAM,UAAU,WAAwB;EAExC,MAAM,cAAc,WAA4B;EAEhD,IAAI,iBAAiB;EAErB,SAAS,YAAY;GACnB,iBAAiB;GACjB,eAAe;IACb,iBAAiB;GACnB,CAAC;EACH;;EAGA,MAAM,aAAa,eAAe;GAChC,OAAO,MAAM,OAAO,WAAW,QAAQ,OAAO,OAAO;EACvD,CAAC;;EAGD,MAAM,gBAAgB,eAAe;GACnC,OAAO,MAAM,MAAM,SAAU,KAAK,CAAC,WAAW;EAChD,CAAC;;EAGD,MAAM,kBAAkB,YAAqB;GAC3C,QAAQ,OAAO,SAAS,OAAO;GAE/B,YAAY,OAAO,eAAe;EACpC;;EAGA,MAAM,eAAe,SAA8B,gBAAuC;GACxF,UAAU;GACV,KAAK,QAAQ;GACb,KAAK,UAAU,WAAY;GAE3B,YAAY,OAAO,eAAe;EACpC;;EAGA,MAAM,gBAAgB,UAAkB;GACtC,UAAU;GACV,KAAK,QAAQ,KAAK,MAAM,QAAQ,GAAG,MAAM,MAAM,KAAK;GACpD,MAAM,QAAQ,MAAM,MAAM,QAAQ,GAAG,MAAM,MAAM,KAAK;GACtD,KAAK,UAAU,KAAK,KAAK;EAC3B;;EAGA,MAAM,oBAAoB;GACxB,UAAU;GACV,KAAK,QAAQ,CAAC;GACd,MAAM,QAAQ,CAAC;GACf,KAAK,OAAO;EACd;EAEA,MAAM,WAAW,2BAAW,IAAI,IAA0C,CAAC;EAE3E,YACQ,MAAM,OACX,SAAS;GACR,IAAI,CAAC,MAAM,QACT,SAAS,wBAAQ,IAAI,IAAI;QACpB;IACL,MAAM,0BAAU,IAAI,IAAI;IACxB,KAAK,SAAS,SAAS;KACrB,IACE,OACC,MAAM;MACL,QAAQ,IAAI,EAAE,SAAS,QAAQ,CAAC;KAClC,GACA,MAAM,WACR;IACF,CAAC;IACD,SAAS,QAAQ;GACnB;EACF,GACA,EAAE,WAAW,KAAK,CACpB;EAEA,MACE,CAAC,UAAU,KAAK,IACf,CAAC,UAAU,WAAW;GACrB,IAAI,gBAAgB;GAEpB,IAAI,CAAC,SAAS,QAAQ,CAAC,OAAO,QAAQ;IACpC,KAAK,QAAQ,CAAC;IACd;GACF;GAEA,KAAK,QAAQ,MAAM,QAAQ,MAAM,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,SAAS,IAAI,CAAC,CAAE;EAC/E,GACA,EAAE,WAAW,KAAK,CACpB;EAEA,MAAM,cAAc,WAAW,MAAM,SAAS;EAC9C,SAAS,wBAAwB;GAC/B,YAAY,QAAQ,CAAC,YAAY;GACjC,YAAY,QAAQ,QAAQ,OAAO,UAAU,IAAI,QAAQ,OAAO,YAAY;EAC9E;EAEA,MAAM,UAAU,YAAY;GAC1B,IAAI,CAAC,SACH,YAAY,QAAQ,MAAM;EAE9B,CAAC;EAED,MAAM,cAAc;GAClB,IAAI,EAAE,oBAAoB;GAE1B,IAAI,kBAAkB,GACpB,kBAAkB;GAEpB,IAAI,SAAS,SAAS,SAAS,OAC7B,kBAAkB,MAAM,OAAO,UAAU;GAE3C,OAAO;EACT;EAEA,MAAM,cAAc,eAAe;GACjC,IAAI,KAAK,MAAM,SAAS,MAAM,GAC5B,OAAO,KAAK,MAAM,MAAM,GAAG,MAAM,CAAC;GAEpC,OAAO,KAAK;EACd,CAAC;EAED,MAAM,cAAc,eAAe;GACjC,IAAI,KAAK,MAAM,SAAS,MAAM,GAC5B,OAAO,KAAK,MAAM,SAAS,MAAM;GAEnC,OAAO;EACT,CAAC;EAED,MAAM,kBAAkB,WAAW,KAAK;EAExC,MAAM,WAAW,eAAiC,UAAU;EAE5D,MAAM,yBAAyB,YAAqB;GAClD,gBAAgB,QAAQ;GACxB,IAAI,CAAC,SACH,GAAG,QAAQ;EAEf;;;;;EAMA,MAAM,yBAAyB;GAC7B,IAAI,CAAC,gBAAgB,OAAO,YAAY,OAAO,KAAK;EACtD;EAEA,MAAM,yBAAyB;GAC7B,IAAI,CAAC,gBAAgB,OAAO,YAAY,OAAO,KAAK;EACtD;;GA5UW,OAAA,CAAA,MAAA,QAAA,KADT,UAAA,GAAA,YAqFa,MAAA,WAAA,GArFb,WAqFa,EAAA,KAAA,EAAA,GAnFHA,KAAAA,QAAM;IACb,OAAK;KAAG,MAAA,GAAA,CAAG,CAAC;KAAG,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI;KAAG,MAAA,GAAA,CAAG,CAAC,GAAE,YAAa,MAAA,QAAA,CAAQ;KAAG,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,gBAAA,KAAe;IAAA;IAC1F,SAAQ;IACP,iBAAa;KAAG,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA;KAAW,MAAA,GAAA,CAAG,CAAC,GAAE,SAAU,MAAA,IAAA,CAAI;KAAG,QAAA;IAAY;IACnE,iBAAe,QAAA;IACf,UAAU,MAAA,QAAA;IACV,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,QAAO;IACnB,cAAU,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,QAAO;IAChB,SAAA;IAAJ,KAAI;IACH,aAAW,QAAA;IACX,OAAO,QAAA;IACP,oBAAgB;;IAEN,SAAO,cACH;KAAb,mBAAA,QAAA;KAC2C,CAAA,QAAA,cAAU,CAAK,KAAA,MAAK,UAA/D,UAAA,GAAA,mBAEO,QAAA;;MAFA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,aAAA,CAAA;KACd,GAAA,gBAAA,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,QAAA,IAAA;KAGhB,mBAAA,UAAA;KACW,KAAA,MAAK,UAAU,QAAA,cAA1B,UAAA,GAAA,mBAsBM,OAAA;;MAtBiC,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,CAAA;;OACjD,UAAA,IAAA,GAAA,mBAOQ,UAAA,MAAA,WANiB,YAAA,QAAf,KAAK,UAAK;OADpB,OAAA,UAAA,GAAA,YAOQ,MAAA,WAAA,GAAA;QALL,KAAK,IAAI,SAAA;QACT,UAAQ,CAAG,MAAA,QAAA;QACX,UAAK,WAAE,aAAa,KAAK;;QAE1B,SAAA,cAAmB,CAAhB,gBAAA,gBAAA,IAAI,SAAA,MAAQ,GAAA,CAAA,CAAA,CAAA;;;;MAEJ,YAAA,QAAW,KAAxB,UAAA,GAAA,YAAwD,MAAA,WAAA,GAAA,EAAA,KAAA,EAAA,GAAA;OAA1B,SAAA,cAAC,CAAD,gBAAA,MAAC,gBAAG,YAAA,KAAW,GAAA,CAAA,CAAA,CAAA;;;MAE7C,mBAAA,gBAAA;MAEQ,QAAA,aADR,gBAAA,UAAA,GAAA,mBASE,SAAA;;OAPI,SAAA;OAAJ,KAAI;OACH,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;OACJ,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,GAAE,QAAA;OACV,aAAa,KAAA,MAAK,SAAM,KAAQ,QAAA;OAChC,UAAU,MAAA,QAAA;OACV,SAAK,cAAO,kBAAgB,CAAA,MAAA,CAAA;OAC5B,SAAO;MAJC,GAAA,MAAA,IAAA,UAAA,IAAA,CAAA,CAAA,YAAA,GAAA,KAAE,CAAA,CAAA,IAAA,mBAAA,QAAA,IAAA;;KAOf,mBAAA,WAAA;KACA,YASa,YAAA;MATD,MAAK;MAAU,MAAK;;MAC9B,SAAA,cAES,CAFK,UAAA,SAAd,UAAA,GAAA,YAES,MAAA,WAAA,GAAA;;OAFiB,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;OAAY,SAAK,cAAO,aAAW,CAAA,MAAA,CAAA;;OACvE,SAAA,cAAS,CAAT,YAAS,MAAA,KAAA,CAAA,CAAA,CAAA;;MAIiC,GAAA,GAAA,CAAA,OAAA,CAAA,KAAA,CAAA,MAAA,QAAA,KAA5C,UAAA,GAAA,YAES,MAAA,WAAA,GAAA;;OAFA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,OAAA,CAAA;;OACnB,SAAA,cAAa,CAAb,YAAa,MAAA,SAAA,CAAA,CAAA,CAAA;;;;;;IAIR,SAAO,cAcV;KAbN,mBAaM,OAAA,EAbA,OAAK,eAAA,CAAG,MAAA,GAAA,CAAG,CAAC,EAAC,gBAAA,GAAoB,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI,CAAA,CAAA,EAAA,GAAA;MAC/C,mBAAA,MAAA;MACA,YAMa,MAAA,WAAA,GAAA;OALV,eAAa,WAAA;OACb,eAAe,cAAA;OACf,uBAAoB;;OACtB,SAAA,cAED,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFC,gBAAA,QAED,EAAA,CAAA,EAAA,CAAA;;;MAEA,YAEW,MAAA,WAAA,GAAA;OAFD,MAAK;OAAQ,MAAA;OAAK,MAAK;OAAW,SAAO;;OACjD,SAAA,cAAmC,CAAhC,gBAAA,gBAAA,YAAA,QAAW,SAAA,MAAA,GAAA,CAAA,CAAA,CAAA;;;;KAGlB,mBAAA,QAAA;KACA,YAUU,MAAA,WAAA,GAVV,WACU,UASA,OATS;MACT,SAAS,MAAA;MAAA,oBAAA,CAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAK,QAAA,SACL,WAAA;MACb,SAAA;MAAJ,KAAI;MACH,OAAO,MAAA,GAAA,CAAG,CAAC,EAAC,cAAA;MACb,WAAA;MACC,MAAM,QAAA;MACC;MACR,kBAAA;;;;;;;;;;;;;;;GAKU,CAAA,KAAA,MAAA,MAAM,UAAtB,UAAA,GAAA,mBAMM,OAAA;;IANyB,OAAK,eAAA,CAAG,MAAA,GAAA,CAAG,CAAC,EAAE,MAAA,IAAA,CAAI,GAAG,MAAA,GAAA,CAAG,CAAC,EAAC,eAAA,CAAA,CAAA;GACvD,GAAA,CAAA,mBAIM,OAAA,EAJA,OAAK,eAAE,MAAA,GAAA,CAAG,CAAC,EAAC,MAAA,CAAA,EAAA,GAChB,EAAA,UAAA,IAAA,GAAA,mBAEQ,UAAA,MAAA,WAFgB,KAAA,QAAV,WAAM;IAApB,OAAA,UAAA,GAAA,YAEQ,MAAA,WAAA,GAAA,EAFuB,KAAK,OAAO,SAAA,OAAA,GAAA;KACzC,SAAA,cAAsB,CAAnB,gBAAA,gBAAA,OAAO,SAAA,MAAQ,GAAA,CAAA,CAAA,CAAA;;;GAKxB,CAAA,GAAA,GAAA,EAAA,GAAA,CAAA,CAAA,GAAA,CAAA,MAAA,UAAA,GAAA,mBAEW,UAAA,EAAA,KAAA,EAAA,GAAA,CADN,gBAAA,gBAAA,MAAA,kBAAA,CAAkB,GAAA,CAAA,CAAA,GAAA,EAAA"}
|
|
1
|
+
{"version":3,"file":"multi-tree-select.js","names":["$attrs"],"sources":["../../../src/components/multi-tree-select/multi-tree-select.vue"],"sourcesContent":["<template>\n <u-dropdown\n v-if=\"!readonly\"\n v-bind=\"$attrs\"\n :class=\"[cls.b, cls.m(size), bem.is('disabled', disabled), bem.is('focus', dropdownVisible)]\"\n trigger=\"click\"\n :content-class=\"[cls.e('panel'), cls.em('panel', size), contentClass]\"\n :content-style=\"contentStyle\"\n :disabled=\"disabled\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n ref=\"dropdownRef\"\n :min-width=\"minWidth\"\n :width=\"width\"\n @update:visible=\"handleDropdownVisible\"\n >\n <template #trigger>\n <!-- 默认展示 -->\n <span :class=\"cls.e('placeholder')\" v-if=\"!filterable && !tags.length\">\n {{ placeholder }}\n </span>\n\n <!-- 选择的数据项 -->\n <div v-if=\"tags.length || filterable\" :class=\"cls.e('tags')\">\n <u-tag\n v-for=\"(tag, index) in visibleTags\"\n :key=\"tag[valueKey]\"\n :closable=\"!disabled\"\n @close=\"handleRemove(index)\"\n >\n {{ tag[labelKey] }}\n </u-tag>\n <u-tag v-if=\"hiddenCount > 0\">+{{ hiddenCount }}</u-tag>\n\n <!-- 内嵌查询输入框:承载过滤 -->\n <input\n v-if=\"filterable\"\n ref=\"inputRef\"\n :class=\"cls.e('input')\"\n v-model=\"qs\"\n :placeholder=\"tags.length ? '' : placeholder\"\n :disabled=\"disabled\"\n @click.stop=\"handleInputClick\"\n @focus=\"handleInputFocus\"\n />\n </div>\n <!-- 清空 icon -->\n <transition name=\"zoom-in\" mode=\"out-in\">\n <u-icon v-if=\"showClear\" :class=\"cls.e('clear')\" @click.stop=\"handleClear\">\n <Close />\n </u-icon>\n\n <!-- 下拉 icon -->\n <u-icon :class=\"cls.e(`arrow`)\" v-else-if=\"!readonly\">\n <ArrowDown />\n </u-icon>\n </transition>\n </template>\n <template #content>\n <div :class=\"[cls.e('content-header'), cls.m(size)]\">\n <!-- 全选 -->\n <u-checkbox\n :model-value=\"allChecked\"\n :indeterminate=\"indeterminate\"\n @update:model-value=\"handleCheckAll\"\n >\n 全选\n </u-checkbox>\n\n <u-button size=\"small\" text type=\"primary\" @click=\"handleToggleExpandAll\">\n {{ allExpanded ? '收起全部' : '展开全部' }}\n </u-button>\n </div>\n <div v-if=\"remoteLoading\" :class=\"cls.e('loading')\">\n <ULoading type=\"dual-ring\" />\n </div>\n <!-- 菜单列表 -->\n <u-tree\n v-else\n v-bind=\"treeProps\"\n v-model:checked=\"model\"\n @update:checked=\"handleCheck\"\n ref=\"treeRef\"\n :class=\"cls.e('content-tree')\"\n checkable\n :data=\"treeData\"\n :slots=\"slots\"\n scroll-to-view\n ></u-tree>\n </template>\n </u-dropdown>\n\n <div v-else-if=\"model.length\" :class=\"[cls.m(size), cls.e('readonly-tags')]\">\n <div :class=\"cls.e('tags')\">\n <u-tag v-for=\"option of tags\" :key=\"option[valueKey]\">\n {{ option[labelKey] }}\n </u-tag>\n </div>\n </div>\n\n <template v-else>\n {{ FORM_EMPTY_CONTENT }}\n </template>\n</template>\n\n<script lang=\"ts\" setup>\nimport { debounce, dfs, o } from '@cat-kit/core'\nimport { useFormFallbackProps } from '@veltra/compositions'\nimport { ArrowDown, Close } from '@veltra/icons/normal'\nimport { bem, fieldKey, FORM_EMPTY_CONTENT } from '@veltra/utils'\nimport { injectFormContext } from '@veltra/utils'\nimport { computed, nextTick, shallowRef, useTemplateRef, watch } from 'vue'\n\nimport type { MultiTreeSelectProps, MultiTreeSelectEmits, TreeExposed } from '../../types'\nimport type { DropdownExposed } from '../../types'\nimport { UButton } from '../button'\nimport { UCheckbox } from '../checkbox'\nimport { UDropdown } from '../dropdown'\nimport { UIcon } from '../icon'\nimport { ULoading } from '../loading'\nimport { UTag } from '../tag'\nimport { UTree } from '../tree'\nimport type { TreeSlotsScope } from '../tree/di'\n\ndefineOptions({ name: 'UMultiTreeSelect', inheritAttrs: false })\n\nconst cls = bem('multi-tree-select')\n\nconst props = withDefaults(defineProps<MultiTreeSelectProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n placeholder: '请选择',\n expandAll: false,\n clearable: true,\n disabled: undefined,\n readonly: undefined,\n filterable: false,\n visibilityLimit: 3,\n minWidth: '280px',\n checkStrictly: false,\n checkOnClickNode: true\n})\n\nconst labelKey = computed(() => fieldKey(props.labelKey, 'label'))\nconst valueKey = computed(() => fieldKey(props.valueKey, 'value'))\n\nconst treeProps = computed(() => {\n return o(props as Record<string, any>).omit([\n 'tips',\n 'field',\n 'placeholder',\n 'disabled',\n 'label',\n 'readonly',\n 'modelValue',\n 'data',\n 'contentClass',\n 'contentStyle',\n 'minWidth',\n 'width'\n ])\n})\n\nconst emit = defineEmits<MultiTreeSelectEmits>()\n\nconst slots = defineSlots<{ default?: (props: TreeSlotsScope) => any }>()\n\n/** 是否可搜索:显式声明或数据源为远程函数 */\nconst filterable = computed(() => props.filterable || typeof props.data === 'function')\n\n/** 过滤 */\nconst qs = shallowRef('')\n\nconst treeRef = shallowRef<TreeExposed>()\n\n/** 远程搜索返回的树数据 */\nconst remoteData = shallowRef<Record<string, any>[]>()\n\n/** 面板渲染的树数据:data 为函数时来自远程搜索,否则为静态数据 */\nconst treeData = computed(() => (typeof props.data === 'function' ? remoteData.value : props.data))\n\nconst remoteLoading = shallowRef(false)\n/** 远程请求序号;响应返回时序号不一致说明已有更新的请求,结果作废 */\nlet remoteSeq = 0\n\nconst debouncedRemoteSearch = debounce(\n async (\n query: string,\n dataFn: (qs: string) => Promise<Record<string, any>[]> | Record<string, any>[]\n ) => {\n const seq = ++remoteSeq\n remoteLoading.value = true\n try {\n const data = await dataFn(query)\n // 响应到达时查询词可能已变化或已有更新的请求,过期结果直接丢弃\n if (seq !== remoteSeq || query !== qs.value) return\n remoteData.value = data ?? []\n // 搜索结果展示完整命中路径,与本地过滤自动展开祖先的行为对齐\n if (query) nextTick(() => treeRef.value?.expandAll())\n } finally {\n if (seq === remoteSeq) remoteLoading.value = false\n }\n },\n 200\n)\n\nwatch(\n [qs, () => props.data],\n ([query, data]) => {\n if (typeof data === 'function') {\n debouncedRemoteSearch(query, data)\n return\n }\n treeRef.value?.filter(query)\n },\n { immediate: true }\n)\n\nconst model = defineModel<(string | number)[]>({ default: () => [] })\n\nconst hovered = shallowRef(false)\n\nconst tags = shallowRef<Record<string, any>[]>([])\n\nconst { formProps } = injectFormContext()\n\nconst { size, disabled, readonly } = useFormFallbackProps([formProps ?? {}, props])\n\nconst showClear = computed(() => {\n return props.clearable && model.value?.length && hovered.value && !disabled.value\n})\n\nconst dropdownRef = shallowRef<DropdownExposed>()\n\nlet changedByEvent = false\n\nfunction markEvent() {\n changedByEvent = true\n nextTick(() => {\n changedByEvent = false\n })\n}\n\n/**是否全选 */\nconst allChecked = computed(() => {\n return model.value?.length === treeRef.value?.forest.size\n})\n\n/**部分 */\nconst indeterminate = computed(() => {\n return model.value.length! > 0 && !allChecked.value\n})\n\n/** 全选*/\nconst handleCheckAll = (checked: boolean) => {\n treeRef.value?.checkAll(checked)\n\n dropdownRef.value?.updateDropdown()\n}\n\n/**选中 */\nconst handleCheck = (checked: (string | number)[], checkedData: Record<string, any>[]) => {\n markEvent()\n tags.value = checkedData\n emit('change', checkedData!)\n\n dropdownRef.value?.updateDropdown()\n}\n\n/**删除 */\nconst handleRemove = (index: number) => {\n markEvent()\n tags.value = tags.value.filter((_, i) => i !== index)\n model.value = model.value.filter((_, i) => i !== index)\n emit('change', tags.value)\n}\n\n/**清空 */\nconst handleClear = () => {\n markEvent()\n tags.value = []\n model.value = []\n emit('clear')\n}\n\nconst keyDicts = shallowRef(new Map<string | number, Record<string, any>>())\n\nwatch(\n treeData,\n (data) => {\n if (!data?.length) {\n keyDicts.value = new Map()\n } else {\n const newDict = new Map()\n data.forEach((item) => {\n dfs(\n item,\n (v) => {\n newDict.set(v[valueKey.value], v)\n },\n props.childrenKey\n )\n })\n keyDicts.value = newDict\n }\n },\n { immediate: true }\n)\n\nwatch(\n [keyDicts, model],\n ([keyDicts, model]) => {\n if (changedByEvent) return\n\n if (!keyDicts.size || !model?.length) {\n tags.value = []\n return\n }\n\n tags.value = model.filter((v) => keyDicts.has(v)).map((v) => keyDicts.get(v)!)\n },\n { immediate: true }\n)\n\nconst allExpanded = shallowRef(props.expandAll)\nfunction handleToggleExpandAll() {\n allExpanded.value = !allExpanded.value\n allExpanded.value ? treeRef.value?.expandAll() : treeRef.value?.collapseAll()\n}\n\nwatch(treeRef, (treeRef) => {\n if (!treeRef) {\n allExpanded.value = props.expandAll\n }\n})\n\nconst limit = () => {\n let { visibilityLimit } = props\n\n if (visibilityLimit < 0) {\n visibilityLimit = 0\n }\n if (disabled.value || readonly.value) {\n visibilityLimit = model.value?.length ?? 0\n }\n return visibilityLimit\n}\n\nconst visibleTags = computed(() => {\n if (tags.value.length > limit()) {\n return tags.value.slice(0, limit())\n }\n return tags.value\n})\n\nconst hiddenCount = computed(() => {\n if (tags.value.length > limit()) {\n return tags.value.length - limit()\n }\n return 0\n})\n\nconst dropdownVisible = shallowRef(false)\n\nconst inputRef = useTemplateRef<HTMLInputElement>('inputRef')\n\nconst handleDropdownVisible = (visible: boolean) => {\n dropdownVisible.value = visible\n if (!visible) {\n qs.value = ''\n }\n}\n\n/**\n * 拦截输入区域的点击(@click.stop):阻止 dropdown 的 trigger 开合切换,\n * 保持面板展开以不中断输入。\n */\nconst handleInputClick = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n\nconst handleInputFocus = () => {\n if (!dropdownVisible.value) dropdownRef.value?.open()\n}\n</script>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { $insertNodes, DecoratorNode } from "lexical";
|
|
2
|
+
//#region src/components/rich-text-editor/image-node.ts
|
|
3
|
+
let imageUid = 0;
|
|
4
|
+
function nextImageId() {
|
|
5
|
+
return `rte-img-${++imageUid}`;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 图片节点:插入时 src 为本地 objectURL、__file 持有原始文件,提交前由宿主调用
|
|
9
|
+
* uploadImages 换成服务器地址。__file 不参与序列化,仅会话内有效。
|
|
10
|
+
* 本仓库为手写 Vue 绑定(无 React 适配层),不走 decorate 渲染管道,
|
|
11
|
+
* createDOM 直接返回 <img> 元素。
|
|
12
|
+
*/
|
|
13
|
+
var ImageNode = class ImageNode extends DecoratorNode {
|
|
14
|
+
__src;
|
|
15
|
+
__alt;
|
|
16
|
+
__id;
|
|
17
|
+
__file;
|
|
18
|
+
static getType() {
|
|
19
|
+
return "u-image";
|
|
20
|
+
}
|
|
21
|
+
static clone(node) {
|
|
22
|
+
return new ImageNode(node.__src, node.__alt, node.__id, node.__file, node.__key);
|
|
23
|
+
}
|
|
24
|
+
static importJSON(serializedNode) {
|
|
25
|
+
return $createImageNode({
|
|
26
|
+
src: serializedNode.src,
|
|
27
|
+
alt: serializedNode.alt,
|
|
28
|
+
id: serializedNode.id
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
constructor(src, alt = "", id = nextImageId(), file = null, key) {
|
|
32
|
+
super(key);
|
|
33
|
+
this.__src = src;
|
|
34
|
+
this.__alt = alt;
|
|
35
|
+
this.__id = id;
|
|
36
|
+
this.__file = file;
|
|
37
|
+
}
|
|
38
|
+
static importDOM() {
|
|
39
|
+
return { img: () => ({
|
|
40
|
+
conversion: convertImageElement,
|
|
41
|
+
priority: 0
|
|
42
|
+
}) };
|
|
43
|
+
}
|
|
44
|
+
exportDOM() {
|
|
45
|
+
const element = document.createElement("img");
|
|
46
|
+
element.setAttribute("src", this.__src);
|
|
47
|
+
element.setAttribute("class", "u-rte-image");
|
|
48
|
+
element.setAttribute("alt", this.__alt);
|
|
49
|
+
element.setAttribute("data-rte-image-id", this.__id);
|
|
50
|
+
return { element };
|
|
51
|
+
}
|
|
52
|
+
exportJSON() {
|
|
53
|
+
return {
|
|
54
|
+
type: "u-image",
|
|
55
|
+
version: 1,
|
|
56
|
+
src: this.__src,
|
|
57
|
+
alt: this.__alt,
|
|
58
|
+
id: this.__id
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
createDOM() {
|
|
62
|
+
const element = document.createElement("img");
|
|
63
|
+
element.className = "u-rte-image";
|
|
64
|
+
element.src = this.__src;
|
|
65
|
+
element.alt = this.__alt;
|
|
66
|
+
element.draggable = false;
|
|
67
|
+
return element;
|
|
68
|
+
}
|
|
69
|
+
updateDOM(prevNode, element) {
|
|
70
|
+
const img = element;
|
|
71
|
+
if (prevNode.__src !== this.__src) img.src = this.__src;
|
|
72
|
+
if (prevNode.__alt !== this.__alt) img.alt = this.__alt;
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/** Vue 环境无 React 渲染管道,装饰内容即 createDOM 返回的元素本身 */
|
|
76
|
+
decorate() {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
getSrc() {
|
|
80
|
+
return this.__src;
|
|
81
|
+
}
|
|
82
|
+
getFile() {
|
|
83
|
+
return this.__file;
|
|
84
|
+
}
|
|
85
|
+
/** 替换为服务器地址,同时清除待上传标记(已上传的节点不再重复上传) */
|
|
86
|
+
setSrc(src) {
|
|
87
|
+
const self = this.getWritable();
|
|
88
|
+
self.__src = src;
|
|
89
|
+
self.__file = null;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
function convertImageElement(domNode) {
|
|
93
|
+
const src = domNode.getAttribute("src");
|
|
94
|
+
if (!src) return { node: null };
|
|
95
|
+
return { node: $createImageNode({
|
|
96
|
+
src,
|
|
97
|
+
alt: domNode.getAttribute("alt") ?? "",
|
|
98
|
+
id: domNode.getAttribute("data-rte-image-id") ?? void 0
|
|
99
|
+
}) };
|
|
100
|
+
}
|
|
101
|
+
function $createImageNode(options) {
|
|
102
|
+
return new ImageNode(options.src, options.alt ?? "", options.id ?? nextImageId(), options.file ?? null);
|
|
103
|
+
}
|
|
104
|
+
function $isImageNode(node) {
|
|
105
|
+
return node instanceof ImageNode;
|
|
106
|
+
}
|
|
107
|
+
const objectUrls = /* @__PURE__ */ new WeakMap();
|
|
108
|
+
function getImageObjectUrls(editor) {
|
|
109
|
+
let urls = objectUrls.get(editor);
|
|
110
|
+
if (!urls) {
|
|
111
|
+
urls = /* @__PURE__ */ new Set();
|
|
112
|
+
objectUrls.set(editor, urls);
|
|
113
|
+
}
|
|
114
|
+
return urls;
|
|
115
|
+
}
|
|
116
|
+
/** 插入图片文件:objectURL 即时预览,File 挂在节点上等待提交时上传。返回插入的图片数量 */
|
|
117
|
+
function insertImageFiles(editor, files) {
|
|
118
|
+
const images = Array.from(files).filter((file) => file.type.startsWith("image/"));
|
|
119
|
+
if (!images.length) return 0;
|
|
120
|
+
const urls = getImageObjectUrls(editor);
|
|
121
|
+
editor.update(() => {
|
|
122
|
+
const nodes = images.map((file) => {
|
|
123
|
+
const url = URL.createObjectURL(file);
|
|
124
|
+
urls.add(url);
|
|
125
|
+
return $createImageNode({
|
|
126
|
+
src: url,
|
|
127
|
+
alt: file.name,
|
|
128
|
+
file
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
$insertNodes(nodes);
|
|
132
|
+
});
|
|
133
|
+
return images.length;
|
|
134
|
+
}
|
|
135
|
+
/** 回收已从内容中移除的图片 objectURL,aliveUrls 为当前内容中仍存活的图片地址 */
|
|
136
|
+
function gcImageObjectUrls(editor, aliveUrls) {
|
|
137
|
+
const urls = objectUrls.get(editor);
|
|
138
|
+
if (!urls?.size) return;
|
|
139
|
+
urls.forEach((url) => {
|
|
140
|
+
if (!aliveUrls.has(url)) {
|
|
141
|
+
URL.revokeObjectURL(url);
|
|
142
|
+
urls.delete(url);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/** 回收该编辑器创建的全部图片 objectURL(组件卸载时调用) */
|
|
147
|
+
function revokeImageObjectUrls(editor) {
|
|
148
|
+
objectUrls.get(editor)?.forEach((url) => URL.revokeObjectURL(url));
|
|
149
|
+
objectUrls.delete(editor);
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
export { $createImageNode, $isImageNode, ImageNode, gcImageObjectUrls, insertImageFiles, revokeImageObjectUrls };
|
|
153
|
+
|
|
154
|
+
//# sourceMappingURL=image-node.js.map
|