前端初始化
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
import { CheckboxValueType } from "../../../checkbox/src/checkbox.js";
|
||||
import { Tree, TreeKey, TreeNode, TreeNodeData, TreeProps } from "../types.js";
|
||||
import { Ref } from "vue";
|
||||
|
||||
//#region ../../packages/components/tree-v2/src/composables/useCheck.d.ts
|
||||
declare function useCheck(props: TreeProps, tree: Ref<Tree | undefined>): {
|
||||
updateCheckedKeys: (deep?: boolean) => void;
|
||||
toggleCheckbox: (node: TreeNode, isChecked: CheckboxValueType, nodeClick?: boolean, immediateUpdate?: boolean, deep?: boolean) => void;
|
||||
isChecked: (node: TreeNode) => boolean;
|
||||
isIndeterminate: (node: TreeNode) => boolean;
|
||||
getCheckedKeys: (leafOnly?: boolean) => TreeKey[];
|
||||
getCheckedNodes: (leafOnly?: boolean) => TreeNodeData[];
|
||||
getHalfCheckedKeys: () => TreeKey[];
|
||||
getHalfCheckedNodes: () => TreeNodeData[];
|
||||
setChecked: (key: TreeKey, isChecked: boolean, deep?: boolean) => void;
|
||||
setCheckedKeys: (keys: TreeKey[]) => void;
|
||||
};
|
||||
//#endregion
|
||||
export { useCheck };
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
import { NODE_CHECK, NODE_CHECK_CHANGE } from "../virtual-tree.mjs";
|
||||
import { getCurrentInstance, nextTick, ref, watch } from "vue";
|
||||
//#region ../../packages/components/tree-v2/src/composables/useCheck.ts
|
||||
function useCheck(props, tree) {
|
||||
const checkedKeys = ref(/* @__PURE__ */ new Set());
|
||||
const indeterminateKeys = ref(/* @__PURE__ */ new Set());
|
||||
const { emit } = getCurrentInstance();
|
||||
watch([() => tree.value, () => props.defaultCheckedKeys], () => {
|
||||
return nextTick(() => {
|
||||
_setCheckedKeys(props.defaultCheckedKeys);
|
||||
});
|
||||
}, { immediate: true });
|
||||
const updateCheckedKeys = (deep = false) => {
|
||||
if (!tree.value || !props.showCheckbox || props.checkStrictly && !deep) return;
|
||||
const { levelTreeNodeMap, maxLevel } = tree.value;
|
||||
const checkedKeySet = checkedKeys.value;
|
||||
const indeterminateKeySet = /* @__PURE__ */ new Set();
|
||||
for (let level = maxLevel; level >= 1; --level) {
|
||||
const nodes = levelTreeNodeMap.get(level);
|
||||
if (!nodes) continue;
|
||||
nodes.forEach((node) => {
|
||||
const children = node.children;
|
||||
let isEffectivelyChecked = !node.isLeaf || node.disabled || checkedKeySet.has(node.key);
|
||||
if (children) {
|
||||
let allChecked = true;
|
||||
let hasChecked = false;
|
||||
for (const childNode of children) {
|
||||
const key = childNode.key;
|
||||
if (!childNode.isEffectivelyChecked) isEffectivelyChecked = false;
|
||||
if (checkedKeySet.has(key)) hasChecked = true;
|
||||
else if (indeterminateKeySet.has(key)) {
|
||||
allChecked = false;
|
||||
hasChecked = true;
|
||||
break;
|
||||
} else allChecked = false;
|
||||
}
|
||||
if (allChecked) checkedKeySet.add(node.key);
|
||||
else if (hasChecked) {
|
||||
indeterminateKeySet.add(node.key);
|
||||
checkedKeySet.delete(node.key);
|
||||
} else {
|
||||
checkedKeySet.delete(node.key);
|
||||
indeterminateKeySet.delete(node.key);
|
||||
}
|
||||
}
|
||||
node.isEffectivelyChecked = isEffectivelyChecked;
|
||||
});
|
||||
}
|
||||
indeterminateKeys.value = indeterminateKeySet;
|
||||
};
|
||||
const isChecked = (node) => checkedKeys.value.has(node.key);
|
||||
const isIndeterminate = (node) => indeterminateKeys.value.has(node.key);
|
||||
const toggleCheckbox = (node, isChecked, nodeClick = true, immediateUpdate = true, deep = false) => {
|
||||
const checkedKeySet = checkedKeys.value;
|
||||
const children = node.children;
|
||||
if ((!props.checkStrictly || deep) && nodeClick && children?.length) isChecked = children.some((node) => !node.isEffectivelyChecked);
|
||||
const toggle = (node, checked) => {
|
||||
checkedKeySet[checked ? "add" : "delete"](node.key);
|
||||
const children = node.children;
|
||||
if ((!props.checkStrictly || deep) && children) children.forEach((childNode) => {
|
||||
if (!childNode.disabled || childNode.children) toggle(childNode, checked);
|
||||
});
|
||||
};
|
||||
toggle(node, isChecked);
|
||||
if (immediateUpdate) updateCheckedKeys();
|
||||
if (nodeClick) afterNodeCheck(node, isChecked);
|
||||
};
|
||||
const afterNodeCheck = (node, checked) => {
|
||||
const { checkedNodes, checkedKeys } = getChecked();
|
||||
const { halfCheckedNodes, halfCheckedKeys } = getHalfChecked();
|
||||
emit(NODE_CHECK, node.data, {
|
||||
checkedKeys,
|
||||
checkedNodes,
|
||||
halfCheckedKeys,
|
||||
halfCheckedNodes
|
||||
});
|
||||
emit(NODE_CHECK_CHANGE, node.data, checked);
|
||||
};
|
||||
function getCheckedKeys(leafOnly = false) {
|
||||
return getChecked(leafOnly).checkedKeys;
|
||||
}
|
||||
function getCheckedNodes(leafOnly = false) {
|
||||
return getChecked(leafOnly).checkedNodes;
|
||||
}
|
||||
function getHalfCheckedKeys() {
|
||||
return getHalfChecked().halfCheckedKeys;
|
||||
}
|
||||
function getHalfCheckedNodes() {
|
||||
return getHalfChecked().halfCheckedNodes;
|
||||
}
|
||||
function getChecked(leafOnly = false) {
|
||||
const checkedNodes = [];
|
||||
const keys = [];
|
||||
if (tree?.value && props.showCheckbox) {
|
||||
const { treeNodeMap } = tree.value;
|
||||
checkedKeys.value.forEach((key) => {
|
||||
const node = treeNodeMap.get(key);
|
||||
if (node && (!leafOnly || leafOnly && node.isLeaf)) {
|
||||
keys.push(key);
|
||||
checkedNodes.push(node.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
checkedKeys: keys,
|
||||
checkedNodes
|
||||
};
|
||||
}
|
||||
function getHalfChecked() {
|
||||
const halfCheckedNodes = [];
|
||||
const halfCheckedKeys = [];
|
||||
if (tree?.value && props.showCheckbox) {
|
||||
const { treeNodeMap } = tree.value;
|
||||
indeterminateKeys.value.forEach((key) => {
|
||||
const node = treeNodeMap.get(key);
|
||||
if (node) {
|
||||
halfCheckedKeys.push(key);
|
||||
halfCheckedNodes.push(node.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
halfCheckedNodes,
|
||||
halfCheckedKeys
|
||||
};
|
||||
}
|
||||
function setCheckedKeys(keys) {
|
||||
checkedKeys.value.clear();
|
||||
indeterminateKeys.value.clear();
|
||||
nextTick(() => {
|
||||
_setCheckedKeys(keys);
|
||||
});
|
||||
}
|
||||
function setChecked(key, isChecked, deep) {
|
||||
if (tree?.value && props.showCheckbox) {
|
||||
const node = tree.value.treeNodeMap.get(key);
|
||||
if (node) toggleCheckbox(node, isChecked, false, void 0, deep);
|
||||
}
|
||||
}
|
||||
function _setCheckedKeys(keys) {
|
||||
if (tree?.value) {
|
||||
const { treeNodeMap } = tree.value;
|
||||
if (props.showCheckbox && treeNodeMap && keys?.length > 0) {
|
||||
for (const key of keys) {
|
||||
const node = treeNodeMap.get(key);
|
||||
if (node && !isChecked(node)) toggleCheckbox(node, true, false, false);
|
||||
}
|
||||
updateCheckedKeys();
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
updateCheckedKeys,
|
||||
toggleCheckbox,
|
||||
isChecked,
|
||||
isIndeterminate,
|
||||
getCheckedKeys,
|
||||
getCheckedNodes,
|
||||
getHalfCheckedKeys,
|
||||
getHalfCheckedNodes,
|
||||
setChecked,
|
||||
setCheckedKeys
|
||||
};
|
||||
}
|
||||
//#endregion
|
||||
export { useCheck };
|
||||
|
||||
//# sourceMappingURL=useCheck.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
+12
@@ -0,0 +1,12 @@
|
||||
import { Tree, TreeKey, TreeNode, TreeProps } from "../types.js";
|
||||
import { Ref } from "vue";
|
||||
|
||||
//#region ../../packages/components/tree-v2/src/composables/useFilter.d.ts
|
||||
declare function useFilter(props: TreeProps, tree: Ref<Tree | undefined>): {
|
||||
hiddenExpandIconKeySet: Ref<Set<TreeKey> & Omit<Set<TreeKey>, keyof Set<any>>, Set<TreeKey> | (Set<TreeKey> & Omit<Set<TreeKey>, keyof Set<any>>)>;
|
||||
hiddenNodeKeySet: Ref<Set<TreeKey> & Omit<Set<TreeKey>, keyof Set<any>>, Set<TreeKey> | (Set<TreeKey> & Omit<Set<TreeKey>, keyof Set<any>>)>;
|
||||
doFilter: (query: string) => Set<TreeKey> | undefined;
|
||||
isForceHiddenExpandIcon: (node: TreeNode) => boolean;
|
||||
};
|
||||
//#endregion
|
||||
export { useFilter };
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
import { isFunction } from "../../../../utils/types.mjs";
|
||||
import { computed, ref } from "vue";
|
||||
//#region ../../packages/components/tree-v2/src/composables/useFilter.ts
|
||||
function useFilter(props, tree) {
|
||||
const hiddenNodeKeySet = ref(/* @__PURE__ */ new Set([]));
|
||||
const hiddenExpandIconKeySet = ref(/* @__PURE__ */ new Set([]));
|
||||
const filterable = computed(() => {
|
||||
return isFunction(props.filterMethod);
|
||||
});
|
||||
function doFilter(query) {
|
||||
if (!filterable.value) return;
|
||||
const expandKeySet = /* @__PURE__ */ new Set();
|
||||
const hiddenExpandIconKeys = hiddenExpandIconKeySet.value;
|
||||
const hiddenKeys = hiddenNodeKeySet.value;
|
||||
const family = [];
|
||||
const nodes = tree.value?.treeNodes || [];
|
||||
const filter = props.filterMethod;
|
||||
hiddenKeys.clear();
|
||||
function traverse(nodes) {
|
||||
nodes.forEach((node) => {
|
||||
family.push(node);
|
||||
if (filter?.(query, node.data, node)) family.forEach((member) => {
|
||||
expandKeySet.add(member.key);
|
||||
member.expanded = true;
|
||||
});
|
||||
else {
|
||||
node.expanded = false;
|
||||
if (node.isLeaf) hiddenKeys.add(node.key);
|
||||
}
|
||||
const children = node.children;
|
||||
if (children) traverse(children);
|
||||
if (!node.isLeaf) {
|
||||
if (!expandKeySet.has(node.key)) hiddenKeys.add(node.key);
|
||||
else if (children) {
|
||||
let allHidden = true;
|
||||
for (const childNode of children) if (!hiddenKeys.has(childNode.key)) {
|
||||
allHidden = false;
|
||||
break;
|
||||
}
|
||||
if (allHidden) hiddenExpandIconKeys.add(node.key);
|
||||
else hiddenExpandIconKeys.delete(node.key);
|
||||
}
|
||||
}
|
||||
family.pop();
|
||||
});
|
||||
}
|
||||
traverse(nodes);
|
||||
return expandKeySet;
|
||||
}
|
||||
function isForceHiddenExpandIcon(node) {
|
||||
return hiddenExpandIconKeySet.value.has(node.key);
|
||||
}
|
||||
return {
|
||||
hiddenExpandIconKeySet,
|
||||
hiddenNodeKeySet,
|
||||
doFilter,
|
||||
isForceHiddenExpandIcon
|
||||
};
|
||||
}
|
||||
//#endregion
|
||||
export { useFilter };
|
||||
|
||||
//# sourceMappingURL=useFilter.mjs.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"useFilter.mjs","names":[],"sources":["../../../../../../../packages/components/tree-v2/src/composables/useFilter.ts"],"sourcesContent":["import { computed, ref } from 'vue'\nimport { isFunction } from '@element-plus/utils'\n\nimport type { Ref } from 'vue'\nimport type { Tree, TreeKey, TreeNode, TreeProps } from '../types'\n\n// When the data volume is very large using filter will cause lag\n// I haven't found a better way to optimize it for now\n// Maybe this problem should be left to the server side\nexport function useFilter(props: TreeProps, tree: Ref<Tree | undefined>) {\n const hiddenNodeKeySet = ref<Set<TreeKey>>(new Set([]))\n const hiddenExpandIconKeySet = ref<Set<TreeKey>>(new Set([]))\n\n const filterable = computed(() => {\n return isFunction(props.filterMethod)\n })\n\n function doFilter(query: string) {\n if (!filterable.value) {\n return\n }\n const expandKeySet = new Set<TreeKey>()\n const hiddenExpandIconKeys = hiddenExpandIconKeySet.value\n const hiddenKeys = hiddenNodeKeySet.value\n const family: TreeNode[] = []\n const nodes = tree.value?.treeNodes || []\n const filter = props.filterMethod\n hiddenKeys.clear()\n function traverse(nodes: TreeNode[]) {\n nodes.forEach((node) => {\n family.push(node)\n if (filter?.(query, node.data, node)) {\n family.forEach((member) => {\n expandKeySet.add(member.key)\n member.expanded = true\n })\n } else {\n node.expanded = false\n if (node.isLeaf) {\n hiddenKeys.add(node.key)\n }\n }\n const children = node.children\n if (children) {\n traverse(children)\n }\n if (!node.isLeaf) {\n if (!expandKeySet.has(node.key)) {\n hiddenKeys.add(node.key)\n } else if (children) {\n // If all child nodes are hidden, then the expand icon will be hidden\n let allHidden = true\n for (const childNode of children) {\n if (!hiddenKeys.has(childNode.key)) {\n allHidden = false\n break\n }\n }\n if (allHidden) {\n hiddenExpandIconKeys.add(node.key)\n } else {\n hiddenExpandIconKeys.delete(node.key)\n }\n }\n }\n family.pop()\n })\n }\n traverse(nodes)\n return expandKeySet\n }\n\n function isForceHiddenExpandIcon(node: TreeNode): boolean {\n return hiddenExpandIconKeySet.value.has(node.key)\n }\n\n return {\n hiddenExpandIconKeySet,\n hiddenNodeKeySet,\n doFilter,\n isForceHiddenExpandIcon,\n }\n}\n"],"mappings":";;;AASA,SAAgB,UAAU,OAAkB,MAA6B;CACvE,MAAM,mBAAmB,oBAAkB,IAAI,IAAI,EAAE,CAAC,CAAC;CACvD,MAAM,yBAAyB,oBAAkB,IAAI,IAAI,EAAE,CAAC,CAAC;CAE7D,MAAM,aAAa,eAAe;EAChC,OAAO,WAAW,MAAM,aAAa;GACrC;CAEF,SAAS,SAAS,OAAe;EAC/B,IAAI,CAAC,WAAW,OACd;EAEF,MAAM,+BAAe,IAAI,KAAc;EACvC,MAAM,uBAAuB,uBAAuB;EACpD,MAAM,aAAa,iBAAiB;EACpC,MAAM,SAAqB,EAAE;EAC7B,MAAM,QAAQ,KAAK,OAAO,aAAa,EAAE;EACzC,MAAM,SAAS,MAAM;EACrB,WAAW,OAAO;EAClB,SAAS,SAAS,OAAmB;GACnC,MAAM,SAAS,SAAS;IACtB,OAAO,KAAK,KAAK;IACjB,IAAI,SAAS,OAAO,KAAK,MAAM,KAAK,EAClC,OAAO,SAAS,WAAW;KACzB,aAAa,IAAI,OAAO,IAAI;KAC5B,OAAO,WAAW;MAClB;SACG;KACL,KAAK,WAAW;KAChB,IAAI,KAAK,QACP,WAAW,IAAI,KAAK,IAAI;;IAG5B,MAAM,WAAW,KAAK;IACtB,IAAI,UACF,SAAS,SAAS;IAEpB,IAAI,CAAC,KAAK;SACJ,CAAC,aAAa,IAAI,KAAK,IAAI,EAC7B,WAAW,IAAI,KAAK,IAAI;UACnB,IAAI,UAAU;MAEnB,IAAI,YAAY;MAChB,KAAK,MAAM,aAAa,UACtB,IAAI,CAAC,WAAW,IAAI,UAAU,IAAI,EAAE;OAClC,YAAY;OACZ;;MAGJ,IAAI,WACF,qBAAqB,IAAI,KAAK,IAAI;WAElC,qBAAqB,OAAO,KAAK,IAAI;;;IAI3C,OAAO,KAAK;KACZ;;EAEJ,SAAS,MAAM;EACf,OAAO;;CAGT,SAAS,wBAAwB,MAAyB;EACxD,OAAO,uBAAuB,MAAM,IAAI,KAAK,IAAI;;CAGnD,OAAO;EACL;EACA;EACA;EACA;EACD"}
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
import { EpPropFinalized, EpPropMergeType } from "../../../../utils/vue/props/types.js";
|
||||
import { ClassValue } from "../../../../utils/typescript.js";
|
||||
import { Alignment, ItemSize, ScrollDirection } from "../../../virtual-list/src/types.js";
|
||||
import { CheckboxValueType } from "../../../checkbox/src/checkbox.js";
|
||||
import { treeEmits } from "../virtual-tree.js";
|
||||
import { Tree, TreeData, TreeKey, TreeNode, TreeNodeData, TreeProps } from "../types.js";
|
||||
import * as _$vue from "vue";
|
||||
import { SetupContext } from "vue";
|
||||
|
||||
//#region ../../packages/components/tree-v2/src/composables/useTree.d.ts
|
||||
declare function useTree(props: TreeProps, emit: SetupContext<typeof treeEmits>['emit']): {
|
||||
tree: _$vue.ShallowRef<Tree | undefined, Tree | undefined>;
|
||||
flattenTree: _$vue.ComputedRef<TreeNode[]>;
|
||||
isNotEmpty: _$vue.ComputedRef<boolean>;
|
||||
listRef: _$vue.Ref<_$vue.DefineComponent<_$vue.ExtractPropTypes<{
|
||||
readonly className: EpPropFinalized<(new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue) | (((new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue)) | null)[], unknown, unknown, "", boolean>;
|
||||
readonly containerElement: EpPropFinalized<(new (...args: any[]) => string | Element) | (() => string | Element) | (((new (...args: any[]) => string | Element) | (() => string | Element)) | null)[], unknown, unknown, "div", boolean>;
|
||||
readonly data: EpPropFinalized<(new (...args: any[]) => any[]) | (() => any[]) | (((new (...args: any[]) => any[]) | (() => any[])) | null)[], unknown, unknown, () => [], boolean>;
|
||||
readonly direction: EpPropFinalized<StringConstructor, "ltr" | "rtl", never, "ltr", false>;
|
||||
readonly height: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [StringConstructor, NumberConstructor], unknown, unknown>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerElement: EpPropFinalized<readonly [StringConstructor, ObjectConstructor], unknown, unknown, "div", boolean>;
|
||||
readonly innerProps: EpPropFinalized<(new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>) | (((new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>)) | null)[], unknown, unknown, () => {}, boolean>;
|
||||
readonly style: EpPropFinalized<(new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue) | (((new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue)) | null)[], unknown, unknown, undefined, boolean>;
|
||||
readonly useIsScrolling: BooleanConstructor;
|
||||
readonly width: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerWidth: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly perfMode: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
|
||||
readonly scrollbarAlwaysOn: BooleanConstructor;
|
||||
readonly cache: EpPropFinalized<NumberConstructor, never, never, 2, false>;
|
||||
readonly estimatedItemSize: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly layout: EpPropFinalized<StringConstructor, "horizontal" | "vertical", never, "vertical", false>;
|
||||
readonly initScrollOffset: EpPropFinalized<NumberConstructor, never, never, 0, false>;
|
||||
readonly total: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly itemSize: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => number | ItemSize) | (() => number | ItemSize) | (((new (...args: any[]) => number | ItemSize) | (() => number | ItemSize)) | null)[], never, never>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
}>, {
|
||||
ns: {
|
||||
namespace: _$vue.ComputedRef<string>;
|
||||
b: (blockSuffix?: string) => string;
|
||||
e: (element?: string) => string;
|
||||
m: (modifier?: string) => string;
|
||||
be: (blockSuffix?: string, element?: string) => string;
|
||||
em: (element?: string, modifier?: string) => string;
|
||||
bm: (blockSuffix?: string, modifier?: string) => string;
|
||||
bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
|
||||
is: {
|
||||
(name: string, state: boolean | undefined): string;
|
||||
(name: string): string;
|
||||
};
|
||||
cssVar: (object: Record<string, string>) => Record<string, string>;
|
||||
cssVarName: (name: string) => string;
|
||||
cssVarBlock: (object: Record<string, string>) => Record<string, string>;
|
||||
cssVarBlockName: (name: string) => string;
|
||||
};
|
||||
clientSize: _$vue.ComputedRef<string | number | undefined>;
|
||||
estimatedTotalSize: _$vue.ComputedRef<number>;
|
||||
windowStyle: _$vue.ComputedRef<(string | false | _$vue.CSSProperties | _$vue.StyleValue[] | {
|
||||
[x: string]: string;
|
||||
position: string;
|
||||
WebkitOverflowScrolling: string;
|
||||
willChange: string;
|
||||
} | null | undefined)[]>;
|
||||
windowRef: _$vue.Ref<HTMLElement | undefined, HTMLElement | undefined>;
|
||||
innerRef: _$vue.Ref<HTMLElement | undefined, HTMLElement | undefined>;
|
||||
innerStyle: _$vue.ComputedRef<{
|
||||
height: string;
|
||||
pointerEvents: string | undefined;
|
||||
width: string;
|
||||
margin: number;
|
||||
boxSizing: string;
|
||||
}>;
|
||||
itemsToRender: _$vue.ComputedRef<number[]>;
|
||||
scrollbarRef: _$vue.Ref<any, any>;
|
||||
states: _$vue.Ref<{
|
||||
isScrolling: boolean;
|
||||
scrollDir: ScrollDirection;
|
||||
scrollOffset: number;
|
||||
updateRequested: boolean;
|
||||
isScrollbarDragging: boolean;
|
||||
}, {
|
||||
isScrolling: boolean;
|
||||
scrollDir: ScrollDirection;
|
||||
scrollOffset: number;
|
||||
updateRequested: boolean;
|
||||
isScrollbarDragging: boolean;
|
||||
} | {
|
||||
isScrolling: boolean;
|
||||
scrollDir: ScrollDirection;
|
||||
scrollOffset: number;
|
||||
updateRequested: boolean;
|
||||
isScrollbarDragging: boolean;
|
||||
}>;
|
||||
getItemStyle: (idx: number) => _$vue.CSSProperties;
|
||||
onScroll: (e: Event) => void;
|
||||
onScrollbarScroll: (distanceToGo: number, totalSteps: number) => void;
|
||||
onWheel: (e: WheelEvent) => void;
|
||||
scrollTo: (offset: number) => void;
|
||||
scrollToItem: (idx: number, alignment?: Alignment) => void;
|
||||
resetScrollTop: () => void;
|
||||
}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, ("scroll" | "end-reached" | "itemRendered")[], "scroll" | "end-reached" | "itemRendered", _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
|
||||
readonly className: EpPropFinalized<(new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue) | (((new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue)) | null)[], unknown, unknown, "", boolean>;
|
||||
readonly containerElement: EpPropFinalized<(new (...args: any[]) => string | Element) | (() => string | Element) | (((new (...args: any[]) => string | Element) | (() => string | Element)) | null)[], unknown, unknown, "div", boolean>;
|
||||
readonly data: EpPropFinalized<(new (...args: any[]) => any[]) | (() => any[]) | (((new (...args: any[]) => any[]) | (() => any[])) | null)[], unknown, unknown, () => [], boolean>;
|
||||
readonly direction: EpPropFinalized<StringConstructor, "ltr" | "rtl", never, "ltr", false>;
|
||||
readonly height: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [StringConstructor, NumberConstructor], unknown, unknown>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerElement: EpPropFinalized<readonly [StringConstructor, ObjectConstructor], unknown, unknown, "div", boolean>;
|
||||
readonly innerProps: EpPropFinalized<(new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>) | (((new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>)) | null)[], unknown, unknown, () => {}, boolean>;
|
||||
readonly style: EpPropFinalized<(new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue) | (((new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue)) | null)[], unknown, unknown, undefined, boolean>;
|
||||
readonly useIsScrolling: BooleanConstructor;
|
||||
readonly width: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerWidth: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly perfMode: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
|
||||
readonly scrollbarAlwaysOn: BooleanConstructor;
|
||||
readonly cache: EpPropFinalized<NumberConstructor, never, never, 2, false>;
|
||||
readonly estimatedItemSize: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly layout: EpPropFinalized<StringConstructor, "horizontal" | "vertical", never, "vertical", false>;
|
||||
readonly initScrollOffset: EpPropFinalized<NumberConstructor, never, never, 0, false>;
|
||||
readonly total: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly itemSize: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => number | ItemSize) | (() => number | ItemSize) | (((new (...args: any[]) => number | ItemSize) | (() => number | ItemSize)) | null)[], never, never>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
}>> & Readonly<{
|
||||
onScroll?: ((...args: any[]) => any) | undefined;
|
||||
"onEnd-reached"?: ((...args: any[]) => any) | undefined;
|
||||
onItemRendered?: ((...args: any[]) => any) | undefined;
|
||||
}>, {
|
||||
readonly style: _$vue.StyleValue;
|
||||
readonly className: ClassValue;
|
||||
readonly data: any[];
|
||||
readonly direction: EpPropMergeType<StringConstructor, "ltr" | "rtl", never>;
|
||||
readonly layout: EpPropMergeType<StringConstructor, "horizontal" | "vertical", never>;
|
||||
readonly scrollbarAlwaysOn: boolean;
|
||||
readonly containerElement: EpPropMergeType<(new (...args: any[]) => string | Element) | (() => string | Element) | (((new (...args: any[]) => string | Element) | (() => string | Element)) | null)[], unknown, unknown>;
|
||||
readonly innerElement: EpPropMergeType<readonly [StringConstructor, ObjectConstructor], unknown, unknown>;
|
||||
readonly innerProps: Record<string, unknown>;
|
||||
readonly perfMode: EpPropMergeType<BooleanConstructor, unknown, unknown>;
|
||||
readonly useIsScrolling: boolean;
|
||||
readonly cache: number;
|
||||
readonly initScrollOffset: number;
|
||||
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any> | undefined, _$vue.DefineComponent<_$vue.ExtractPropTypes<{
|
||||
readonly className: EpPropFinalized<(new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue) | (((new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue)) | null)[], unknown, unknown, "", boolean>;
|
||||
readonly containerElement: EpPropFinalized<(new (...args: any[]) => string | Element) | (() => string | Element) | (((new (...args: any[]) => string | Element) | (() => string | Element)) | null)[], unknown, unknown, "div", boolean>;
|
||||
readonly data: EpPropFinalized<(new (...args: any[]) => any[]) | (() => any[]) | (((new (...args: any[]) => any[]) | (() => any[])) | null)[], unknown, unknown, () => [], boolean>;
|
||||
readonly direction: EpPropFinalized<StringConstructor, "ltr" | "rtl", never, "ltr", false>;
|
||||
readonly height: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [StringConstructor, NumberConstructor], unknown, unknown>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerElement: EpPropFinalized<readonly [StringConstructor, ObjectConstructor], unknown, unknown, "div", boolean>;
|
||||
readonly innerProps: EpPropFinalized<(new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>) | (((new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>)) | null)[], unknown, unknown, () => {}, boolean>;
|
||||
readonly style: EpPropFinalized<(new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue) | (((new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue)) | null)[], unknown, unknown, undefined, boolean>;
|
||||
readonly useIsScrolling: BooleanConstructor;
|
||||
readonly width: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerWidth: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly perfMode: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
|
||||
readonly scrollbarAlwaysOn: BooleanConstructor;
|
||||
readonly cache: EpPropFinalized<NumberConstructor, never, never, 2, false>;
|
||||
readonly estimatedItemSize: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly layout: EpPropFinalized<StringConstructor, "horizontal" | "vertical", never, "vertical", false>;
|
||||
readonly initScrollOffset: EpPropFinalized<NumberConstructor, never, never, 0, false>;
|
||||
readonly total: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly itemSize: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => number | ItemSize) | (() => number | ItemSize) | (((new (...args: any[]) => number | ItemSize) | (() => number | ItemSize)) | null)[], never, never>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
}>, {
|
||||
ns: {
|
||||
namespace: _$vue.ComputedRef<string>;
|
||||
b: (blockSuffix?: string) => string;
|
||||
e: (element?: string) => string;
|
||||
m: (modifier?: string) => string;
|
||||
be: (blockSuffix?: string, element?: string) => string;
|
||||
em: (element?: string, modifier?: string) => string;
|
||||
bm: (blockSuffix?: string, modifier?: string) => string;
|
||||
bem: (blockSuffix?: string, element?: string, modifier?: string) => string;
|
||||
is: {
|
||||
(name: string, state: boolean | undefined): string;
|
||||
(name: string): string;
|
||||
};
|
||||
cssVar: (object: Record<string, string>) => Record<string, string>;
|
||||
cssVarName: (name: string) => string;
|
||||
cssVarBlock: (object: Record<string, string>) => Record<string, string>;
|
||||
cssVarBlockName: (name: string) => string;
|
||||
};
|
||||
clientSize: _$vue.ComputedRef<string | number | undefined>;
|
||||
estimatedTotalSize: _$vue.ComputedRef<number>;
|
||||
windowStyle: _$vue.ComputedRef<(string | false | _$vue.CSSProperties | _$vue.StyleValue[] | {
|
||||
[x: string]: string;
|
||||
position: string;
|
||||
WebkitOverflowScrolling: string;
|
||||
willChange: string;
|
||||
} | null | undefined)[]>;
|
||||
windowRef: _$vue.Ref<HTMLElement | undefined, HTMLElement | undefined>;
|
||||
innerRef: _$vue.Ref<HTMLElement | undefined, HTMLElement | undefined>;
|
||||
innerStyle: _$vue.ComputedRef<{
|
||||
height: string;
|
||||
pointerEvents: string | undefined;
|
||||
width: string;
|
||||
margin: number;
|
||||
boxSizing: string;
|
||||
}>;
|
||||
itemsToRender: _$vue.ComputedRef<number[]>;
|
||||
scrollbarRef: _$vue.Ref<any, any>;
|
||||
states: _$vue.Ref<{
|
||||
isScrolling: boolean;
|
||||
scrollDir: ScrollDirection;
|
||||
scrollOffset: number;
|
||||
updateRequested: boolean;
|
||||
isScrollbarDragging: boolean;
|
||||
}, {
|
||||
isScrolling: boolean;
|
||||
scrollDir: ScrollDirection;
|
||||
scrollOffset: number;
|
||||
updateRequested: boolean;
|
||||
isScrollbarDragging: boolean;
|
||||
} | {
|
||||
isScrolling: boolean;
|
||||
scrollDir: ScrollDirection;
|
||||
scrollOffset: number;
|
||||
updateRequested: boolean;
|
||||
isScrollbarDragging: boolean;
|
||||
}>;
|
||||
getItemStyle: (idx: number) => _$vue.CSSProperties;
|
||||
onScroll: (e: Event) => void;
|
||||
onScrollbarScroll: (distanceToGo: number, totalSteps: number) => void;
|
||||
onWheel: (e: WheelEvent) => void;
|
||||
scrollTo: (offset: number) => void;
|
||||
scrollToItem: (idx: number, alignment?: Alignment) => void;
|
||||
resetScrollTop: () => void;
|
||||
}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, ("scroll" | "end-reached" | "itemRendered")[], "scroll" | "end-reached" | "itemRendered", _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
|
||||
readonly className: EpPropFinalized<(new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue) | (((new (...args: any[]) => string | false | Record<string, any> | ClassValue[]) | (() => ClassValue)) | null)[], unknown, unknown, "", boolean>;
|
||||
readonly containerElement: EpPropFinalized<(new (...args: any[]) => string | Element) | (() => string | Element) | (((new (...args: any[]) => string | Element) | (() => string | Element)) | null)[], unknown, unknown, "div", boolean>;
|
||||
readonly data: EpPropFinalized<(new (...args: any[]) => any[]) | (() => any[]) | (((new (...args: any[]) => any[]) | (() => any[])) | null)[], unknown, unknown, () => [], boolean>;
|
||||
readonly direction: EpPropFinalized<StringConstructor, "ltr" | "rtl", never, "ltr", false>;
|
||||
readonly height: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [StringConstructor, NumberConstructor], unknown, unknown>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerElement: EpPropFinalized<readonly [StringConstructor, ObjectConstructor], unknown, unknown, "div", boolean>;
|
||||
readonly innerProps: EpPropFinalized<(new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>) | (((new (...args: any[]) => Record<string, unknown>) | (() => Record<string, unknown>)) | null)[], unknown, unknown, () => {}, boolean>;
|
||||
readonly style: EpPropFinalized<(new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue) | (((new (...args: any[]) => string | false | _$vue.CSSProperties | _$vue.StyleValue[]) | (() => _$vue.StyleValue)) | null)[], unknown, unknown, undefined, boolean>;
|
||||
readonly useIsScrolling: BooleanConstructor;
|
||||
readonly width: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly innerWidth: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<readonly [NumberConstructor, StringConstructor], unknown, unknown>>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly perfMode: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
|
||||
readonly scrollbarAlwaysOn: BooleanConstructor;
|
||||
readonly cache: EpPropFinalized<NumberConstructor, never, never, 2, false>;
|
||||
readonly estimatedItemSize: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: false;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly layout: EpPropFinalized<StringConstructor, "horizontal" | "vertical", never, "vertical", false>;
|
||||
readonly initScrollOffset: EpPropFinalized<NumberConstructor, never, never, 0, false>;
|
||||
readonly total: {
|
||||
readonly type: _$vue.PropType<number>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
readonly itemSize: {
|
||||
readonly type: _$vue.PropType<EpPropMergeType<(new (...args: any[]) => number | ItemSize) | (() => number | ItemSize) | (((new (...args: any[]) => number | ItemSize) | (() => number | ItemSize)) | null)[], never, never>>;
|
||||
readonly required: true;
|
||||
readonly validator: ((val: unknown) => boolean) | undefined;
|
||||
__epPropKey: true;
|
||||
};
|
||||
}>> & Readonly<{
|
||||
onScroll?: ((...args: any[]) => any) | undefined;
|
||||
"onEnd-reached"?: ((...args: any[]) => any) | undefined;
|
||||
onItemRendered?: ((...args: any[]) => any) | undefined;
|
||||
}>, {
|
||||
readonly style: _$vue.StyleValue;
|
||||
readonly className: ClassValue;
|
||||
readonly data: any[];
|
||||
readonly direction: EpPropMergeType<StringConstructor, "ltr" | "rtl", never>;
|
||||
readonly layout: EpPropMergeType<StringConstructor, "horizontal" | "vertical", never>;
|
||||
readonly scrollbarAlwaysOn: boolean;
|
||||
readonly containerElement: EpPropMergeType<(new (...args: any[]) => string | Element) | (() => string | Element) | (((new (...args: any[]) => string | Element) | (() => string | Element)) | null)[], unknown, unknown>;
|
||||
readonly innerElement: EpPropMergeType<readonly [StringConstructor, ObjectConstructor], unknown, unknown>;
|
||||
readonly innerProps: Record<string, unknown>;
|
||||
readonly perfMode: EpPropMergeType<BooleanConstructor, unknown, unknown>;
|
||||
readonly useIsScrolling: boolean;
|
||||
readonly cache: number;
|
||||
readonly initScrollOffset: number;
|
||||
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any> | undefined>;
|
||||
getKey: (node: TreeNodeData) => TreeKey;
|
||||
getChildren: (node: TreeNodeData) => TreeNodeData[];
|
||||
toggleExpand: (node: TreeNode) => void;
|
||||
toggleCheckbox: (node: TreeNode, isChecked: CheckboxValueType, nodeClick?: boolean, immediateUpdate?: boolean, deep?: boolean) => void;
|
||||
isChecked: (node: TreeNode) => boolean;
|
||||
isIndeterminate: (node: TreeNode) => boolean;
|
||||
isDisabled: (node: TreeNode) => boolean;
|
||||
isCurrent: (node: TreeNode) => boolean;
|
||||
isForceHiddenExpandIcon: (node: TreeNode) => boolean;
|
||||
handleNodeClick: (node: TreeNode, e: MouseEvent) => void;
|
||||
handleNodeDrop: (node: TreeNode, e: DragEvent) => void;
|
||||
handleNodeCheck: (node: TreeNode, checked: CheckboxValueType) => void;
|
||||
getCurrentNode: () => TreeNodeData | undefined;
|
||||
getCurrentKey: () => TreeKey | undefined;
|
||||
setCurrentKey: (key: TreeKey) => void;
|
||||
getCheckedKeys: (leafOnly?: boolean) => TreeKey[];
|
||||
getCheckedNodes: (leafOnly?: boolean) => TreeNodeData[];
|
||||
getHalfCheckedKeys: () => TreeKey[];
|
||||
getHalfCheckedNodes: () => TreeNodeData[];
|
||||
setChecked: (key: TreeKey, isChecked: boolean, deep?: boolean) => void;
|
||||
setCheckedKeys: (keys: TreeKey[]) => void;
|
||||
filter: (query: string) => void;
|
||||
setData: (data: TreeData) => void;
|
||||
getNode: (data: TreeKey | TreeNodeData) => TreeNode | undefined;
|
||||
expandNode: (node: TreeNode) => void;
|
||||
collapseNode: (node: TreeNode) => void;
|
||||
setExpandedKeys: (keys: TreeKey[]) => void;
|
||||
scrollToNode: (key: TreeKey, strategy?: Alignment) => void;
|
||||
scrollTo: (offset: number) => void;
|
||||
};
|
||||
//#endregion
|
||||
export { useTree };
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
import { isObject } from "../../../../utils/types.mjs";
|
||||
import { CURRENT_CHANGE, NODE_CLICK, NODE_COLLAPSE, NODE_DROP, NODE_EXPAND } from "../virtual-tree.mjs";
|
||||
import { useCheck } from "./useCheck.mjs";
|
||||
import { useFilter } from "./useFilter.mjs";
|
||||
import { computed, ref, shallowRef, watch } from "vue";
|
||||
//#region ../../packages/components/tree-v2/src/composables/useTree.ts
|
||||
function useTree(props, emit) {
|
||||
const expandedKeySet = ref(/* @__PURE__ */ new Set());
|
||||
const currentKey = ref();
|
||||
const tree = shallowRef();
|
||||
const listRef = ref();
|
||||
const { isIndeterminate, isChecked, toggleCheckbox, getCheckedKeys, getCheckedNodes, getHalfCheckedKeys, getHalfCheckedNodes, setChecked, setCheckedKeys } = useCheck(props, tree);
|
||||
const { doFilter, hiddenNodeKeySet, isForceHiddenExpandIcon } = useFilter(props, tree);
|
||||
const valueKey = computed(() => {
|
||||
return props.props?.value || "id";
|
||||
});
|
||||
const childrenKey = computed(() => {
|
||||
return props.props?.children || "children";
|
||||
});
|
||||
const disabledKey = computed(() => {
|
||||
return props.props?.disabled || "disabled";
|
||||
});
|
||||
const labelKey = computed(() => {
|
||||
return props.props?.label || "label";
|
||||
});
|
||||
const flattenTree = computed(() => {
|
||||
const expandedKeys = expandedKeySet.value;
|
||||
const hiddenKeys = hiddenNodeKeySet.value;
|
||||
const flattenNodes = [];
|
||||
const nodes = tree.value?.treeNodes || [];
|
||||
const stack = [];
|
||||
for (let i = nodes.length - 1; i >= 0; --i) stack.push(nodes[i]);
|
||||
while (stack.length) {
|
||||
const node = stack.pop();
|
||||
if (hiddenKeys.has(node.key)) continue;
|
||||
flattenNodes.push(node);
|
||||
if (node.children && expandedKeys.has(node.key)) for (let i = node.children.length - 1; i >= 0; --i) stack.push(node.children[i]);
|
||||
}
|
||||
return flattenNodes;
|
||||
});
|
||||
const isNotEmpty = computed(() => {
|
||||
return flattenTree.value.length > 0;
|
||||
});
|
||||
function createTree(data) {
|
||||
const treeNodeMap = /* @__PURE__ */ new Map();
|
||||
const levelTreeNodeMap = /* @__PURE__ */ new Map();
|
||||
let maxLevel = 1;
|
||||
function traverse(nodes, level = 1, parent = void 0) {
|
||||
const siblings = [];
|
||||
for (const rawNode of nodes) {
|
||||
const value = getKey(rawNode);
|
||||
const node = {
|
||||
level,
|
||||
key: value,
|
||||
data: rawNode
|
||||
};
|
||||
node.label = getLabel(rawNode);
|
||||
node.parent = parent;
|
||||
const children = getChildren(rawNode);
|
||||
node.disabled = getDisabled(rawNode);
|
||||
node.isLeaf = !children || children.length === 0;
|
||||
node.expanded = expandedKeySet.value.has(value);
|
||||
if (children && children.length) node.children = traverse(children, level + 1, node);
|
||||
siblings.push(node);
|
||||
treeNodeMap.set(value, node);
|
||||
if (!levelTreeNodeMap.has(level)) levelTreeNodeMap.set(level, []);
|
||||
levelTreeNodeMap.get(level)?.push(node);
|
||||
}
|
||||
if (level > maxLevel) maxLevel = level;
|
||||
return siblings;
|
||||
}
|
||||
const treeNodes = traverse(data);
|
||||
return {
|
||||
treeNodeMap,
|
||||
levelTreeNodeMap,
|
||||
maxLevel,
|
||||
treeNodes
|
||||
};
|
||||
}
|
||||
function filter(query) {
|
||||
const keys = doFilter(query);
|
||||
if (keys) expandedKeySet.value = keys;
|
||||
}
|
||||
function getChildren(node) {
|
||||
return node[childrenKey.value];
|
||||
}
|
||||
function getKey(node) {
|
||||
if (!node) return "";
|
||||
return node[valueKey.value];
|
||||
}
|
||||
function getDisabled(node) {
|
||||
return node[disabledKey.value];
|
||||
}
|
||||
function getLabel(node) {
|
||||
return node[labelKey.value];
|
||||
}
|
||||
function toggleExpand(node) {
|
||||
if (expandedKeySet.value.has(node.key)) collapseNode(node);
|
||||
else expandNode(node);
|
||||
}
|
||||
function setExpandedKeys(keys) {
|
||||
const expandedKeys = /* @__PURE__ */ new Set();
|
||||
const nodeMap = tree.value.treeNodeMap;
|
||||
expandedKeySet.value.forEach((key) => {
|
||||
const node = nodeMap.get(key);
|
||||
if (node) node.expanded = false;
|
||||
});
|
||||
keys.forEach((k) => {
|
||||
let node = nodeMap.get(k);
|
||||
while (node && !expandedKeys.has(node.key)) {
|
||||
expandedKeys.add(node.key);
|
||||
node.expanded = true;
|
||||
node = node.parent;
|
||||
}
|
||||
});
|
||||
expandedKeySet.value = expandedKeys;
|
||||
}
|
||||
function handleNodeClick(node, e) {
|
||||
handleCurrentChange(node);
|
||||
emit(NODE_CLICK, node.data, node, e);
|
||||
if (props.expandOnClickNode) toggleExpand(node);
|
||||
if (props.showCheckbox && (props.checkOnClickNode || node.isLeaf && props.checkOnClickLeaf) && !node.disabled) toggleCheckbox(node, !isChecked(node), true);
|
||||
}
|
||||
function handleNodeDrop(node, e) {
|
||||
emit(NODE_DROP, node.data, node, e);
|
||||
}
|
||||
function handleCurrentChange(node) {
|
||||
if (!isCurrent(node)) {
|
||||
currentKey.value = node.key;
|
||||
emit(CURRENT_CHANGE, node.data, node);
|
||||
}
|
||||
}
|
||||
function handleNodeCheck(node, checked) {
|
||||
toggleCheckbox(node, checked);
|
||||
}
|
||||
function expandNode(node) {
|
||||
const keySet = expandedKeySet.value;
|
||||
if (tree.value && props.accordion) {
|
||||
const { treeNodeMap } = tree.value;
|
||||
keySet.forEach((key) => {
|
||||
const treeNode = treeNodeMap.get(key);
|
||||
if (node && node.level === treeNode?.level) {
|
||||
keySet.delete(key);
|
||||
treeNode.expanded = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
keySet.add(node.key);
|
||||
const _node = getNode(node.key);
|
||||
if (_node) {
|
||||
_node.expanded = true;
|
||||
emit(NODE_EXPAND, _node.data, _node);
|
||||
}
|
||||
}
|
||||
function collapseNode(node) {
|
||||
expandedKeySet.value.delete(node.key);
|
||||
const _node = getNode(node.key);
|
||||
if (_node) {
|
||||
_node.expanded = false;
|
||||
emit(NODE_COLLAPSE, _node.data, _node);
|
||||
}
|
||||
}
|
||||
function isDisabled(node) {
|
||||
return !!node.disabled;
|
||||
}
|
||||
function isCurrent(node) {
|
||||
const current = currentKey.value;
|
||||
return current !== void 0 && current === node.key;
|
||||
}
|
||||
function getCurrentNode() {
|
||||
if (currentKey.value === void 0) return void 0;
|
||||
return tree.value?.treeNodeMap.get(currentKey.value)?.data;
|
||||
}
|
||||
function getCurrentKey() {
|
||||
return currentKey.value;
|
||||
}
|
||||
function setCurrentKey(key) {
|
||||
currentKey.value = key;
|
||||
}
|
||||
function setData(data) {
|
||||
tree.value = createTree(data);
|
||||
}
|
||||
function getNode(data) {
|
||||
const key = isObject(data) ? getKey(data) : data;
|
||||
return tree.value?.treeNodeMap.get(key);
|
||||
}
|
||||
function scrollToNode(key, strategy = "auto") {
|
||||
const node = getNode(key);
|
||||
if (node && listRef.value) listRef.value.scrollToItem(flattenTree.value.indexOf(node), strategy);
|
||||
}
|
||||
function scrollTo(offset) {
|
||||
listRef.value?.scrollTo(offset);
|
||||
}
|
||||
watch(() => props.currentNodeKey, (key) => {
|
||||
currentKey.value = key;
|
||||
}, { immediate: true });
|
||||
watch(() => props.defaultExpandedKeys, (keys) => {
|
||||
setExpandedKeys(keys || []);
|
||||
});
|
||||
watch(() => props.data, (data) => {
|
||||
setData(data);
|
||||
setExpandedKeys(props.defaultExpandedKeys || []);
|
||||
}, { immediate: true });
|
||||
return {
|
||||
tree,
|
||||
flattenTree,
|
||||
isNotEmpty,
|
||||
listRef,
|
||||
getKey,
|
||||
getChildren,
|
||||
toggleExpand,
|
||||
toggleCheckbox,
|
||||
isChecked,
|
||||
isIndeterminate,
|
||||
isDisabled,
|
||||
isCurrent,
|
||||
isForceHiddenExpandIcon,
|
||||
handleNodeClick,
|
||||
handleNodeDrop,
|
||||
handleNodeCheck,
|
||||
getCurrentNode,
|
||||
getCurrentKey,
|
||||
setCurrentKey,
|
||||
getCheckedKeys,
|
||||
getCheckedNodes,
|
||||
getHalfCheckedKeys,
|
||||
getHalfCheckedNodes,
|
||||
setChecked,
|
||||
setCheckedKeys,
|
||||
filter,
|
||||
setData,
|
||||
getNode,
|
||||
expandNode,
|
||||
collapseNode,
|
||||
setExpandedKeys,
|
||||
scrollToNode,
|
||||
scrollTo
|
||||
};
|
||||
}
|
||||
//#endregion
|
||||
export { useTree };
|
||||
|
||||
//# sourceMappingURL=useTree.mjs.map
|
||||
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user