tree-element 0.1.1 → 0.3.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 (155) hide show
  1. package/README.md +43 -31
  2. package/lib/animation.d.ts +2 -2
  3. package/lib/animation.d.ts.map +1 -1
  4. package/lib/animation.js +16 -12
  5. package/lib/animation.js.map +1 -1
  6. package/lib/classNames.d.ts.map +1 -1
  7. package/lib/classNames.js +2 -2
  8. package/lib/classNames.js.map +1 -1
  9. package/lib/dataLoader.d.ts +1 -0
  10. package/lib/dataLoader.d.ts.map +1 -1
  11. package/lib/dataLoader.js +22 -20
  12. package/lib/dataLoader.js.map +1 -1
  13. package/lib/dragAndDropHandler/binarySearch.js +3 -3
  14. package/lib/dragAndDropHandler/binarySearch.js.map +1 -1
  15. package/lib/dragAndDropHandler/dragElement.d.ts.map +1 -1
  16. package/lib/dragAndDropHandler/dragElement.js +11 -13
  17. package/lib/dragAndDropHandler/dragElement.js.map +1 -1
  18. package/lib/dragAndDropHandler/generateHitAreas.d.ts.map +1 -1
  19. package/lib/dragAndDropHandler/generateHitAreas.js +25 -25
  20. package/lib/dragAndDropHandler/generateHitAreas.js.map +1 -1
  21. package/lib/dragAndDropHandler/index.d.ts.map +1 -1
  22. package/lib/dragAndDropHandler/index.js +125 -158
  23. package/lib/dragAndDropHandler/index.js.map +1 -1
  24. package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts.map +1 -1
  25. package/lib/dragAndDropHandler/iterateVisibleNodes.js +23 -22
  26. package/lib/dragAndDropHandler/iterateVisibleNodes.js.map +1 -1
  27. package/lib/dragAndDropHandler/types.d.ts.map +1 -1
  28. package/lib/elementsRenderer.d.ts +20 -7
  29. package/lib/elementsRenderer.d.ts.map +1 -1
  30. package/lib/elementsRenderer.js +195 -136
  31. package/lib/elementsRenderer.js.map +1 -1
  32. package/lib/events.d.ts +44 -11
  33. package/lib/events.d.ts.map +1 -1
  34. package/lib/index.d.ts +36 -13
  35. package/lib/index.d.ts.map +1 -1
  36. package/lib/index.js +386 -349
  37. package/lib/index.js.map +1 -1
  38. package/lib/keyHandler.d.ts +13 -8
  39. package/lib/keyHandler.d.ts.map +1 -1
  40. package/lib/keyHandler.js +106 -51
  41. package/lib/keyHandler.js.map +1 -1
  42. package/lib/methodTypes.d.ts +3 -3
  43. package/lib/methodTypes.d.ts.map +1 -1
  44. package/lib/mouseHandler.d.ts +1 -1
  45. package/lib/mouseHandler.d.ts.map +1 -1
  46. package/lib/mouseHandler.js +36 -49
  47. package/lib/mouseHandler.js.map +1 -1
  48. package/lib/mouseUtils.d.ts.map +1 -1
  49. package/lib/mouseUtils.js +2 -2
  50. package/lib/mouseUtils.js.map +1 -1
  51. package/lib/node.d.ts +47 -16
  52. package/lib/node.d.ts.map +1 -1
  53. package/lib/node.js +169 -171
  54. package/lib/node.js.map +1 -1
  55. package/lib/nodeElement/borderDropHint.d.ts.map +1 -1
  56. package/lib/nodeElement/borderDropHint.js +4 -5
  57. package/lib/nodeElement/borderDropHint.js.map +1 -1
  58. package/lib/nodeElement/folderElement.d.ts +8 -5
  59. package/lib/nodeElement/folderElement.d.ts.map +1 -1
  60. package/lib/nodeElement/folderElement.js +75 -67
  61. package/lib/nodeElement/folderElement.js.map +1 -1
  62. package/lib/nodeElement/ghostDropHint.d.ts.map +1 -1
  63. package/lib/nodeElement/ghostDropHint.js +13 -13
  64. package/lib/nodeElement/ghostDropHint.js.map +1 -1
  65. package/lib/nodeElement/index.d.ts +2 -1
  66. package/lib/nodeElement/index.d.ts.map +1 -1
  67. package/lib/nodeElement/index.js +38 -30
  68. package/lib/nodeElement/index.js.map +1 -1
  69. package/lib/nodeUtils.d.ts.map +1 -1
  70. package/lib/nodeUtils.js +1 -1
  71. package/lib/nodeUtils.js.map +1 -1
  72. package/lib/options.d.ts +19 -3
  73. package/lib/options.d.ts.map +1 -1
  74. package/lib/positionUtils.js +3 -3
  75. package/lib/positionUtils.js.map +1 -1
  76. package/lib/requestUrl.d.ts +1 -1
  77. package/lib/requestUrl.d.ts.map +1 -1
  78. package/lib/requestUrl.js +6 -17
  79. package/lib/requestUrl.js.map +1 -1
  80. package/lib/saveStateHandler.d.ts.map +1 -1
  81. package/lib/saveStateHandler.js +59 -89
  82. package/lib/saveStateHandler.js.map +1 -1
  83. package/lib/scrollHandler/containerScrollParent.d.ts.map +1 -1
  84. package/lib/scrollHandler/containerScrollParent.js +11 -18
  85. package/lib/scrollHandler/containerScrollParent.js.map +1 -1
  86. package/lib/scrollHandler/createScrollParent.d.ts.map +1 -1
  87. package/lib/scrollHandler/createScrollParent.js +12 -13
  88. package/lib/scrollHandler/createScrollParent.js.map +1 -1
  89. package/lib/scrollHandler/documentScrollParent.d.ts.map +1 -1
  90. package/lib/scrollHandler/documentScrollParent.js +18 -27
  91. package/lib/scrollHandler/documentScrollParent.js.map +1 -1
  92. package/lib/scrollHandler/scrollParent.d.ts.map +1 -1
  93. package/lib/scrollHandler/scrollParent.js +30 -34
  94. package/lib/scrollHandler/scrollParent.js.map +1 -1
  95. package/lib/scrollHandler.d.ts.map +1 -1
  96. package/lib/scrollHandler.js +11 -14
  97. package/lib/scrollHandler.js.map +1 -1
  98. package/lib/selectNodeHandler.d.ts +4 -2
  99. package/lib/selectNodeHandler.d.ts.map +1 -1
  100. package/lib/selectNodeHandler.js +64 -83
  101. package/lib/selectNodeHandler.js.map +1 -1
  102. package/lib/setDefaultOptions.d.ts.map +1 -1
  103. package/lib/setDefaultOptions.js +34 -38
  104. package/lib/setDefaultOptions.js.map +1 -1
  105. package/lib/triggerCustomEvent.d.ts.map +1 -1
  106. package/lib/triggerCustomEvent.js +2 -2
  107. package/lib/triggerCustomEvent.js.map +1 -1
  108. package/lib/util.d.ts.map +1 -1
  109. package/lib/util.js +2 -2
  110. package/lib/util.js.map +1 -1
  111. package/lib/version.d.ts +1 -1
  112. package/lib/version.js +1 -1
  113. package/lib/version.js.map +1 -1
  114. package/package.json +43 -32
  115. package/src/animation.ts +14 -12
  116. package/src/classNames.ts +52 -52
  117. package/src/dataLoader.ts +79 -71
  118. package/src/dragAndDropHandler/binarySearch.ts +17 -17
  119. package/src/dragAndDropHandler/dragElement.ts +51 -50
  120. package/src/dragAndDropHandler/generateHitAreas.ts +156 -161
  121. package/src/dragAndDropHandler/index.ts +334 -348
  122. package/src/dragAndDropHandler/iterateVisibleNodes.ts +61 -63
  123. package/src/dragAndDropHandler/types.ts +5 -5
  124. package/src/elementsRenderer.ts +377 -294
  125. package/src/events.ts +241 -208
  126. package/src/header.txt +1 -1
  127. package/src/index.ts +259 -229
  128. package/src/keyHandler.ts +179 -115
  129. package/src/methodTypes.ts +7 -10
  130. package/src/mouseHandler.ts +316 -316
  131. package/src/mouseUtils.ts +14 -14
  132. package/src/node.ts +773 -771
  133. package/src/nodeElement/borderDropHint.ts +25 -25
  134. package/src/nodeElement/folderElement.ts +116 -102
  135. package/src/nodeElement/ghostDropHint.ts +64 -62
  136. package/src/nodeElement/index.ts +81 -73
  137. package/src/nodeUtils.ts +5 -5
  138. package/src/options.ts +25 -5
  139. package/src/requestUrl.ts +7 -14
  140. package/src/saveStateHandler.ts +191 -207
  141. package/src/scrollHandler/containerScrollParent.ts +40 -49
  142. package/src/scrollHandler/createScrollParent.ts +26 -27
  143. package/src/scrollHandler/documentScrollParent.ts +66 -72
  144. package/src/scrollHandler/scrollParent.ts +90 -86
  145. package/src/scrollHandler.ts +45 -45
  146. package/src/selectNodeHandler.ts +171 -165
  147. package/src/setDefaultOptions.ts +44 -32
  148. package/src/triggerCustomEvent.ts +7 -3
  149. package/src/util.ts +2 -3
  150. package/src/version.ts +1 -1
  151. package/tree_element.css +87 -69
  152. package/tree_element.debug.js +3866 -3831
  153. package/tree_element.debug.js.map +1 -1
  154. package/tree_element.js +2 -2
  155. package/tree_element.js.map +1 -1
package/src/keyHandler.ts CHANGED
@@ -1,139 +1,203 @@
1
1
  import type {
2
- CloseNode,
3
- GetSelectedNode,
4
- IsFocusOnTree,
5
- OpenNode,
6
- SelectNode,
2
+ CloseNode,
3
+ GetFocusedNode,
4
+ GetSelectedNode,
5
+ GetTree,
6
+ OpenNode,
7
+ SelectNode,
8
+ TriggerEvent,
7
9
  } from "./methodTypes";
8
10
  import type { Node } from "./node";
9
11
 
10
12
  interface KeyHandlerParams {
11
- closeNode: CloseNode;
12
- getSelectedNode: GetSelectedNode;
13
- isFocusOnTree: IsFocusOnTree;
14
- keyboardSupport: boolean;
15
- openNode: OpenNode;
16
- selectNode: SelectNode;
13
+ closeNode: CloseNode;
14
+ getFocusedNode: GetFocusedNode;
15
+ getSelectedNode: GetSelectedNode;
16
+ getTree: GetTree;
17
+ keyboardSupport: boolean;
18
+ openNode: OpenNode;
19
+ selectNode: SelectNode;
20
+ triggerEvent: TriggerEvent;
17
21
  }
18
22
 
19
23
  export default class KeyHandler {
20
- private closeNode: CloseNode;
21
- private getSelectedNode: GetSelectedNode;
22
-
23
- private isFocusOnTree: IsFocusOnTree;
24
-
25
- private keyboardSupport: boolean;
26
- private openNode: OpenNode;
27
- private originalSelectNode: SelectNode;
28
- constructor({
29
- closeNode,
30
- getSelectedNode,
31
- isFocusOnTree,
32
- keyboardSupport,
33
- openNode,
34
- selectNode,
35
- }: KeyHandlerParams) {
36
- this.closeNode = closeNode;
37
- this.getSelectedNode = getSelectedNode;
38
- this.isFocusOnTree = isFocusOnTree;
39
- this.keyboardSupport = keyboardSupport;
40
- this.openNode = openNode;
41
- this.originalSelectNode = selectNode;
42
-
43
- if (keyboardSupport) {
44
- document.addEventListener("keydown", this.handleKeyDown);
45
- }
24
+ private closeNode: CloseNode;
25
+ private getFocusedNode: GetFocusedNode;
26
+ private getSelectedNode: GetSelectedNode;
27
+ private getTree: GetTree;
28
+
29
+ private keyboardSupport: boolean;
30
+ private openNode: OpenNode;
31
+ private originalSelectNode: SelectNode;
32
+ private triggerEvent: TriggerEvent;
33
+
34
+ constructor({
35
+ closeNode,
36
+ getFocusedNode,
37
+ getSelectedNode,
38
+ getTree,
39
+ keyboardSupport,
40
+ openNode,
41
+ selectNode,
42
+ triggerEvent,
43
+ }: KeyHandlerParams) {
44
+ this.closeNode = closeNode;
45
+ this.getFocusedNode = getFocusedNode;
46
+ this.getSelectedNode = getSelectedNode;
47
+ this.getTree = getTree;
48
+ this.keyboardSupport = keyboardSupport;
49
+ this.openNode = openNode;
50
+ this.originalSelectNode = selectNode;
51
+ this.triggerEvent = triggerEvent;
52
+
53
+ if (keyboardSupport) {
54
+ document.addEventListener("keydown", this.handleKeyDown);
46
55
  }
56
+ }
47
57
 
48
- public deinit(): void {
49
- if (this.keyboardSupport) {
50
- document.removeEventListener("keydown", this.handleKeyDown);
51
- }
58
+ public deinit(): void {
59
+ if (this.keyboardSupport) {
60
+ document.removeEventListener("keydown", this.handleKeyDown);
52
61
  }
62
+ }
63
+
64
+ public moveDown(): boolean {
65
+ return this.selectNode(this.getSelectedNode()?.getNextVisibleNode());
66
+ }
67
+
68
+ public moveUp(): boolean {
69
+ return this.selectNode(this.getSelectedNode()?.getPreviousVisibleNode());
70
+ }
71
+
72
+ // Activate the node, for example to open its edit page.
73
+ private activate(node: Node, originalEvent: KeyboardEvent): boolean {
74
+ this.triggerEvent("tree.activate", { node, originalEvent });
75
+ return true;
76
+ }
77
+
78
+ private handleArrowKey(key: string): boolean {
79
+ switch (key) {
80
+ case "ArrowDown": {
81
+ return this.moveDown();
82
+ }
83
+
84
+ case "ArrowLeft": {
85
+ return this.moveLeft();
86
+ }
87
+
88
+ case "ArrowRight": {
89
+ return this.moveRight();
90
+ }
91
+
92
+ case "ArrowUp": {
93
+ return this.moveUp();
94
+ }
95
+
96
+ default: {
97
+ return false;
98
+ }
99
+ }
100
+ }
53
101
 
54
- public moveDown(selectedNode: Node): boolean {
55
- return this.selectNode(selectedNode.getNextVisibleNode());
102
+ private handleKeyDown = (e: KeyboardEvent): void => {
103
+ const focusedNode = this.getFocusedNode();
104
+
105
+ if (!focusedNode) {
106
+ return;
56
107
  }
57
108
 
58
- public moveUp(selectedNode: Node): boolean {
59
- return this.selectNode(selectedNode.getPreviousVisibleNode());
109
+ let isKeyHandled: boolean;
110
+
111
+ const selectedNode = this.getSelectedNode();
112
+
113
+ switch (e.key) {
114
+ case "End": {
115
+ isKeyHandled = this.selectNode(this.getTree()?.getLastChild());
116
+ break;
117
+ }
118
+
119
+ case "Enter": {
120
+ // Without a selected node, activate the focused node
121
+ isKeyHandled = this.activate(selectedNode ?? focusedNode, e);
122
+ break;
123
+ }
124
+
125
+ case "Home": {
126
+ isKeyHandled = this.selectNode(this.getTree()?.children[0]);
127
+ break;
128
+ }
129
+
130
+ default: {
131
+ isKeyHandled = selectedNode
132
+ ? this.handleArrowKey(e.key)
133
+ : this.handleKeyWithoutSelection(e.key, focusedNode);
134
+ }
60
135
  }
61
136
 
62
- private canHandleKeyboard(): boolean {
63
- return this.keyboardSupport && this.isFocusOnTree();
137
+ if (isKeyHandled) {
138
+ e.preventDefault();
139
+ }
140
+ };
141
+
142
+ // No node is selected. These keys select the focused node, which is
143
+ // usually the first node, see TreeElement.updateTabStop.
144
+ private handleKeyWithoutSelection(key: string, focusedNode: Node): boolean {
145
+ switch (key) {
146
+ case " ":
147
+ case "ArrowDown":
148
+ case "ArrowRight": {
149
+ return this.selectNode(focusedNode);
150
+ }
151
+
152
+ default: {
153
+ return false;
154
+ }
64
155
  }
156
+ }
157
+
158
+ private moveLeft(): boolean {
159
+ const selectedNode = this.getSelectedNode();
65
160
 
66
- private handleKeyDown = (e: KeyboardEvent): void => {
67
- if (!this.canHandleKeyboard()) {
68
- return;
69
- }
70
-
71
- let isKeyHandled = false;
72
-
73
- const selectedNode = this.getSelectedNode();
74
- if (selectedNode) {
75
- switch (e.key) {
76
- case "ArrowDown":
77
- isKeyHandled = this.moveDown(selectedNode);
78
- break;
79
-
80
- case "ArrowLeft":
81
- isKeyHandled = this.moveLeft(selectedNode);
82
- break;
83
-
84
- case "ArrowRight":
85
- isKeyHandled = this.moveRight(selectedNode);
86
- break;
87
-
88
- case "ArrowUp":
89
- isKeyHandled = this.moveUp(selectedNode);
90
- break;
91
- }
92
- }
93
-
94
- if (isKeyHandled) {
95
- e.preventDefault();
96
- }
97
- };
98
-
99
- private moveLeft(selectedNode: Node): boolean {
100
- if (selectedNode.isFolder() && selectedNode.is_open) {
101
- // Left on an open node closes the node
102
- this.closeNode(selectedNode);
103
- return true;
104
- } else {
105
- // Left on a closed or end node moves focus to the node's parent
106
- return this.selectNode(selectedNode.getParent());
107
- }
161
+ /* istanbul ignore if */
162
+ if (!selectedNode) {
163
+ return false;
108
164
  }
109
165
 
110
- private moveRight(selectedNode: Node): boolean {
111
- if (!selectedNode.isFolder()) {
112
- return false;
113
- } else {
114
- // folder node
115
- if (selectedNode.is_open) {
116
- // Right moves to the first child of an open node
117
- return this.selectNode(selectedNode.getNextVisibleNode());
118
- } else {
119
- // Right expands a closed node
120
- void this.openNode(selectedNode);
121
- return true;
122
- }
123
- }
166
+ if (selectedNode.isFolder() && selectedNode.is_open) {
167
+ // Left on an open node closes the node
168
+ void this.closeNode(selectedNode);
169
+ return true;
124
170
  }
171
+ // Left on a closed or end node moves focus to the node's parent
172
+ return this.selectNode(selectedNode.getParent());
173
+ }
125
174
 
126
- /* Select the node.
127
- * Don't do anything if the node is null.
128
- * Result: a different node was selected.
129
- */
130
- private selectNode(node: Node | null): boolean {
131
- if (!node) {
132
- return false;
133
- } else {
134
- this.originalSelectNode(node);
135
-
136
- return true;
137
- }
175
+ private moveRight(): boolean {
176
+ const selectedNode = this.getSelectedNode();
177
+
178
+ if (selectedNode?.isFolder()) {
179
+ // folder node
180
+ if (selectedNode.is_open) {
181
+ // Right moves to the first child of an open node
182
+ return this.selectNode(selectedNode.getNextVisibleNode());
183
+ }
184
+ // Right expands a closed node
185
+ void this.openNode(selectedNode);
186
+ return true;
187
+ }
188
+ return false;
189
+ }
190
+
191
+ /* Select the node.
192
+ * Don't do anything if the node is null.
193
+ * Result: a different node was selected.
194
+ */
195
+ private selectNode(node?: Node | null): boolean {
196
+ if (node) {
197
+ this.originalSelectNode(node);
198
+
199
+ return true;
138
200
  }
201
+ return false;
202
+ }
139
203
  }
@@ -4,7 +4,9 @@ import type NodeElement from "./nodeElement";
4
4
 
5
5
  export type AddToSelection = (node: Node) => void;
6
6
 
7
- export type CloseNode = (node: Node) => void;
7
+ export type CloseNode = (node: Node) => Promise<void>;
8
+
9
+ export type GetFocusedNode = () => Node | null;
8
10
 
9
11
  export type GetNodeById = (nodeId: NodeId) => Node | null;
10
12
 
@@ -12,22 +14,17 @@ export type GetNodeElementForNode = (node: Node) => NodeElement;
12
14
 
13
15
  export type GetScrollLeft = () => number;
14
16
 
15
- export type GetSelectedNode = () => false | Node;
17
+ export type GetSelectedNode = () => Node | null;
16
18
 
17
19
  export type GetSelectedNodes = () => Node[];
18
20
 
19
21
  export type GetTree = () => Node | null;
20
22
 
21
- export type IsFocusOnTree = () => boolean;
22
-
23
23
  export type IsNodeSelected = (node: Node) => boolean;
24
24
 
25
25
  export type LoadData = (data: NodeData[], parentNode?: Node) => void;
26
26
 
27
- export type OpenNode = (
28
- node: Node,
29
- slide?: boolean,
30
- ) => Promise<void>;
27
+ export type OpenNode = (node: Node, slide?: boolean) => Promise<void>;
31
28
 
32
29
  export type OpenParents = (node: Node) => void;
33
30
 
@@ -39,6 +36,6 @@ export type SelectNode = (node: Node) => void;
39
36
 
40
37
  // Trigger an event. Return if the event is processed (true) or cancelled (false).
41
38
  export type TriggerEvent = <Name extends TreeEventName>(
42
- eventName: Name,
43
- values?: TreeEvents[Name],
39
+ eventName: Name,
40
+ values?: TreeEvents[Name],
44
41
  ) => boolean;