tree-element 0.4.0 → 0.4.1
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 +22 -20
- package/lib/dataLoader.d.ts.map +1 -1
- package/lib/dataLoader.js +4 -1
- package/lib/dataLoader.js.map +1 -1
- package/lib/dragAndDropHandler/generateHitAreas.d.ts.map +1 -1
- package/lib/dragAndDropHandler/generateHitAreas.js +3 -2
- package/lib/dragAndDropHandler/generateHitAreas.js.map +1 -1
- package/lib/dragAndDropHandler/index.d.ts +2 -4
- package/lib/dragAndDropHandler/index.d.ts.map +1 -1
- package/lib/dragAndDropHandler/index.js +2 -9
- package/lib/dragAndDropHandler/index.js.map +1 -1
- package/lib/elementsRenderer.d.ts +7 -2
- package/lib/elementsRenderer.d.ts.map +1 -1
- package/lib/elementsRenderer.js +70 -23
- package/lib/elementsRenderer.js.map +1 -1
- package/lib/events.d.ts +13 -7
- package/lib/events.d.ts.map +1 -1
- package/lib/folderOpenState.d.ts +8 -0
- package/lib/folderOpenState.d.ts.map +1 -0
- package/lib/folderOpenState.js +22 -0
- package/lib/folderOpenState.js.map +1 -0
- package/lib/index.d.ts +17 -16
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +93 -49
- package/lib/index.js.map +1 -1
- package/lib/keyHandler.d.ts +2 -0
- package/lib/keyHandler.d.ts.map +1 -1
- package/lib/keyHandler.js +18 -0
- package/lib/keyHandler.js.map +1 -1
- package/lib/mouseHandler.d.ts.map +1 -1
- package/lib/mouseHandler.js +12 -12
- package/lib/mouseHandler.js.map +1 -1
- package/lib/node.d.ts +12 -10
- package/lib/node.d.ts.map +1 -1
- package/lib/node.js +12 -10
- package/lib/node.js.map +1 -1
- package/lib/nodeElement/folderElement.d.ts +7 -5
- package/lib/nodeElement/folderElement.d.ts.map +1 -1
- package/lib/nodeElement/folderElement.js +33 -53
- package/lib/nodeElement/folderElement.js.map +1 -1
- package/lib/options.d.ts +19 -17
- package/lib/options.d.ts.map +1 -1
- package/lib/options.js +12 -0
- package/lib/options.js.map +1 -0
- package/lib/saveStateHandler.d.ts.map +1 -1
- package/lib/saveStateHandler.js +6 -6
- package/lib/saveStateHandler.js.map +1 -1
- package/lib/selectNodeHandler.d.ts.map +1 -1
- package/lib/selectNodeHandler.js +13 -1
- package/lib/selectNodeHandler.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +35 -29
- package/src/dataLoader.ts +3 -1
- package/src/dragAndDropHandler/generateHitAreas.ts +3 -2
- package/src/dragAndDropHandler/index.ts +3 -17
- package/src/elementsRenderer.ts +84 -33
- package/src/events.ts +13 -7
- package/src/folderOpenState.ts +38 -0
- package/src/index.ts +109 -59
- package/src/keyHandler.ts +20 -0
- package/src/mouseHandler.ts +15 -13
- package/src/node.ts +12 -10
- package/src/nodeElement/folderElement.ts +45 -70
- package/src/options.ts +36 -17
- package/src/saveStateHandler.ts +5 -8
- package/src/selectNodeHandler.ts +12 -1
- package/src/version.ts +1 -1
- package/tree_element.css +32 -5
- package/tree_element.debug.js +291 -165
- package/tree_element.debug.js.map +1 -1
- package/tree_element.js +2 -2
- package/tree_element.js.map +1 -1
package/src/options.ts
CHANGED
|
@@ -31,10 +31,32 @@ export type OnIsMoveHandle = (el: HTMLElement) => boolean;
|
|
|
31
31
|
|
|
32
32
|
export type OnSetStateFromStorage = ((data: string) => void) | undefined;
|
|
33
33
|
|
|
34
|
+
/* The options that setOption can change. The others are read once, in the
|
|
35
|
+
* constructor, so changing them later would have no effect or leave the tree
|
|
36
|
+
* in an inconsistent state.
|
|
37
|
+
*/
|
|
38
|
+
export const changeableOptions = [
|
|
39
|
+
"animationSpeed",
|
|
40
|
+
"dataUrl",
|
|
41
|
+
"dragAndDrop",
|
|
42
|
+
"keyboardSupport",
|
|
43
|
+
"multiSelect",
|
|
44
|
+
"onCanSelectNode",
|
|
45
|
+
"selectable",
|
|
46
|
+
"slide",
|
|
47
|
+
"startDndDelay",
|
|
48
|
+
"tabIndex",
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The options that `setOption` can change.
|
|
53
|
+
*/
|
|
54
|
+
export type ChangeableOption = (typeof changeableOptions)[number];
|
|
55
|
+
|
|
34
56
|
export interface TreeElementOptions {
|
|
35
57
|
/**
|
|
36
|
-
* The duration of the slide animation: `"fast"` is
|
|
37
|
-
*
|
|
58
|
+
* The duration of the slide animation: `"fast"` is 200 milliseconds,
|
|
59
|
+
* `"slow"` is 600, and a number is milliseconds.
|
|
38
60
|
*
|
|
39
61
|
* @defaultValue `"fast"`, or `0` when the user prefers reduced motion
|
|
40
62
|
* (`prefers-reduced-motion: reduce`).
|
|
@@ -56,7 +78,7 @@ export interface TreeElementOptions {
|
|
|
56
78
|
*/
|
|
57
79
|
ariaLabelledBy?: string;
|
|
58
80
|
/**
|
|
59
|
-
* Escape node names. With `false`, names are inserted as
|
|
81
|
+
* Escape node names. With `false`, names are inserted as HTML—only do
|
|
60
82
|
* that for data you control.
|
|
61
83
|
*
|
|
62
84
|
* @defaultValue `true`
|
|
@@ -81,10 +103,10 @@ export interface TreeElementOptions {
|
|
|
81
103
|
*/
|
|
82
104
|
buttonLeft: boolean;
|
|
83
105
|
/**
|
|
84
|
-
* The prefix of the
|
|
106
|
+
* The prefix of the CSS classes the widget puts on the elements it
|
|
85
107
|
* creates: with `"my-tree"` a title gets `my-tree-title` instead of
|
|
86
|
-
* `tree-element-title`. The bundled
|
|
87
|
-
* change it only if you bring your own
|
|
108
|
+
* `tree-element-title`. The bundled style sheet uses the default prefix,
|
|
109
|
+
* so change it only if you bring your own CSS. See
|
|
88
110
|
* [Styling](/guide/styling#changing-the-class-names).
|
|
89
111
|
*
|
|
90
112
|
* @defaultValue `"tree-element"`
|
|
@@ -92,12 +114,12 @@ export interface TreeElementOptions {
|
|
|
92
114
|
*/
|
|
93
115
|
classPrefix: string;
|
|
94
116
|
/**
|
|
95
|
-
* The icon of a closed folder. A string is inserted as
|
|
96
|
-
* cloned for every node.
|
|
117
|
+
* The icon of a closed folder. A string is inserted as HTML, and an element
|
|
118
|
+
* is cloned for every node.
|
|
97
119
|
*
|
|
98
120
|
* Type: `HTMLElement | string`
|
|
99
121
|
*
|
|
100
|
-
* @defaultValue An
|
|
122
|
+
* @defaultValue An SVG triangle pointing right, or left when `rtl` is
|
|
101
123
|
* true. It is sized in em and filled with `currentColor`.
|
|
102
124
|
* @group Appearance
|
|
103
125
|
*/
|
|
@@ -125,7 +147,7 @@ export interface TreeElementOptions {
|
|
|
125
147
|
*/
|
|
126
148
|
dataFilter?: DataFilter;
|
|
127
149
|
/**
|
|
128
|
-
* A
|
|
150
|
+
* A URL to fetch the data from, or a function that returns one. The
|
|
129
151
|
* function is called with the node that is being loaded, and without an
|
|
130
152
|
* argument for the initial load. See
|
|
131
153
|
* [Loading on demand](/guide/loading-on-demand).
|
|
@@ -157,9 +179,6 @@ export interface TreeElementOptions {
|
|
|
157
179
|
* focus instead of the selection, and `Space` adds the focused node or
|
|
158
180
|
* removes it. See [Selection](/guide/selection#multiple-nodes).
|
|
159
181
|
*
|
|
160
|
-
* Set it in the constructor; changing it with `setOption` is not
|
|
161
|
-
* supported.
|
|
162
|
-
*
|
|
163
182
|
* @defaultValue `false`
|
|
164
183
|
* @group Selection
|
|
165
184
|
*/
|
|
@@ -240,7 +259,7 @@ export interface TreeElementOptions {
|
|
|
240
259
|
*/
|
|
241
260
|
onDragStop?: DragMethod;
|
|
242
261
|
/**
|
|
243
|
-
* Read the saved state, as a
|
|
262
|
+
* Read the saved state, as a JSON string, from somewhere other than
|
|
244
263
|
* `localStorage`.
|
|
245
264
|
*
|
|
246
265
|
* Type: `() => string`
|
|
@@ -258,7 +277,7 @@ export interface TreeElementOptions {
|
|
|
258
277
|
*/
|
|
259
278
|
onIsMoveHandle?: OnIsMoveHandle;
|
|
260
279
|
/**
|
|
261
|
-
* Write the state, as a
|
|
280
|
+
* Write the state, as a JSON string, to somewhere other than
|
|
262
281
|
* `localStorage`.
|
|
263
282
|
*
|
|
264
283
|
* Type: `(state: string) => void`
|
|
@@ -271,7 +290,7 @@ export interface TreeElementOptions {
|
|
|
271
290
|
*
|
|
272
291
|
* Type: `HTMLElement | string`
|
|
273
292
|
*
|
|
274
|
-
* @defaultValue An
|
|
293
|
+
* @defaultValue An SVG triangle pointing down, sized in em and filled with
|
|
275
294
|
* `currentColor`.
|
|
276
295
|
* @group Appearance
|
|
277
296
|
*/
|
|
@@ -293,7 +312,7 @@ export interface TreeElementOptions {
|
|
|
293
312
|
rtl?: boolean;
|
|
294
313
|
/**
|
|
295
314
|
* Remember the open and selected nodes in `localStorage`. A string is used
|
|
296
|
-
* as the storage key
|
|
315
|
+
* as the storage key, and `true` uses `tree`. See
|
|
297
316
|
* [Saving state](/guide/saving-state).
|
|
298
317
|
*
|
|
299
318
|
* @defaultValue `false`
|
package/src/saveStateHandler.ts
CHANGED
|
@@ -67,10 +67,7 @@ export default class SaveStateHandler {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
public getNodeIdToBeSelected(): NodeId | null {
|
|
70
|
-
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
70
|
+
// Without the saveState option there is no state
|
|
74
71
|
const state = this.getStateFromStorage();
|
|
75
72
|
|
|
76
73
|
return state?.selected_node ? (state.selected_node[0] ?? null) : null;
|
|
@@ -243,8 +240,9 @@ export default class SaveStateHandler {
|
|
|
243
240
|
}
|
|
244
241
|
}
|
|
245
242
|
|
|
243
|
+
// result: is a node selected?
|
|
246
244
|
private selectInitialNodes(nodeIds: NodeId[]): boolean {
|
|
247
|
-
let
|
|
245
|
+
let isNodeSelected = false;
|
|
248
246
|
|
|
249
247
|
for (const nodeId of nodeIds) {
|
|
250
248
|
const node = this.getNodeById(nodeId);
|
|
@@ -253,11 +251,10 @@ export default class SaveStateHandler {
|
|
|
253
251
|
continue;
|
|
254
252
|
}
|
|
255
253
|
|
|
256
|
-
selectCount += 1;
|
|
257
|
-
|
|
258
254
|
this.addToSelection(node);
|
|
255
|
+
isNodeSelected = true;
|
|
259
256
|
}
|
|
260
257
|
|
|
261
|
-
return
|
|
258
|
+
return isNodeSelected;
|
|
262
259
|
}
|
|
263
260
|
}
|
package/src/selectNodeHandler.ts
CHANGED
|
@@ -166,12 +166,19 @@ export default class SelectNodeHandler {
|
|
|
166
166
|
for (const otherNode of otherSelectedNodes) {
|
|
167
167
|
this.deselectNode(otherNode);
|
|
168
168
|
}
|
|
169
|
+
|
|
170
|
+
for (const otherNode of otherSelectedNodes) {
|
|
171
|
+
this.triggerEvent("tree.deselect", { node: otherNode });
|
|
172
|
+
}
|
|
169
173
|
} else if (selectOptions.mustToggle) {
|
|
170
174
|
this.deselectNode(node);
|
|
171
175
|
this.triggerEvent("tree.deselect", { node });
|
|
172
176
|
}
|
|
173
177
|
} else {
|
|
174
|
-
|
|
178
|
+
// tree.select reports the first deselected node; the others, from a
|
|
179
|
+
// multiple selection, get a tree.deselect.
|
|
180
|
+
const [deselectedNode = null, ...alsoDeselectedNodes] =
|
|
181
|
+
otherSelectedNodes;
|
|
175
182
|
|
|
176
183
|
for (const otherNode of otherSelectedNodes) {
|
|
177
184
|
this.deselectNode(otherNode);
|
|
@@ -181,6 +188,10 @@ export default class SelectNodeHandler {
|
|
|
181
188
|
this.openParents(node);
|
|
182
189
|
this.getNodeElementForNode(node).select(selectOptions.mustSetFocus);
|
|
183
190
|
|
|
191
|
+
for (const otherNode of alsoDeselectedNodes) {
|
|
192
|
+
this.triggerEvent("tree.deselect", { node: otherNode });
|
|
193
|
+
}
|
|
194
|
+
|
|
184
195
|
this.triggerEvent("tree.select", {
|
|
185
196
|
deselectedNode,
|
|
186
197
|
node,
|
package/src/version.ts
CHANGED
package/tree_element.css
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Colors. Override them on :root or on an element around the tree, for example
|
|
3
3
|
for a dark theme. :where keeps the specificity at 0, so any rule wins.
|
|
4
4
|
--tree-element-selected-color defaults to --tree-element-title-color.
|
|
5
|
+
Set --tree-element-line-color to transparent to hide the tree lines.
|
|
5
6
|
*/
|
|
6
7
|
:where(:root) {
|
|
7
8
|
--tree-element-title-color: #1c4257;
|
|
@@ -12,6 +13,19 @@
|
|
|
12
13
|
--tree-element-drop-hint-color: #00f;
|
|
13
14
|
--tree-element-dragging-color: #fff;
|
|
14
15
|
--tree-element-dragging-background: #000;
|
|
16
|
+
--tree-element-line-color: #d5dbe1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
The width of the toggler. The indentation and the tree lines follow it, so
|
|
21
|
+
the line stays under the center of the toggler. 1.5em is 24px at a 16px
|
|
22
|
+
font: above that the toggler grows with the font, so the space around the
|
|
23
|
+
0.8em icon, which separates it from the title, grows along. Set it to the
|
|
24
|
+
width of a custom icon that is wider. It is resolved where it is used, so em
|
|
25
|
+
is the font size of the tree.
|
|
26
|
+
*/
|
|
27
|
+
:where(:root) {
|
|
28
|
+
--tree-element-toggler-size: max(24px, 1.5em);
|
|
15
29
|
}
|
|
16
30
|
|
|
17
31
|
ul.tree-element {
|
|
@@ -27,11 +41,14 @@ ul.tree-element.tree-element-dnd {
|
|
|
27
41
|
|
|
28
42
|
ul.tree-element ul.tree-element-common {
|
|
29
43
|
list-style: none outside;
|
|
30
|
-
margin-left:
|
|
44
|
+
margin-left: calc(var(--tree-element-toggler-size) / 2);
|
|
31
45
|
margin-right: 0;
|
|
32
46
|
margin-bottom: 0;
|
|
33
47
|
padding: 0;
|
|
34
48
|
display: block;
|
|
49
|
+
/* The line down from the toggler of the folder: the indent is half the
|
|
50
|
+
width of the toggler, so the line is under its center. */
|
|
51
|
+
border-left: 1px solid var(--tree-element-line-color);
|
|
35
52
|
}
|
|
36
53
|
|
|
37
54
|
ul.tree-element li.tree-element-closed > ul.tree-element-common {
|
|
@@ -52,12 +69,16 @@ ul.tree-element .tree-element-toggler {
|
|
|
52
69
|
align-items: center;
|
|
53
70
|
justify-content: center;
|
|
54
71
|
box-sizing: border-box;
|
|
55
|
-
min-width:
|
|
72
|
+
min-width: var(--tree-element-toggler-size);
|
|
56
73
|
min-height: 24px;
|
|
57
74
|
border-bottom: none;
|
|
58
75
|
color: var(--tree-element-toggler-color);
|
|
59
76
|
text-decoration: none;
|
|
60
77
|
vertical-align: middle;
|
|
78
|
+
/* The line under the toggler is 1px wide, so its center is half a pixel
|
|
79
|
+
after the center of the toggler. Move the toggler along.
|
|
80
|
+
Margin or padding would be rounded to a whole pixel; translate isn't. */
|
|
81
|
+
translate: 0.5px;
|
|
61
82
|
}
|
|
62
83
|
|
|
63
84
|
ul.tree-element .tree-element-toggler:hover {
|
|
@@ -105,7 +126,7 @@ ul.tree-element li.tree-element-common:focus-visible
|
|
|
105
126
|
/* Line up with the titles of folders, after the toggler */
|
|
106
127
|
|
|
107
128
|
ul.tree-element .tree-element-title-button-left {
|
|
108
|
-
margin-left:
|
|
129
|
+
margin-left: var(--tree-element-toggler-size);
|
|
109
130
|
}
|
|
110
131
|
|
|
111
132
|
ul.tree-element .tree-element-title-button-left.tree-element-title-folder {
|
|
@@ -186,12 +207,18 @@ ul.tree-element.tree-element-rtl {
|
|
|
186
207
|
|
|
187
208
|
ul.tree-element.tree-element-rtl ul.tree-element-common {
|
|
188
209
|
margin-left: 0;
|
|
189
|
-
margin-right:
|
|
210
|
+
margin-right: calc(var(--tree-element-toggler-size) / 2);
|
|
211
|
+
border-left: none;
|
|
212
|
+
border-right: 1px solid var(--tree-element-line-color);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
ul.tree-element.tree-element-rtl .tree-element-toggler {
|
|
216
|
+
translate: -0.5px;
|
|
190
217
|
}
|
|
191
218
|
|
|
192
219
|
ul.tree-element.tree-element-rtl .tree-element-title {
|
|
193
220
|
margin-left: 0;
|
|
194
|
-
margin-right:
|
|
221
|
+
margin-right: var(--tree-element-toggler-size);
|
|
195
222
|
}
|
|
196
223
|
|
|
197
224
|
ul.tree-element.tree-element-rtl .tree-element-title.tree-element-title-folder {
|