@keenmate/svelte-treeview 4.2.1 → 4.4.0
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/README.md +38 -0
- package/dist/components/Node.svelte +3 -3
- package/dist/components/Tree.svelte +116 -12
- package/dist/components/Tree.svelte.d.ts +107 -2
- package/dist/ltree/ltree-demo.js +18 -18
- package/dist/ltree/types.d.ts +2 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -554,6 +554,7 @@ Without both requirements, no search indexing will occur.
|
|
|
554
554
|
| `filterNodes` | `searchText: string, searchOptions?: SearchOptions` | Filter the tree display using internal search index with optional FlexSearch options |
|
|
555
555
|
| `searchNodes` | `searchText: string \| null \| undefined, searchOptions?: SearchOptions` | Search nodes using internal search index and return matching nodes with optional FlexSearch options |
|
|
556
556
|
| `scrollToPath` | `path: string, options?: ScrollToPathOptions` | Scroll to and highlight a specific node |
|
|
557
|
+
| `update` | `updates: Partial<Props>` | Programmatically update component props from external JavaScript |
|
|
557
558
|
|
|
558
559
|
#### ScrollToPath Options
|
|
559
560
|
|
|
@@ -631,6 +632,43 @@ if (isIndexing) {
|
|
|
631
632
|
}
|
|
632
633
|
```
|
|
633
634
|
|
|
635
|
+
#### External Updates (Vanilla JavaScript)
|
|
636
|
+
|
|
637
|
+
The `update()` method allows you to programmatically update component props from external JavaScript code (outside of Svelte's reactivity system). This is particularly useful for HTML/JavaScript integration or dynamic configuration from non-Svelte code.
|
|
638
|
+
|
|
639
|
+
```javascript
|
|
640
|
+
// Get reference to the tree component
|
|
641
|
+
const treeElement = document.querySelector('#my-tree');
|
|
642
|
+
|
|
643
|
+
// Update multiple props at once
|
|
644
|
+
treeElement.update({
|
|
645
|
+
searchText: 'Production',
|
|
646
|
+
expandLevel: 3,
|
|
647
|
+
shouldDisplayDebugInformation: true,
|
|
648
|
+
data: newDataArray,
|
|
649
|
+
contextMenuXOffset: 10
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
// Update single prop
|
|
653
|
+
treeElement.update({ searchText: 'new search' });
|
|
654
|
+
|
|
655
|
+
// Update data and configuration
|
|
656
|
+
treeElement.update({
|
|
657
|
+
data: fetchedData,
|
|
658
|
+
expandLevel: 5,
|
|
659
|
+
selectedNodeClass: 'custom-selected'
|
|
660
|
+
});
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**Updatable Properties:**
|
|
664
|
+
All Tree props can be updated except snippets/templates, including:
|
|
665
|
+
- Data and state: `data`, `searchText`, `selectedNode`, `expandLevel`
|
|
666
|
+
- Members: `idMember`, `pathMember`, `displayValueMember`, `searchValueMember`
|
|
667
|
+
- Callbacks: `sortCallback`, `getDisplayValueCallback`, `onNodeClicked`, etc.
|
|
668
|
+
- Visual: `bodyClass`, `selectedNodeClass`, `expandIconClass`, etc.
|
|
669
|
+
- Context menu: `contextMenuCallback`, `contextMenuXOffset`, `contextMenuYOffset`
|
|
670
|
+
- Behavior: `shouldToggleOnNodeClick`, `shouldUseInternalSearchIndex`, etc.
|
|
671
|
+
|
|
634
672
|
### Debug Information
|
|
635
673
|
|
|
636
674
|
Enable debug information to see real-time tree statistics and console logging:
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
isDraggedNode = false,
|
|
49
49
|
}: Props = $props()
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const tree = getContext<Ltree<T>>("Ltree")
|
|
52
52
|
|
|
53
53
|
// Drag over state
|
|
54
54
|
let isDraggedOver = $state(false);
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
function toggleExpanded() {
|
|
64
64
|
if (node.hasChildren) {
|
|
65
65
|
node.isExpanded = !node.isExpanded
|
|
66
|
-
|
|
66
|
+
tree.refresh()
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
{#if children}
|
|
156
156
|
{@render children(node)}
|
|
157
157
|
{:else}
|
|
158
|
-
{
|
|
158
|
+
{tree.getNodeDisplayValue(node)}
|
|
159
159
|
{/if}
|
|
160
160
|
</div>
|
|
161
161
|
</div>
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
let draggedNode: LTreeNode<any> | null = $state.raw(null);
|
|
17
17
|
|
|
18
18
|
interface Props {
|
|
19
|
-
trieId?: string | null | undefined;
|
|
20
|
-
|
|
21
19
|
// MAPPINGS
|
|
22
20
|
idMember: string;
|
|
23
21
|
pathMember: string;
|
|
@@ -69,7 +67,7 @@
|
|
|
69
67
|
onNodeDragStart?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
70
68
|
onNodeDragOver?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
71
69
|
onNodeDrop?: (node: LTreeNode<T>, draggedNode: LTreeNode<T>, event: DragEvent) => void;
|
|
72
|
-
contextMenuCallback?: (node: LTreeNode<T
|
|
70
|
+
contextMenuCallback?: (node: LTreeNode<T>, closeMenuCallback: () => void) => ContextMenuItem[];
|
|
73
71
|
|
|
74
72
|
// VISUALS
|
|
75
73
|
bodyClass?: string | null | undefined;
|
|
@@ -178,6 +176,13 @@
|
|
|
178
176
|
return tree?.searchNodes(searchText, searchOptions) || [];
|
|
179
177
|
}
|
|
180
178
|
|
|
179
|
+
// svelte-ignore non_reactive_update
|
|
180
|
+
export function closeContextMenu() {
|
|
181
|
+
contextMenuVisible = false;
|
|
182
|
+
contextMenuNode = null;
|
|
183
|
+
isDebugMenuActive = false;
|
|
184
|
+
}
|
|
185
|
+
|
|
181
186
|
export async function scrollToPath(
|
|
182
187
|
path: string,
|
|
183
188
|
options?: { expand?: boolean; highlight?: boolean; scrollOptions?: ScrollIntoViewOptions }
|
|
@@ -228,6 +233,102 @@
|
|
|
228
233
|
return true;
|
|
229
234
|
}
|
|
230
235
|
|
|
236
|
+
// External update method for HTML/JavaScript usage
|
|
237
|
+
export function update(
|
|
238
|
+
updates: Partial<
|
|
239
|
+
Pick<
|
|
240
|
+
Props,
|
|
241
|
+
| "treeId"
|
|
242
|
+
| "treePathSeparator"
|
|
243
|
+
| "idMember"
|
|
244
|
+
| "pathMember"
|
|
245
|
+
| "parentPathMember"
|
|
246
|
+
| "levelMember"
|
|
247
|
+
| "hasChildrenMember"
|
|
248
|
+
| "isExpandedMember"
|
|
249
|
+
| "isSelectedMember"
|
|
250
|
+
| "isDraggableMember"
|
|
251
|
+
| "isDropAllowedMember"
|
|
252
|
+
| "displayValueMember"
|
|
253
|
+
| "getDisplayValueCallback"
|
|
254
|
+
| "searchValueMember"
|
|
255
|
+
| "getSearchValueCallback"
|
|
256
|
+
| "isSorted"
|
|
257
|
+
| "sortCallback"
|
|
258
|
+
| "data"
|
|
259
|
+
| "selectedNode"
|
|
260
|
+
| "expandLevel"
|
|
261
|
+
| "shouldToggleOnNodeClick"
|
|
262
|
+
| "shouldUseInternalSearchIndex"
|
|
263
|
+
| "initializeIndexCallback"
|
|
264
|
+
| "searchText"
|
|
265
|
+
| "indexerBatchSize"
|
|
266
|
+
| "indexerTimeout"
|
|
267
|
+
| "shouldDisplayDebugInformation"
|
|
268
|
+
| "shouldDisplayContextMenuInDebugMode"
|
|
269
|
+
| "onNodeClicked"
|
|
270
|
+
| "onNodeDragStart"
|
|
271
|
+
| "onNodeDragOver"
|
|
272
|
+
| "onNodeDrop"
|
|
273
|
+
| "contextMenuCallback"
|
|
274
|
+
| "bodyClass"
|
|
275
|
+
| "expandIconClass"
|
|
276
|
+
| "collapseIconClass"
|
|
277
|
+
| "leafIconClass"
|
|
278
|
+
| "selectedNodeClass"
|
|
279
|
+
| "dragOverNodeClass"
|
|
280
|
+
| "scrollHighlightTimeout"
|
|
281
|
+
| "scrollHighlightClass"
|
|
282
|
+
| "contextMenuXOffset"
|
|
283
|
+
| "contextMenuYOffset"
|
|
284
|
+
>
|
|
285
|
+
>
|
|
286
|
+
) {
|
|
287
|
+
if (updates.treeId !== undefined) treeId = updates.treeId;
|
|
288
|
+
if (updates.treePathSeparator !== undefined) treePathSeparator = updates.treePathSeparator;
|
|
289
|
+
if (updates.idMember !== undefined) idMember = updates.idMember;
|
|
290
|
+
if (updates.pathMember !== undefined) pathMember = updates.pathMember;
|
|
291
|
+
if (updates.parentPathMember !== undefined) parentPathMember = updates.parentPathMember;
|
|
292
|
+
if (updates.levelMember !== undefined) levelMember = updates.levelMember;
|
|
293
|
+
if (updates.hasChildrenMember !== undefined) hasChildrenMember = updates.hasChildrenMember;
|
|
294
|
+
if (updates.isExpandedMember !== undefined) isExpandedMember = updates.isExpandedMember;
|
|
295
|
+
if (updates.isSelectedMember !== undefined) isSelectedMember = updates.isSelectedMember;
|
|
296
|
+
if (updates.isDraggableMember !== undefined) isDraggableMember = updates.isDraggableMember;
|
|
297
|
+
if (updates.isDropAllowedMember !== undefined) isDropAllowedMember = updates.isDropAllowedMember;
|
|
298
|
+
if (updates.displayValueMember !== undefined) displayValueMember = updates.displayValueMember;
|
|
299
|
+
if (updates.getDisplayValueCallback !== undefined) getDisplayValueCallback = updates.getDisplayValueCallback;
|
|
300
|
+
if (updates.searchValueMember !== undefined) searchValueMember = updates.searchValueMember;
|
|
301
|
+
if (updates.getSearchValueCallback !== undefined) getSearchValueCallback = updates.getSearchValueCallback;
|
|
302
|
+
if (updates.isSorted !== undefined) isSorted = updates.isSorted;
|
|
303
|
+
if (updates.sortCallback !== undefined) sortCallback = updates.sortCallback;
|
|
304
|
+
if (updates.data !== undefined) data = updates.data;
|
|
305
|
+
if (updates.selectedNode !== undefined) selectedNode = updates.selectedNode;
|
|
306
|
+
if (updates.expandLevel !== undefined) expandLevel = updates.expandLevel;
|
|
307
|
+
if (updates.shouldToggleOnNodeClick !== undefined) shouldToggleOnNodeClick = updates.shouldToggleOnNodeClick;
|
|
308
|
+
if (updates.shouldUseInternalSearchIndex !== undefined) shouldUseInternalSearchIndex = updates.shouldUseInternalSearchIndex;
|
|
309
|
+
if (updates.initializeIndexCallback !== undefined) initializeIndexCallback = updates.initializeIndexCallback;
|
|
310
|
+
if (updates.searchText !== undefined) searchText = updates.searchText;
|
|
311
|
+
if (updates.indexerBatchSize !== undefined) indexerBatchSize = updates.indexerBatchSize;
|
|
312
|
+
if (updates.indexerTimeout !== undefined) indexerTimeout = updates.indexerTimeout;
|
|
313
|
+
if (updates.shouldDisplayDebugInformation !== undefined) shouldDisplayDebugInformation = updates.shouldDisplayDebugInformation;
|
|
314
|
+
if (updates.shouldDisplayContextMenuInDebugMode !== undefined) shouldDisplayContextMenuInDebugMode = updates.shouldDisplayContextMenuInDebugMode;
|
|
315
|
+
if (updates.onNodeClicked !== undefined) onNodeClicked = updates.onNodeClicked;
|
|
316
|
+
if (updates.onNodeDragStart !== undefined) onNodeDragStart = updates.onNodeDragStart;
|
|
317
|
+
if (updates.onNodeDragOver !== undefined) onNodeDragOver = updates.onNodeDragOver;
|
|
318
|
+
if (updates.onNodeDrop !== undefined) onNodeDrop = updates.onNodeDrop;
|
|
319
|
+
if (updates.contextMenuCallback !== undefined) contextMenuCallback = updates.contextMenuCallback;
|
|
320
|
+
if (updates.bodyClass !== undefined) bodyClass = updates.bodyClass;
|
|
321
|
+
if (updates.expandIconClass !== undefined) expandIconClass = updates.expandIconClass;
|
|
322
|
+
if (updates.collapseIconClass !== undefined) collapseIconClass = updates.collapseIconClass;
|
|
323
|
+
if (updates.leafIconClass !== undefined) leafIconClass = updates.leafIconClass;
|
|
324
|
+
if (updates.selectedNodeClass !== undefined) selectedNodeClass = updates.selectedNodeClass;
|
|
325
|
+
if (updates.dragOverNodeClass !== undefined) dragOverNodeClass = updates.dragOverNodeClass;
|
|
326
|
+
if (updates.scrollHighlightTimeout !== undefined) scrollHighlightTimeout = updates.scrollHighlightTimeout;
|
|
327
|
+
if (updates.scrollHighlightClass !== undefined) scrollHighlightClass = updates.scrollHighlightClass;
|
|
328
|
+
if (updates.contextMenuXOffset !== undefined) contextMenuXOffset = updates.contextMenuXOffset;
|
|
329
|
+
if (updates.contextMenuYOffset !== undefined) contextMenuYOffset = updates.contextMenuYOffset;
|
|
330
|
+
}
|
|
331
|
+
|
|
231
332
|
treeId = treeId || generateTreeId();
|
|
232
333
|
|
|
233
334
|
if (shouldDisplayDebugInformation)
|
|
@@ -283,7 +384,7 @@
|
|
|
283
384
|
}
|
|
284
385
|
});
|
|
285
386
|
|
|
286
|
-
// $inspect("
|
|
387
|
+
// $inspect("tree change tracker", tree?.changeTracker?.toString());
|
|
287
388
|
|
|
288
389
|
function generateTreeId(): string {
|
|
289
390
|
return `${Date.now()}${Math.floor(Math.random() * 10000)}`;
|
|
@@ -325,11 +426,6 @@
|
|
|
325
426
|
isDebugMenuActive = false; // This is a user-triggered menu, not debug menu
|
|
326
427
|
}
|
|
327
428
|
|
|
328
|
-
function closeContextMenu() {
|
|
329
|
-
contextMenuVisible = false;
|
|
330
|
-
contextMenuNode = null;
|
|
331
|
-
isDebugMenuActive = false;
|
|
332
|
-
}
|
|
333
429
|
|
|
334
430
|
function _onNodeDragStart(node: LTreeNode<T>, event: DragEvent) {
|
|
335
431
|
draggedNode = node;
|
|
@@ -529,15 +625,23 @@
|
|
|
529
625
|
{#if contextMenuVisible && contextMenuNode}
|
|
530
626
|
<div class="ltree-context-menu" style="left: {contextMenuX}px; top: {contextMenuY}px;">
|
|
531
627
|
{#if contextMenuCallback}
|
|
532
|
-
{@const menuItems = contextMenuCallback(contextMenuNode)}
|
|
628
|
+
{@const menuItems = contextMenuCallback(contextMenuNode, closeContextMenu)}
|
|
533
629
|
{#each menuItems as item}
|
|
534
630
|
{#if item.isDivider}
|
|
535
631
|
<div class="ltree-context-menu-divider"></div>
|
|
536
632
|
{:else}
|
|
537
633
|
<div
|
|
538
|
-
class="ltree-context-menu-item"
|
|
634
|
+
class="ltree-context-menu-item {item.className || ''}"
|
|
539
635
|
class:ltree-context-menu-item-disabled={item.isDisabled}
|
|
540
|
-
onclick={() =>
|
|
636
|
+
onclick={async () => {
|
|
637
|
+
if (!item.isDisabled) {
|
|
638
|
+
try {
|
|
639
|
+
await item.callback();
|
|
640
|
+
} catch (error) {
|
|
641
|
+
console.error('Context menu callback error:', error);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}}
|
|
541
645
|
>
|
|
542
646
|
{#if item.icon}
|
|
543
647
|
<span class="ltree-context-menu-icon">{item.icon}</span>
|
|
@@ -3,7 +3,6 @@ import { type LTreeNode } from '../ltree/ltree-node.svelte.js';
|
|
|
3
3
|
import { type InsertArrayResult, type ContextMenuItem } from '../ltree/types.js';
|
|
4
4
|
declare function $$render<T>(): {
|
|
5
5
|
props: {
|
|
6
|
-
trieId?: string | null | undefined;
|
|
7
6
|
idMember: string;
|
|
8
7
|
pathMember: string;
|
|
9
8
|
parentPathMember?: string | null | undefined;
|
|
@@ -43,7 +42,7 @@ declare function $$render<T>(): {
|
|
|
43
42
|
onNodeDragStart?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
44
43
|
onNodeDragOver?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
45
44
|
onNodeDrop?: (node: LTreeNode<T>, draggedNode: LTreeNode<T>, event: DragEvent) => void;
|
|
46
|
-
contextMenuCallback?: (node: LTreeNode<T
|
|
45
|
+
contextMenuCallback?: (node: LTreeNode<T>, closeMenuCallback: () => void) => ContextMenuItem[];
|
|
47
46
|
bodyClass?: string | null | undefined;
|
|
48
47
|
selectedNodeClass?: string | null | undefined;
|
|
49
48
|
dragOverNodeClass?: string | null | undefined;
|
|
@@ -62,11 +61,64 @@ declare function $$render<T>(): {
|
|
|
62
61
|
collapseAll: (nodePath?: string | null | undefined) => void;
|
|
63
62
|
filterNodes: (searchText: string, searchOptions?: SearchOptions) => void;
|
|
64
63
|
searchNodes: (searchText: string | null | undefined, searchOptions?: SearchOptions) => LTreeNode<T>[];
|
|
64
|
+
closeContextMenu: () => void;
|
|
65
65
|
scrollToPath: (path: string, options?: {
|
|
66
66
|
expand?: boolean;
|
|
67
67
|
highlight?: boolean;
|
|
68
68
|
scrollOptions?: ScrollIntoViewOptions;
|
|
69
69
|
}) => Promise<boolean>;
|
|
70
|
+
update: (updates: Partial<Pick<{
|
|
71
|
+
idMember: string;
|
|
72
|
+
pathMember: string;
|
|
73
|
+
parentPathMember?: string | null | undefined;
|
|
74
|
+
levelMember?: string | null | undefined;
|
|
75
|
+
isExpandedMember?: string | null | undefined;
|
|
76
|
+
isSelectedMember?: string | null | undefined;
|
|
77
|
+
isDraggableMember?: string | null | undefined;
|
|
78
|
+
isDropAllowedMember?: string | null | undefined;
|
|
79
|
+
hasChildrenMember?: string | null | undefined;
|
|
80
|
+
isSorted?: boolean | null | undefined;
|
|
81
|
+
displayValueMember?: string | null | undefined;
|
|
82
|
+
getDisplayValueCallback?: (node: LTreeNode<T>) => string;
|
|
83
|
+
searchValueMember?: string | null | undefined;
|
|
84
|
+
getSearchValueCallback?: (node: LTreeNode<T>) => string;
|
|
85
|
+
treeId?: string | null | undefined;
|
|
86
|
+
treePathSeparator?: string | null | undefined;
|
|
87
|
+
sortCallback?: (items: LTreeNode<T>[]) => LTreeNode<T>[];
|
|
88
|
+
data: T[];
|
|
89
|
+
selectedNode?: LTreeNode<T> | null | undefined;
|
|
90
|
+
insertResult?: InsertArrayResult<T> | null | undefined;
|
|
91
|
+
nodeTemplate?: any;
|
|
92
|
+
treeHeader?: any;
|
|
93
|
+
treeBody?: any;
|
|
94
|
+
treeFooter?: any;
|
|
95
|
+
noDataFound?: any;
|
|
96
|
+
contextMenu?: any;
|
|
97
|
+
expandLevel?: number | null | undefined;
|
|
98
|
+
shouldToggleOnNodeClick?: boolean | null | undefined;
|
|
99
|
+
initializeIndexCallback?: () => Index;
|
|
100
|
+
searchText?: string | null | undefined;
|
|
101
|
+
shouldUseInternalSearchIndex?: boolean | null | undefined;
|
|
102
|
+
indexerBatchSize?: number | null | undefined;
|
|
103
|
+
indexerTimeout?: number | null | undefined;
|
|
104
|
+
shouldDisplayDebugInformation?: boolean;
|
|
105
|
+
shouldDisplayContextMenuInDebugMode?: boolean;
|
|
106
|
+
onNodeClicked?: (node: LTreeNode<T>) => void;
|
|
107
|
+
onNodeDragStart?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
108
|
+
onNodeDragOver?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
109
|
+
onNodeDrop?: (node: LTreeNode<T>, draggedNode: LTreeNode<T>, event: DragEvent) => void;
|
|
110
|
+
contextMenuCallback?: (node: LTreeNode<T>, closeMenuCallback: () => void) => ContextMenuItem[];
|
|
111
|
+
bodyClass?: string | null | undefined;
|
|
112
|
+
selectedNodeClass?: string | null | undefined;
|
|
113
|
+
dragOverNodeClass?: string | null | undefined;
|
|
114
|
+
expandIconClass?: string | null | undefined;
|
|
115
|
+
collapseIconClass?: string | null | undefined;
|
|
116
|
+
leafIconClass?: string | null | undefined;
|
|
117
|
+
scrollHighlightTimeout?: number | null | undefined;
|
|
118
|
+
scrollHighlightClass?: string | null | undefined;
|
|
119
|
+
contextMenuXOffset?: number | null | undefined;
|
|
120
|
+
contextMenuYOffset?: number | null | undefined;
|
|
121
|
+
}, "treeId" | "treePathSeparator" | "idMember" | "pathMember" | "parentPathMember" | "levelMember" | "hasChildrenMember" | "isExpandedMember" | "isSelectedMember" | "isDraggableMember" | "isDropAllowedMember" | "displayValueMember" | "getDisplayValueCallback" | "searchValueMember" | "getSearchValueCallback" | "isSorted" | "sortCallback" | "data" | "selectedNode" | "expandLevel" | "shouldToggleOnNodeClick" | "shouldUseInternalSearchIndex" | "initializeIndexCallback" | "searchText" | "indexerBatchSize" | "indexerTimeout" | "shouldDisplayDebugInformation" | "shouldDisplayContextMenuInDebugMode" | "onNodeClicked" | "onNodeDragStart" | "onNodeDragOver" | "onNodeDrop" | "contextMenuCallback" | "bodyClass" | "expandIconClass" | "collapseIconClass" | "leafIconClass" | "selectedNodeClass" | "dragOverNodeClass" | "scrollHighlightTimeout" | "scrollHighlightClass" | "contextMenuXOffset" | "contextMenuYOffset">>) => void;
|
|
70
122
|
};
|
|
71
123
|
bindings: "data" | "selectedNode" | "insertResult" | "searchText";
|
|
72
124
|
slots: {};
|
|
@@ -84,11 +136,64 @@ declare class __sveltets_Render<T> {
|
|
|
84
136
|
collapseAll: (nodePath?: string | null | undefined) => void;
|
|
85
137
|
filterNodes: (searchText: string, searchOptions?: SearchOptions) => void;
|
|
86
138
|
searchNodes: (searchText: string | null | undefined, searchOptions?: SearchOptions) => LTreeNode<T>[];
|
|
139
|
+
closeContextMenu: () => void;
|
|
87
140
|
scrollToPath: (path: string, options?: {
|
|
88
141
|
expand?: boolean;
|
|
89
142
|
highlight?: boolean;
|
|
90
143
|
scrollOptions?: ScrollIntoViewOptions;
|
|
91
144
|
} | undefined) => Promise<boolean>;
|
|
145
|
+
update: (updates: Partial<Pick<{
|
|
146
|
+
idMember: string;
|
|
147
|
+
pathMember: string;
|
|
148
|
+
parentPathMember?: string | null | undefined;
|
|
149
|
+
levelMember?: string | null | undefined;
|
|
150
|
+
isExpandedMember?: string | null | undefined;
|
|
151
|
+
isSelectedMember?: string | null | undefined;
|
|
152
|
+
isDraggableMember?: string | null | undefined;
|
|
153
|
+
isDropAllowedMember?: string | null | undefined;
|
|
154
|
+
hasChildrenMember?: string | null | undefined;
|
|
155
|
+
isSorted?: boolean | null | undefined;
|
|
156
|
+
displayValueMember?: string | null | undefined;
|
|
157
|
+
getDisplayValueCallback?: ((node: LTreeNode<T>) => string) | undefined;
|
|
158
|
+
searchValueMember?: string | null | undefined;
|
|
159
|
+
getSearchValueCallback?: ((node: LTreeNode<T>) => string) | undefined;
|
|
160
|
+
treeId?: string | null | undefined;
|
|
161
|
+
treePathSeparator?: string | null | undefined;
|
|
162
|
+
sortCallback?: ((items: LTreeNode<T>[]) => LTreeNode<T>[]) | undefined;
|
|
163
|
+
data: T[];
|
|
164
|
+
selectedNode?: LTreeNode<T> | null | undefined;
|
|
165
|
+
insertResult?: InsertArrayResult<T> | null | undefined;
|
|
166
|
+
nodeTemplate?: any;
|
|
167
|
+
treeHeader?: any;
|
|
168
|
+
treeBody?: any;
|
|
169
|
+
treeFooter?: any;
|
|
170
|
+
noDataFound?: any;
|
|
171
|
+
contextMenu?: any;
|
|
172
|
+
expandLevel?: number | null | undefined;
|
|
173
|
+
shouldToggleOnNodeClick?: boolean | null | undefined;
|
|
174
|
+
initializeIndexCallback?: (() => Index) | undefined;
|
|
175
|
+
searchText?: string | null | undefined;
|
|
176
|
+
shouldUseInternalSearchIndex?: boolean | null | undefined;
|
|
177
|
+
indexerBatchSize?: number | null | undefined;
|
|
178
|
+
indexerTimeout?: number | null | undefined;
|
|
179
|
+
shouldDisplayDebugInformation?: boolean;
|
|
180
|
+
shouldDisplayContextMenuInDebugMode?: boolean;
|
|
181
|
+
onNodeClicked?: ((node: LTreeNode<T>) => void) | undefined;
|
|
182
|
+
onNodeDragStart?: ((node: LTreeNode<T>, event: DragEvent) => void) | undefined;
|
|
183
|
+
onNodeDragOver?: ((node: LTreeNode<T>, event: DragEvent) => void) | undefined;
|
|
184
|
+
onNodeDrop?: ((node: LTreeNode<T>, draggedNode: LTreeNode<T>, event: DragEvent) => void) | undefined;
|
|
185
|
+
contextMenuCallback?: ((node: LTreeNode<T>, closeMenuCallback: () => void) => ContextMenuItem[]) | undefined;
|
|
186
|
+
bodyClass?: string | null | undefined;
|
|
187
|
+
selectedNodeClass?: string | null | undefined;
|
|
188
|
+
dragOverNodeClass?: string | null | undefined;
|
|
189
|
+
expandIconClass?: string | null | undefined;
|
|
190
|
+
collapseIconClass?: string | null | undefined;
|
|
191
|
+
leafIconClass?: string | null | undefined;
|
|
192
|
+
scrollHighlightTimeout?: number | null | undefined;
|
|
193
|
+
scrollHighlightClass?: string | null | undefined;
|
|
194
|
+
contextMenuXOffset?: number | null | undefined;
|
|
195
|
+
contextMenuYOffset?: number | null | undefined;
|
|
196
|
+
}, "treeId" | "data" | "onNodeClicked" | "onNodeDragStart" | "onNodeDragOver" | "onNodeDrop" | "shouldToggleOnNodeClick" | "expandIconClass" | "collapseIconClass" | "leafIconClass" | "selectedNodeClass" | "dragOverNodeClass" | "treePathSeparator" | "idMember" | "pathMember" | "parentPathMember" | "levelMember" | "hasChildrenMember" | "isExpandedMember" | "displayValueMember" | "getDisplayValueCallback" | "searchValueMember" | "getSearchValueCallback" | "isSorted" | "sortCallback" | "isDraggableMember" | "isDropAllowedMember" | "shouldDisplayDebugInformation" | "isSelectedMember" | "selectedNode" | "expandLevel" | "shouldUseInternalSearchIndex" | "initializeIndexCallback" | "searchText" | "indexerBatchSize" | "indexerTimeout" | "shouldDisplayContextMenuInDebugMode" | "contextMenuCallback" | "bodyClass" | "scrollHighlightTimeout" | "scrollHighlightClass" | "contextMenuXOffset" | "contextMenuYOffset">>) => void;
|
|
92
197
|
};
|
|
93
198
|
}
|
|
94
199
|
interface $$IsomorphicComponent {
|
package/dist/ltree/ltree-demo.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLTree } from './ltree.svelte';
|
|
2
2
|
// Usage Examples and Performance Test
|
|
3
3
|
export function demonstrateLTree() {
|
|
4
|
-
const
|
|
4
|
+
const tree = createLTree('id', 'path', null, null, null, null, null, null, null, null, null, null, null, { isSorted: false, sortCallback: null });
|
|
5
5
|
// Sample ltree paths
|
|
6
6
|
const paths = [
|
|
7
7
|
'1',
|
|
@@ -16,37 +16,37 @@ export function demonstrateLTree() {
|
|
|
16
16
|
'2.1',
|
|
17
17
|
'2.1.1'
|
|
18
18
|
];
|
|
19
|
-
console.log('=== LTree
|
|
19
|
+
console.log('=== LTree Demo ===');
|
|
20
20
|
// Insert paths with some sample data
|
|
21
21
|
console.log('\n1. Inserting paths...');
|
|
22
22
|
paths.forEach((path, index) => {
|
|
23
|
-
|
|
23
|
+
tree.insert(path, { id: index, name: `Node ${path}` });
|
|
24
24
|
console.log(`Inserted: ${path}`);
|
|
25
25
|
});
|
|
26
26
|
// Search for specific paths
|
|
27
27
|
console.log('\n2. Searching for paths...');
|
|
28
|
-
console.log('Search "1.1.2":',
|
|
29
|
-
console.log('Search "1.3" (non-existent):',
|
|
28
|
+
console.log('Search "1.1.2":', tree.search('1.1.2'));
|
|
29
|
+
console.log('Search "1.3" (non-existent):', tree.search('1.3'));
|
|
30
30
|
// Find by prefix
|
|
31
31
|
console.log('\n3. Finding paths by prefix...');
|
|
32
|
-
console.log('Prefix "1.1":',
|
|
33
|
-
console.log('Prefix "1.2":',
|
|
32
|
+
console.log('Prefix "1.1":', tree.findByPrefix('1.1'));
|
|
33
|
+
console.log('Prefix "1.2":', tree.findByPrefix('1.2'));
|
|
34
34
|
// Get direct children
|
|
35
35
|
console.log('\n4. Getting direct children...');
|
|
36
|
-
console.log('Children of "1":',
|
|
37
|
-
console.log('Children of "1.1":',
|
|
36
|
+
console.log('Children of "1":', tree.getDirectChildren('1'));
|
|
37
|
+
console.log('Children of "1.1":', tree.getDirectChildren('1.1'));
|
|
38
38
|
// Get ancestors
|
|
39
39
|
console.log('\n5. Getting ancestors...');
|
|
40
|
-
console.log('Ancestors of "1.1.2.1":',
|
|
40
|
+
console.log('Ancestors of "1.1.2.1":', tree.getAncestors('1.1.2.1'));
|
|
41
41
|
// Statistics
|
|
42
|
-
console.log('\n6.
|
|
43
|
-
console.log(
|
|
44
|
-
return
|
|
42
|
+
console.log('\n6. Tree statistics:');
|
|
43
|
+
console.log(tree.getStats());
|
|
44
|
+
return tree;
|
|
45
45
|
}
|
|
46
46
|
// Performance test with larger dataset
|
|
47
47
|
export function performanceTest() {
|
|
48
48
|
console.log('\n=== Performance Test ===');
|
|
49
|
-
const
|
|
49
|
+
const tree = createLtree('path', 'path', null, null, null, null, null, null, null, null, null, null, null, { isSorted: false, sortCallback: null });
|
|
50
50
|
const paths = [];
|
|
51
51
|
// Generate test data: hierarchical paths up to 4 levels deep
|
|
52
52
|
console.log('Generating test data...');
|
|
@@ -65,22 +65,22 @@ export function performanceTest() {
|
|
|
65
65
|
console.log(`Generated ${paths.length} paths`);
|
|
66
66
|
// Test insertion
|
|
67
67
|
console.time('Insertion');
|
|
68
|
-
paths.forEach(path =>
|
|
68
|
+
paths.forEach(path => tree.insert(path, { path }));
|
|
69
69
|
console.timeEnd('Insertion');
|
|
70
70
|
// Test search performance
|
|
71
71
|
console.time('Search 1000 random paths');
|
|
72
72
|
for (let i = 0; i < 1000; i++) {
|
|
73
73
|
const randomPath = paths[Math.floor(Math.random() * paths.length)];
|
|
74
|
-
|
|
74
|
+
tree.search(randomPath);
|
|
75
75
|
}
|
|
76
76
|
console.timeEnd('Search 1000 random paths');
|
|
77
77
|
// Test prefix search
|
|
78
78
|
console.time('Prefix search for "1."');
|
|
79
|
-
const results =
|
|
79
|
+
const results = tree.findByPrefix('1.');
|
|
80
80
|
console.timeEnd('Prefix search for "1."');
|
|
81
81
|
console.log(`Found ${results?.length} paths with prefix "1."`);
|
|
82
82
|
// Memory usage
|
|
83
|
-
const stats =
|
|
83
|
+
const stats = tree.getStats();
|
|
84
84
|
console.log('Final statistics:', stats);
|
|
85
85
|
}
|
|
86
86
|
// Run demonstrations if this file is executed directly
|
package/dist/ltree/types.d.ts
CHANGED
|
@@ -5,8 +5,9 @@ export interface ContextMenuItem {
|
|
|
5
5
|
icon?: string;
|
|
6
6
|
title: string;
|
|
7
7
|
isDisabled?: boolean;
|
|
8
|
-
callback: () => void
|
|
8
|
+
callback: () => void | Promise<void>;
|
|
9
9
|
isDivider?: boolean;
|
|
10
|
+
className?: string;
|
|
10
11
|
}
|
|
11
12
|
export interface InsertArrayResult<T> {
|
|
12
13
|
successful: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keenmate/svelte-treeview",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev --port 17777",
|
|
6
6
|
"build": "vite build && npm run prepack",
|
|
@@ -74,7 +74,6 @@
|
|
|
74
74
|
"treeview",
|
|
75
75
|
"hierarchical",
|
|
76
76
|
"ltree",
|
|
77
|
-
"trie",
|
|
78
77
|
"drag-drop",
|
|
79
78
|
"search",
|
|
80
79
|
"flexsearch",
|