@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.
@@ -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>
@@ -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(computeTree(helper, selectionProvider, tree, filter, treeProps, expandedPaths, value));
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(helper, selectionProvider, userProvidedTree, filter, props, expandedPaths, value) {
91
- if (!Array.isArray(userProvidedTree) || !Array.isArray(value)) {
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(userProvidedTree, { ...defaultPropNames, ...props });
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
- expandedPaths = uniq([...expandedPaths, ...filteredTree.map((node) => node.path)]);
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}`, computeTree);
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
- min-width: 1.25em;
453
+ }
454
+ :global(.treeview-parent) :global(.treeview) :global(.tree-item) > :global(.child-offset) {
455
+ width: 1.25em;
430
456
  }</style>
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keenmate/svelte-treeview",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "repository": {
5
5
  "url": "https://github.com/keenmate/svelte-treeview"
6
6
  },