@veltra/desktop 1.0.8 → 1.0.9
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/action/action-group.vue.d.ts +2 -2
- package/dist/components/action/action.vue.d.ts +3 -3
- package/dist/components/auto-complete/auto-complete.vue.d.ts +1 -1
- package/dist/components/batch-edit/style.js +2 -2
- package/dist/components/button/button.vue.d.ts +1 -1
- package/dist/components/cascade/cascade.js +15 -13
- package/dist/components/cascade/cascade.js.map +1 -1
- package/dist/components/cascade/cascade.vue.d.ts +4 -4
- package/dist/components/cascade/node.js.map +1 -1
- package/dist/components/cascade/use-check.js +3 -2
- package/dist/components/cascade/use-check.js.map +1 -1
- package/dist/components/cascade/use-select.js +3 -3
- package/dist/components/cascade/use-select.js.map +1 -1
- package/dist/components/date-panel/date-panel.vue.d.ts +1 -1
- package/dist/components/date-picker/date-picker.js +9 -9
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-picker/date-picker.vue.d.ts +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +9 -9
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.vue.d.ts +1 -1
- package/dist/components/empty/empty.vue.d.ts +1 -1
- package/dist/components/file-picker/file-picker.vue.d.ts +1 -1
- package/dist/components/file-picker/helper.js +19 -7
- package/dist/components/file-picker/helper.js.map +1 -1
- package/dist/components/file-viewer/file-viewer.js +294 -0
- package/dist/components/file-viewer/file-viewer.js.map +1 -0
- package/dist/components/file-viewer/file-viewer.vue.d.ts +42 -0
- package/dist/components/file-viewer/helper.js +185 -0
- package/dist/components/file-viewer/helper.js.map +1 -0
- package/dist/components/file-viewer/index.d.ts +1 -0
- package/dist/components/file-viewer/previewers/docx-previewer.js +76 -0
- package/dist/components/file-viewer/previewers/docx-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/image-previewer.js +64 -0
- package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/pdf-previewer.js +90 -0
- package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/sheet-previewer.js +175 -0
- package/dist/components/file-viewer/previewers/sheet-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/text-previewer.js +74 -0
- package/dist/components/file-viewer/previewers/text-previewer.js.map +1 -0
- package/dist/components/file-viewer/previewers/video-previewer.js +62 -0
- package/dist/components/file-viewer/previewers/video-previewer.js.map +1 -0
- package/dist/components/file-viewer/style.d.ts +1 -0
- package/dist/components/file-viewer/style.js +4 -0
- package/dist/components/file-viewer/style2.css +445 -0
- package/dist/components/grid-input/grid-input.vue.d.ts +1 -1
- package/dist/components/index.d.ts +12 -9
- package/dist/components/input/input.vue.d.ts +1 -1
- package/dist/components/multi-select/multi-select-option.js +14 -10
- package/dist/components/multi-select/multi-select-option.js.map +1 -1
- package/dist/components/multi-select/multi-select.js +16 -19
- package/dist/components/multi-select/multi-select.js.map +1 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +3 -3
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +4 -4
- package/dist/components/notification/notification.vue.d.ts +1 -1
- package/dist/components/number-input/number-input.vue.d.ts +1 -1
- package/dist/components/number-range-input/number-range-input.vue.d.ts +2 -2
- package/dist/components/palette/di.js.map +1 -1
- package/dist/components/palette/palette-alpha.js +7 -10
- package/dist/components/palette/palette-alpha.js.map +1 -1
- package/dist/components/palette/palette-hue.js +5 -7
- package/dist/components/palette/palette-hue.js.map +1 -1
- package/dist/components/palette/palette-sv.js +8 -10
- package/dist/components/palette/palette-sv.js.map +1 -1
- package/dist/components/palette/palette.js +22 -24
- package/dist/components/palette/palette.js.map +1 -1
- package/dist/components/password-input/password-input.vue.d.ts +1 -1
- package/dist/components/pop-confirm/pop-confirm.vue.d.ts +1 -1
- package/dist/components/progress-nodes/progress-nodes.vue.d.ts +3 -3
- package/dist/components/rich-text-editor/rich-text-editor.vue.d.ts +2 -2
- package/dist/components/select/select.js +14 -12
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select/select.vue.d.ts +2 -2
- package/dist/components/slider/slider-thumb.js +10 -13
- package/dist/components/slider/slider-thumb.js.map +1 -1
- package/dist/components/slider/slider.js +12 -15
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/table/di.js.map +1 -1
- package/dist/components/table/node/row.d.ts +10 -1
- package/dist/components/table/node/row.js +9 -0
- package/dist/components/table/node/row.js.map +1 -1
- package/dist/components/table/style.js +1 -1
- package/dist/components/table/table-body.js +25 -26
- package/dist/components/table/table-body.js.map +1 -1
- package/dist/components/table/table-cell.js +16 -9
- package/dist/components/table/table-cell.js.map +1 -1
- package/dist/components/table/table-row.js +78 -19
- package/dist/components/table/table-row.js.map +1 -1
- package/dist/components/table/table.js +76 -34
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/use-fixed-columns.js +27 -8
- package/dist/components/table/use-fixed-columns.js.map +1 -1
- package/dist/components/table/use-rows.js +2 -2
- package/dist/components/table/use-rows.js.map +1 -1
- package/dist/components/table/use-table.js +25 -3
- package/dist/components/table/use-table.js.map +1 -1
- package/dist/components/tabs/index.d.ts +3 -1
- package/dist/components/tabs/style2.css +169 -107
- package/dist/components/tabs/tabs-horizontal.js +133 -0
- package/dist/components/tabs/tabs-horizontal.js.map +1 -0
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +29 -0
- package/dist/components/tabs/tabs-vertical.js +89 -0
- package/dist/components/tabs/tabs-vertical.js.map +1 -0
- package/dist/components/tabs/tabs-vertical.vue.d.ts +28 -0
- package/dist/components/tabs/tabs.js +75 -105
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/tabs/tabs.vue.d.ts +9 -23
- package/dist/components/tabs/use-tabs-bar.js +105 -0
- package/dist/components/tabs/use-tabs-bar.js.map +1 -0
- package/dist/components/textarea/textarea.vue.d.ts +1 -1
- package/dist/components/tip/tip.vue.d.ts +2 -2
- package/dist/components/tree/style2.css +45 -23
- package/dist/components/tree/tree-node.js +50 -35
- package/dist/components/tree/tree-node.js.map +1 -1
- package/dist/components/tree/tree.js +27 -20
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree/tree.vue.d.ts +1 -1
- package/dist/components/tree/use-check.js +52 -14
- package/dist/components/tree/use-check.js.map +1 -1
- package/dist/components/tree/use-tree-nodes.js +51 -24
- package/dist/components/tree/use-tree-nodes.js.map +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +3 -3
- package/dist/components/watermark/watermark.vue.d.ts +1 -1
- package/dist/index.d.ts +57 -53
- package/dist/index.js +51 -48
- package/dist/types/file-viewer.d.ts +71 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/tabs.d.ts +106 -14
- package/dist/types/tree.d.ts +6 -1
- package/package.json +32 -31
- package/src/components/cascade/cascade.vue +18 -18
- package/src/components/cascade/node.ts +4 -1
- package/src/components/cascade/use-check.ts +5 -4
- package/src/components/cascade/use-select.ts +4 -5
- package/src/components/date-picker/date-picker.vue +10 -9
- package/src/components/date-range-picker/date-range-picker.vue +12 -12
- package/src/components/file-picker/helper.ts +21 -10
- package/src/components/file-viewer/file-viewer.vue +311 -0
- package/src/components/file-viewer/helper.ts +193 -0
- package/src/components/file-viewer/index.ts +1 -0
- package/src/components/file-viewer/previewers/docx-previewer.vue +78 -0
- package/src/components/file-viewer/previewers/image-previewer.vue +64 -0
- package/src/components/file-viewer/previewers/pdf-previewer.vue +90 -0
- package/src/components/file-viewer/previewers/sheet-previewer.vue +210 -0
- package/src/components/file-viewer/previewers/text-previewer.vue +76 -0
- package/src/components/file-viewer/previewers/video-previewer.vue +72 -0
- package/src/components/file-viewer/style.scss +504 -0
- package/src/components/file-viewer/style.ts +4 -0
- package/src/components/index.ts +2 -0
- package/src/components/multi-select/multi-select-option.vue +16 -3
- package/src/components/multi-select/multi-select.vue +17 -9
- package/src/components/palette/di.ts +5 -3
- package/src/components/palette/palette-alpha.vue +7 -10
- package/src/components/palette/palette-hue.vue +5 -7
- package/src/components/palette/palette-sv.vue +12 -14
- package/src/components/palette/palette.vue +19 -21
- package/src/components/select/select.vue +21 -19
- package/src/components/slider/slider-thumb.vue +11 -14
- package/src/components/slider/slider.vue +15 -15
- package/src/components/table/di.ts +20 -3
- package/src/components/table/node/row.ts +10 -1
- package/src/components/table/table-body.vue +28 -33
- package/src/components/table/table-cell.vue +17 -9
- package/src/components/table/table-row.tsx +83 -17
- package/src/components/table/table.vue +73 -45
- package/src/components/table/use-fixed-columns.ts +46 -12
- package/src/components/table/use-rows.ts +14 -3
- package/src/components/table/use-table.ts +27 -3
- package/src/components/tabs/index.ts +2 -0
- package/src/components/tabs/style.scss +217 -134
- package/src/components/tabs/tabs-horizontal.vue +125 -0
- package/src/components/tabs/tabs-vertical.vue +75 -0
- package/src/components/tabs/tabs.vue +56 -127
- package/src/components/tabs/use-tabs-bar.ts +119 -0
- package/src/components/tree/style.scss +74 -29
- package/src/components/tree/tree-node.vue +10 -4
- package/src/components/tree/tree.vue +39 -12
- package/src/components/tree/use-check.ts +79 -23
- package/src/components/tree/use-tree-nodes.ts +85 -34
- package/src/types/file-viewer.ts +69 -0
- package/src/types/index.ts +1 -0
- package/src/types/tabs.ts +113 -19
- package/src/types/tree.ts +6 -1
|
@@ -2,8 +2,8 @@ import _sfc_main$1 from "../icon/icon.js";
|
|
|
2
2
|
import NodeRender from "../node-render/node-render.js";
|
|
3
3
|
import _sfc_main$2 from "../checkbox/checkbox.js";
|
|
4
4
|
import { TreeDIKey } from "./di.js";
|
|
5
|
-
import { createBlock, createCommentVNode, createElementBlock, createVNode, defineComponent, inject, normalizeClass,
|
|
6
|
-
import { bem
|
|
5
|
+
import { Fragment, createBlock, createCommentVNode, createElementBlock, createVNode, defineComponent, inject, normalizeClass, openBlock, renderList, unref, withCtx, withDirectives, withModifiers } from "vue";
|
|
6
|
+
import { bem } from "@veltra/utils";
|
|
7
7
|
import { vRipple } from "@veltra/directives";
|
|
8
8
|
import { ArrowRight } from "@veltra/icons/normal";
|
|
9
9
|
//#region src/components/tree/tree-node.vue
|
|
@@ -12,11 +12,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12
12
|
__name: "tree-node",
|
|
13
13
|
props: {
|
|
14
14
|
node: {},
|
|
15
|
+
index: {},
|
|
15
16
|
measureElement: { type: Function }
|
|
16
17
|
},
|
|
17
18
|
setup(__props) {
|
|
18
19
|
const props = __props;
|
|
19
20
|
const { treeProps, treeEmit, cls, getTreeSlotsNode, getFlattedNodes, toggleCheck, handleSelect } = inject(TreeDIKey);
|
|
21
|
+
function measureRef(el) {
|
|
22
|
+
if (typeof props.index !== "number" || !props.measureElement) return;
|
|
23
|
+
props.measureElement(props.index, el);
|
|
24
|
+
}
|
|
20
25
|
function toggleExpand() {
|
|
21
26
|
const { node } = props;
|
|
22
27
|
node.expanded = !node.expanded;
|
|
@@ -40,39 +45,49 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
40
45
|
unref(bem).is("expanded", __props.node.expanded),
|
|
41
46
|
unref(bem).is("disabled", __props.node.disabled)
|
|
42
47
|
]),
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
48
|
+
ref: measureRef
|
|
49
|
+
}, [
|
|
50
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.node.depth, (i) => {
|
|
51
|
+
return openBlock(), createElementBlock("span", {
|
|
52
|
+
key: i,
|
|
53
|
+
class: normalizeClass(unref(cls).e("indent")),
|
|
54
|
+
"aria-hidden": "true"
|
|
55
|
+
}, null, 2);
|
|
56
|
+
}), 128)),
|
|
57
|
+
!__props.node.isLeaf ? (openBlock(), createBlock(unref(_sfc_main$1), {
|
|
58
|
+
key: 0,
|
|
59
|
+
class: normalizeClass(unref(cls).e("expand-icon")),
|
|
60
|
+
onClick: withModifiers(toggleExpand, ["stop"])
|
|
61
|
+
}, {
|
|
62
|
+
default: withCtx(() => [createVNode(unref(ArrowRight))]),
|
|
63
|
+
_: 1
|
|
64
|
+
}, 8, ["class"])) : (openBlock(), createElementBlock("i", {
|
|
65
|
+
key: 1,
|
|
66
|
+
class: normalizeClass([unref(cls).e("indent"), unref(cls).em("indent", "leaf")]),
|
|
67
|
+
"aria-hidden": "true"
|
|
68
|
+
}, null, 2)),
|
|
69
|
+
withDirectives((openBlock(), createElementBlock("div", {
|
|
70
|
+
class: normalizeClass(unref(cls).e("node-content")),
|
|
71
|
+
onClick: handleClick,
|
|
72
|
+
onContextmenu: _cache[1] || (_cache[1] = ($event) => unref(treeEmit)("node-contextmenu", $event, __props.node))
|
|
73
|
+
}, [unref(treeProps).checkable ? (openBlock(), createBlock(_sfc_main$2, {
|
|
74
|
+
key: 0,
|
|
75
|
+
class: normalizeClass(unref(cls).e("checkbox")),
|
|
76
|
+
"model-value": __props.node.checked,
|
|
77
|
+
indeterminate: __props.node.indeterminate,
|
|
78
|
+
disabled: __props.node.disabled,
|
|
79
|
+
onChange: handleChange,
|
|
80
|
+
onClick: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"]))
|
|
81
|
+
}, null, 8, [
|
|
82
|
+
"class",
|
|
83
|
+
"model-value",
|
|
84
|
+
"indeterminate",
|
|
85
|
+
"disabled"
|
|
86
|
+
])) : createCommentVNode("v-if", true), createVNode(unref(NodeRender), { content: unref(getTreeSlotsNode)({
|
|
87
|
+
node: __props.node,
|
|
88
|
+
data: __props.node.data
|
|
89
|
+
}) }, null, 8, ["content"])], 34)), [[unref(vRipple), (unref(treeProps).checkable || unref(treeProps).selectable) && !__props.node.disabled ? unref(cls).e("ripple") : false]])
|
|
90
|
+
], 2);
|
|
76
91
|
};
|
|
77
92
|
}
|
|
78
93
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-node.js","names":[],"sources":["../../../src/components/tree/tree-node.vue"],"sourcesContent":["<template>\n <div\n :class=\"[cls.e('node'), bem.is('expanded', node.expanded), bem.is('disabled', node.disabled)]\"\n :
|
|
1
|
+
{"version":3,"file":"tree-node.js","names":[],"sources":["../../../src/components/tree/tree-node.vue"],"sourcesContent":["<template>\n <div\n :class=\"[cls.e('node'), bem.is('expanded', node.expanded), bem.is('disabled', node.disabled)]\"\n :ref=\"measureRef\"\n >\n <span v-for=\"i in node.depth\" :key=\"i\" :class=\"cls.e('indent')\" aria-hidden=\"true\"></span>\n\n <u-icon v-if=\"!node.isLeaf\" :class=\"cls.e('expand-icon')\" @click.stop=\"toggleExpand\">\n <ArrowRight />\n </u-icon>\n <i v-else :class=\"[cls.e('indent'), cls.em('indent', 'leaf')]\" aria-hidden=\"true\"></i>\n\n <div\n :class=\"cls.e('node-content')\"\n @click=\"handleClick\"\n @contextmenu=\"treeEmit('node-contextmenu', $event, node)\"\n v-ripple=\"\n (treeProps.checkable || treeProps.selectable) && !node.disabled ? cls.e('ripple') : false\n \"\n >\n <u-checkbox\n v-if=\"treeProps.checkable\"\n :class=\"cls.e('checkbox')\"\n :model-value=\"node.checked\"\n :indeterminate=\"node.indeterminate\"\n :disabled=\"node.disabled\"\n @change=\"handleChange\"\n @click.stop\n />\n\n <u-node-render :content=\"getTreeSlotsNode({ node, data: node.data })\" />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport { vRipple } from '@veltra/directives'\nimport { ArrowRight } from '@veltra/icons/normal'\nimport { bem } from '@veltra/utils'\nimport { inject } from 'vue'\n\nimport type { TreeNodeProps } from '../../types'\nimport UCheckbox from '../checkbox/checkbox.vue'\nimport { UIcon } from '../icon'\nimport { UNodeRender } from '../node-render'\nimport { TreeDIKey } from './di'\n\ndefineOptions({\n name: 'TreeNode'\n})\n\nconst props = defineProps<TreeNodeProps>()\n\nconst { treeProps, treeEmit, cls, getTreeSlotsNode, getFlattedNodes, toggleCheck, handleSelect } =\n inject(TreeDIKey)!\n\nfunction measureRef(el: unknown) {\n if (typeof props.index !== 'number' || !props.measureElement) return\n props.measureElement(props.index, el as Element | null)\n}\n\nfunction toggleExpand() {\n const { node } = props\n node.expanded = !node.expanded\n getFlattedNodes()\n\n treeEmit('expand', node)\n}\n\nfunction handleChange(checked: boolean, e: MouseEvent) {\n toggleCheck(props.node, checked, e.ctrlKey)\n}\n\nfunction handleClick(e: MouseEvent) {\n const { node } = props\n treeEmit('node-click', node)\n\n treeProps.selectable && handleSelect(node)\n treeProps.expandOnClickNode && toggleExpand()\n treeProps.checkable &&\n !node.disabled &&\n !treeProps.expandOnClickNode &&\n toggleCheck(node, !node.checked, e.ctrlKey)\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAmDA,MAAM,QAAQ;EAEd,MAAM,EAAE,WAAW,UAAU,KAAK,kBAAkB,iBAAiB,aAAa,iBAChF,OAAO,UAAU;EAEnB,SAAS,WAAW,IAAa;AAC/B,OAAI,OAAO,MAAM,UAAU,YAAY,CAAC,MAAM,eAAgB;AAC9D,SAAM,eAAe,MAAM,OAAO,GAAoB;;EAGxD,SAAS,eAAe;GACtB,MAAM,EAAE,SAAS;AACjB,QAAK,WAAW,CAAC,KAAK;AACtB,oBAAgB;AAEhB,YAAS,UAAU,KAAI;;EAGzB,SAAS,aAAa,SAAkB,GAAe;AACrD,eAAY,MAAM,MAAM,SAAS,EAAE,QAAO;;EAG5C,SAAS,YAAY,GAAe;GAClC,MAAM,EAAE,SAAS;AACjB,YAAS,cAAc,KAAI;AAE3B,aAAU,cAAc,aAAa,KAAI;AACzC,aAAU,qBAAqB,cAAa;AAC5C,aAAU,aACR,CAAC,KAAK,YACN,CAAC,UAAU,qBACX,YAAY,MAAM,CAAC,KAAK,SAAS,EAAE,QAAO;;;uBAjF5C,mBA+BM,OAAA;IA9BH,OAAK,eAAA;KAAG,MAAA,IAAG,CAAC,EAAC,OAAA;KAAU,MAAA,IAAG,CAAC,GAAE,YAAa,QAAA,KAAK,SAAQ;KAAG,MAAA,IAAG,CAAC,GAAE,YAAa,QAAA,KAAK,SAAQ;KAAA,CAAA;IAC1F,KAAK;;sBAEN,mBAA0F,UAAA,MAAA,WAAxE,QAAA,KAAK,QAAV,MAAC;yBAAd,mBAA0F,QAAA;MAA3D,KAAK;MAAI,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,SAAA,CAAA;MAAY,eAAY;;;KAE7D,QAAA,KAAK,UAAA,WAAA,EAApB,YAES,MAAA,YAAA,EAAA;;KAFoB,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,cAAA,CAAA;KAAkB,SAAK,cAAO,cAAY,CAAA,OAAA,CAAA;;4BACnE,CAAd,YAAc,MAAA,WAAA,CAAA,CAAA,CAAA;;sCAEhB,mBAAsF,KAAA;;KAA3E,OAAK,eAAA,CAAG,MAAA,IAAG,CAAC,EAAC,SAAA,EAAY,MAAA,IAAG,CAAC,GAAE,UAAA,OAAA,CAAA,CAAA;KAAqB,eAAY;;iCAE3E,mBAmBM,OAAA;KAlBH,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,eAAA,CAAA;KACZ,SAAO;KACP,eAAW,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,SAAQ,CAAA,oBAAqB,QAAQ,QAAA,KAAI;QAM/C,MAAA,UAAS,CAAC,aAAA,WAAA,EADlB,YAQE,aAAA;;KANC,OAAK,eAAE,MAAA,IAAG,CAAC,EAAC,WAAA,CAAA;KACZ,eAAa,QAAA,KAAK;KAClB,eAAe,QAAA,KAAK;KACpB,UAAU,QAAA,KAAK;KACf,UAAQ;KACR,SAAK,OAAA,OAAA,OAAA,KAAA,oBAAN,IAAW,CAAA,OAAA,CAAA;;;;;;4CAGb,YAAwE,MAAA,WAAA,EAAA,EAAxD,SAAS,MAAA,iBAAgB,CAAA;KAAA,MAAG,QAAA;KAAI,MAAQ,QAAA,KAAK;KAAI,CAAA,EAAA,EAAA,MAAA,GAAA,CAAA,UAAA,CAAA,CAAA,EAAA,GAAA,GAAA,CAAA,CAAA,MAAA,QAAA,GAd7C,MAAA,UAAS,CAAC,aAAa,MAAA,UAAS,CAAC,eAAU,CAAM,QAAA,KAAK,WAAW,MAAA,IAAG,CAAC,EAAC,SAAA,GAAA,MAAA,CAAA,CAAA"}
|
|
@@ -7,8 +7,8 @@ import { useFilter } from "./use-filter.js";
|
|
|
7
7
|
import { useSelect } from "./use-select.js";
|
|
8
8
|
import { useTreeNodes } from "./use-tree-nodes.js";
|
|
9
9
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, provide, renderList, shallowRef, unref, useSlots, watch, watchEffect, withCtx } from "vue";
|
|
10
|
-
import { bem, nextFrame, scrollIntoContainerView
|
|
11
|
-
import { useFormComponent, useFormFallbackProps,
|
|
10
|
+
import { bem, nextFrame, scrollIntoContainerView } from "@veltra/utils";
|
|
11
|
+
import { useFormComponent, useFormFallbackProps, useVirtualizer } from "@veltra/compositions";
|
|
12
12
|
//#region src/components/tree/tree.vue
|
|
13
13
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
14
14
|
name: "Tree",
|
|
@@ -87,25 +87,38 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
87
87
|
nodeDict,
|
|
88
88
|
getFlattedNodes
|
|
89
89
|
});
|
|
90
|
-
const
|
|
90
|
+
const estimateSize = () => {
|
|
91
|
+
switch (size.value) {
|
|
92
|
+
case "small": return 32;
|
|
93
|
+
case "large": return 44;
|
|
94
|
+
default: return 36;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const virtualEnabled = computed(() => nodes.value.length > 80);
|
|
98
|
+
const { virtualizer, items } = useVirtualizer({
|
|
91
99
|
count: computed(() => nodes.value.length),
|
|
92
|
-
|
|
100
|
+
scrollEl: () => scrollRef.value?.containerRef ?? null,
|
|
101
|
+
contentEl: () => virtualEnabled.value ? scrollRef.value?.contentRef ?? null : null,
|
|
102
|
+
estimateSize,
|
|
93
103
|
gap: 2,
|
|
94
|
-
|
|
95
|
-
scrollEl: computed(() => scrollRef.value?.containerRef ?? null)
|
|
104
|
+
getItemKey: (i) => nodes.value[i]?.key ?? i
|
|
96
105
|
});
|
|
97
106
|
const virtualNodes = computed(() => {
|
|
98
107
|
const _nodes = nodes.value;
|
|
99
|
-
return
|
|
108
|
+
return items.value.map((item) => {
|
|
100
109
|
const node = _nodes[item.index];
|
|
101
110
|
return {
|
|
102
111
|
node,
|
|
103
|
-
key: node
|
|
112
|
+
key: node?.key ?? item.index,
|
|
104
113
|
offset: item.start,
|
|
105
114
|
index: item.index
|
|
106
115
|
};
|
|
107
116
|
});
|
|
108
117
|
});
|
|
118
|
+
const measureElement = (index, el) => virtualizer.measureElement(index, el);
|
|
119
|
+
function scrollTo(index) {
|
|
120
|
+
virtualizer.scrollToIndex(index, { align: "center" });
|
|
121
|
+
}
|
|
109
122
|
function scrollIntoView() {
|
|
110
123
|
const { selectable, checkable, scrollToView } = props;
|
|
111
124
|
if (!scrollToView || !selectable && !checkable || !nodes.value) return;
|
|
@@ -176,22 +189,20 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
176
189
|
class: normalizeClass(className.value),
|
|
177
190
|
ref_key: "scrollRef",
|
|
178
191
|
ref: scrollRef,
|
|
179
|
-
"content-
|
|
180
|
-
"content-class": [unref(cls).e("wrap"), unref(bem).is("virtual", unref(virtualEnabled))]
|
|
192
|
+
"content-class": [unref(cls).e("wrap"), unref(bem).is("virtual", virtualEnabled.value)]
|
|
181
193
|
}, {
|
|
182
|
-
default: withCtx(() => [
|
|
194
|
+
default: withCtx(() => [virtualEnabled.value ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(virtualNodes.value, ({ node, key, offset, index }) => {
|
|
183
195
|
return openBlock(), createBlock(_sfc_main$3, {
|
|
184
196
|
node,
|
|
185
197
|
key,
|
|
186
198
|
class: normalizeClass(unref(bem).is("selected", node.data === unref(selectedData))),
|
|
187
|
-
|
|
188
|
-
"measure-element":
|
|
199
|
+
index,
|
|
200
|
+
"measure-element": measureElement,
|
|
189
201
|
style: normalizeStyle({ transform: `translateY(${offset}px)` })
|
|
190
202
|
}, null, 8, [
|
|
191
203
|
"node",
|
|
192
204
|
"class",
|
|
193
|
-
"
|
|
194
|
-
"measure-element",
|
|
205
|
+
"index",
|
|
195
206
|
"style"
|
|
196
207
|
]);
|
|
197
208
|
}), 128)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(nodes), (node) => {
|
|
@@ -205,11 +216,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
205
216
|
class: normalizeClass(unref(cls).e("empty"))
|
|
206
217
|
}, [createVNode(unref(_sfc_main$2))], 2)) : createCommentVNode("v-if", true)]),
|
|
207
218
|
_: 1
|
|
208
|
-
}, 8, [
|
|
209
|
-
"class",
|
|
210
|
-
"content-style",
|
|
211
|
-
"content-class"
|
|
212
|
-
]);
|
|
219
|
+
}, 8, ["class", "content-class"]);
|
|
213
220
|
};
|
|
214
221
|
}
|
|
215
222
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.js","names":[],"sources":["../../../src/components/tree/tree.vue"],"sourcesContent":["<template>\n <u-scroll\n :class=\"className\"\n ref=\"scrollRef\"\n :content-
|
|
1
|
+
{"version":3,"file":"tree.js","names":[],"sources":["../../../src/components/tree/tree.vue"],"sourcesContent":["<template>\n <u-scroll\n :class=\"className\"\n ref=\"scrollRef\"\n :content-class=\"[cls.e('wrap'), bem.is('virtual', virtualEnabled)]\"\n >\n <template v-if=\"virtualEnabled\">\n <UTreeNode\n v-for=\"{ node, key, offset, index } of virtualNodes\"\n :node=\"node\"\n :key=\"key\"\n :class=\"bem.is('selected', node.data === selectedData)\"\n :index=\"index\"\n :measure-element=\"measureElement\"\n :style=\"{ transform: `translateY(${offset}px)` }\"\n />\n </template>\n <template v-else>\n <UTreeNode\n v-for=\"node of nodes\"\n :node=\"node\"\n :key=\"node.key\"\n :class=\"bem.is('selected', node.data === selectedData)\"\n />\n </template>\n\n <div :class=\"cls.e('empty')\" v-if=\"!nodes.length\">\n <UEmpty />\n </div>\n </u-scroll>\n</template>\n\n<script lang=\"ts\" setup>\nimport { useFormComponent, useFormFallbackProps, useVirtualizer } from '@veltra/compositions'\nimport { bem, nextFrame, scrollIntoContainerView } from '@veltra/utils'\nimport { computed, provide, shallowRef, useSlots, watch, watchEffect, type VNode } from 'vue'\n\nimport type { TreeProps, TreeEmit, _TreeExposed } from '../../types'\nimport type { ScrollExposed } from '../../types'\nimport { UEmpty } from '../empty'\nimport { UScroll } from '../scroll'\nimport { TreeDIKey, type TreeConText, type TreeSlotsScope } from './di'\nimport UTreeNode from './tree-node.vue'\nimport { useCheck } from './use-check'\nimport { useFilter } from './use-filter'\nimport { useSelect } from './use-select'\nimport { useTreeNodes } from './use-tree-nodes'\n\ndefineOptions({\n name: 'Tree'\n})\n\nconst props = withDefaults(defineProps<TreeProps>(), {\n labelKey: 'label',\n valueKey: 'value',\n childrenKey: 'children',\n expandOnClickNode: false,\n checkStrictly: false,\n data: () => []\n})\n\nconst emit = defineEmits<TreeEmit>()\n\nconst cls = bem('tree')\n\nconst { formProps } = useFormComponent()\n\nconst { size } = useFormFallbackProps([formProps ?? {}, props], {\n size: 'default'\n})\n\nconst scrollRef = shallowRef<ScrollExposed>()\n\nconst className = computed(() => {\n return [\n cls.b,\n cls.m(size.value),\n bem.is('selectable', props.selectable),\n bem.is('checkable', props.checkable)\n ]\n})\n\ndefineSlots<{\n default: (props: TreeSlotsScope) => any\n}>()\n\nconst slots = useSlots()\n\nfunction getTreeSlotsNode(ctx: TreeSlotsScope): VNode[] | string | undefined {\n return (props.slots?.default ?? slots.default)?.(ctx) ?? ctx.node.label\n}\n\nconst { nodes, forest, getFlattedNodes, nodeDict } = useTreeNodes({\n props\n})\n\nwatch(\n [() => props.selectable, () => props.checkable, forest],\n ([s, c]) => {\n // 如果选择或勾选,则不更新节点\n if (s || c) return\n getFlattedNodes()\n },\n { immediate: true }\n)\n\nconst { filter } = useFilter({ forest, getFlattedNodes })\n\nconst { handleSelect, selectedData } = useSelect({\n props,\n emit,\n nodeDict,\n getFlattedNodes\n})\n\nconst { checkedData, toggleCheck } = useCheck({\n props,\n emit,\n nodeDict,\n getFlattedNodes\n})\n\nconst estimateSize = (): number => {\n // 基于 style.scss 中节点稳态高度推算的默认值;\n // 实际高度仍由 `measureElement` 通过 ResizeObserver 回填覆盖。\n switch (size.value) {\n case 'small':\n return 32\n case 'large':\n return 44\n default:\n return 36\n }\n}\n\n// 80 阈值内化为消费者侧语义;低于此值时不启用虚拟化。\nconst virtualEnabled = computed(() => nodes.value.length > 80)\n\nconst { virtualizer, items } = useVirtualizer({\n count: computed(() => nodes.value.length),\n scrollEl: () => scrollRef.value?.containerRef ?? null,\n // 仅在虚拟化启用时把内容容器的 height 撑开到 totalSize;\n // 关闭时传 null,hook 会清除此前写入的内联 height,回到 CSS 默认。\n contentEl: () => (virtualEnabled.value ? (scrollRef.value?.contentRef ?? null) : null),\n estimateSize,\n gap: 2,\n // 以节点稳定 key 作为虚拟项身份,展开 / 收起 / 过滤引起的 nodes 数组变更\n // 保留未移动节点的真实测量值,避免再次滚动首屏抖动。\n getItemKey: (i) => nodes.value[i]?.key ?? i\n})\n\n// 身份稳定性已由底层 `getItemKey` 保证;直接以 `node.key` 作为 Vue 层 key。\n// `item.index` 仅作为 nodes / snapshot 竞态边缘的 fallback。\nconst virtualNodes = computed(() => {\n const _nodes = nodes.value\n return items.value.map((item) => {\n const node = _nodes[item.index]!\n return {\n node,\n key: node?.key ?? item.index,\n offset: item.start,\n index: item.index\n }\n })\n})\n\nconst measureElement: (index: number, el: Element | null) => void = (index, el) =>\n virtualizer.measureElement(index, el)\n\nfunction scrollTo(index: number): void {\n virtualizer.scrollToIndex(index, { align: 'center' })\n}\n\nfunction scrollIntoView() {\n const { selectable, checkable, scrollToView } = props\n if (!scrollToView || (!selectable && !checkable) || !nodes.value) return\n let index = -1\n\n if (selectable) {\n if (!selectedData.value) return\n index = nodes.value.findIndex((node) => node.data === selectedData.value)\n } else if (checkable) {\n if (!checkedData.size) return\n index = nodes.value.findIndex((node) => checkedData.has(node.data))\n }\n\n if (virtualEnabled.value) {\n scrollTo(index)\n } else {\n const { contentRef, containerRef } = scrollRef.value ?? {}\n const el = contentRef?.children[index]\n el && scrollIntoContainerView(el as HTMLElement, containerRef ?? null)\n }\n}\n\nwatchEffect(() => {\n nextFrame(() => {\n scrollIntoView()\n })\n})\n\nprovide(TreeDIKey, {\n cls,\n selectedData,\n checkedData,\n getFlattedNodes,\n getTreeSlotsNode,\n treeEmit: emit as TreeEmit,\n treeProps: props as TreeProps,\n toggleCheck: toggleCheck as TreeConText['toggleCheck'],\n handleSelect: handleSelect as TreeConText['handleSelect']\n})\n\ndefineExpose<_TreeExposed>({\n filter,\n forest,\n nodes,\n checkNode: toggleCheck,\n selectNode: handleSelect,\n checkAll(check: boolean) {\n forest.value.roots.forEach((node) => {\n toggleCheck(node, check)\n })\n },\n getSelected() {\n return selectedData\n },\n getChecked() {\n return Array.from(checkedData)\n },\n scrollTo,\n\n expandAll() {\n forest.value.dfs((node) => {\n node.expanded = true\n })\n getFlattedNodes()\n },\n collapseAll() {\n forest.value.dfs((node) => {\n node.expanded = false\n })\n getFlattedNodes()\n }\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -23,9 +23,9 @@ declare const __VLS_base: _$vue.DefineComponent<TreeProps, _TreeExposed, {}, {},
|
|
|
23
23
|
}>, {
|
|
24
24
|
labelKey: string;
|
|
25
25
|
valueKey: string;
|
|
26
|
-
childrenKey: string;
|
|
27
26
|
data: Record<string, any>[];
|
|
28
27
|
expandOnClickNode: boolean;
|
|
28
|
+
childrenKey: string;
|
|
29
29
|
checkStrictly: boolean;
|
|
30
30
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
31
31
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,15 +1,38 @@
|
|
|
1
1
|
import { nextTick, watch } from "vue";
|
|
2
2
|
import { dfs, o } from "@cat-kit/core";
|
|
3
3
|
//#region src/components/tree/use-check.ts
|
|
4
|
+
/**
|
|
5
|
+
* 展开目标节点的所有祖先。返回是否发生了实际展开。
|
|
6
|
+
*/
|
|
7
|
+
function expandAncestors(node) {
|
|
8
|
+
let changed = false;
|
|
9
|
+
node.bubbleSet((n) => {
|
|
10
|
+
if (n.parent) {
|
|
11
|
+
if (n.parent.expanded) return false;
|
|
12
|
+
n.parent.expanded = true;
|
|
13
|
+
changed = true;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
return changed;
|
|
17
|
+
}
|
|
4
18
|
function useCheck(options) {
|
|
5
19
|
const { emit, props, nodeDict, getFlattedNodes } = options;
|
|
6
20
|
const checkedData = /* @__PURE__ */ new Set();
|
|
21
|
+
/**
|
|
22
|
+
* 上一次回显使用的 value 集合(仅限 props.checked)。
|
|
23
|
+
* 用于在相同 `nodeDict` 下走差集回显,避免每次全量清空再重建。
|
|
24
|
+
*/
|
|
25
|
+
let lastCheckedSet = /* @__PURE__ */ new Set();
|
|
26
|
+
/** 最近一次参与差集比较的 nodeDict 引用;引用变化时视为整棵树重建。 */
|
|
27
|
+
let lastDict = null;
|
|
7
28
|
function checkNode(node) {
|
|
29
|
+
if (node.checked) return;
|
|
8
30
|
node.checked = true;
|
|
9
31
|
if (node.parent) node.parent.childrenCheckCount++;
|
|
10
32
|
checkedData.add(node.data);
|
|
11
33
|
}
|
|
12
34
|
function uncheckNode(node) {
|
|
35
|
+
if (!node.checked) return;
|
|
13
36
|
node.checked = false;
|
|
14
37
|
if (node.parent) node.parent.childrenCheckCount--;
|
|
15
38
|
checkedData.delete(node.data);
|
|
@@ -18,23 +41,35 @@ function useCheck(options) {
|
|
|
18
41
|
* 模型值是否由事件触发
|
|
19
42
|
*/
|
|
20
43
|
let checkedByEvent = false;
|
|
21
|
-
watch([() => props.checked, nodeDict], ([c,
|
|
44
|
+
watch([() => props.checked, nodeDict], ([c, dict]) => {
|
|
22
45
|
if (checkedByEvent || !props.checkable) return;
|
|
23
|
-
if (!
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
46
|
+
if (!dict.size) return;
|
|
47
|
+
const nextSet = new Set(c ?? []);
|
|
48
|
+
const dictChanged = dict !== lastDict;
|
|
49
|
+
if (dictChanged) {
|
|
50
|
+
checkedData.clear();
|
|
51
|
+
lastCheckedSet = /* @__PURE__ */ new Set();
|
|
52
|
+
}
|
|
53
|
+
let mutated = false;
|
|
54
|
+
for (const v of lastCheckedSet) if (!nextSet.has(v)) {
|
|
55
|
+
const node = dict.get(v);
|
|
56
|
+
if (node) {
|
|
57
|
+
uncheckNode(node);
|
|
58
|
+
mutated = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
let ancestorsExpanded = false;
|
|
62
|
+
for (const v of nextSet) if (!lastCheckedSet.has(v) || dictChanged) {
|
|
63
|
+
const node = dict.get(v);
|
|
27
64
|
if (node) {
|
|
28
65
|
checkNode(node);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (node.parent.expanded) return false;
|
|
32
|
-
node.parent.expanded = true;
|
|
33
|
-
}
|
|
34
|
-
});
|
|
66
|
+
mutated = true;
|
|
67
|
+
if (expandAncestors(node)) ancestorsExpanded = true;
|
|
35
68
|
}
|
|
36
|
-
}
|
|
37
|
-
|
|
69
|
+
}
|
|
70
|
+
lastCheckedSet = nextSet;
|
|
71
|
+
lastDict = dict;
|
|
72
|
+
if (mutated || ancestorsExpanded) getFlattedNodes();
|
|
38
73
|
}, { immediate: true });
|
|
39
74
|
function handleCheck(node, ctrlKey) {
|
|
40
75
|
const { checkStrictly } = props;
|
|
@@ -64,7 +99,10 @@ function useCheck(options) {
|
|
|
64
99
|
checkedByEvent = true;
|
|
65
100
|
check ? handleCheck(node, ctrlKey) : handleUncheck(node, ctrlKey);
|
|
66
101
|
const checkedArr = Array.from(checkedData);
|
|
67
|
-
|
|
102
|
+
const valueKey = props.valueKey;
|
|
103
|
+
const nextValues = checkedArr.map((item) => o(item).get(valueKey));
|
|
104
|
+
lastCheckedSet = new Set(nextValues);
|
|
105
|
+
emit("update:checked", nextValues, checkedArr);
|
|
68
106
|
nextTick(() => {
|
|
69
107
|
checkedByEvent = false;
|
|
70
108
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-check.js","names":[],"sources":["../../../src/components/tree/use-check.ts"],"sourcesContent":["import { dfs, o } from '@cat-kit/core'\nimport { nextTick, watch, type ComputedRef } from 'vue'\n\nimport type { TreeEmit, TreeProps } from '../../types'\nimport type { TreeNode } from './tree-node'\n\ninterface Options {\n emit: TreeEmit\n props: TreeProps\n nodeDict: ComputedRef<Map<any, TreeNode>>\n getFlattedNodes: () => void\n}\n\ninterface UseCheckReturned {\n checkedData: Set<Record<string, any>>\n toggleCheck: (node: TreeNode, check: boolean, ctrlKey?: boolean) => void\n}\n\nexport function useCheck(options: Options): UseCheckReturned {\n const { emit, props, nodeDict, getFlattedNodes } = options\n\n const checkedData = new Set<Record<string, any>>()\n\n function checkNode(node: TreeNode) {\n node.checked = true\n if (node.parent) {\n node.parent.childrenCheckCount++\n }\n checkedData.add(node.data)\n }\n\n function uncheckNode(node: TreeNode) {\n node.checked = false\n if (node.parent) {\n node.parent.childrenCheckCount--\n }\n checkedData.delete(node.data)\n }\n\n /**\n * 模型值是否由事件触发\n */\n let checkedByEvent = false\n\n // 回显\n watch(\n [() => props.checked, nodeDict],\n ([c,
|
|
1
|
+
{"version":3,"file":"use-check.js","names":[],"sources":["../../../src/components/tree/use-check.ts"],"sourcesContent":["import { dfs, o } from '@cat-kit/core'\nimport { nextTick, watch, type ComputedRef } from 'vue'\n\nimport type { TreeEmit, TreeProps } from '../../types'\nimport type { TreeNode } from './tree-node'\n\ninterface Options {\n emit: TreeEmit\n props: TreeProps\n nodeDict: ComputedRef<Map<any, TreeNode>>\n getFlattedNodes: () => void\n}\n\ninterface UseCheckReturned {\n checkedData: Set<Record<string, any>>\n toggleCheck: (node: TreeNode, check: boolean, ctrlKey?: boolean) => void\n}\n\n/**\n * 展开目标节点的所有祖先。返回是否发生了实际展开。\n */\nfunction expandAncestors(node: TreeNode): boolean {\n let changed = false\n node.bubbleSet((n) => {\n if (n.parent) {\n if (n.parent.expanded) return false\n n.parent.expanded = true\n changed = true\n }\n })\n return changed\n}\n\nexport function useCheck(options: Options): UseCheckReturned {\n const { emit, props, nodeDict, getFlattedNodes } = options\n\n const checkedData = new Set<Record<string, any>>()\n\n /**\n * 上一次回显使用的 value 集合(仅限 props.checked)。\n * 用于在相同 `nodeDict` 下走差集回显,避免每次全量清空再重建。\n */\n let lastCheckedSet = new Set<unknown>()\n /** 最近一次参与差集比较的 nodeDict 引用;引用变化时视为整棵树重建。 */\n let lastDict: Map<any, TreeNode> | null = null\n\n function checkNode(node: TreeNode): void {\n if (node.checked) return\n node.checked = true\n if (node.parent) {\n node.parent.childrenCheckCount++\n }\n checkedData.add(node.data)\n }\n\n function uncheckNode(node: TreeNode): void {\n if (!node.checked) return\n node.checked = false\n if (node.parent) {\n node.parent.childrenCheckCount--\n }\n checkedData.delete(node.data)\n }\n\n /**\n * 模型值是否由事件触发\n */\n let checkedByEvent = false\n\n // 回显\n watch(\n [() => props.checked, nodeDict],\n ([c, dict]) => {\n // 事件已经触发模型变更了,所以不再进行下面的计算\n if (checkedByEvent || !props.checkable) return\n if (!dict.size) return\n\n const nextSet = new Set<unknown>(c ?? [])\n\n // 森林重建(dict 引用变化)→ 走全量清空重建路径,\n // 因为所有 TreeNode 实例都是新的,上一轮缓存的 lastCheckedSet 失效。\n const dictChanged = dict !== lastDict\n if (dictChanged) {\n checkedData.clear()\n lastCheckedSet = new Set()\n }\n\n let mutated = false\n\n // 取消:上一轮有但本轮没有的 value\n for (const v of lastCheckedSet) {\n if (!nextSet.has(v)) {\n const node = dict.get(v)\n if (node) {\n uncheckNode(node)\n mutated = true\n }\n }\n }\n\n // 新增:本轮有但上一轮没有的 value\n let ancestorsExpanded = false\n for (const v of nextSet) {\n if (!lastCheckedSet.has(v) || dictChanged) {\n const node = dict.get(v)\n if (node) {\n checkNode(node)\n mutated = true\n if (expandAncestors(node)) {\n ancestorsExpanded = true\n }\n }\n }\n }\n\n lastCheckedSet = nextSet\n lastDict = dict\n\n // 只在真实发生变化时才触发扁平化,避免空转。\n if (mutated || ancestorsExpanded) {\n getFlattedNodes()\n }\n },\n { immediate: true }\n )\n\n function handleCheck(node: TreeNode, ctrlKey?: boolean) {\n const { checkStrictly } = props\n\n if (ctrlKey) {\n checkNode(node)\n } else {\n dfs(\n node as unknown as Record<string, unknown>,\n (n) => {\n const tn = n as unknown as TreeNode\n !tn.disabled && checkNode(tn)\n },\n props.childrenKey ?? 'children'\n )\n }\n\n // 非严格选择时还需要更新祖先节点,\n // 一旦子节点全部选中,父节点也要设置为选中状态\n if (!checkStrictly) {\n node.bubbleSet((node) => {\n const { parent } = node\n\n if (parent) {\n const parentChecked = parent.childrenCheckCount === parent.children!.length\n\n parentChecked ? checkNode(parent) : uncheckNode(parent)\n }\n })\n }\n }\n\n function handleUncheck(node: TreeNode, ctrlKey?: boolean) {\n const { checkStrictly } = props\n if (ctrlKey) {\n uncheckNode(node)\n } else {\n dfs(\n node as unknown as Record<string, unknown>,\n (n) => {\n const tn = n as unknown as TreeNode\n !tn.disabled && uncheckNode(tn)\n },\n props.childrenKey ?? 'children'\n )\n }\n\n // 非严格模式下,取消选中时,需要更新父节点\n if (!checkStrictly) {\n node.bubbleSet((node) => {\n const { parent } = node\n if (parent) {\n uncheckNode(parent)\n }\n })\n }\n }\n\n function toggleCheck(node: TreeNode, check: boolean, ctrlKey?: boolean) {\n checkedByEvent = true\n\n check ? handleCheck(node, ctrlKey) : handleUncheck(node, ctrlKey)\n\n const checkedArr = Array.from(checkedData)\n\n const valueKey = props.valueKey!\n const nextValues = checkedArr.map((item) => o(item).get(valueKey) as unknown)\n\n // 与外部 checked 保持差集缓存同步,避免下一次 watch 回调把刚勾选的值又误判为“新增”。\n lastCheckedSet = new Set(nextValues)\n\n emit('update:checked', nextValues as any[], checkedArr)\n\n nextTick(() => {\n checkedByEvent = false\n })\n }\n\n return { checkedData, toggleCheck }\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { TreeNode as TreeNode$1 } from "./tree-node2.js";
|
|
2
|
-
import { computed, shallowRef } from "vue";
|
|
2
|
+
import { computed, shallowRef, triggerRef, watch } from "vue";
|
|
3
3
|
import { Forest } from "@cat-kit/core";
|
|
4
4
|
//#region src/components/tree/use-tree-nodes.ts
|
|
5
5
|
function useTreeNodes(options) {
|
|
6
6
|
const { props } = options;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const forestRef = shallowRef(new Forest({
|
|
8
|
+
data: [],
|
|
9
|
+
childrenKey: props.childrenKey ?? "children"
|
|
10
|
+
}));
|
|
11
|
+
const nodeDictRef = shallowRef(/* @__PURE__ */ new Map());
|
|
12
|
+
const nodes = shallowRef([]);
|
|
13
|
+
function buildForest() {
|
|
9
14
|
const { disabledNode, expandAll = false, valueKey, labelKey } = props;
|
|
10
15
|
const childrenKey = props.childrenKey ?? "children";
|
|
11
|
-
function createNode(data, index, depth,
|
|
16
|
+
function createNode(data, index, depth, parent) {
|
|
12
17
|
const node = new TreeNode$1({
|
|
13
18
|
data,
|
|
14
19
|
index,
|
|
@@ -21,36 +26,58 @@ function useTreeNodes(options) {
|
|
|
21
26
|
return node;
|
|
22
27
|
}
|
|
23
28
|
return new Forest({
|
|
24
|
-
data: props.data,
|
|
29
|
+
data: props.data ?? [],
|
|
25
30
|
childrenKey,
|
|
26
|
-
createNode: disabledNode ? (data, index, depth,
|
|
27
|
-
const node = createNode(data, index, depth,
|
|
31
|
+
createNode: disabledNode ? (data, index, depth, _f, parent) => {
|
|
32
|
+
const node = createNode(data, index, depth, parent);
|
|
28
33
|
if (data) node.disabled = disabledNode(data, node) ?? false;
|
|
29
34
|
return node;
|
|
30
|
-
} : (data, index, depth,
|
|
35
|
+
} : (data, index, depth, _f, parent) => createNode(data, index, depth, parent)
|
|
31
36
|
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const nodeDict = computed(() => {
|
|
39
|
-
const dict = /* @__PURE__ */ new Map();
|
|
40
|
-
forest.value.dfs((node) => {
|
|
41
|
-
dict.set(node.key, node);
|
|
37
|
+
}
|
|
38
|
+
function rebuildForest() {
|
|
39
|
+
const nextForest = buildForest();
|
|
40
|
+
const nextDict = /* @__PURE__ */ new Map();
|
|
41
|
+
nextForest.dfs((node) => {
|
|
42
|
+
nextDict.set(node.key, node);
|
|
42
43
|
});
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
forestRef.value = nextForest;
|
|
45
|
+
nodeDictRef.value = nextDict;
|
|
46
|
+
getFlattedNodes();
|
|
47
|
+
}
|
|
48
|
+
/** 按展开与可见性扁平化:仅一次 DFS。 */
|
|
46
49
|
function getFlattedNodes() {
|
|
47
|
-
|
|
50
|
+
const result = [];
|
|
51
|
+
const roots = forestRef.value.roots;
|
|
52
|
+
const stack = [];
|
|
53
|
+
for (let i = roots.length - 1; i >= 0; i--) stack.push(roots[i]);
|
|
54
|
+
while (stack.length) {
|
|
55
|
+
const node = stack.pop();
|
|
56
|
+
if (!node.visible) continue;
|
|
57
|
+
result.push(node);
|
|
58
|
+
if (node.expanded && node.children && node.children.length) for (let i = node.children.length - 1; i >= 0; i--) stack.push(node.children[i]);
|
|
59
|
+
}
|
|
60
|
+
nodes.value = result;
|
|
61
|
+
}
|
|
62
|
+
function triggerNodes() {
|
|
63
|
+
triggerRef(nodes);
|
|
48
64
|
}
|
|
65
|
+
watch([
|
|
66
|
+
() => props.data,
|
|
67
|
+
() => props.disabledNode,
|
|
68
|
+
() => props.childrenKey,
|
|
69
|
+
() => props.valueKey,
|
|
70
|
+
() => props.labelKey,
|
|
71
|
+
() => props.expandAll
|
|
72
|
+
], () => {
|
|
73
|
+
rebuildForest();
|
|
74
|
+
}, { immediate: true });
|
|
49
75
|
return {
|
|
50
76
|
nodes,
|
|
51
|
-
forest,
|
|
77
|
+
forest: computed(() => forestRef.value),
|
|
52
78
|
getFlattedNodes,
|
|
53
|
-
nodeDict
|
|
79
|
+
nodeDict: computed(() => nodeDictRef.value),
|
|
80
|
+
triggerNodes
|
|
54
81
|
};
|
|
55
82
|
}
|
|
56
83
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tree-nodes.js","names":["TreeNode"],"sources":["../../../src/components/tree/use-tree-nodes.ts"],"sourcesContent":["import { Forest } from '@cat-kit/core'\nimport { computed, shallowRef, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { TreeProps } from '../../types'\nimport { TreeNode } from './tree-node'\n\ninterface Options {\n props: TreeProps\n}\n\ninterface UseTreeNodesReturned {\n nodes: ShallowRef<TreeNode[]>\n forest: ComputedRef<Forest<Record<string, unknown>, any>>\n getFlattedNodes: () => void\n nodeDict: ComputedRef<Map<string | number, TreeNode>>\n}\nexport function useTreeNodes(options: Options): UseTreeNodesReturned {\n const { props } = options\n\n
|
|
1
|
+
{"version":3,"file":"use-tree-nodes.js","names":["TreeNode"],"sources":["../../../src/components/tree/use-tree-nodes.ts"],"sourcesContent":["import { Forest } from '@cat-kit/core'\nimport { computed, shallowRef, triggerRef, watch, type ShallowRef, type ComputedRef } from 'vue'\n\nimport type { TreeProps } from '../../types'\nimport { TreeNode } from './tree-node'\n\ninterface Options {\n props: TreeProps\n}\n\ninterface UseTreeNodesReturned {\n nodes: ShallowRef<TreeNode[]>\n forest: ComputedRef<Forest<Record<string, unknown>, any>>\n getFlattedNodes: () => void\n nodeDict: ComputedRef<Map<string | number, TreeNode>>\n /** 强制刷新 `nodes` 的订阅者(供字段级别变化但列表引用不变时手动触发)。 */\n triggerNodes: () => void\n}\n\nexport function useTreeNodes(options: Options): UseTreeNodesReturned {\n const { props } = options\n\n // forest / nodeDict 保持为 shallowRef 而非 computed:\n // - computed 会因为任一 prop 变化(尤其是内联 disabledNode 函数)而整棵重建,\n // 丢失 expanded/checked/visible 等运行时状态;\n // - 显式 watch 仅在真正影响结构的输入变化时才重建,行为可控、可测量。\n const forestRef = shallowRef<Forest<Record<string, unknown>, any>>(\n new Forest<Record<string, unknown>, any>({\n data: [],\n childrenKey: props.childrenKey ?? 'children'\n })\n )\n\n const nodeDictRef = shallowRef<Map<string | number, TreeNode>>(new Map())\n\n const nodes = shallowRef<TreeNode[]>([])\n\n function buildForest(): Forest<Record<string, unknown>, any> {\n const { disabledNode, expandAll = false, valueKey, labelKey } = props\n const childrenKey = props.childrenKey ?? 'children'\n\n function createNode(\n data: Record<string, any>,\n index: number,\n depth: number,\n parent?: TreeNode\n ): TreeNode {\n const node = new TreeNode({\n data,\n index,\n depth,\n parent,\n valueKey: valueKey!,\n labelKey: labelKey!\n })\n node.expanded = expandAll\n return node\n }\n\n return new Forest<Record<string, unknown>, any>({\n data: (props.data ?? []) as Record<string, unknown>[],\n childrenKey,\n createNode: disabledNode\n ? (data, index, depth, _f, parent) => {\n const node = createNode(data as Record<string, any>, index, depth, parent as TreeNode)\n if (data) {\n node.disabled = disabledNode(data as Record<string, any>, node) ?? false\n }\n return node\n }\n : (data, index, depth, _f, parent) =>\n createNode(data as Record<string, any>, index, depth, parent as TreeNode)\n })\n }\n\n function rebuildForest(): void {\n const nextForest = buildForest()\n const nextDict = new Map<string | number, TreeNode>()\n\n // 构建森林的同时一次 DFS 同步填充字典,\n // 避免旧版 “forest computed → nodeDict computed” 两次完整遍历。\n nextForest.dfs((node) => {\n nextDict.set(node.key, node)\n })\n\n forestRef.value = nextForest\n nodeDictRef.value = nextDict\n\n getFlattedNodes()\n }\n\n /** 按展开与可见性扁平化:仅一次 DFS。 */\n function getFlattedNodes(): void {\n const result: TreeNode[] = []\n const roots = forestRef.value.roots as TreeNode[]\n\n const stack: TreeNode[] = []\n for (let i = roots.length - 1; i >= 0; i--) {\n stack.push(roots[i]!)\n }\n\n while (stack.length) {\n const node = stack.pop()!\n if (!node.visible) continue\n result.push(node)\n if (node.expanded && node.children && node.children.length) {\n for (let i = node.children.length - 1; i >= 0; i--) {\n stack.push(node.children[i]!)\n }\n }\n }\n\n nodes.value = result\n }\n\n function triggerNodes(): void {\n triggerRef(nodes)\n }\n\n watch(\n [\n () => props.data,\n () => props.disabledNode,\n () => props.childrenKey,\n () => props.valueKey,\n () => props.labelKey,\n () => props.expandAll\n ],\n () => {\n rebuildForest()\n },\n { immediate: true }\n )\n\n const forest = computed(() => forestRef.value)\n const nodeDict = computed(() => nodeDictRef.value)\n\n return { nodes, forest, getFlattedNodes, nodeDict, triggerNodes }\n}\n"],"mappings":";;;;AAmBA,SAAgB,aAAa,SAAwC;CACnE,MAAM,EAAE,UAAU;CAMlB,MAAM,YAAY,WAChB,IAAI,OAAqC;EACvC,MAAM,EAAE;EACR,aAAa,MAAM,eAAe;EACnC,CAAC,CACH;CAED,MAAM,cAAc,2BAA2C,IAAI,KAAK,CAAC;CAEzE,MAAM,QAAQ,WAAuB,EAAE,CAAC;CAExC,SAAS,cAAoD;EAC3D,MAAM,EAAE,cAAc,YAAY,OAAO,UAAU,aAAa;EAChE,MAAM,cAAc,MAAM,eAAe;EAEzC,SAAS,WACP,MACA,OACA,OACA,QACU;GACV,MAAM,OAAO,IAAIA,WAAS;IACxB;IACA;IACA;IACA;IACU;IACA;IACX,CAAC;AACF,QAAK,WAAW;AAChB,UAAO;;AAGT,SAAO,IAAI,OAAqC;GAC9C,MAAO,MAAM,QAAQ,EAAE;GACvB;GACA,YAAY,gBACP,MAAM,OAAO,OAAO,IAAI,WAAW;IAClC,MAAM,OAAO,WAAW,MAA6B,OAAO,OAAO,OAAmB;AACtF,QAAI,KACF,MAAK,WAAW,aAAa,MAA6B,KAAK,IAAI;AAErE,WAAO;QAER,MAAM,OAAO,OAAO,IAAI,WACvB,WAAW,MAA6B,OAAO,OAAO,OAAmB;GAChF,CAAC;;CAGJ,SAAS,gBAAsB;EAC7B,MAAM,aAAa,aAAa;EAChC,MAAM,2BAAW,IAAI,KAAgC;AAIrD,aAAW,KAAK,SAAS;AACvB,YAAS,IAAI,KAAK,KAAK,KAAK;IAC5B;AAEF,YAAU,QAAQ;AAClB,cAAY,QAAQ;AAEpB,mBAAiB;;;CAInB,SAAS,kBAAwB;EAC/B,MAAM,SAAqB,EAAE;EAC7B,MAAM,QAAQ,UAAU,MAAM;EAE9B,MAAM,QAAoB,EAAE;AAC5B,OAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,IACrC,OAAM,KAAK,MAAM,GAAI;AAGvB,SAAO,MAAM,QAAQ;GACnB,MAAM,OAAO,MAAM,KAAK;AACxB,OAAI,CAAC,KAAK,QAAS;AACnB,UAAO,KAAK,KAAK;AACjB,OAAI,KAAK,YAAY,KAAK,YAAY,KAAK,SAAS,OAClD,MAAK,IAAI,IAAI,KAAK,SAAS,SAAS,GAAG,KAAK,GAAG,IAC7C,OAAM,KAAK,KAAK,SAAS,GAAI;;AAKnC,QAAM,QAAQ;;CAGhB,SAAS,eAAqB;AAC5B,aAAW,MAAM;;AAGnB,OACE;QACQ,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;EACb,QACK;AACJ,iBAAe;IAEjB,EAAE,WAAW,MAAM,CACpB;AAKD,QAAO;EAAE;EAAO,QAHD,eAAe,UAAU,MAAM;EAGtB;EAAiB,UAFxB,eAAe,YAAY,MAAM;EAEC;EAAc"}
|
|
@@ -25,14 +25,14 @@ declare const __VLS_base: _$vue.DefineComponent<__VLS_PublicProps, {}, {}, {}, {
|
|
|
25
25
|
"onUpdate:text"?: ((text?: string | undefined) => any) | undefined;
|
|
26
26
|
}>, {
|
|
27
27
|
disabled: boolean;
|
|
28
|
-
placeholder: string;
|
|
29
|
-
clearable: boolean;
|
|
30
28
|
readonly: boolean;
|
|
31
29
|
labelKey: string;
|
|
32
30
|
valueKey: string;
|
|
33
|
-
|
|
31
|
+
placeholder: string;
|
|
32
|
+
clearable: boolean;
|
|
34
33
|
minWidth: string;
|
|
35
34
|
expandAll: boolean;
|
|
35
|
+
filterable: boolean;
|
|
36
36
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
37
37
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
38
38
|
declare const _default: typeof __VLS_export;
|
|
@@ -7,8 +7,8 @@ type __VLS_Slots = {} & {
|
|
|
7
7
|
default?: (props: typeof __VLS_7) => any;
|
|
8
8
|
};
|
|
9
9
|
declare const __VLS_base: _$vue.DefineComponent<WatermarkProps, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<WatermarkProps> & Readonly<{}>, {
|
|
10
|
-
fontSize: number;
|
|
11
10
|
route: number;
|
|
11
|
+
fontSize: number;
|
|
12
12
|
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
|
|
13
13
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
14
14
|
declare const _default: typeof __VLS_export;
|