@keenmate/svelte-treeview 4.1.0 → 4.2.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 +126 -2
- package/dist/components/Tree.svelte +83 -10
- package/dist/components/Tree.svelte.d.ts +5 -1
- package/dist/ltree/types.d.ts +7 -0
- package/dist/styles/main.scss +16 -2
- package/dist/styles.css +14 -2
- package/dist/styles.css.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A high-performance, feature-rich hierarchical tree view component for Svelte 5 w
|
|
|
12
12
|
- **Drag & Drop**: Built-in drag and drop support with validation and visual feedback
|
|
13
13
|
- **Search & Filter**: Integrated FlexSearch for fast, full-text search capabilities
|
|
14
14
|
- **Flexible Data Sources**: Works with any hierarchical data structure
|
|
15
|
-
- **Context Menus**:
|
|
15
|
+
- **Context Menus**: Dynamic right-click menus with callback-based generation, icons, disabled states
|
|
16
16
|
- **Visual Customization**: Extensive styling options and icon customization
|
|
17
17
|
- **TypeScript Support**: Full TypeScript support with comprehensive type definitions
|
|
18
18
|
- **Accessibility**: Built with accessibility in mind
|
|
@@ -258,6 +258,104 @@ For complete FlexSearch documentation, visit: [FlexSearch Options](https://githu
|
|
|
258
258
|
</div>
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
+
### With Context Menus
|
|
262
|
+
|
|
263
|
+
The tree supports context menus with two approaches: callback-based (recommended) and snippet-based.
|
|
264
|
+
|
|
265
|
+
#### Callback-Based Context Menus
|
|
266
|
+
|
|
267
|
+
```svelte
|
|
268
|
+
<script lang="ts">
|
|
269
|
+
import { Tree } from '@keenmate/svelte-treeview';
|
|
270
|
+
import type { ContextMenuItem } from '@keenmate/svelte-treeview';
|
|
271
|
+
|
|
272
|
+
const data = [
|
|
273
|
+
{ path: '1', name: 'Documents', type: 'folder', canEdit: true, canDelete: true },
|
|
274
|
+
{ path: '1.1', name: 'report.pdf', type: 'file', canEdit: true, canDelete: false },
|
|
275
|
+
{ path: '2', name: 'Images', type: 'folder', canEdit: false, canDelete: true }
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
function createContextMenu(node): ContextMenuItem[] {
|
|
279
|
+
const items: ContextMenuItem[] = [];
|
|
280
|
+
|
|
281
|
+
// Always available
|
|
282
|
+
items.push({
|
|
283
|
+
icon: '📂',
|
|
284
|
+
title: 'Open',
|
|
285
|
+
callback: () => alert(`Opening ${node.data.name}`)
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Conditional actions based on node data
|
|
289
|
+
if (node.data.canEdit) {
|
|
290
|
+
items.push({
|
|
291
|
+
icon: '✏️',
|
|
292
|
+
title: 'Edit',
|
|
293
|
+
callback: () => alert(`Editing ${node.data.name}`)
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (node.data.canDelete) {
|
|
298
|
+
items.push({
|
|
299
|
+
icon: '🗑️',
|
|
300
|
+
title: 'Delete',
|
|
301
|
+
callback: () => confirm(`Delete ${node.data.name}?`) && alert('Deleted!')
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Divider
|
|
306
|
+
items.push({ isDivider: true });
|
|
307
|
+
|
|
308
|
+
// Disabled item example
|
|
309
|
+
items.push({
|
|
310
|
+
icon: '🔒',
|
|
311
|
+
title: 'Restricted Action',
|
|
312
|
+
isDisabled: true,
|
|
313
|
+
callback: () => {}
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
return items;
|
|
317
|
+
}
|
|
318
|
+
</script>
|
|
319
|
+
|
|
320
|
+
<Tree
|
|
321
|
+
{data}
|
|
322
|
+
idMember="path"
|
|
323
|
+
pathMember="path"
|
|
324
|
+
contextMenuCallback={createContextMenu}
|
|
325
|
+
contextMenuXOffset={8}
|
|
326
|
+
contextMenuYOffset={0}
|
|
327
|
+
/>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### Snippet-Based Context Menus
|
|
331
|
+
|
|
332
|
+
```svelte
|
|
333
|
+
<Tree
|
|
334
|
+
{data}
|
|
335
|
+
idMember="path"
|
|
336
|
+
pathMember="path"
|
|
337
|
+
>
|
|
338
|
+
{#snippet contextMenu(node, closeMenu)}
|
|
339
|
+
<div class="context-menu-item" onclick={() => { alert(`Open ${node.data.name}`); closeMenu(); }}>
|
|
340
|
+
📂 Open
|
|
341
|
+
</div>
|
|
342
|
+
<div class="context-menu-divider"></div>
|
|
343
|
+
<div class="context-menu-item" onclick={() => { alert(`Delete ${node.data.name}`); closeMenu(); }}>
|
|
344
|
+
🗑️ Delete
|
|
345
|
+
</div>
|
|
346
|
+
{/snippet}
|
|
347
|
+
</Tree>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
#### Context Menu Features
|
|
351
|
+
|
|
352
|
+
- **Dynamic menus**: Generate menu items based on node properties
|
|
353
|
+
- **Icons and dividers**: Visual organization and identification
|
|
354
|
+
- **Disabled states**: Context-sensitive menu availability
|
|
355
|
+
- **Position offset**: `contextMenuXOffset`/`contextMenuYOffset` for cursor clearance
|
|
356
|
+
- **Auto-close**: Closes on scroll, click outside, or programmatically
|
|
357
|
+
- **Type safety**: Full TypeScript support with `ContextMenuItem` interface
|
|
358
|
+
|
|
261
359
|
## 🎨 Styling and Customization
|
|
262
360
|
|
|
263
361
|
The component comes with default styles that provide a clean, modern look. You can customize it extensively:
|
|
@@ -598,7 +696,7 @@ Custom template for rendering node content.
|
|
|
598
696
|
```
|
|
599
697
|
|
|
600
698
|
#### contextMenu
|
|
601
|
-
Custom context menu template.
|
|
699
|
+
Custom context menu template (snippet-based approach).
|
|
602
700
|
|
|
603
701
|
```svelte
|
|
604
702
|
{#snippet contextMenu(node, closeMenu)}
|
|
@@ -608,6 +706,32 @@ Custom context menu template.
|
|
|
608
706
|
{/snippet}
|
|
609
707
|
```
|
|
610
708
|
|
|
709
|
+
### Context Menu Properties
|
|
710
|
+
|
|
711
|
+
#### contextMenuCallback
|
|
712
|
+
Function that generates context menu items dynamically.
|
|
713
|
+
|
|
714
|
+
```typescript
|
|
715
|
+
contextMenuCallback: (node: LTreeNode<T>) => ContextMenuItem[]
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Where `ContextMenuItem` is:
|
|
719
|
+
```typescript
|
|
720
|
+
interface ContextMenuItem {
|
|
721
|
+
icon?: string; // Optional icon (emoji or text)
|
|
722
|
+
title: string; // Menu item text
|
|
723
|
+
isDisabled?: boolean; // Whether item is disabled
|
|
724
|
+
callback: () => void; // Action to perform
|
|
725
|
+
isDivider?: boolean; // Render as divider instead of item
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
#### contextMenuXOffset
|
|
730
|
+
Horizontal offset from cursor position (default: 8px).
|
|
731
|
+
|
|
732
|
+
#### contextMenuYOffset
|
|
733
|
+
Vertical offset from cursor position (default: 0px).
|
|
734
|
+
|
|
611
735
|
## 🏗️ Data Structure
|
|
612
736
|
|
|
613
737
|
The component expects hierarchical data with path-based organization:
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import Node from './Node.svelte';
|
|
4
4
|
import { type LTreeNode } from '../ltree/ltree-node.svelte.js';
|
|
5
5
|
import { createLTree } from '../ltree/ltree.svelte.js';
|
|
6
|
-
import { type Ltree, type InsertArrayResult } from '../ltree/types.js';
|
|
6
|
+
import { type Ltree, type InsertArrayResult, type ContextMenuItem } from '../ltree/types.js';
|
|
7
7
|
import { setContext, tick } from 'svelte';
|
|
8
8
|
|
|
9
9
|
// Context menu state
|
|
@@ -62,12 +62,14 @@
|
|
|
62
62
|
indexerBatchSize?: number | null | undefined;
|
|
63
63
|
indexerTimeout?: number | null | undefined;
|
|
64
64
|
shouldDisplayDebugInformation?: boolean;
|
|
65
|
+
shouldDisplayContextMenuInDebugMode?: boolean;
|
|
65
66
|
|
|
66
67
|
// EVENTS
|
|
67
68
|
onNodeClicked?: (node: LTreeNode<T>) => void;
|
|
68
69
|
onNodeDragStart?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
69
70
|
onNodeDragOver?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
70
71
|
onNodeDrop?: (node: LTreeNode<T>, draggedNode: LTreeNode<T>, event: DragEvent) => void;
|
|
72
|
+
contextMenuCallback?: (node: LTreeNode<T>) => ContextMenuItem[];
|
|
71
73
|
|
|
72
74
|
// VISUALS
|
|
73
75
|
bodyClass?: string | null | undefined;
|
|
@@ -78,11 +80,13 @@
|
|
|
78
80
|
leafIconClass?: string | null | undefined;
|
|
79
81
|
scrollHighlightTimeout?: number | null | undefined;
|
|
80
82
|
scrollHighlightClass?: string | null | undefined;
|
|
83
|
+
contextMenuXOffset?: number | null | undefined;
|
|
84
|
+
contextMenuYOffset?: number | null | undefined;
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
let {
|
|
84
88
|
treeId,
|
|
85
|
-
treePathSeparator,
|
|
89
|
+
treePathSeparator = '.',
|
|
86
90
|
|
|
87
91
|
// MAPPINGS
|
|
88
92
|
idMember,
|
|
@@ -125,12 +129,14 @@
|
|
|
125
129
|
indexerBatchSize = 25,
|
|
126
130
|
indexerTimeout = 50,
|
|
127
131
|
shouldDisplayDebugInformation = false,
|
|
132
|
+
shouldDisplayContextMenuInDebugMode = false,
|
|
128
133
|
|
|
129
134
|
// EVENTS
|
|
130
135
|
onNodeClicked,
|
|
131
136
|
onNodeDragStart,
|
|
132
137
|
onNodeDragOver,
|
|
133
138
|
onNodeDrop,
|
|
139
|
+
contextMenuCallback,
|
|
134
140
|
|
|
135
141
|
// VISUALS
|
|
136
142
|
bodyClass,
|
|
@@ -140,7 +146,9 @@
|
|
|
140
146
|
selectedNodeClass,
|
|
141
147
|
dragOverNodeClass,
|
|
142
148
|
scrollHighlightTimeout = 4000,
|
|
143
|
-
scrollHighlightClass = 'ltree-scroll-highlight'
|
|
149
|
+
scrollHighlightClass = 'ltree-scroll-highlight',
|
|
150
|
+
contextMenuXOffset = 8,
|
|
151
|
+
contextMenuYOffset = 0
|
|
144
152
|
}: Props = $props();
|
|
145
153
|
|
|
146
154
|
export async function expandNodes(nodePath: string) {
|
|
@@ -305,20 +313,22 @@
|
|
|
305
313
|
}
|
|
306
314
|
|
|
307
315
|
function _onNodeRightClicked(node: LTreeNode<T>, event: MouseEvent) {
|
|
308
|
-
if (!contextMenu) {
|
|
316
|
+
if (!contextMenu && !contextMenuCallback) {
|
|
309
317
|
return;
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
event.preventDefault();
|
|
313
321
|
contextMenuNode = node;
|
|
314
|
-
contextMenuX = event.clientX;
|
|
315
|
-
contextMenuY = event.clientY;
|
|
322
|
+
contextMenuX = event.clientX + contextMenuXOffset;
|
|
323
|
+
contextMenuY = event.clientY + contextMenuYOffset;
|
|
316
324
|
contextMenuVisible = true;
|
|
325
|
+
isDebugMenuActive = false; // This is a user-triggered menu, not debug menu
|
|
317
326
|
}
|
|
318
327
|
|
|
319
328
|
function closeContextMenu() {
|
|
320
329
|
contextMenuVisible = false;
|
|
321
330
|
contextMenuNode = null;
|
|
331
|
+
isDebugMenuActive = false;
|
|
322
332
|
}
|
|
323
333
|
|
|
324
334
|
function _onNodeDragStart(node: LTreeNode<T>, event: DragEvent) {
|
|
@@ -388,8 +398,8 @@
|
|
|
388
398
|
}
|
|
389
399
|
}
|
|
390
400
|
|
|
391
|
-
// Add global event listener for document clicks
|
|
392
|
-
$effect
|
|
401
|
+
// Add global event listener for document clicks and scroll events
|
|
402
|
+
$effect(() => {
|
|
393
403
|
if (contextMenuVisible) {
|
|
394
404
|
const handleGlobalClick = (event: MouseEvent) => {
|
|
395
405
|
const target = event.target as Element;
|
|
@@ -398,15 +408,58 @@
|
|
|
398
408
|
}
|
|
399
409
|
};
|
|
400
410
|
|
|
411
|
+
const handleGlobalScroll = (event?: Event) => {
|
|
412
|
+
if (shouldDisplayDebugInformation) {
|
|
413
|
+
console.log('Scroll/wheel event detected, closing context menu', event?.type);
|
|
414
|
+
}
|
|
415
|
+
closeContextMenu();
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// Add scroll listeners to both window and document to catch all scroll events
|
|
401
419
|
document.addEventListener('click', handleGlobalClick);
|
|
402
420
|
document.addEventListener('contextmenu', handleGlobalClick);
|
|
421
|
+
window.addEventListener('scroll', handleGlobalScroll, true);
|
|
422
|
+
document.addEventListener('scroll', handleGlobalScroll, true);
|
|
423
|
+
|
|
424
|
+
// Also listen for wheel events which might not trigger scroll
|
|
425
|
+
window.addEventListener('wheel', handleGlobalScroll, { passive: true });
|
|
403
426
|
|
|
404
427
|
return () => {
|
|
405
428
|
document.removeEventListener('click', handleGlobalClick);
|
|
406
429
|
document.removeEventListener('contextmenu', handleGlobalClick);
|
|
430
|
+
window.removeEventListener('scroll', handleGlobalScroll, true);
|
|
431
|
+
document.removeEventListener('scroll', handleGlobalScroll, true);
|
|
432
|
+
window.removeEventListener('wheel', handleGlobalScroll);
|
|
407
433
|
};
|
|
408
434
|
}
|
|
409
435
|
});
|
|
436
|
+
|
|
437
|
+
// Debug context menu - show context menu on second node for styling development
|
|
438
|
+
let isDebugMenuActive = $state(false);
|
|
439
|
+
|
|
440
|
+
$effect(() => {
|
|
441
|
+
if (shouldDisplayContextMenuInDebugMode && (contextMenu || contextMenuCallback) && tree?.tree && tree.tree.length > 1) {
|
|
442
|
+
// Find the second node in the tree
|
|
443
|
+
const secondNode = tree.tree[1];
|
|
444
|
+
if (secondNode) {
|
|
445
|
+
// Position the context menu at a fixed location for easy styling
|
|
446
|
+
contextMenuNode = secondNode;
|
|
447
|
+
contextMenuX = 200; // Fixed position for consistent styling work
|
|
448
|
+
contextMenuY = 100;
|
|
449
|
+
contextMenuVisible = true;
|
|
450
|
+
isDebugMenuActive = true;
|
|
451
|
+
|
|
452
|
+
if (shouldDisplayDebugInformation) {
|
|
453
|
+
console.log('Debug context menu displayed for node:', secondNode.data);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
} else if (!shouldDisplayContextMenuInDebugMode && isDebugMenuActive) {
|
|
457
|
+
// Only hide the context menu if it was opened by debug mode
|
|
458
|
+
contextMenuVisible = false;
|
|
459
|
+
contextMenuNode = null;
|
|
460
|
+
isDebugMenuActive = false;
|
|
461
|
+
}
|
|
462
|
+
});
|
|
410
463
|
</script>
|
|
411
464
|
|
|
412
465
|
<div>
|
|
@@ -471,9 +524,29 @@
|
|
|
471
524
|
{@render treeFooter?.()}
|
|
472
525
|
|
|
473
526
|
<!-- Context Menu -->
|
|
474
|
-
{#if contextMenuVisible &&
|
|
527
|
+
{#if contextMenuVisible && contextMenuNode}
|
|
475
528
|
<div class="ltree-context-menu" style="left: {contextMenuX}px; top: {contextMenuY}px;">
|
|
476
|
-
{
|
|
529
|
+
{#if contextMenuCallback}
|
|
530
|
+
{@const menuItems = contextMenuCallback(contextMenuNode)}
|
|
531
|
+
{#each menuItems as item}
|
|
532
|
+
{#if item.isDivider}
|
|
533
|
+
<div class="ltree-context-menu-divider"></div>
|
|
534
|
+
{:else}
|
|
535
|
+
<div
|
|
536
|
+
class="ltree-context-menu-item"
|
|
537
|
+
class:ltree-context-menu-item-disabled={item.isDisabled}
|
|
538
|
+
onclick={() => !item.isDisabled && item.callback()}
|
|
539
|
+
>
|
|
540
|
+
{#if item.icon}
|
|
541
|
+
<span class="ltree-context-menu-icon">{item.icon}</span>
|
|
542
|
+
{/if}
|
|
543
|
+
{item.title}
|
|
544
|
+
</div>
|
|
545
|
+
{/if}
|
|
546
|
+
{/each}
|
|
547
|
+
{:else if contextMenu}
|
|
548
|
+
{@render contextMenu(contextMenuNode, closeContextMenu)}
|
|
549
|
+
{/if}
|
|
477
550
|
</div>
|
|
478
551
|
{/if}
|
|
479
552
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Index, SearchOptions } from 'flexsearch';
|
|
2
2
|
import { type LTreeNode } from '../ltree/ltree-node.svelte.js';
|
|
3
|
-
import { type InsertArrayResult } from '../ltree/types.js';
|
|
3
|
+
import { type InsertArrayResult, type ContextMenuItem } from '../ltree/types.js';
|
|
4
4
|
declare function $$render<T>(): {
|
|
5
5
|
props: {
|
|
6
6
|
trieId?: string | null | undefined;
|
|
@@ -38,10 +38,12 @@ declare function $$render<T>(): {
|
|
|
38
38
|
indexerBatchSize?: number | null | undefined;
|
|
39
39
|
indexerTimeout?: number | null | undefined;
|
|
40
40
|
shouldDisplayDebugInformation?: boolean;
|
|
41
|
+
shouldDisplayContextMenuInDebugMode?: boolean;
|
|
41
42
|
onNodeClicked?: (node: LTreeNode<T>) => void;
|
|
42
43
|
onNodeDragStart?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
43
44
|
onNodeDragOver?: (node: LTreeNode<T>, event: DragEvent) => void;
|
|
44
45
|
onNodeDrop?: (node: LTreeNode<T>, draggedNode: LTreeNode<T>, event: DragEvent) => void;
|
|
46
|
+
contextMenuCallback?: (node: LTreeNode<T>) => ContextMenuItem[];
|
|
45
47
|
bodyClass?: string | null | undefined;
|
|
46
48
|
selectedNodeClass?: string | null | undefined;
|
|
47
49
|
dragOverNodeClass?: string | null | undefined;
|
|
@@ -50,6 +52,8 @@ declare function $$render<T>(): {
|
|
|
50
52
|
leafIconClass?: string | null | undefined;
|
|
51
53
|
scrollHighlightTimeout?: number | null | undefined;
|
|
52
54
|
scrollHighlightClass?: string | null | undefined;
|
|
55
|
+
contextMenuXOffset?: number | null | undefined;
|
|
56
|
+
contextMenuYOffset?: number | null | undefined;
|
|
53
57
|
};
|
|
54
58
|
exports: {
|
|
55
59
|
expandNodes: (nodePath: string) => Promise<void>;
|
package/dist/ltree/types.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { SearchOptions } from 'flexsearch';
|
|
2
2
|
import type { LTreeNode } from './ltree-node.svelte';
|
|
3
3
|
export type Tuple<T, U> = [T, U];
|
|
4
|
+
export interface ContextMenuItem {
|
|
5
|
+
icon?: string;
|
|
6
|
+
title: string;
|
|
7
|
+
isDisabled?: boolean;
|
|
8
|
+
callback: () => void;
|
|
9
|
+
isDivider?: boolean;
|
|
10
|
+
}
|
|
4
11
|
export interface InsertArrayResult<T> {
|
|
5
12
|
successful: number;
|
|
6
13
|
failed: Array<{
|
package/dist/styles/main.scss
CHANGED
|
@@ -278,7 +278,8 @@ $body-color: #212529 !default;
|
|
|
278
278
|
min-width: 150px;
|
|
279
279
|
|
|
280
280
|
.ltree-context-menu-item {
|
|
281
|
-
display:
|
|
281
|
+
display: flex;
|
|
282
|
+
align-items: center;
|
|
282
283
|
padding: 8px 16px;
|
|
283
284
|
border: none;
|
|
284
285
|
background: none;
|
|
@@ -293,7 +294,7 @@ $body-color: #212529 !default;
|
|
|
293
294
|
background-color: var(--ltree-light);
|
|
294
295
|
}
|
|
295
296
|
|
|
296
|
-
|
|
297
|
+
&.ltree-context-menu-item-disabled {
|
|
297
298
|
opacity: 0.5;
|
|
298
299
|
cursor: not-allowed;
|
|
299
300
|
}
|
|
@@ -307,6 +308,19 @@ $body-color: #212529 !default;
|
|
|
307
308
|
}
|
|
308
309
|
}
|
|
309
310
|
|
|
311
|
+
.ltree-context-menu-icon {
|
|
312
|
+
margin-right: 8px;
|
|
313
|
+
font-size: 12px;
|
|
314
|
+
width: 16px;
|
|
315
|
+
text-align: center;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.ltree-context-menu-divider {
|
|
319
|
+
height: 1px;
|
|
320
|
+
background-color: var(--ltree-border);
|
|
321
|
+
margin: 4px 0;
|
|
322
|
+
}
|
|
323
|
+
|
|
310
324
|
.ltree-context-menu-separator {
|
|
311
325
|
height: 1px;
|
|
312
326
|
background-color: var(--ltree-border);
|
package/dist/styles.css
CHANGED
|
@@ -210,7 +210,8 @@
|
|
|
210
210
|
min-width: 150px;
|
|
211
211
|
}
|
|
212
212
|
.ltree-context-menu .ltree-context-menu-item {
|
|
213
|
-
display:
|
|
213
|
+
display: flex;
|
|
214
|
+
align-items: center;
|
|
214
215
|
padding: 8px 16px;
|
|
215
216
|
border: none;
|
|
216
217
|
background: none;
|
|
@@ -224,7 +225,7 @@
|
|
|
224
225
|
.ltree-context-menu .ltree-context-menu-item:hover {
|
|
225
226
|
background-color: var(--ltree-light);
|
|
226
227
|
}
|
|
227
|
-
.ltree-context-menu .ltree-context-menu-item
|
|
228
|
+
.ltree-context-menu .ltree-context-menu-item.ltree-context-menu-item-disabled {
|
|
228
229
|
opacity: 0.5;
|
|
229
230
|
cursor: not-allowed;
|
|
230
231
|
}
|
|
@@ -234,6 +235,17 @@
|
|
|
234
235
|
.ltree-context-menu .ltree-context-menu-item.danger:hover {
|
|
235
236
|
background-color: rgba(var(--ltree-danger-rgb), 0.1);
|
|
236
237
|
}
|
|
238
|
+
.ltree-context-menu .ltree-context-menu-icon {
|
|
239
|
+
margin-right: 8px;
|
|
240
|
+
font-size: 12px;
|
|
241
|
+
width: 16px;
|
|
242
|
+
text-align: center;
|
|
243
|
+
}
|
|
244
|
+
.ltree-context-menu .ltree-context-menu-divider {
|
|
245
|
+
height: 1px;
|
|
246
|
+
background-color: var(--ltree-border);
|
|
247
|
+
margin: 4px 0;
|
|
248
|
+
}
|
|
237
249
|
.ltree-context-menu .ltree-context-menu-separator {
|
|
238
250
|
height: 1px;
|
|
239
251
|
background-color: var(--ltree-border);
|
package/dist/styles.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../src/lib/styles/main.scss"],"names":[],"mappings":";AAmCA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAID;EACC,aA5CA;;AA+CA;EACC;EACA,OAlCqB;EAmCrB;EACA;;;AAIF;EACC,aAxDA;EAyDA,WAvDqB;;AAyDrB;EACC;EACA;;AAGD;EACC;EACA;EACA,SAhE0B;EAiE1B,eAhEgC;EAiEhC;EACA;EACA;;AAEA;EACC,kBArEkB;;AAyEpB;EACC;;AAGD;EACC,OA7EuB;EA8EvB;EACA;EACA,cA7E8B;EA8E9B,WAhF2B;EAiF3B,OAhFuB;EAiFvB;EACA;;AAEA;EACC;;AAIF;EACC,cAxF4B;EAyF5B,WAxFyB;;AA2F1B;EACC,aA3F4B;EA4F5B,cA3F6B;;AA8F9B;EACC,WA9FyB;EA+FzB,OA9FqB;;AAiGtB;EACC,YAjGyB;;;AAsG3B;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;;AAEA;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;;AAKF;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;IAKC;;EAED;IACC;;EAED;IACC;;;AAKF;EACC;;AAEA;EACC;;;AAIF;EACC;EACA;EACA,YACC;;;AAKD;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;EACA;;AAGD;EACC;EACA;;;AAKF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAGD;EACC;;AAEA;EACC;;AAKH;EACC;EACA;EACA;;;AAKF;EACC,
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../src/lib/styles/main.scss"],"names":[],"mappings":";AAmCA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAID;EACC,aA5CA;;AA+CA;EACC;EACA,OAlCqB;EAmCrB;EACA;;;AAIF;EACC,aAxDA;EAyDA,WAvDqB;;AAyDrB;EACC;EACA;;AAGD;EACC;EACA;EACA,SAhE0B;EAiE1B,eAhEgC;EAiEhC;EACA;EACA;;AAEA;EACC,kBArEkB;;AAyEpB;EACC;;AAGD;EACC,OA7EuB;EA8EvB;EACA;EACA,cA7E8B;EA8E9B,WAhF2B;EAiF3B,OAhFuB;EAiFvB;EACA;;AAEA;EACC;;AAIF;EACC,cAxF4B;EAyF5B,WAxFyB;;AA2F1B;EACC,aA3F4B;EA4F5B,cA3F6B;;AA8F9B;EACC,WA9FyB;EA+FzB,OA9FqB;;AAiGtB;EACC,YAjGyB;;;AAsG3B;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;;AAEA;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;;AAKF;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;IAKC;;EAED;IACC;;EAED;IACC;;;AAKF;EACC;;AAEA;EACC;;;AAIF;EACC;EACA;EACA,YACC;;;AAKD;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACC;EACA;;AAGD;EACC;EACA;;;AAKF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAGD;EACC;;AAEA;EACC;;AAKH;EACC;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;;AAGD;EACC;EACA;EACA;;;AAKF;EACC,aAtUA;EAuUA;EACA;EACA;EACA;EACA;EACA;;AAGC;EACC;EACA;EACA;EACA;;AAEA;EACC;;AAIF;EACC;EACA;;AAIF;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMH;EACC;EACA;EACA;;;AAGD;EACC;;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;;AAKF;EAEC;EACA;EACA;EAGA","file":"styles.css"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keenmate/svelte-treeview",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev --port 17777",
|
|
6
6
|
"build": "vite build && npm run prepack",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
"drag-drop",
|
|
79
79
|
"search",
|
|
80
80
|
"flexsearch",
|
|
81
|
+
"context-menu",
|
|
81
82
|
"component",
|
|
82
83
|
"ui"
|
|
83
84
|
],
|