@keenmate/svelte-treeview 1.2.11 → 2.0.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/dist/Branch.svelte +15 -14
- package/dist/Branch.svelte.d.ts +2 -2
- package/dist/Checkbox.svelte +6 -4
- package/dist/Checkbox.svelte.d.ts +1 -1
- package/dist/TreeView.svelte +41 -38
- package/dist/TreeView.svelte.d.ts +2 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +25 -25
- package/dist/helpers/tree-helper.d.ts +5 -7
- package/dist/helpers/tree-helper.js +44 -40
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/menu/ContextMenu.svelte +1 -1
- package/dist/menu/ContextMenu.svelte.d.ts +1 -1
- package/dist/menu/Menu.svelte +23 -16
- package/dist/menu/MenuOption.svelte +15 -11
- package/dist/menu/menu.js +2 -2
- package/dist/providers/drag-drop-provider.d.ts +2 -2
- package/dist/providers/drag-drop-provider.js +1 -1
- package/dist/providers/movement-provider.d.ts +2 -2
- package/dist/providers/movement-provider.js +8 -7
- package/dist/providers/selection-provider.d.ts +2 -2
- package/dist/providers/selection-provider.js +15 -13
- package/dist/tree-styles.sass +119 -108
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/Branch.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<script>import { createEventDispatcher } from
|
|
2
|
-
import Checkbox from
|
|
3
|
-
import {
|
|
4
|
-
import { capturedKeys } from
|
|
1
|
+
<script>import { createEventDispatcher } from "svelte";
|
|
2
|
+
import Checkbox from "./Checkbox.svelte";
|
|
3
|
+
import { InsertionType, SelectionModes } from "./types.js";
|
|
4
|
+
import { capturedKeys } from "./constants.js";
|
|
5
5
|
const dispatch = createEventDispatcher();
|
|
6
6
|
export let tree;
|
|
7
7
|
export let treeId;
|
|
@@ -29,7 +29,7 @@ $: if (focusedNode && liElements[getNodeId(focusedNode)]) {
|
|
|
29
29
|
liElements[getNodeId(focusedNode)].focus();
|
|
30
30
|
}
|
|
31
31
|
function setExpansion(node, changeTo) {
|
|
32
|
-
dispatch(
|
|
32
|
+
dispatch("internal-expand", { node: node, changeTo });
|
|
33
33
|
}
|
|
34
34
|
function isExpanded(node, depth, expandToDepth) {
|
|
35
35
|
const nodeExpanded = node.expanded;
|
|
@@ -41,26 +41,26 @@ function isExpanded(node, depth, expandToDepth) {
|
|
|
41
41
|
}
|
|
42
42
|
//checkboxes
|
|
43
43
|
function selectionChanged(node) {
|
|
44
|
-
dispatch(
|
|
44
|
+
dispatch("internal-selectionChanged", { node: node });
|
|
45
45
|
}
|
|
46
46
|
// drag and drop
|
|
47
47
|
function handleDragStart(e, node) {
|
|
48
|
-
dispatch(
|
|
48
|
+
dispatch("internal-handleDragStart", { node: node, e: e });
|
|
49
49
|
}
|
|
50
50
|
function handleDragDrop(e, node, el) {
|
|
51
|
-
dispatch(
|
|
51
|
+
dispatch("internal-handleDragDrop", { node: node, event: e, element: el });
|
|
52
52
|
}
|
|
53
53
|
function handleDragOver(e, node, el, nest) {
|
|
54
|
-
dispatch(
|
|
54
|
+
dispatch("internal-handleDragOver", { node: node, event: e, element: el, nest });
|
|
55
55
|
}
|
|
56
56
|
function handleDragEnter(e, node, el) {
|
|
57
|
-
dispatch(
|
|
57
|
+
dispatch("internal-handleDragEnter", { node: node, event: e, element: el });
|
|
58
58
|
}
|
|
59
59
|
function handleDragEnd(e, node) {
|
|
60
|
-
dispatch(
|
|
60
|
+
dispatch("internal-handleDragEnd", { node: node, event: e });
|
|
61
61
|
}
|
|
62
62
|
function handleDragLeave(e, node, el) {
|
|
63
|
-
dispatch(
|
|
63
|
+
dispatch("internal-handleDragLeave", { node: node, event: e, element: el });
|
|
64
64
|
}
|
|
65
65
|
function handleKeyPress(e, node) {
|
|
66
66
|
if (!capturedKeys.includes(e.key)) {
|
|
@@ -68,12 +68,13 @@ function handleKeyPress(e, node) {
|
|
|
68
68
|
}
|
|
69
69
|
e.preventDefault();
|
|
70
70
|
e.stopPropagation();
|
|
71
|
-
dispatch(
|
|
71
|
+
dispatch("internal-keypress", { event: e, node });
|
|
72
72
|
}
|
|
73
73
|
function getHighlighMode(node, highlightedNode, insertionType) {
|
|
74
74
|
// return InsertionType.insertAbove;
|
|
75
|
-
if (highlightedNode?.path !== node.path)
|
|
75
|
+
if (highlightedNode?.path !== node.path) {
|
|
76
76
|
return InsertionType.none;
|
|
77
|
+
}
|
|
77
78
|
return insertionType;
|
|
78
79
|
}
|
|
79
80
|
</script>
|
package/dist/Branch.svelte.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import {
|
|
3
|
-
import type { TreeHelper } from
|
|
2
|
+
import { type CustomizableClasses, InsertionType, type Node, SelectionModes } from "./types.js";
|
|
3
|
+
import type { TreeHelper } from "./helpers/tree-helper.js";
|
|
4
4
|
declare const __propDef: {
|
|
5
5
|
props: {
|
|
6
6
|
tree: Node[];
|
package/dist/Checkbox.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script>import { createEventDispatcher } from
|
|
2
|
-
import { SelectionModes, VisualState } from
|
|
3
|
-
import { isSelectable } from
|
|
1
|
+
<script>import { createEventDispatcher } from "svelte";
|
|
2
|
+
import { SelectionModes, VisualState } from "./types.js";
|
|
3
|
+
import { isSelectable } from "./providers/selection-provider.js";
|
|
4
4
|
export let checkboxes;
|
|
5
5
|
export let recursive;
|
|
6
6
|
export let node;
|
|
@@ -10,7 +10,7 @@ export let readonly = false;
|
|
|
10
10
|
const dispatch = createEventDispatcher();
|
|
11
11
|
function onSelect(e, node) {
|
|
12
12
|
// e.preventDefault();
|
|
13
|
-
dispatch(
|
|
13
|
+
dispatch("select", { node });
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
16
16
|
</script>
|
|
@@ -35,6 +35,8 @@ function onSelect(e, node) {
|
|
|
35
35
|
type="checkbox"
|
|
36
36
|
on:click={null}
|
|
37
37
|
disabled={true}
|
|
38
|
+
checked={node.visualState === VisualState.selected}
|
|
39
|
+
indeterminate={node.visualState === VisualState.indeterminate}
|
|
38
40
|
class:invisible={hideDisabledCheckboxes}
|
|
39
41
|
/>
|
|
40
42
|
{/if}
|
package/dist/TreeView.svelte
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<script>import ContextMenu from
|
|
2
|
-
import { createEventDispatcher } from
|
|
3
|
-
import { defaultClasses, defaultPropNames } from
|
|
4
|
-
import { SelectionModes as SelectionModes
|
|
5
|
-
import { TreeHelper } from
|
|
6
|
-
import Branch from
|
|
7
|
-
import { SelectionProvider } from
|
|
8
|
-
import { DragDropProvider } from
|
|
9
|
-
import uniq from
|
|
10
|
-
import { calculateNewFocusedNode, parseMovementDirection } from
|
|
1
|
+
<script>import ContextMenu from "./menu/ContextMenu.svelte";
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
import { defaultClasses, defaultPropNames } from "./constants.js";
|
|
4
|
+
import { InsertionType, SelectionModes as SelectionModes } from "./types.js";
|
|
5
|
+
import { TreeHelper } from "./index.js";
|
|
6
|
+
import Branch from "./Branch.svelte";
|
|
7
|
+
import { SelectionProvider } from "./providers/selection-provider.js";
|
|
8
|
+
import { DragDropProvider } from "./providers/drag-drop-provider.js";
|
|
9
|
+
import uniq from "lodash.uniq";
|
|
10
|
+
import { calculateNewFocusedNode, parseMovementDirection } from "./providers/movement-provider.js";
|
|
11
11
|
const dispatch = createEventDispatcher();
|
|
12
12
|
export let treeId;
|
|
13
13
|
/**
|
|
@@ -36,7 +36,7 @@ export let readonly = false;
|
|
|
36
36
|
* Separator used to parse paths. It is used for getting node depth and getting parent node.
|
|
37
37
|
* Default is '.'.
|
|
38
38
|
*/
|
|
39
|
-
export let separator =
|
|
39
|
+
export let separator = ".";
|
|
40
40
|
/**
|
|
41
41
|
* only leaf nodes can be selected, non-leaf nodes only select/deselect its children.
|
|
42
42
|
* Their visual state is calculated based on their children
|
|
@@ -99,6 +99,7 @@ export let filter = null;
|
|
|
99
99
|
* Used mostly for debugging
|
|
100
100
|
*/
|
|
101
101
|
export let logger = null;
|
|
102
|
+
export let nodeSorter = null;
|
|
102
103
|
/*
|
|
103
104
|
* Drag and drop mode allows all nodes, that don't have dragDisabled property set to true
|
|
104
105
|
* to be dragged and dropped. By default you can only insert at same level node you are dropping on,
|
|
@@ -122,15 +123,16 @@ let highlightedNode = null;
|
|
|
122
123
|
let insertionType = InsertionType.none;
|
|
123
124
|
let focusedNode = null;
|
|
124
125
|
$: computedClasses = { ...defaultClasses, ...(customClasses ?? {}) };
|
|
125
|
-
$: dragAndDrop && console.warn(
|
|
126
|
+
$: dragAndDrop && console.warn("Drag and drop is not supported in this version");
|
|
126
127
|
$: helper = new TreeHelper({
|
|
127
|
-
separator
|
|
128
|
+
separator,
|
|
129
|
+
nodeSorter
|
|
128
130
|
});
|
|
129
131
|
$: dragAndDropProvider = new DragDropProvider(helper);
|
|
130
132
|
$: selectionProvider = new SelectionProvider(helper, recursiveSelection);
|
|
131
133
|
$: computedTree = computeTree(helper, selectionProvider, tree, filter, props, expandedPaths, value);
|
|
132
134
|
export function changeAllExpansion(changeTo) {
|
|
133
|
-
debugLog(
|
|
135
|
+
debugLog("changing expansion of every node to ", changeTo ? "expanded" : "collapsed");
|
|
134
136
|
if (changeTo) {
|
|
135
137
|
expandedPaths = computedTree.map((node) => node.path);
|
|
136
138
|
}
|
|
@@ -140,11 +142,11 @@ export function changeAllExpansion(changeTo) {
|
|
|
140
142
|
}
|
|
141
143
|
export function expandToNode(targetNodePath) {
|
|
142
144
|
if (!targetNodePath) {
|
|
143
|
-
console.warn(
|
|
145
|
+
console.warn("Cannot expand to node with null path");
|
|
144
146
|
return;
|
|
145
147
|
}
|
|
146
148
|
const parentPaths = helper.getParentsPaths(targetNodePath);
|
|
147
|
-
debugLog("expanding to node '" + targetNodePath + "'" +
|
|
149
|
+
debugLog("expanding to node '" + targetNodePath + "'" + " parents", parentPaths);
|
|
148
150
|
expandedPaths = uniq([...expandedPaths, ...parentPaths]);
|
|
149
151
|
}
|
|
150
152
|
/**
|
|
@@ -153,7 +155,7 @@ export function expandToNode(targetNodePath) {
|
|
|
153
155
|
*/
|
|
154
156
|
export function setNodeExpansion(nodePath, changeTo) {
|
|
155
157
|
if (!nodePath) {
|
|
156
|
-
console.warn(
|
|
158
|
+
console.warn("Cannot expand node with null path");
|
|
157
159
|
return;
|
|
158
160
|
}
|
|
159
161
|
if (changeTo === null) {
|
|
@@ -163,7 +165,7 @@ export function setNodeExpansion(nodePath, changeTo) {
|
|
|
163
165
|
}
|
|
164
166
|
export function setExpansions(expansions) {
|
|
165
167
|
if (!Array.isArray(expansions)) {
|
|
166
|
-
console.error(
|
|
168
|
+
console.error("expansions must be an array");
|
|
167
169
|
return;
|
|
168
170
|
}
|
|
169
171
|
expandedPaths = expansions;
|
|
@@ -183,12 +185,12 @@ export function focusFirstNode() {
|
|
|
183
185
|
return null;
|
|
184
186
|
}
|
|
185
187
|
focusedNode = rootChildren[0];
|
|
186
|
-
dispatch(
|
|
188
|
+
dispatch("focus", focusedNode);
|
|
187
189
|
return focusedNode;
|
|
188
190
|
}
|
|
189
191
|
function computeTree(helper, selectionProvider, userProvidedTree, filter, props, expandedPaths, value) {
|
|
190
192
|
if (!Array.isArray(userProvidedTree) || !Array.isArray(value)) {
|
|
191
|
-
console.error(
|
|
193
|
+
console.error("value and tree must be arrays!!");
|
|
192
194
|
return [];
|
|
193
195
|
}
|
|
194
196
|
const start = Date.now();
|
|
@@ -215,15 +217,15 @@ function onExpand(detail) {
|
|
|
215
217
|
handleCallback(node);
|
|
216
218
|
}
|
|
217
219
|
//expansion events
|
|
218
|
-
dispatch(
|
|
220
|
+
dispatch("expansion", {
|
|
219
221
|
node: node,
|
|
220
222
|
value: changeTo
|
|
221
223
|
});
|
|
222
224
|
if (changeTo) {
|
|
223
|
-
dispatch(
|
|
225
|
+
dispatch("expanded", node);
|
|
224
226
|
}
|
|
225
227
|
else {
|
|
226
|
-
dispatch(
|
|
228
|
+
dispatch("closed", node);
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
231
|
function handleCallback(node) {
|
|
@@ -235,10 +237,10 @@ function handleCallback(node) {
|
|
|
235
237
|
return;
|
|
236
238
|
}
|
|
237
239
|
if (loadChildrenAsync == null) {
|
|
238
|
-
console.warn(
|
|
240
|
+
console.warn("loadChildrenAsync is not set, but useCallback is set to true on node with path", node.path);
|
|
239
241
|
return;
|
|
240
242
|
}
|
|
241
|
-
debugLog(
|
|
243
|
+
debugLog("calling callback for node", node);
|
|
242
244
|
// TODO mark node as loaded and don't call callback again
|
|
243
245
|
// this is now responsibility of user
|
|
244
246
|
loadChildrenAsync(node);
|
|
@@ -248,23 +250,24 @@ function onSelectionChanged(detail) {
|
|
|
248
250
|
const nodePath = node.path;
|
|
249
251
|
const changeTo = !selectionProvider.isNodeSelected(node);
|
|
250
252
|
const newValue = selectionProvider.setSelection(computedTree, nodePath, changeTo, value);
|
|
251
|
-
debugLog("changing selection of node '", nodePath, "' to ", changeTo,
|
|
252
|
-
dispatch(
|
|
253
|
-
dispatch(
|
|
253
|
+
debugLog("changing selection of node '", nodePath, "' to ", changeTo, " returning value ", newValue);
|
|
254
|
+
dispatch("change", newValue);
|
|
255
|
+
dispatch("selection", {
|
|
254
256
|
node: node,
|
|
255
257
|
value: changeTo
|
|
256
258
|
});
|
|
257
259
|
if (changeTo) {
|
|
258
|
-
dispatch(
|
|
260
|
+
dispatch("selected", { node, value: newValue });
|
|
259
261
|
}
|
|
260
262
|
else {
|
|
261
|
-
dispatch(
|
|
263
|
+
dispatch("unselected", { node, value: newValue });
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
266
|
function openContextMenu(ce) {
|
|
265
267
|
const { e, node } = ce.detail;
|
|
266
|
-
if (!showContextMenu)
|
|
268
|
+
if (!showContextMenu) {
|
|
267
269
|
return;
|
|
270
|
+
}
|
|
268
271
|
e.preventDefault();
|
|
269
272
|
ctxMenu.onRightClick(e, node);
|
|
270
273
|
}
|
|
@@ -288,8 +291,8 @@ function onDragDrop({ detail: { node, event, element } }) {
|
|
|
288
291
|
return;
|
|
289
292
|
}
|
|
290
293
|
highlightedNode = null;
|
|
291
|
-
debugLog(
|
|
292
|
-
dispatch(
|
|
294
|
+
debugLog("DROPPED: ", draggedNode, "on", node);
|
|
295
|
+
dispatch("moved", {
|
|
293
296
|
node: draggedNode,
|
|
294
297
|
target: node,
|
|
295
298
|
insertType: insertionType
|
|
@@ -305,7 +308,7 @@ function onDragEnter({ detail: { node, event, element } }) {
|
|
|
305
308
|
if (!dragAndDropProvider.isDropAllowed(draggedNode, node)) {
|
|
306
309
|
return;
|
|
307
310
|
}
|
|
308
|
-
if (typeof dropDisabledCallback ===
|
|
311
|
+
if (typeof dropDisabledCallback === "function") {
|
|
309
312
|
// possible bug, if the promise is resolved, when user is over another node
|
|
310
313
|
dropDisabledCallback(draggedNode, node).then((dropDisabled) => {
|
|
311
314
|
if (!dropDisabled) {
|
|
@@ -343,19 +346,19 @@ function onKeyPress(detail) {
|
|
|
343
346
|
if (setExpansion !== null) {
|
|
344
347
|
onExpand({ node: node, changeTo: setExpansion });
|
|
345
348
|
}
|
|
346
|
-
dispatch(
|
|
349
|
+
dispatch("focus", node);
|
|
347
350
|
return;
|
|
348
351
|
}
|
|
349
|
-
if (event.key ===
|
|
352
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
350
353
|
onSelectionChanged({ node: targetNode });
|
|
351
354
|
return;
|
|
352
355
|
}
|
|
353
|
-
if (event.key ===
|
|
356
|
+
if (event.key === "Escape") {
|
|
354
357
|
focusedNode = null;
|
|
355
358
|
if (document.activeElement instanceof HTMLElement) {
|
|
356
359
|
document.activeElement.blur();
|
|
357
360
|
}
|
|
358
|
-
dispatch(
|
|
361
|
+
dispatch("focus-leave");
|
|
359
362
|
return;
|
|
360
363
|
}
|
|
361
364
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import {
|
|
2
|
+
import { type CustomizableClasses, type DragEnterCallback, type ExpandedCallback, type FilterFunction, type Node, type NodeId, type NodeSorter, type Props, type ProvidedTree, SelectionModes as SelectionModes } from "./types.js";
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
5
|
treeId: string;
|
|
@@ -74,6 +74,7 @@ declare const __propDef: {
|
|
|
74
74
|
* Log function that will be called when something happens in tree.
|
|
75
75
|
* Used mostly for debugging
|
|
76
76
|
*/ logger?: ((...data: any[]) => void) | null | undefined;
|
|
77
|
+
nodeSorter?: NodeSorter | null | undefined;
|
|
77
78
|
dragAndDrop?: boolean | undefined;
|
|
78
79
|
/**
|
|
79
80
|
* Callback that will be called when user drags above node.
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CustomizableClasses, HelperConfig, Props } from "./types.js";
|
|
2
2
|
export declare const defaultPropNames: Props;
|
|
3
3
|
export declare const defaultClasses: CustomizableClasses;
|
|
4
4
|
export declare const defaultConfig: HelperConfig;
|
package/dist/constants.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
export const defaultPropNames = {
|
|
2
|
-
nodePath:
|
|
3
|
-
nodeId:
|
|
4
|
-
hasChildren:
|
|
5
|
-
useCallback:
|
|
6
|
-
priority:
|
|
7
|
-
dragDisabled:
|
|
8
|
-
insertDisabled:
|
|
9
|
-
nestAllowed:
|
|
10
|
-
checkbox:
|
|
2
|
+
nodePath: "nodePath",
|
|
3
|
+
nodeId: "nodePath",
|
|
4
|
+
hasChildren: "hasChildren",
|
|
5
|
+
useCallback: "__useCallback",
|
|
6
|
+
priority: "priority",
|
|
7
|
+
dragDisabled: "dragDisabled",
|
|
8
|
+
insertDisabled: "insertDisabled",
|
|
9
|
+
nestAllowed: "nestAllowed",
|
|
10
|
+
checkbox: "checkbox"
|
|
11
11
|
};
|
|
12
12
|
export const defaultClasses = {
|
|
13
|
-
treeClass:
|
|
14
|
-
expandClass:
|
|
15
|
-
currentlyDraggedClass:
|
|
16
|
-
nodeClass:
|
|
17
|
-
expandIcon:
|
|
18
|
-
collapseIcon:
|
|
19
|
-
insertLineClass:
|
|
20
|
-
nestIcon:
|
|
13
|
+
treeClass: "treeview",
|
|
14
|
+
expandClass: "inserting-highlighted",
|
|
15
|
+
currentlyDraggedClass: "currently-dragged",
|
|
16
|
+
nodeClass: "",
|
|
17
|
+
expandIcon: "far fa-fw fa-plus-square",
|
|
18
|
+
collapseIcon: "far fa-fw fa-minus-square",
|
|
19
|
+
insertLineClass: "",
|
|
20
|
+
nestIcon: "fas fa-level-down-alt"
|
|
21
21
|
};
|
|
22
22
|
export const defaultConfig = {
|
|
23
|
-
separator:
|
|
23
|
+
separator: "."
|
|
24
24
|
};
|
|
25
25
|
export const capturedKeys = [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
"ArrowUp",
|
|
27
|
+
"ArrowDown",
|
|
28
|
+
"ArrowLeft",
|
|
29
|
+
"ArrowRight",
|
|
30
|
+
"Enter",
|
|
31
|
+
" ",
|
|
32
|
+
"Escape"
|
|
33
33
|
];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type FilterFunction, type HelperConfig, type Node, type Props, type Tree } from "../types.js";
|
|
2
2
|
export declare class TreeHelper {
|
|
3
3
|
config: HelperConfig;
|
|
4
4
|
constructor(config?: HelperConfig);
|
|
@@ -10,10 +10,7 @@ export declare class TreeHelper {
|
|
|
10
10
|
findNode(tree: Tree, nodePath: string): Node | null;
|
|
11
11
|
nodePathIsChild(nodePath: string): boolean;
|
|
12
12
|
getDirectChildren(tree: Tree, parentNodePath: string | null): Tree;
|
|
13
|
-
|
|
14
|
-
getAllLeafNodes(tree: Tree): Node[];
|
|
15
|
-
joinTrees(filteredTree: Tree, tree: Tree): Node[];
|
|
16
|
-
mergeTrees(oldTree: Tree, addedTree: Tree, nodePath?: string): Node[];
|
|
13
|
+
allChildren(tree: Tree, parentNodePath: string | null): Node[];
|
|
17
14
|
/** toggles expansion on
|
|
18
15
|
*/
|
|
19
16
|
changeExpansion(targetNodePath: string, changeTo: boolean, previousExpandedPaths: string[]): string[];
|
|
@@ -28,7 +25,8 @@ export declare class TreeHelper {
|
|
|
28
25
|
};
|
|
29
26
|
getParentsPaths(targetNodePath: string): string[];
|
|
30
27
|
getParents(tree: Tree, targetNode: Node): Node[];
|
|
31
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Sorts nodes if sorter override is specified
|
|
32
30
|
*/
|
|
33
|
-
|
|
31
|
+
sortNodes(tree: Tree): Tree;
|
|
34
32
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { defaultConfig } from '../constants.js';
|
|
1
|
+
import uniqueBy from "lodash.uniqby"; // used by tree merge
|
|
2
|
+
import { VisualState } from "../types.js";
|
|
3
|
+
import { defaultConfig } from "../constants.js";
|
|
5
4
|
export class TreeHelper {
|
|
6
5
|
config;
|
|
7
6
|
constructor(config = defaultConfig) {
|
|
@@ -35,24 +34,27 @@ export class TreeHelper {
|
|
|
35
34
|
markExpanded(tree, expandedPaths) {
|
|
36
35
|
{
|
|
37
36
|
tree.forEach((node) => {
|
|
38
|
-
node.expanded = expandedPaths.includes(node.path ??
|
|
37
|
+
node.expanded = expandedPaths.includes(node.path ?? "");
|
|
39
38
|
});
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
//#region basic helpers
|
|
43
42
|
getParentNodePath(nodePath) {
|
|
44
|
-
if (nodePath == null)
|
|
45
|
-
throw new Error(
|
|
43
|
+
if (nodePath == null) {
|
|
44
|
+
throw new Error("cannot get parent of root");
|
|
45
|
+
}
|
|
46
46
|
const separator = this.config.separator;
|
|
47
47
|
const parentPath = nodePath?.substring(0, nodePath.lastIndexOf(separator));
|
|
48
|
-
if (parentPath ===
|
|
48
|
+
if (parentPath === "") {
|
|
49
49
|
return null;
|
|
50
|
+
}
|
|
50
51
|
return parentPath ?? null;
|
|
51
52
|
}
|
|
52
53
|
isChildrenOf(parentNodePath, childrenNodePath) {
|
|
53
|
-
if (parentNodePath === childrenNodePath)
|
|
54
|
+
if (parentNodePath === childrenNodePath) {
|
|
54
55
|
return false;
|
|
55
|
-
|
|
56
|
+
}
|
|
57
|
+
return childrenNodePath?.startsWith(parentNodePath ?? "");
|
|
56
58
|
}
|
|
57
59
|
hasChildren(tree, nodePath) {
|
|
58
60
|
return tree?.find((x) => this.getParentNodePath(x.path) === nodePath);
|
|
@@ -62,31 +64,30 @@ export class TreeHelper {
|
|
|
62
64
|
}
|
|
63
65
|
nodePathIsChild(nodePath) {
|
|
64
66
|
const separator = this.config.separator;
|
|
65
|
-
|
|
66
|
-
return includesSeparator;
|
|
67
|
+
return nodePath?.includes(separator);
|
|
67
68
|
}
|
|
68
69
|
getDirectChildren(tree, parentNodePath) {
|
|
69
70
|
const children = tree.filter((node) => !parentNodePath
|
|
70
71
|
? !this.nodePathIsChild(node.path)
|
|
71
72
|
: this.getParentNodePath(node.path) === parentNodePath);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
mergeTrees(oldTree, addedTree, nodePath = 'nodePath') {
|
|
88
|
-
|
|
89
|
-
}
|
|
73
|
+
return this.sortNodes(children);
|
|
74
|
+
}
|
|
75
|
+
allChildren(tree, parentNodePath) {
|
|
76
|
+
return tree.filter((node) => this.isChildrenOf(parentNodePath, node.path));
|
|
77
|
+
}
|
|
78
|
+
// getAllLeafNodes(tree: Tree) {
|
|
79
|
+
// return tree.filter((node) => {
|
|
80
|
+
// return node.hasChildren !== true;
|
|
81
|
+
// });
|
|
82
|
+
// }
|
|
83
|
+
//
|
|
84
|
+
// joinTrees(filteredTree: Tree, tree: Tree) {
|
|
85
|
+
// return tree.map((node) => this.findNode(filteredTree, node.path) || node);
|
|
86
|
+
// }
|
|
87
|
+
//
|
|
88
|
+
// mergeTrees(oldTree: Tree, addedTree: Tree, nodePath = 'nodePath') {
|
|
89
|
+
// return orderBy(addedTree, oldTree, nodePath);
|
|
90
|
+
// }
|
|
90
91
|
/** toggles expansion on
|
|
91
92
|
*/
|
|
92
93
|
changeExpansion(targetNodePath, changeTo, previousExpandedPaths) {
|
|
@@ -107,15 +108,17 @@ export class TreeHelper {
|
|
|
107
108
|
}
|
|
108
109
|
//based on number of dots
|
|
109
110
|
getDepthLevel(nodePath) {
|
|
110
|
-
if (nodePath == null)
|
|
111
|
+
if (nodePath == null) {
|
|
111
112
|
return 0;
|
|
113
|
+
}
|
|
112
114
|
const separator = this.config.separator;
|
|
113
115
|
return nodePath.split(separator).length - 1;
|
|
114
116
|
}
|
|
115
117
|
//#endregion
|
|
116
118
|
searchTree(tree, filter) {
|
|
117
|
-
if (!filter)
|
|
119
|
+
if (!filter) {
|
|
118
120
|
return { count: tree.length, tree };
|
|
121
|
+
}
|
|
119
122
|
const filteredNodes = tree.filter(filter);
|
|
120
123
|
const resultNodes = [];
|
|
121
124
|
// add all parents from each node
|
|
@@ -133,7 +136,7 @@ export class TreeHelper {
|
|
|
133
136
|
// TODO refactor
|
|
134
137
|
let nodePath = targetNodePath;
|
|
135
138
|
// get all parents
|
|
136
|
-
while (nodePath !== null && nodePath !==
|
|
139
|
+
while (nodePath !== null && nodePath !== "") {
|
|
137
140
|
nodePath = this.getParentNodePath(nodePath);
|
|
138
141
|
if (nodePath === null) {
|
|
139
142
|
break;
|
|
@@ -148,14 +151,15 @@ export class TreeHelper {
|
|
|
148
151
|
}
|
|
149
152
|
const parentsPaths = this.getParentsPaths(targetNode.path);
|
|
150
153
|
//find nodes for given ids
|
|
151
|
-
|
|
152
|
-
return parentNodes;
|
|
154
|
+
return tree.filter((node) => parentsPaths.some((parentNodePath) => node.path === parentNodePath));
|
|
153
155
|
}
|
|
154
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* Sorts nodes if sorter override is specified
|
|
155
158
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
sortNodes(tree) {
|
|
160
|
+
if (!this.config.nodeSorter) {
|
|
161
|
+
return tree;
|
|
162
|
+
}
|
|
163
|
+
return tree.slice().sort(this.config.nodeSorter);
|
|
160
164
|
}
|
|
161
165
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export { TreeHelper } from
|
|
3
|
-
export { default as TreeView } from
|
|
4
|
-
export { default as MenuDivider } from
|
|
5
|
-
export { default as MenuOption } from
|
|
6
|
-
export * from
|
|
1
|
+
export * from "./constants.js";
|
|
2
|
+
export { TreeHelper } from "./helpers/tree-helper.js";
|
|
3
|
+
export { default as TreeView } from "./TreeView.svelte";
|
|
4
|
+
export { default as MenuDivider } from "./menu/MenuDivider.svelte";
|
|
5
|
+
export { default as MenuOption } from "./menu/MenuOption.svelte";
|
|
6
|
+
export * from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export { TreeHelper } from
|
|
3
|
-
export { default as TreeView } from
|
|
4
|
-
export { default as MenuDivider } from
|
|
5
|
-
export { default as MenuOption } from
|
|
6
|
-
export * from
|
|
1
|
+
export * from "./constants.js";
|
|
2
|
+
export { TreeHelper } from "./helpers/tree-helper.js";
|
|
3
|
+
export { default as TreeView } from "./TreeView.svelte";
|
|
4
|
+
export { default as MenuDivider } from "./menu/MenuDivider.svelte";
|
|
5
|
+
export { default as MenuOption } from "./menu/MenuOption.svelte";
|
|
6
|
+
export * from "./types.js";
|
package/dist/menu/Menu.svelte
CHANGED
|
@@ -3,32 +3,39 @@
|
|
|
3
3
|
<script>
|
|
4
4
|
// @ts-nocheck
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import {createEventDispatcher, setContext} from "svelte"
|
|
7
|
+
import {fade} from "svelte/transition"
|
|
8
|
+
import {key} from "./menu.js"
|
|
9
9
|
|
|
10
|
-
export let x
|
|
11
|
-
export let y
|
|
10
|
+
export let x
|
|
11
|
+
export let y
|
|
12
12
|
|
|
13
13
|
// whenever x and y is changed, restrict box to be within bounds
|
|
14
14
|
$: (() => {
|
|
15
|
-
if (!menuEl)
|
|
15
|
+
if (!menuEl) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
16
18
|
|
|
17
|
-
const rect = menuEl.getBoundingClientRect()
|
|
18
|
-
x
|
|
19
|
-
if (y > window.innerHeight - rect.height)
|
|
20
|
-
|
|
19
|
+
const rect = menuEl.getBoundingClientRect()
|
|
20
|
+
x = Math.min(window.innerWidth - rect.width, x)
|
|
21
|
+
if (y > window.innerHeight - rect.height) {
|
|
22
|
+
y -= rect.height
|
|
23
|
+
}
|
|
24
|
+
})(x, y)
|
|
21
25
|
|
|
22
|
-
const dispatch = createEventDispatcher()
|
|
26
|
+
const dispatch = createEventDispatcher()
|
|
23
27
|
|
|
24
28
|
setContext(key, {
|
|
25
|
-
dispatchClick: () => dispatch(
|
|
26
|
-
})
|
|
29
|
+
dispatchClick: () => dispatch("click")
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
let menuEl
|
|
27
33
|
|
|
28
|
-
let menuEl;
|
|
29
34
|
function onPageClick(e) {
|
|
30
|
-
if (e.target === menuEl || menuEl.contains(e.target))
|
|
31
|
-
|
|
35
|
+
if (e.target === menuEl || menuEl.contains(e.target)) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
dispatch("clickoutside")
|
|
32
39
|
}
|
|
33
40
|
</script>
|
|
34
41
|
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
// @ts-nocheck
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import {createEventDispatcher, getContext} from "svelte"
|
|
5
|
+
import {key} from "./menu.js"
|
|
6
6
|
|
|
7
|
-
export let isDisabled = false
|
|
8
|
-
export let text
|
|
7
|
+
export let isDisabled = false
|
|
8
|
+
export let text = ""
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const dispatch = createEventDispatcher();
|
|
10
|
+
const dispatch = createEventDispatcher()
|
|
12
11
|
|
|
13
|
-
const {
|
|
12
|
+
const {dispatchClick} = getContext(key)
|
|
14
13
|
|
|
15
14
|
const handleClick = (e) => {
|
|
16
|
-
if (isDisabled)
|
|
15
|
+
if (isDisabled) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
17
18
|
|
|
18
|
-
dispatch(
|
|
19
|
-
dispatchClick()
|
|
20
|
-
}
|
|
19
|
+
dispatch("click")
|
|
20
|
+
dispatchClick()
|
|
21
|
+
}
|
|
21
22
|
</script>
|
|
22
23
|
|
|
23
24
|
<div class:disabled={isDisabled} on:click={handleClick} on:keydown={handleClick} role="button" tabindex="">
|
|
@@ -37,12 +38,15 @@
|
|
|
37
38
|
align-items: center;
|
|
38
39
|
grid-gap: 5px;
|
|
39
40
|
}
|
|
41
|
+
|
|
40
42
|
div:hover {
|
|
41
43
|
background: #0002;
|
|
42
44
|
}
|
|
45
|
+
|
|
43
46
|
div.disabled {
|
|
44
47
|
color: #0006;
|
|
45
48
|
}
|
|
49
|
+
|
|
46
50
|
div.disabled:hover {
|
|
47
51
|
background: white;
|
|
48
52
|
}
|
package/dist/menu/menu.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const key = {}
|
|
1
|
+
const key = {}
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export {key}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TreeHelper } from
|
|
2
|
-
import { type Node
|
|
1
|
+
import type { TreeHelper } from "../helpers/tree-helper.js";
|
|
2
|
+
import { InsertionType, type Node } from "../types.js";
|
|
3
3
|
export declare class DragDropProvider {
|
|
4
4
|
helper: TreeHelper;
|
|
5
5
|
constructor(treeHelper: TreeHelper);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TreeHelper } from
|
|
2
|
-
import { KeyboardMovement as MovementDirection, type Node } from
|
|
1
|
+
import type { TreeHelper } from "../helpers/tree-helper.js";
|
|
2
|
+
import { KeyboardMovement as MovementDirection, type Node } from "../types.js";
|
|
3
3
|
export declare function calculateNewFocusedNode(helper: TreeHelper, tree: Node[], targetNode: Node, movementDirection: MovementDirection): {
|
|
4
4
|
node: Node;
|
|
5
5
|
setExpansion: boolean | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KeyboardMovement as MovementDirection } from
|
|
1
|
+
import { KeyboardMovement as MovementDirection } from "../types.js";
|
|
2
2
|
export function calculateNewFocusedNode(helper, tree, targetNode, movementDirection) {
|
|
3
3
|
// TODO this could use some refactoring
|
|
4
4
|
const parentNodePath = helper.getParentNodePath(targetNode.path);
|
|
@@ -66,7 +66,7 @@ export function calculateNewFocusedNode(helper, tree, targetNode, movementDirect
|
|
|
66
66
|
const parentNode = helper.findNode(tree, parentNodePath);
|
|
67
67
|
// assertion
|
|
68
68
|
if (!parentNode) {
|
|
69
|
-
console.warn(
|
|
69
|
+
console.warn("Parent node not found, this should never happen");
|
|
70
70
|
return wrapReturn(targetNode);
|
|
71
71
|
}
|
|
72
72
|
return wrapReturn(parentNode);
|
|
@@ -75,13 +75,13 @@ export function calculateNewFocusedNode(helper, tree, targetNode, movementDirect
|
|
|
75
75
|
}
|
|
76
76
|
export function parseMovementDirection(key) {
|
|
77
77
|
switch (key) {
|
|
78
|
-
case
|
|
78
|
+
case "ArrowRight":
|
|
79
79
|
return MovementDirection.Right;
|
|
80
|
-
case
|
|
80
|
+
case "ArrowLeft":
|
|
81
81
|
return MovementDirection.Left;
|
|
82
|
-
case
|
|
82
|
+
case "ArrowDown":
|
|
83
83
|
return MovementDirection.Down;
|
|
84
|
-
case
|
|
84
|
+
case "ArrowUp":
|
|
85
85
|
return MovementDirection.Up;
|
|
86
86
|
default:
|
|
87
87
|
return null;
|
|
@@ -95,7 +95,8 @@ function getRelativeSibling(helper, tree, node, relativeIndex) {
|
|
|
95
95
|
const parentDirectChildren = helper.getDirectChildren(tree, parentNodePath);
|
|
96
96
|
const nodeIndex = parentDirectChildren.findIndex((x) => x.path === node.path);
|
|
97
97
|
const siblingIndex = nodeIndex + relativeIndex;
|
|
98
|
-
if (siblingIndex < 0 || siblingIndex >= parentDirectChildren.length)
|
|
98
|
+
if (siblingIndex < 0 || siblingIndex >= parentDirectChildren.length) {
|
|
99
99
|
return null;
|
|
100
|
+
}
|
|
100
101
|
return parentDirectChildren[siblingIndex];
|
|
101
102
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TreeHelper } from
|
|
2
|
-
import {
|
|
1
|
+
import type { TreeHelper } from "../helpers/tree-helper.js";
|
|
2
|
+
import { type Node, type NodeId, SelectionModes, type Tree, type TreeVisualStates } from "../types.js";
|
|
3
3
|
export declare class SelectionProvider {
|
|
4
4
|
helper: TreeHelper;
|
|
5
5
|
recursiveMode: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SelectionModes, VisualState } from
|
|
1
|
+
import { SelectionModes, VisualState } from "../types.js";
|
|
2
2
|
export class SelectionProvider {
|
|
3
3
|
helper;
|
|
4
4
|
recursiveMode;
|
|
@@ -9,13 +9,13 @@ export class SelectionProvider {
|
|
|
9
9
|
markSelected(tree, selectedNodeIds) {
|
|
10
10
|
const visualStates = this.computeVisualStates(tree, selectedNodeIds);
|
|
11
11
|
tree.forEach((node) => {
|
|
12
|
-
if (selectedNodeIds.includes(node.id ??
|
|
12
|
+
if (selectedNodeIds.includes(node.id ?? "")) {
|
|
13
13
|
node.selected = true;
|
|
14
14
|
node.visualState = VisualState.selected;
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
node.selected = false;
|
|
18
|
-
const visualState = visualStates[node.id ??
|
|
18
|
+
const visualState = visualStates[node.id ?? ""];
|
|
19
19
|
if (!visualState) {
|
|
20
20
|
node.visualState = VisualState.notSelected;
|
|
21
21
|
}
|
|
@@ -27,8 +27,9 @@ export class SelectionProvider {
|
|
|
27
27
|
}
|
|
28
28
|
isSelected(nodeId, visualStates, selectedNodeIds) {
|
|
29
29
|
const selected = selectedNodeIds.includes(nodeId);
|
|
30
|
-
if (selected)
|
|
30
|
+
if (selected) {
|
|
31
31
|
return true;
|
|
32
|
+
}
|
|
32
33
|
const visualState = visualStates[nodeId];
|
|
33
34
|
return visualState === VisualState.selected;
|
|
34
35
|
}
|
|
@@ -47,10 +48,10 @@ export class SelectionProvider {
|
|
|
47
48
|
else {
|
|
48
49
|
if (!node) {
|
|
49
50
|
// throw new Error('Node not found ' + nodePath);
|
|
50
|
-
console.warn(
|
|
51
|
+
console.warn("Node %s doesnt exits", nodePath);
|
|
51
52
|
return oldSelection;
|
|
52
53
|
}
|
|
53
|
-
const nodeId = node.id ??
|
|
54
|
+
const nodeId = node.id ?? "";
|
|
54
55
|
// prevent double selection
|
|
55
56
|
const filteredSelection = oldSelection.filter((x) => x !== nodeId);
|
|
56
57
|
if (changeTo === false) {
|
|
@@ -68,14 +69,15 @@ export class SelectionProvider {
|
|
|
68
69
|
rootELements.forEach((node) => {
|
|
69
70
|
if (node.hasChildren == true) {
|
|
70
71
|
const result = this.computeVisualStateRecursively(tree, node, selectedNodeIds, visualStates);
|
|
71
|
-
visualStates[node.id ??
|
|
72
|
+
visualStates[node.id ?? ""] = result.state;
|
|
72
73
|
}
|
|
73
74
|
});
|
|
74
75
|
return visualStates;
|
|
75
76
|
}
|
|
76
77
|
computeVisualState(directChildrenVisualStates) {
|
|
77
|
-
if (!directChildrenVisualStates || directChildrenVisualStates?.length == 0)
|
|
78
|
+
if (!directChildrenVisualStates || directChildrenVisualStates?.length == 0) {
|
|
78
79
|
return VisualState.selected;
|
|
80
|
+
}
|
|
79
81
|
//if every child is selected or vs=true return true
|
|
80
82
|
if (directChildrenVisualStates.every((state) => state === VisualState.selected)) {
|
|
81
83
|
return VisualState.selected;
|
|
@@ -101,14 +103,14 @@ export class SelectionProvider {
|
|
|
101
103
|
// using recustion compute from leaft nodes to root
|
|
102
104
|
directChildren.forEach((child) => {
|
|
103
105
|
if (!child.hasChildren) {
|
|
104
|
-
const childState = selectedNodeIds.includes(child.id ??
|
|
106
|
+
const childState = selectedNodeIds.includes(child.id ?? "")
|
|
105
107
|
? VisualState.selected
|
|
106
108
|
: VisualState.notSelected;
|
|
107
109
|
directChildrenStates.push(childState);
|
|
108
110
|
return;
|
|
109
111
|
}
|
|
110
112
|
const result = this.computeVisualStateRecursively(tree, child, selectedNodeIds, visualStates);
|
|
111
|
-
visualStates[child.id ??
|
|
113
|
+
visualStates[child.id ?? ""] = result.state;
|
|
112
114
|
if (!result.ignore) {
|
|
113
115
|
directChildrenStates.push(result.state);
|
|
114
116
|
}
|
|
@@ -121,7 +123,7 @@ export class SelectionProvider {
|
|
|
121
123
|
let newSelection = [...oldSelection];
|
|
122
124
|
tree.forEach((node) => {
|
|
123
125
|
// match itself and all children
|
|
124
|
-
if (node.path?.startsWith(parentNodePath ? parentNodePath + this.helper.config.separator :
|
|
126
|
+
if (node.path?.startsWith(parentNodePath ? parentNodePath + this.helper.config.separator : "")) {
|
|
125
127
|
//don't change if not selectable
|
|
126
128
|
if (!isSelectable(node, SelectionModes.all)) {
|
|
127
129
|
return;
|
|
@@ -131,9 +133,9 @@ export class SelectionProvider {
|
|
|
131
133
|
return;
|
|
132
134
|
}
|
|
133
135
|
// prevent double selection
|
|
134
|
-
newSelection = newSelection.filter((x) => x !== node.id ??
|
|
136
|
+
newSelection = newSelection.filter((x) => x !== (node.id ?? ""));
|
|
135
137
|
if (changeTo === true) {
|
|
136
|
-
newSelection.push(node.id ??
|
|
138
|
+
newSelection.push(node.id ?? "");
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
});
|
package/dist/tree-styles.sass
CHANGED
|
@@ -1,110 +1,121 @@
|
|
|
1
|
-
|
|
2
1
|
$treeview-lines: solid black 1px
|
|
3
2
|
.treeview
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
3
|
+
padding: 0
|
|
4
|
+
//will show lines if you set show-lines to root element
|
|
5
|
+
&.show-lines
|
|
6
|
+
ul
|
|
7
|
+
&:before
|
|
8
|
+
border-left: $treeview-lines
|
|
9
|
+
|
|
10
|
+
li:before
|
|
11
|
+
border-top: $treeview-lines
|
|
12
|
+
margin: 0
|
|
13
|
+
padding: 0
|
|
14
|
+
list-style: none
|
|
15
|
+
|
|
16
|
+
ul, li
|
|
17
|
+
margin: 0
|
|
18
|
+
padding: 0
|
|
19
|
+
list-style: none
|
|
20
|
+
|
|
21
|
+
ul
|
|
22
|
+
margin-left: 0.4em
|
|
23
|
+
position: relative
|
|
24
|
+
margin-left: .3em
|
|
25
|
+
|
|
26
|
+
&:before
|
|
27
|
+
content: ""
|
|
28
|
+
display: block
|
|
29
|
+
width: 0
|
|
30
|
+
position: absolute
|
|
31
|
+
top: 0
|
|
32
|
+
bottom: 0
|
|
33
|
+
left: 0
|
|
34
|
+
|
|
35
|
+
li:before
|
|
36
|
+
content: ""
|
|
37
|
+
display: block
|
|
38
|
+
width: 10px
|
|
39
|
+
height: 0
|
|
40
|
+
margin-top: -1px
|
|
41
|
+
position: absolute
|
|
42
|
+
top: 0.8em
|
|
43
|
+
left: 0
|
|
44
|
+
|
|
45
|
+
li:not(.has-children):before
|
|
46
|
+
width: 26px
|
|
47
|
+
|
|
48
|
+
li:last-child:before
|
|
49
|
+
background: #fff
|
|
50
|
+
height: auto
|
|
51
|
+
top: 1em
|
|
52
|
+
bottom: 0
|
|
53
|
+
|
|
54
|
+
li
|
|
55
|
+
margin: 0
|
|
56
|
+
padding: 0 0.8em
|
|
57
|
+
color: #555
|
|
58
|
+
font-weight: 700
|
|
59
|
+
position: relative
|
|
60
|
+
|
|
61
|
+
.tree-item
|
|
62
|
+
display: flex
|
|
63
|
+
column-gap: 0.4em
|
|
64
|
+
align-items: center
|
|
65
|
+
padding: 4px 0
|
|
66
|
+
|
|
67
|
+
.no-arrow
|
|
68
|
+
padding-left: .5rem
|
|
69
|
+
|
|
70
|
+
.arrow
|
|
71
|
+
cursor: pointer
|
|
72
|
+
display: inline-block
|
|
73
|
+
|
|
74
|
+
.arrowDown
|
|
75
|
+
transform: rotate(90deg)
|
|
76
|
+
|
|
77
|
+
.invisible
|
|
78
|
+
visibility: hidden
|
|
79
|
+
|
|
80
|
+
.inserting-highlighted
|
|
81
|
+
color: red
|
|
82
|
+
|
|
83
|
+
.hover
|
|
84
|
+
font-weight: bold
|
|
85
|
+
|
|
86
|
+
.insert-line
|
|
87
|
+
position: absolute
|
|
88
|
+
left: 0
|
|
89
|
+
z-index: 99
|
|
90
|
+
height: 2px
|
|
91
|
+
width: 200px
|
|
92
|
+
background-color: blue
|
|
93
|
+
display: block
|
|
94
|
+
border-radius: 3px
|
|
95
|
+
margin-left: 28px
|
|
96
|
+
pointer-events: none
|
|
97
|
+
//! this is needed to fix flickering issue
|
|
98
|
+
// margin-bottom: -2px
|
|
99
|
+
// margin-top: -2px
|
|
100
|
+
.insert-line-child
|
|
101
|
+
margin-left: calc(28px + 5em)
|
|
102
|
+
background-color: red
|
|
103
|
+
height: 6px
|
|
104
|
+
|
|
105
|
+
.insert-line-wrapper
|
|
106
|
+
position: relative
|
|
107
|
+
|
|
108
|
+
.currently-dragged
|
|
109
|
+
color: LightGray
|
|
110
|
+
|
|
111
|
+
.pointer-cursor
|
|
112
|
+
cursor: grab
|
|
113
|
+
|
|
114
|
+
.expansion-button
|
|
115
|
+
all: unset
|
|
116
|
+
|
|
117
|
+
.fixed-icon
|
|
118
|
+
text-align: center
|
|
119
|
+
width: 1.25em
|
|
120
|
+
// fix deformation on small screens
|
|
121
|
+
min-width: 1.25em
|
package/dist/types.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ export type BeforeMovedCallback = (draggedNode: Node, oldParent: Node, newParent
|
|
|
63
63
|
export type ExpandedCallback = (node: Node) => Promise<void>;
|
|
64
64
|
export type HelperConfig = {
|
|
65
65
|
separator: string;
|
|
66
|
+
nodeSorter?: NodeSorter | null;
|
|
66
67
|
};
|
|
67
68
|
export declare enum InsertionType {
|
|
68
69
|
nest = "nest",
|
|
@@ -81,3 +82,4 @@ export declare enum KeyboardMovement {
|
|
|
81
82
|
Left = "ArrowLeft",
|
|
82
83
|
Right = "ArrowRight"
|
|
83
84
|
}
|
|
85
|
+
export type NodeSorter = (left: Node, right: Node) => number;
|