@keenmate/svelte-treeview 3.1.0 → 3.1.2
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/Branch.svelte +1 -1
- package/dist/TreeView.svelte +47 -21
- package/dist/tree-styles.scss +8 -12
- package/package.json +1 -1
package/dist/Branch.svelte
CHANGED
|
@@ -116,9 +116,9 @@ function onContextMenu(ev, node) {
|
|
|
116
116
|
{#if node.hasChildren}
|
|
117
117
|
<button
|
|
118
118
|
class="expansion-button arrow"
|
|
119
|
-
onclick={() => setExpansion(node, !expanded)}
|
|
120
119
|
type="button"
|
|
121
120
|
tabindex="-1"
|
|
121
|
+
onclick={() => setExpansion(node, !expanded)}
|
|
122
122
|
>
|
|
123
123
|
<i class="fixed-icon arrow {expanded ? classes.collapseIcon : classes.expandIcon}"></i>
|
|
124
124
|
</button>
|
package/dist/TreeView.svelte
CHANGED
|
@@ -7,6 +7,7 @@ import { SelectionProvider } from "./providers/selection-provider.js";
|
|
|
7
7
|
import { DragDropProvider } from "./providers/drag-drop-provider.js";
|
|
8
8
|
import uniq from "lodash.uniq";
|
|
9
9
|
import { calculateNewFocusedNode, parseMovementDirection } from "./providers/movement-provider.js";
|
|
10
|
+
import { untrack } from "svelte";
|
|
10
11
|
let { treeId, tree, value = [], treeProps = {}, verticalLines = false, readonly = false, separator = ".", recursiveSelection = false, selectionMode = SelectionModes.none, onlyLeafCheckboxes = false, hideDisabledCheckboxes = false, loadChildrenAsync = null, showContextMenu = false, expandTo = 0, expansionThreshold = 0, customClasses = {}, filter = null, logger = null, nodeSorter = null, dragAndDrop = false, dropDisabledCallback = null, allowKeyboardNavigation = false, onFocus = undefined, onFocusLeave = undefined, onExpansion = undefined, onExpanded = undefined, onClosed = undefined, onChange = undefined, onSelection = undefined, onSelected = undefined, onUnselected = undefined, onMoved = undefined, children, nestHighlight, contextMenu } = $props();
|
|
11
12
|
export function changeAllExpansion(changeTo) {
|
|
12
13
|
debugLog("changing expansion of every node to ", changeTo ? "expanded" : "collapsed");
|
|
@@ -83,33 +84,63 @@ let helper = $derived(new TreeHelper({
|
|
|
83
84
|
}));
|
|
84
85
|
let dragAndDropProvider = $derived(new DragDropProvider(helper));
|
|
85
86
|
let selectionProvider = $derived(new SelectionProvider(helper, recursiveSelection));
|
|
86
|
-
let computedTree = $derived(
|
|
87
|
+
let computedTree = $derived((helper,
|
|
88
|
+
selectionProvider,
|
|
89
|
+
tree,
|
|
90
|
+
filter,
|
|
91
|
+
treeProps,
|
|
92
|
+
expandedPaths,
|
|
93
|
+
value, computeTree()));
|
|
87
94
|
$effect(() => {
|
|
88
95
|
dragAndDrop && console.warn("Drag and drop is not supported in this version");
|
|
89
96
|
});
|
|
90
|
-
function computeTree(
|
|
91
|
-
|
|
97
|
+
function computeTree(
|
|
98
|
+
// helper: TreeHelper,
|
|
99
|
+
// selectionProvider: SelectionProvider,
|
|
100
|
+
// userProvidedTree: any[],
|
|
101
|
+
// filter: FilterFunction | null,
|
|
102
|
+
// props: Partial<TreeProps>,
|
|
103
|
+
// expandedPaths: string[],
|
|
104
|
+
// value: NodeId[]
|
|
105
|
+
) {
|
|
106
|
+
if (!Array.isArray(tree) || !Array.isArray(value)) {
|
|
92
107
|
console.error("value and tree must be arrays!!");
|
|
93
108
|
return [];
|
|
94
109
|
}
|
|
95
110
|
const start = Date.now();
|
|
96
|
-
const mappedTree = helper.mapTree(
|
|
97
|
-
const { tree: filteredTree, count: filteredCount } = helper.searchTree(mappedTree, filter);
|
|
111
|
+
const mappedTree = untrack(() => helper.mapTree(tree, { ...defaultPropNames, ...treeProps }));
|
|
112
|
+
const { tree: filteredTree, count: filteredCount } = untrack(() => helper.searchTree(mappedTree, filter));
|
|
113
|
+
console.log("threshold condition", {
|
|
114
|
+
res: (!expandedPaths?.length || filter) && filteredCount <= expansionThreshold,
|
|
115
|
+
expandedPaths: $state.snapshot(expandedPaths),
|
|
116
|
+
filter,
|
|
117
|
+
filteredCount,
|
|
118
|
+
expansionThreshold
|
|
119
|
+
});
|
|
98
120
|
// threshold applies to nodes that match the filter, not all their parents
|
|
99
|
-
if (filteredCount <= expansionThreshold) {
|
|
100
|
-
|
|
121
|
+
if ((!expandedPaths?.length || filter) && filteredCount <= expansionThreshold) {
|
|
122
|
+
untrack(() => {
|
|
123
|
+
expandedPaths = uniq([...expandedPaths, ...filteredTree.map((node) => node.path)]);
|
|
124
|
+
});
|
|
101
125
|
}
|
|
102
|
-
helper.markExpanded(filteredTree, expandedPaths);
|
|
126
|
+
untrack(() => helper.markExpanded(filteredTree, expandedPaths));
|
|
103
127
|
// TODO here we could save last value and only recompute visual state if value changed
|
|
104
128
|
// or use diff to only update affected nodes
|
|
105
|
-
selectionProvider.markSelected(filteredTree, value);
|
|
129
|
+
untrack(() => selectionProvider.markSelected(filteredTree, value));
|
|
106
130
|
const end = Date.now();
|
|
107
|
-
debugLog(`Tree computed in: ${end - start}
|
|
131
|
+
debugLog(`Tree computed in: ${end - start}`);
|
|
108
132
|
return filteredTree;
|
|
109
133
|
}
|
|
110
134
|
function onExpand(data) {
|
|
111
135
|
const { node, changeTo } = data;
|
|
136
|
+
console.log("expandedPaths before after expand", {
|
|
137
|
+
after: expandedPaths,
|
|
138
|
+
before: $state.snapshot(expandedPaths)
|
|
139
|
+
});
|
|
112
140
|
expandedPaths = helper.changeExpansion(node.path, changeTo, expandedPaths);
|
|
141
|
+
console.log("expandedPaths before after expand", {
|
|
142
|
+
after: $state.snapshot(expandedPaths),
|
|
143
|
+
});
|
|
113
144
|
debugLog("changed expansion of node '", node.id, "' to ", changeTo);
|
|
114
145
|
//trigger callback if it is present and node has useCallback property set to true
|
|
115
146
|
if (changeTo) {
|
|
@@ -343,16 +374,6 @@ function debugLog(...data) {
|
|
|
343
374
|
bottom: 0;
|
|
344
375
|
left: 0;
|
|
345
376
|
}
|
|
346
|
-
:global(.treeview-parent) :global(.treeview) :global(ul) :global(li:before) {
|
|
347
|
-
content: "";
|
|
348
|
-
display: block;
|
|
349
|
-
width: 10px;
|
|
350
|
-
height: 0;
|
|
351
|
-
margin-top: -1px;
|
|
352
|
-
position: absolute;
|
|
353
|
-
top: 0.8em;
|
|
354
|
-
left: 0;
|
|
355
|
-
}
|
|
356
377
|
:global(.treeview-parent) :global(.treeview) :global(ul) :global(li:not(.has-children):before) {
|
|
357
378
|
width: 26px;
|
|
358
379
|
}
|
|
@@ -375,6 +396,9 @@ function debugLog(...data) {
|
|
|
375
396
|
align-items: center;
|
|
376
397
|
padding: 4px 0;
|
|
377
398
|
}
|
|
399
|
+
:global(.treeview-parent) :global(.treeview) :global(.tree-item) + :global(.child-menu) {
|
|
400
|
+
margin-left: var(--treeview-children-offset, 1.25em);
|
|
401
|
+
}
|
|
378
402
|
:global(.treeview-parent) :global(.treeview) :global(.no-arrow) {
|
|
379
403
|
padding-left: 0.5rem;
|
|
380
404
|
}
|
|
@@ -426,5 +450,7 @@ function debugLog(...data) {
|
|
|
426
450
|
:global(.treeview-parent) :global(.treeview) :global(.fixed-icon) {
|
|
427
451
|
text-align: center;
|
|
428
452
|
width: 1.25em;
|
|
429
|
-
|
|
453
|
+
}
|
|
454
|
+
:global(.treeview-parent) :global(.treeview) :global(.tree-item) > :global(.child-offset) {
|
|
455
|
+
width: 1.25em;
|
|
430
456
|
}</style>
|
package/dist/tree-styles.scss
CHANGED
|
@@ -40,16 +40,6 @@ $treeview-lines: solid black 1px;
|
|
|
40
40
|
left: 0;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
li:before {
|
|
44
|
-
content: "";
|
|
45
|
-
display: block;
|
|
46
|
-
width: 10px;
|
|
47
|
-
height: 0;
|
|
48
|
-
margin-top: -1px;
|
|
49
|
-
position: absolute;
|
|
50
|
-
top: 0.8em;
|
|
51
|
-
left: 0;
|
|
52
|
-
}
|
|
53
43
|
|
|
54
44
|
li:not(.has-children):before {
|
|
55
45
|
width: 26px;
|
|
@@ -76,6 +66,9 @@ $treeview-lines: solid black 1px;
|
|
|
76
66
|
column-gap: 0.4em;
|
|
77
67
|
align-items: center;
|
|
78
68
|
padding: 4px 0;
|
|
69
|
+
& + .child-menu {
|
|
70
|
+
margin-left: var(--treeview-children-offset, 1.25em);
|
|
71
|
+
}
|
|
79
72
|
}
|
|
80
73
|
|
|
81
74
|
.no-arrow {
|
|
@@ -144,8 +137,11 @@ $treeview-lines: solid black 1px;
|
|
|
144
137
|
.fixed-icon {
|
|
145
138
|
text-align: center;
|
|
146
139
|
width: 1.25em;
|
|
147
|
-
// fix deformation on small screens
|
|
148
|
-
min-width: 1.25em;
|
|
149
140
|
}
|
|
150
141
|
|
|
142
|
+
.tree-item {
|
|
143
|
+
& > .child-offset {
|
|
144
|
+
width: 1.25em;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
151
147
|
}
|