tree-element 0.1.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.
Files changed (182) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +221 -0
  3. package/lib/animation.d.ts +5 -0
  4. package/lib/animation.d.ts.map +1 -0
  5. package/lib/animation.js +39 -0
  6. package/lib/animation.js.map +1 -0
  7. package/lib/classNames.d.ts +34 -0
  8. package/lib/classNames.d.ts.map +1 -0
  9. package/lib/classNames.js +39 -0
  10. package/lib/classNames.js.map +1 -0
  11. package/lib/dataLoader.d.ts +25 -0
  12. package/lib/dataLoader.d.ts.map +1 -0
  13. package/lib/dataLoader.js +69 -0
  14. package/lib/dataLoader.js.map +1 -0
  15. package/lib/dragAndDropHandler/binarySearch.d.ts +3 -0
  16. package/lib/dragAndDropHandler/binarySearch.d.ts.map +1 -0
  17. package/lib/dragAndDropHandler/binarySearch.js +23 -0
  18. package/lib/dragAndDropHandler/binarySearch.js.map +1 -0
  19. package/lib/dragAndDropHandler/dragElement.d.ts +20 -0
  20. package/lib/dragAndDropHandler/dragElement.d.ts.map +1 -0
  21. package/lib/dragAndDropHandler/dragElement.js +39 -0
  22. package/lib/dragAndDropHandler/dragElement.js.map +1 -0
  23. package/lib/dragAndDropHandler/generateHitAreas.d.ts +13 -0
  24. package/lib/dragAndDropHandler/generateHitAreas.d.ts.map +1 -0
  25. package/lib/dragAndDropHandler/generateHitAreas.js +130 -0
  26. package/lib/dragAndDropHandler/generateHitAreas.js.map +1 -0
  27. package/lib/dragAndDropHandler/index.d.ts +76 -0
  28. package/lib/dragAndDropHandler/index.d.ts.map +1 -0
  29. package/lib/dragAndDropHandler/index.js +311 -0
  30. package/lib/dragAndDropHandler/index.js.map +1 -0
  31. package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts +11 -0
  32. package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts.map +1 -0
  33. package/lib/dragAndDropHandler/iterateVisibleNodes.js +54 -0
  34. package/lib/dragAndDropHandler/iterateVisibleNodes.js.map +1 -0
  35. package/lib/dragAndDropHandler/types.d.ts +11 -0
  36. package/lib/dragAndDropHandler/types.d.ts.map +1 -0
  37. package/lib/elementsRenderer.d.ts +53 -0
  38. package/lib/elementsRenderer.d.ts.map +1 -0
  39. package/lib/elementsRenderer.js +251 -0
  40. package/lib/elementsRenderer.js.map +1 -0
  41. package/lib/events.d.ts +224 -0
  42. package/lib/events.d.ts.map +1 -0
  43. package/lib/index.d.ts +367 -0
  44. package/lib/index.d.ts.map +1 -0
  45. package/lib/index.js +1098 -0
  46. package/lib/index.js.map +1 -0
  47. package/lib/keyHandler.d.ts +29 -0
  48. package/lib/keyHandler.d.ts.map +1 -0
  49. package/lib/keyHandler.js +107 -0
  50. package/lib/keyHandler.js.map +1 -0
  51. package/lib/methodTypes.d.ts +21 -0
  52. package/lib/methodTypes.d.ts.map +1 -0
  53. package/lib/mouseHandler.d.ts +60 -0
  54. package/lib/mouseHandler.d.ts.map +1 -0
  55. package/lib/mouseHandler.js +283 -0
  56. package/lib/mouseHandler.js.map +1 -0
  57. package/lib/mouseUtils.d.ts +9 -0
  58. package/lib/mouseUtils.d.ts.map +1 -0
  59. package/lib/mouseUtils.js +15 -0
  60. package/lib/mouseUtils.js.map +1 -0
  61. package/lib/node.d.ts +320 -0
  62. package/lib/node.d.ts.map +1 -0
  63. package/lib/node.js +737 -0
  64. package/lib/node.js.map +1 -0
  65. package/lib/nodeElement/borderDropHint.d.ts +9 -0
  66. package/lib/nodeElement/borderDropHint.d.ts.map +1 -0
  67. package/lib/nodeElement/borderDropHint.js +24 -0
  68. package/lib/nodeElement/borderDropHint.js.map +1 -0
  69. package/lib/nodeElement/folderElement.d.ts +22 -0
  70. package/lib/nodeElement/folderElement.d.ts.map +1 -0
  71. package/lib/nodeElement/folderElement.js +100 -0
  72. package/lib/nodeElement/folderElement.js.map +1 -0
  73. package/lib/nodeElement/ghostDropHint.d.ts +18 -0
  74. package/lib/nodeElement/ghostDropHint.d.ts.map +1 -0
  75. package/lib/nodeElement/ghostDropHint.js +67 -0
  76. package/lib/nodeElement/ghostDropHint.js.map +1 -0
  77. package/lib/nodeElement/index.d.ts +28 -0
  78. package/lib/nodeElement/index.d.ts.map +1 -0
  79. package/lib/nodeElement/index.js +66 -0
  80. package/lib/nodeElement/index.js.map +1 -0
  81. package/lib/nodeUtils.d.ts +7 -0
  82. package/lib/nodeUtils.d.ts.map +1 -0
  83. package/lib/nodeUtils.js +4 -0
  84. package/lib/nodeUtils.js.map +1 -0
  85. package/lib/options.d.ts +310 -0
  86. package/lib/options.d.ts.map +1 -0
  87. package/lib/package.json +3 -0
  88. package/lib/positionUtils.d.ts +8 -0
  89. package/lib/positionUtils.d.ts.map +1 -0
  90. package/lib/positionUtils.js +14 -0
  91. package/lib/positionUtils.js.map +1 -0
  92. package/lib/requestUrl.d.ts +9 -0
  93. package/lib/requestUrl.d.ts.map +1 -0
  94. package/lib/requestUrl.js +37 -0
  95. package/lib/requestUrl.js.map +1 -0
  96. package/lib/saveStateHandler.d.ts +46 -0
  97. package/lib/saveStateHandler.d.ts.map +1 -0
  98. package/lib/saveStateHandler.js +204 -0
  99. package/lib/saveStateHandler.js.map +1 -0
  100. package/lib/scrollHandler/containerScrollParent.d.ts +12 -0
  101. package/lib/scrollHandler/containerScrollParent.d.ts.map +1 -0
  102. package/lib/scrollHandler/containerScrollParent.js +49 -0
  103. package/lib/scrollHandler/containerScrollParent.js.map +1 -0
  104. package/lib/scrollHandler/createScrollParent.d.ts +4 -0
  105. package/lib/scrollHandler/createScrollParent.d.ts.map +1 -0
  106. package/lib/scrollHandler/createScrollParent.js +38 -0
  107. package/lib/scrollHandler/createScrollParent.js.map +1 -0
  108. package/lib/scrollHandler/documentScrollParent.d.ts +22 -0
  109. package/lib/scrollHandler/documentScrollParent.d.ts.map +1 -0
  110. package/lib/scrollHandler/documentScrollParent.js +71 -0
  111. package/lib/scrollHandler/documentScrollParent.js.map +1 -0
  112. package/lib/scrollHandler/scrollParent.d.ts +26 -0
  113. package/lib/scrollHandler/scrollParent.d.ts.map +1 -0
  114. package/lib/scrollHandler/scrollParent.js +79 -0
  115. package/lib/scrollHandler/scrollParent.js.map +1 -0
  116. package/lib/scrollHandler.d.ts +20 -0
  117. package/lib/scrollHandler.d.ts.map +1 -0
  118. package/lib/scrollHandler.js +41 -0
  119. package/lib/scrollHandler.js.map +1 -0
  120. package/lib/selectNodeHandler.d.ts +38 -0
  121. package/lib/selectNodeHandler.d.ts.map +1 -0
  122. package/lib/selectNodeHandler.js +166 -0
  123. package/lib/selectNodeHandler.js.map +1 -0
  124. package/lib/setDefaultOptions.d.ts +4 -0
  125. package/lib/setDefaultOptions.d.ts.map +1 -0
  126. package/lib/setDefaultOptions.js +86 -0
  127. package/lib/setDefaultOptions.js.map +1 -0
  128. package/lib/triggerCustomEvent.d.ts +3 -0
  129. package/lib/triggerCustomEvent.d.ts.map +1 -0
  130. package/lib/triggerCustomEvent.js +13 -0
  131. package/lib/triggerCustomEvent.js.map +1 -0
  132. package/lib/util.d.ts +3 -0
  133. package/lib/util.d.ts.map +1 -0
  134. package/lib/util.js +5 -0
  135. package/lib/util.js.map +1 -0
  136. package/lib/version.d.ts +3 -0
  137. package/lib/version.d.ts.map +1 -0
  138. package/lib/version.js +5 -0
  139. package/lib/version.js.map +1 -0
  140. package/package.json +110 -0
  141. package/src/animation.ts +48 -0
  142. package/src/classNames.ts +70 -0
  143. package/src/dataLoader.ts +92 -0
  144. package/src/dragAndDropHandler/binarySearch.ts +27 -0
  145. package/src/dragAndDropHandler/dragElement.ts +62 -0
  146. package/src/dragAndDropHandler/generateHitAreas.ts +195 -0
  147. package/src/dragAndDropHandler/index.ts +442 -0
  148. package/src/dragAndDropHandler/iterateVisibleNodes.ts +91 -0
  149. package/src/dragAndDropHandler/types.ts +12 -0
  150. package/src/elementsRenderer.ts +367 -0
  151. package/src/events.ts +237 -0
  152. package/src/header.txt +16 -0
  153. package/src/index.ts +1290 -0
  154. package/src/keyHandler.ts +139 -0
  155. package/src/methodTypes.ts +44 -0
  156. package/src/mouseHandler.ts +391 -0
  157. package/src/mouseUtils.ts +23 -0
  158. package/src/node.ts +831 -0
  159. package/src/nodeElement/borderDropHint.ts +37 -0
  160. package/src/nodeElement/folderElement.ts +140 -0
  161. package/src/nodeElement/ghostDropHint.ts +84 -0
  162. package/src/nodeElement/index.ts +103 -0
  163. package/src/nodeUtils.ts +12 -0
  164. package/src/options.ts +325 -0
  165. package/src/positionUtils.ts +18 -0
  166. package/src/requestUrl.ts +41 -0
  167. package/src/saveStateHandler.ts +279 -0
  168. package/src/scrollHandler/containerScrollParent.ts +71 -0
  169. package/src/scrollHandler/createScrollParent.ts +51 -0
  170. package/src/scrollHandler/documentScrollParent.ts +104 -0
  171. package/src/scrollHandler/scrollParent.ts +117 -0
  172. package/src/scrollHandler.ts +55 -0
  173. package/src/selectNodeHandler.ts +192 -0
  174. package/src/setDefaultOptions.ts +79 -0
  175. package/src/triggerCustomEvent.ts +14 -0
  176. package/src/util.ts +5 -0
  177. package/src/version.ts +4 -0
  178. package/tree_element.css +195 -0
  179. package/tree_element.debug.js +4153 -0
  180. package/tree_element.debug.js.map +1 -0
  181. package/tree_element.js +21 -0
  182. package/tree_element.js.map +1 -0
@@ -0,0 +1,367 @@
1
+ import type { ClassNames } from "./classNames";
2
+ import type { GetTree, IsNodeSelected } from "./methodTypes";
3
+ import type { Node } from "./node";
4
+ import type { IconElement, OnCreateLi } from "./options";
5
+
6
+ import { getBoolString } from "./util";
7
+
8
+ interface ElementsRendererParams {
9
+ autoEscape: boolean;
10
+ buttonLeft: boolean;
11
+ classNames: ClassNames;
12
+ closedIcon?: IconElement;
13
+ dragAndDrop: boolean;
14
+ getTree: GetTree;
15
+ htmlElement: HTMLElement;
16
+ isNodeSelected: IsNodeSelected;
17
+ onCreateLi?: OnCreateLi;
18
+ openedIcon?: IconElement;
19
+ rtl?: boolean;
20
+ setNodeElement: (element: HTMLElement, node: Node) => void;
21
+ showEmptyFolder: boolean;
22
+ tabIndex?: number;
23
+ }
24
+
25
+ export default class ElementsRenderer {
26
+ public closedIconElement?: HTMLElement | Text;
27
+ public openedIconElement?: HTMLElement | Text;
28
+ private autoEscape: boolean;
29
+ private buttonLeft: boolean;
30
+ private classNames: ClassNames;
31
+ private dragAndDrop: boolean;
32
+ private getTree: GetTree;
33
+ private htmlElement: HTMLElement;
34
+ private isNodeSelected: IsNodeSelected;
35
+ private onCreateLi?: OnCreateLi;
36
+ private rtl?: boolean;
37
+ private setNodeElement: (element: HTMLElement, node: Node) => void;
38
+ private showEmptyFolder: boolean;
39
+ private tabIndex?: number;
40
+
41
+ constructor({
42
+ autoEscape,
43
+ buttonLeft,
44
+ classNames,
45
+ closedIcon,
46
+ dragAndDrop,
47
+ getTree,
48
+ htmlElement,
49
+ isNodeSelected,
50
+ onCreateLi,
51
+ openedIcon,
52
+ rtl,
53
+ setNodeElement,
54
+ showEmptyFolder,
55
+ tabIndex,
56
+ }: ElementsRendererParams) {
57
+ this.autoEscape = autoEscape;
58
+ this.buttonLeft = buttonLeft;
59
+ this.classNames = classNames;
60
+ this.dragAndDrop = dragAndDrop;
61
+ this.getTree = getTree;
62
+ this.htmlElement = htmlElement;
63
+ this.isNodeSelected = isNodeSelected;
64
+ this.onCreateLi = onCreateLi;
65
+ this.rtl = rtl;
66
+ this.setNodeElement = setNodeElement;
67
+ this.showEmptyFolder = showEmptyFolder;
68
+ this.tabIndex = tabIndex;
69
+ this.openedIconElement = this.createButtonElement(openedIcon ?? "+");
70
+ this.closedIconElement = this.createButtonElement(closedIcon ?? "-");
71
+ }
72
+
73
+ public render(fromNode: Node | null): void {
74
+ if (fromNode?.parent) {
75
+ this.renderFromNode(fromNode);
76
+ } else {
77
+ this.renderFromRoot();
78
+ }
79
+ }
80
+
81
+ public renderFromNode(node: Node): void {
82
+ if (!node.element) {
83
+ return;
84
+ }
85
+
86
+ const currentLi = node.element;
87
+ const newLi = this.createLi(node, node.getLevel());
88
+ currentLi.replaceWith(newLi);
89
+
90
+ // create children
91
+ this.createDomElements(newLi, node.children, false, node.getLevel() + 1);
92
+ }
93
+
94
+ public renderFromRoot(): void {
95
+ this.htmlElement.textContent = '';
96
+
97
+ const tree = this.getTree();
98
+
99
+ if (tree) {
100
+ this.createDomElements(this.htmlElement, tree.children, true, 1);
101
+ }
102
+ }
103
+
104
+ private attachNodeData(node: Node, li: HTMLElement): void {
105
+ node.element = li;
106
+ this.setNodeElement(li, node);
107
+ }
108
+
109
+ private createButtonElement(
110
+ value: IconElement,
111
+ ): HTMLElement | Text | undefined {
112
+ if (typeof value === "string") {
113
+ // convert value to html
114
+ const div = document.createElement("div");
115
+ div.innerHTML = value;
116
+
117
+ return document.createTextNode(div.innerHTML);
118
+ } else if (value.nodeType) {
119
+ return value;
120
+ } else {
121
+ return undefined;
122
+ }
123
+ }
124
+
125
+ private createDomElements(
126
+ element: Element,
127
+ children: Node[],
128
+ isRootNode: boolean,
129
+ level: number,
130
+ ): void {
131
+ const ul = this.createUl(isRootNode);
132
+ element.appendChild(ul);
133
+
134
+ for (const child of children) {
135
+ const li = this.createLi(child, level);
136
+ ul.appendChild(li);
137
+
138
+ if (child.hasChildren()) {
139
+ this.createDomElements(li, child.children, false, level + 1);
140
+ }
141
+ }
142
+ }
143
+
144
+ private createFolderLi(
145
+ node: Node,
146
+ level: number,
147
+ isSelected: boolean,
148
+ ): HTMLLIElement {
149
+ const buttonClasses = this.getButtonClasses(node);
150
+ const folderClasses = this.getFolderClasses(node, isSelected);
151
+
152
+ const iconElement = node.is_open
153
+ ? this.openedIconElement
154
+ : this.closedIconElement;
155
+
156
+ // li
157
+ const li = document.createElement("li");
158
+ li.className = `${this.classNames.common} ${folderClasses}`;
159
+ li.setAttribute("role", "none");
160
+
161
+ // div
162
+ const div = document.createElement("div");
163
+ div.className = `${this.classNames.element} ${this.classNames.common}`;
164
+ div.setAttribute("role", "none");
165
+
166
+ li.appendChild(div);
167
+
168
+ // button link
169
+ const buttonLink = document.createElement("a");
170
+ buttonLink.className = buttonClasses;
171
+
172
+ if (iconElement) {
173
+ buttonLink.appendChild(iconElement.cloneNode(true));
174
+ }
175
+
176
+ if (this.buttonLeft) {
177
+ div.appendChild(buttonLink);
178
+ }
179
+
180
+ // title span
181
+ const titleSpan = this.createTitleSpan(
182
+ node.name,
183
+ isSelected,
184
+ true,
185
+ level,
186
+ );
187
+ titleSpan.setAttribute("aria-expanded", getBoolString(node.is_open));
188
+ div.appendChild(titleSpan);
189
+
190
+ if (!this.buttonLeft) {
191
+ div.appendChild(buttonLink);
192
+ }
193
+
194
+ return li;
195
+ }
196
+
197
+ /* Create the <li> element
198
+ * Attach it to node.element.
199
+ * Call onCreateLi
200
+ */
201
+ private createLi(node: Node, level: number): HTMLLIElement {
202
+ const isSelected = this.isNodeSelected(node);
203
+
204
+ const mustShowFolder =
205
+ node.isFolder() || (node.isEmptyFolder && this.showEmptyFolder);
206
+
207
+ const li = mustShowFolder
208
+ ? this.createFolderLi(node, level, isSelected)
209
+ : this.createNodeLi(node, level, isSelected);
210
+
211
+ this.attachNodeData(node, li);
212
+
213
+ if (this.onCreateLi) {
214
+ this.onCreateLi(node, li, isSelected);
215
+ }
216
+
217
+ return li;
218
+ }
219
+
220
+ private createNodeLi(
221
+ node: Node,
222
+ level: number,
223
+ isSelected: boolean,
224
+ ): HTMLLIElement {
225
+ const liClasses = [this.classNames.common];
226
+
227
+ if (isSelected) {
228
+ liClasses.push(this.classNames.selected);
229
+ }
230
+
231
+ const classString = liClasses.join(" ");
232
+
233
+ // li
234
+ const li = document.createElement("li");
235
+ li.className = classString;
236
+ li.setAttribute("role", "none");
237
+
238
+ // div
239
+ const div = document.createElement("div");
240
+ div.className = `${this.classNames.element} ${this.classNames.common}`;
241
+ div.setAttribute("role", "none");
242
+
243
+ li.appendChild(div);
244
+
245
+ // title span
246
+ const titleSpan = this.createTitleSpan(
247
+ node.name,
248
+ isSelected,
249
+ false,
250
+ level,
251
+ );
252
+ div.appendChild(titleSpan);
253
+
254
+ return li;
255
+ }
256
+
257
+ private createTitleSpan(
258
+ nodeName: string,
259
+ isSelected: boolean,
260
+ isFolder: boolean,
261
+ level: number,
262
+ ): HTMLSpanElement {
263
+ const titleSpan = document.createElement("span");
264
+
265
+ let classes = `${this.classNames.title} ${this.classNames.common}`;
266
+
267
+ if (isFolder) {
268
+ classes += ` ${this.classNames.titleFolder}`;
269
+ }
270
+
271
+ classes += ` ${this.buttonLeft ? this.classNames.titleButtonLeft : this.classNames.titleButtonRight}`;
272
+
273
+ titleSpan.className = classes;
274
+
275
+ if (isSelected) {
276
+ const tabIndex = this.tabIndex;
277
+
278
+ if (tabIndex !== undefined) {
279
+ titleSpan.setAttribute("tabindex", `${tabIndex}`);
280
+ }
281
+ }
282
+
283
+ this.setTreeItemAriaAttributes(titleSpan, nodeName, level, isSelected);
284
+
285
+ if (this.autoEscape) {
286
+ titleSpan.textContent = nodeName;
287
+ } else {
288
+ titleSpan.innerHTML = nodeName;
289
+ }
290
+
291
+ return titleSpan;
292
+ }
293
+
294
+ private createUl(isRootNode: boolean): HTMLUListElement {
295
+ let classString;
296
+ let role;
297
+
298
+ if (!isRootNode) {
299
+ classString = "";
300
+ role = "group";
301
+ } else {
302
+ classString = this.classNames.tree;
303
+ role = "tree";
304
+
305
+ if (this.rtl) {
306
+ classString += ` ${this.classNames.rtl}`;
307
+ }
308
+ }
309
+
310
+ if (this.dragAndDrop) {
311
+ classString += ` ${this.classNames.dnd}`;
312
+ }
313
+
314
+ const ul = document.createElement("ul");
315
+ ul.className = `${this.classNames.common} ${classString}`;
316
+
317
+ ul.setAttribute("role", role);
318
+
319
+ return ul;
320
+ }
321
+
322
+ private getButtonClasses(node: Node): string {
323
+ const classes = [this.classNames.toggler, this.classNames.common];
324
+
325
+ if (!node.is_open) {
326
+ classes.push(this.classNames.closed);
327
+ }
328
+
329
+ if (this.buttonLeft) {
330
+ classes.push(this.classNames.togglerLeft);
331
+ } else {
332
+ classes.push(this.classNames.togglerRight);
333
+ }
334
+
335
+ return classes.join(" ");
336
+ }
337
+
338
+ private getFolderClasses(node: Node, isSelected: boolean): string {
339
+ const classes = [this.classNames.folder];
340
+
341
+ if (!node.is_open) {
342
+ classes.push(this.classNames.closed);
343
+ }
344
+
345
+ if (isSelected) {
346
+ classes.push(this.classNames.selected);
347
+ }
348
+
349
+ if (node.is_loading) {
350
+ classes.push(this.classNames.loading);
351
+ }
352
+
353
+ return classes.join(" ");
354
+ }
355
+
356
+ private setTreeItemAriaAttributes(
357
+ element: HTMLElement,
358
+ name: string,
359
+ level: number,
360
+ isSelected: boolean,
361
+ ) {
362
+ element.setAttribute("aria-label", name);
363
+ element.setAttribute("aria-level", `${level}`);
364
+ element.setAttribute("aria-selected", getBoolString(isSelected));
365
+ element.setAttribute("role", "treeitem");
366
+ }
367
+ }
package/src/events.ts ADDED
@@ -0,0 +1,237 @@
1
+ import type { Node, NodeData, Position } from "./node";
2
+
3
+ export interface MoveInfo {
4
+ doMove: () => void;
5
+ movedNode: Node;
6
+ originalEvent: Event;
7
+ position: Position;
8
+ previousParent: Node | null;
9
+ targetNode: Node;
10
+ }
11
+
12
+ // The CustomEvent of a tree event, for example `TreeEvent<"tree.select">`.
13
+ export type TreeEvent<Name extends TreeEventName = TreeEventName> = CustomEvent<
14
+ TreeEvents[Name]
15
+ >;
16
+
17
+ export type TreeEventName = keyof TreeEvents;
18
+
19
+ // The events that the tree dispatches, and the type of their `detail`.
20
+ // `undefined` means that the event has no `detail`.
21
+ // The events reference in the docs is generated from this interface, so the
22
+ // events are ordered chronologically instead of alphabetically.
23
+ /* eslint-disable perfectionist/sort-interfaces */
24
+ export interface TreeEvents {
25
+ /**
26
+ * Dispatched once, after the tree is rendered for the first time. With
27
+ * `dataUrl` this is after the data has arrived, so it is the moment the
28
+ * api is safe to use:
29
+ *
30
+ * ```js
31
+ * element.addEventListener("tree.init", () => {
32
+ * tree.selectNode(tree.getNodeByName("node1"));
33
+ * });
34
+ * ```
35
+ *
36
+ * No `detail`.
37
+ *
38
+ * With inline `data`, the tree is rendered inside the constructor, so
39
+ * this event has already fired by the time the constructor returns. Add
40
+ * the listener to the element _before_ creating the tree:
41
+ *
42
+ * ```js
43
+ * const element = document.getElementById("tree1");
44
+ *
45
+ * element.addEventListener("tree.init", () => {
46
+ * // ...
47
+ * });
48
+ *
49
+ * const tree = new TreeElement({ data, htmlElement: element });
50
+ * ```
51
+ *
52
+ * @group Lifecycle
53
+ */
54
+ "tree.init": undefined;
55
+ /**
56
+ * Dispatched after the tree has been re-rendered. No `detail`.
57
+ *
58
+ * @group Lifecycle
59
+ */
60
+ "tree.refresh": undefined;
61
+ /**
62
+ * Dispatched when a node title is clicked. Call `preventDefault()` to
63
+ * stop the tree from selecting the node:
64
+ *
65
+ * ```js
66
+ * element.addEventListener("tree.click", (e) => {
67
+ * e.preventDefault();
68
+ * console.log("clicked", e.detail.node.name, "but not selected");
69
+ * });
70
+ * ```
71
+ *
72
+ * @group Mouse
73
+ */
74
+ "tree.click": {
75
+ node: Node;
76
+ originalEvent: MouseEvent;
77
+ };
78
+ /**
79
+ * Dispatched when a node title is double clicked.
80
+ *
81
+ * @group Mouse
82
+ */
83
+ "tree.dblclick": {
84
+ node: Node;
85
+ originalEvent: MouseEvent;
86
+ };
87
+ /**
88
+ * Dispatched on a right click on a node, unless `useContextMenu` is
89
+ * `false`. The browser's own menu is suppressed.
90
+ *
91
+ * @group Mouse
92
+ */
93
+ "tree.contextmenu": {
94
+ node: Node;
95
+ originalEvent: MouseEvent;
96
+ };
97
+ /**
98
+ * Dispatched when a folder is opened, after the animation.
99
+ *
100
+ * @group Opening and closing
101
+ */
102
+ "tree.open": {
103
+ node: Node;
104
+ };
105
+ /**
106
+ * Dispatched when a folder is closed, after the animation.
107
+ *
108
+ * @group Opening and closing
109
+ */
110
+ "tree.close": {
111
+ node: Node;
112
+ };
113
+ /**
114
+ * Dispatched when a node is selected. A deselection is
115
+ * [`tree.deselect`](#tree-deselect) instead, so `node` is always a node
116
+ * here.
117
+ *
118
+ * ```js
119
+ * element.addEventListener("tree.select", (e) => {
120
+ * console.log("selected", e.detail.node.name);
121
+ * });
122
+ * ```
123
+ *
124
+ * @group Selection
125
+ */
126
+ "tree.select": {
127
+ /** The node that was selected before, if any. */
128
+ deselectedNode: Node | null;
129
+ /** The node that is now selected. */
130
+ node: Node;
131
+ };
132
+ /**
133
+ * Dispatched when the selected node is deselected, which happens when it
134
+ * is clicked again or passed to `selectNode` again. No `tree.select` is
135
+ * dispatched for it.
136
+ *
137
+ * ```js
138
+ * element.addEventListener("tree.deselect", (e) => {
139
+ * console.log("deselected", e.detail.node.name);
140
+ * });
141
+ * ```
142
+ *
143
+ * Selecting another node does not dispatch it — that is a `tree.select`
144
+ * with the previous node in `deselectedNode`. It is also not dispatched
145
+ * with `mustToggle: false`, or by `selectNode(null)`,
146
+ * `removeFromSelection`, `removeNode`, `loadData` and restoring a saved
147
+ * state.
148
+ *
149
+ * @group Selection
150
+ */
151
+ "tree.deselect": {
152
+ node: Node;
153
+ };
154
+ /**
155
+ * Dispatched when a node is dropped after a drag.
156
+ *
157
+ * | `detail` | Type |
158
+ * | ------------------------- | --------------------------------- |
159
+ * | `moveInfo.movedNode` | `Node` |
160
+ * | `moveInfo.targetNode` | `Node` |
161
+ * | `moveInfo.position` | `"before" \| "after" \| "inside"` |
162
+ * | `moveInfo.previousParent` | `Node \| null` |
163
+ * | `moveInfo.originalEvent` | `Event` |
164
+ * | `moveInfo.doMove` | `() => void` |
165
+ *
166
+ * Call `preventDefault()` to keep the tree as it is, and
167
+ * `moveInfo.doMove()` to apply the move later. See
168
+ * [Drag and drop](/guide/drag-and-drop#reacting-to-a-move).
169
+ *
170
+ * @group Drag and drop
171
+ */
172
+ "tree.move": {
173
+ /** @hidden The fields are in the table above. */
174
+ moveInfo: MoveInfo;
175
+ };
176
+ /**
177
+ * Dispatched when data is set on the tree, both from the `data` option
178
+ * and from a url.
179
+ *
180
+ * @group Loading data
181
+ */
182
+ "tree.set_data": {
183
+ /** The node whose children were replaced, if it was a subtree. */
184
+ node?: Node;
185
+ treeData?: NodeData[];
186
+ };
187
+ /**
188
+ * Dispatched when a request starts.
189
+ *
190
+ * @group Loading data
191
+ */
192
+ "tree.loading_data": {
193
+ element: HTMLElement;
194
+ /** The node whose children are loading, if it is a subtree. */
195
+ node?: Node;
196
+ };
197
+ /**
198
+ * Dispatched when a request finishes. It is dispatched when the request
199
+ * fails too; a [`tree.load_failed`](#tree-load-failed) follows it.
200
+ *
201
+ * @group Loading data
202
+ */
203
+ "tree.loaded_data": {
204
+ element: HTMLElement;
205
+ /** The node whose children were loaded, if it was a subtree. */
206
+ node?: Node;
207
+ };
208
+ /**
209
+ * Dispatched when a request returns an error status, after
210
+ * `tree.loaded_data`:
211
+ *
212
+ * ```js
213
+ * element.addEventListener("tree.load_failed", (e) => {
214
+ * console.error("loading the tree failed", e.detail.response.status);
215
+ * });
216
+ * ```
217
+ *
218
+ * @group Loading data
219
+ */
220
+ "tree.load_failed": {
221
+ response: Response;
222
+ };
223
+ }
224
+ /* eslint-enable perfectionist/sort-interfaces */
225
+
226
+ type TreeEventMap = {
227
+ [Name in TreeEventName]: TreeEvent<Name>;
228
+ };
229
+
230
+ // Type `addEventListener("tree.select", ...)` on elements, the document and the window.
231
+ declare global {
232
+ interface DocumentEventMap extends TreeEventMap { }
233
+
234
+ interface HTMLElementEventMap extends TreeEventMap { }
235
+
236
+ interface WindowEventMap extends TreeEventMap { }
237
+ }
package/src/header.txt ADDED
@@ -0,0 +1,16 @@
1
+ Html-tree <%= version %>
2
+
3
+ Copyright <%= year %> Marco Braak
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ @license