tree-element 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -29
- package/lib/animation.js +5 -5
- package/lib/animation.js.map +1 -1
- package/lib/classNames.d.ts.map +1 -1
- package/lib/classNames.js +2 -2
- package/lib/classNames.js.map +1 -1
- package/lib/dataLoader.d.ts.map +1 -1
- package/lib/dataLoader.js +14 -20
- package/lib/dataLoader.js.map +1 -1
- package/lib/dragAndDropHandler/binarySearch.js +3 -3
- package/lib/dragAndDropHandler/binarySearch.js.map +1 -1
- package/lib/dragAndDropHandler/dragElement.d.ts.map +1 -1
- package/lib/dragAndDropHandler/dragElement.js +9 -12
- package/lib/dragAndDropHandler/dragElement.js.map +1 -1
- package/lib/dragAndDropHandler/generateHitAreas.d.ts.map +1 -1
- package/lib/dragAndDropHandler/generateHitAreas.js +25 -25
- package/lib/dragAndDropHandler/generateHitAreas.js.map +1 -1
- package/lib/dragAndDropHandler/index.d.ts.map +1 -1
- package/lib/dragAndDropHandler/index.js +90 -114
- package/lib/dragAndDropHandler/index.js.map +1 -1
- package/lib/dragAndDropHandler/iterateVisibleNodes.d.ts.map +1 -1
- package/lib/dragAndDropHandler/iterateVisibleNodes.js +10 -10
- package/lib/dragAndDropHandler/iterateVisibleNodes.js.map +1 -1
- package/lib/dragAndDropHandler/types.d.ts.map +1 -1
- package/lib/elementsRenderer.d.ts +15 -6
- package/lib/elementsRenderer.d.ts.map +1 -1
- package/lib/elementsRenderer.js +157 -121
- package/lib/elementsRenderer.js.map +1 -1
- package/lib/events.d.ts.map +1 -1
- package/lib/index.d.ts +5 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +249 -252
- package/lib/index.js.map +1 -1
- package/lib/keyHandler.d.ts +2 -3
- package/lib/keyHandler.d.ts.map +1 -1
- package/lib/keyHandler.js +26 -25
- package/lib/keyHandler.js.map +1 -1
- package/lib/methodTypes.d.ts +1 -1
- package/lib/methodTypes.d.ts.map +1 -1
- package/lib/mouseHandler.d.ts.map +1 -1
- package/lib/mouseHandler.js +26 -42
- package/lib/mouseHandler.js.map +1 -1
- package/lib/mouseUtils.d.ts.map +1 -1
- package/lib/mouseUtils.js +2 -2
- package/lib/mouseUtils.js.map +1 -1
- package/lib/node.d.ts +2 -1
- package/lib/node.d.ts.map +1 -1
- package/lib/node.js +36 -35
- package/lib/node.js.map +1 -1
- package/lib/nodeElement/borderDropHint.d.ts.map +1 -1
- package/lib/nodeElement/borderDropHint.js +4 -5
- package/lib/nodeElement/borderDropHint.js.map +1 -1
- package/lib/nodeElement/folderElement.d.ts +7 -4
- package/lib/nodeElement/folderElement.d.ts.map +1 -1
- package/lib/nodeElement/folderElement.js +61 -42
- package/lib/nodeElement/folderElement.js.map +1 -1
- package/lib/nodeElement/ghostDropHint.d.ts.map +1 -1
- package/lib/nodeElement/ghostDropHint.js +5 -9
- package/lib/nodeElement/ghostDropHint.js.map +1 -1
- package/lib/nodeElement/index.d.ts +2 -1
- package/lib/nodeElement/index.d.ts.map +1 -1
- package/lib/nodeElement/index.js +34 -26
- package/lib/nodeElement/index.js.map +1 -1
- package/lib/nodeUtils.d.ts.map +1 -1
- package/lib/nodeUtils.js +1 -1
- package/lib/nodeUtils.js.map +1 -1
- package/lib/options.d.ts.map +1 -1
- package/lib/positionUtils.js +3 -3
- package/lib/positionUtils.js.map +1 -1
- package/lib/requestUrl.d.ts +1 -1
- package/lib/requestUrl.d.ts.map +1 -1
- package/lib/requestUrl.js +4 -6
- package/lib/requestUrl.js.map +1 -1
- package/lib/saveStateHandler.d.ts.map +1 -1
- package/lib/saveStateHandler.js +38 -48
- package/lib/saveStateHandler.js.map +1 -1
- package/lib/scrollHandler/containerScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/containerScrollParent.js +9 -11
- package/lib/scrollHandler/containerScrollParent.js.map +1 -1
- package/lib/scrollHandler/createScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/createScrollParent.js +10 -10
- package/lib/scrollHandler/createScrollParent.js.map +1 -1
- package/lib/scrollHandler/documentScrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/documentScrollParent.js +16 -19
- package/lib/scrollHandler/documentScrollParent.js.map +1 -1
- package/lib/scrollHandler/scrollParent.d.ts.map +1 -1
- package/lib/scrollHandler/scrollParent.js +11 -17
- package/lib/scrollHandler/scrollParent.js.map +1 -1
- package/lib/scrollHandler.d.ts.map +1 -1
- package/lib/scrollHandler.js +11 -14
- package/lib/scrollHandler.js.map +1 -1
- package/lib/selectNodeHandler.d.ts +2 -2
- package/lib/selectNodeHandler.d.ts.map +1 -1
- package/lib/selectNodeHandler.js +45 -54
- package/lib/selectNodeHandler.js.map +1 -1
- package/lib/setDefaultOptions.d.ts.map +1 -1
- package/lib/setDefaultOptions.js +23 -28
- package/lib/setDefaultOptions.js.map +1 -1
- package/lib/triggerCustomEvent.d.ts.map +1 -1
- package/lib/triggerCustomEvent.js +2 -2
- package/lib/triggerCustomEvent.js.map +1 -1
- package/lib/util.d.ts.map +1 -1
- package/lib/util.js +2 -2
- package/lib/util.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 +5 -3
- package/src/animation.ts +1 -1
- package/src/classNames.ts +52 -52
- package/src/dataLoader.ts +68 -71
- package/src/dragAndDropHandler/binarySearch.ts +17 -17
- package/src/dragAndDropHandler/dragElement.ts +50 -50
- package/src/dragAndDropHandler/generateHitAreas.ts +156 -161
- package/src/dragAndDropHandler/index.ts +342 -351
- package/src/dragAndDropHandler/iterateVisibleNodes.ts +59 -63
- package/src/dragAndDropHandler/types.ts +5 -5
- package/src/elementsRenderer.ts +351 -298
- package/src/events.ts +216 -216
- package/src/header.txt +1 -1
- package/src/index.ts +52 -82
- package/src/keyHandler.ts +125 -115
- package/src/methodTypes.ts +4 -7
- package/src/mouseHandler.ts +314 -317
- package/src/mouseUtils.ts +14 -14
- package/src/node.ts +761 -766
- package/src/nodeElement/borderDropHint.ts +25 -25
- package/src/nodeElement/folderElement.ts +135 -112
- package/src/nodeElement/ghostDropHint.ts +62 -62
- package/src/nodeElement/index.ts +88 -74
- package/src/nodeUtils.ts +5 -5
- package/src/options.ts +6 -2
- package/src/requestUrl.ts +3 -3
- package/src/saveStateHandler.ts +204 -206
- package/src/scrollHandler/containerScrollParent.ts +49 -52
- package/src/scrollHandler/createScrollParent.ts +27 -27
- package/src/scrollHandler/documentScrollParent.ts +70 -70
- package/src/scrollHandler/scrollParent.ts +98 -98
- package/src/scrollHandler.ts +45 -45
- package/src/selectNodeHandler.ts +176 -166
- package/src/setDefaultOptions.ts +25 -22
- package/src/triggerCustomEvent.ts +7 -3
- package/src/util.ts +2 -2
- package/src/version.ts +1 -1
- package/tree_element.debug.js +3752 -3784
- package/tree_element.debug.js.map +1 -1
- package/tree_element.js +2 -2
- package/tree_element.js.map +1 -1
|
@@ -2,36 +2,36 @@ import type { ClassNames } from "../classNames";
|
|
|
2
2
|
import type { DropHint } from "../dragAndDropHandler/types";
|
|
3
3
|
|
|
4
4
|
class BorderDropHint implements DropHint {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
private hint?: HTMLElement;
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
element: HTMLElement,
|
|
9
|
+
scrollLeft: number,
|
|
10
|
+
classNames: ClassNames,
|
|
11
|
+
) {
|
|
12
|
+
const div = element.querySelector(`:scope > .${classNames.element}`);
|
|
13
|
+
|
|
14
|
+
if (!div) {
|
|
15
|
+
this.hint = undefined;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
19
|
+
const width = Math.max(element.offsetWidth + scrollLeft - 4, 0);
|
|
20
|
+
const height = Math.max(element.clientHeight - 4, 0);
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
const hint = document.createElement("span");
|
|
23
|
+
hint.className = classNames.border;
|
|
24
|
+
hint.style.width = `${width}px`;
|
|
25
|
+
hint.style.height = `${height}px`;
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
hint.className = classNames.border;
|
|
24
|
-
hint.style.width = `${width}px`;
|
|
25
|
-
hint.style.height = `${height}px`;
|
|
27
|
+
this.hint = hint;
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
div.append(this.hint);
|
|
30
|
+
}
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
public remove(): void {
|
|
33
|
-
this.hint?.remove();
|
|
34
|
-
}
|
|
32
|
+
public remove(): void {
|
|
33
|
+
this.hint?.remove();
|
|
34
|
+
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export default BorderDropHint;
|
|
@@ -1,140 +1,163 @@
|
|
|
1
1
|
import type { AnimationSpeed } from "../animation";
|
|
2
2
|
import type { TriggerEvent } from "../methodTypes";
|
|
3
|
-
import type { Position } from "../node";
|
|
3
|
+
import type { Node, Position } from "../node";
|
|
4
4
|
import type { NodeElementParams } from "./index";
|
|
5
5
|
|
|
6
6
|
import { slideDown, slideUp } from "../animation";
|
|
7
7
|
import NodeElement from "./index";
|
|
8
8
|
|
|
9
|
+
export type RenderChildren = (node: Node) => HTMLUListElement | null;
|
|
10
|
+
|
|
9
11
|
interface FolderElementParams extends NodeElementParams {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
closedIconElement?: globalThis.Node;
|
|
13
|
+
openedIconElement?: globalThis.Node;
|
|
14
|
+
renderChildren: RenderChildren;
|
|
15
|
+
triggerEvent: TriggerEvent;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
class FolderElement extends NodeElement {
|
|
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
|
-
|
|
19
|
+
private closedIconElement?: globalThis.Node;
|
|
20
|
+
private openedIconElement?: globalThis.Node;
|
|
21
|
+
private renderChildren: RenderChildren;
|
|
22
|
+
private triggerEvent: TriggerEvent;
|
|
23
|
+
|
|
24
|
+
constructor({
|
|
25
|
+
classNames,
|
|
26
|
+
closedIconElement,
|
|
27
|
+
getScrollLeft,
|
|
28
|
+
node,
|
|
29
|
+
openedIconElement,
|
|
30
|
+
renderChildren,
|
|
31
|
+
tabIndex,
|
|
32
|
+
treeElement,
|
|
33
|
+
triggerEvent,
|
|
34
|
+
}: FolderElementParams) {
|
|
35
|
+
super({
|
|
36
|
+
classNames,
|
|
37
|
+
getScrollLeft,
|
|
38
|
+
node,
|
|
39
|
+
tabIndex,
|
|
40
|
+
treeElement,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
this.closedIconElement = closedIconElement;
|
|
44
|
+
this.openedIconElement = openedIconElement;
|
|
45
|
+
this.renderChildren = renderChildren;
|
|
46
|
+
this.triggerEvent = triggerEvent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public close(slide: boolean, animationSpeed: AnimationSpeed): void {
|
|
50
|
+
if (!this.node.is_open) {
|
|
51
|
+
return;
|
|
41
52
|
}
|
|
42
53
|
|
|
43
|
-
|
|
44
|
-
if (!this.node.is_open) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
this.node.is_open = false;
|
|
49
|
-
|
|
50
|
-
const button = this.getButton();
|
|
51
|
-
button.classList.add(this.classNames.closed);
|
|
52
|
-
button.innerHTML = "";
|
|
53
|
-
|
|
54
|
-
const closedIconElement = this.closedIconElement;
|
|
55
|
-
|
|
56
|
-
if (closedIconElement) {
|
|
57
|
-
const icon = closedIconElement.cloneNode(true);
|
|
58
|
-
button.appendChild(icon);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const doClose = (): void => {
|
|
62
|
-
this.element.classList.add(this.classNames.closed);
|
|
63
|
-
|
|
64
|
-
const titleSpan = this.getTitleSpan();
|
|
65
|
-
titleSpan.setAttribute("aria-expanded", "false");
|
|
66
|
-
|
|
67
|
-
this.triggerEvent("tree.close", {
|
|
68
|
-
node: this.node,
|
|
69
|
-
});
|
|
70
|
-
};
|
|
54
|
+
this.node.is_open = false;
|
|
71
55
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
slideUp(ul, animationSpeed, doClose);
|
|
76
|
-
} else {
|
|
77
|
-
ul.style.display = "none";
|
|
78
|
-
doClose();
|
|
79
|
-
}
|
|
56
|
+
if (!this.isRendered()) {
|
|
57
|
+
this.triggerEvent("tree.close", { node: this.node });
|
|
58
|
+
return;
|
|
80
59
|
}
|
|
81
60
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
): Promise<void> {
|
|
86
|
-
return new Promise(resolve => {
|
|
87
|
-
if (this.node.is_open) {
|
|
88
|
-
resolve();
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
this.node.is_open = true;
|
|
93
|
-
|
|
94
|
-
const button = this.getButton();
|
|
95
|
-
button.classList.remove(this.classNames.closed);
|
|
96
|
-
button.innerHTML = "";
|
|
97
|
-
|
|
98
|
-
const openedIconElement = this.openedIconElement;
|
|
99
|
-
|
|
100
|
-
if (openedIconElement) {
|
|
101
|
-
const icon = openedIconElement.cloneNode(true);
|
|
102
|
-
button.appendChild(icon);
|
|
103
|
-
}
|
|
61
|
+
const button = this.getButton();
|
|
62
|
+
button.classList.add(this.classNames.closed);
|
|
63
|
+
button.innerHTML = "";
|
|
104
64
|
|
|
105
|
-
|
|
106
|
-
this.element.classList.remove(this.classNames.closed);
|
|
65
|
+
const closedIconElement = this.closedIconElement;
|
|
107
66
|
|
|
108
|
-
|
|
109
|
-
|
|
67
|
+
if (closedIconElement) {
|
|
68
|
+
const icon = closedIconElement.cloneNode(true);
|
|
69
|
+
button.appendChild(icon);
|
|
70
|
+
}
|
|
110
71
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
});
|
|
72
|
+
const doClose = (): void => {
|
|
73
|
+
this.element.classList.add(this.classNames.closed);
|
|
114
74
|
|
|
115
|
-
|
|
116
|
-
|
|
75
|
+
const titleSpan = this.getTitleSpan();
|
|
76
|
+
titleSpan.setAttribute("aria-expanded", "false");
|
|
117
77
|
|
|
118
|
-
|
|
78
|
+
this.triggerEvent("tree.close", {
|
|
79
|
+
node: this.node,
|
|
80
|
+
});
|
|
81
|
+
};
|
|
119
82
|
|
|
120
|
-
|
|
121
|
-
slideDown(ul, animationSpeed, doOpen);
|
|
122
|
-
} else {
|
|
123
|
-
ul.style.display = "block";
|
|
124
|
-
doOpen();
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
83
|
+
const ul = this.getUl();
|
|
128
84
|
|
|
129
|
-
|
|
130
|
-
|
|
85
|
+
if (!ul) {
|
|
86
|
+
doClose();
|
|
87
|
+
} else if (slide) {
|
|
88
|
+
slideUp(ul, animationSpeed, doClose);
|
|
89
|
+
} else {
|
|
90
|
+
ul.style.display = "none";
|
|
91
|
+
doClose();
|
|
131
92
|
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public async open(
|
|
96
|
+
slide: boolean,
|
|
97
|
+
animationSpeed: AnimationSpeed,
|
|
98
|
+
): Promise<void> {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
if (this.node.is_open) {
|
|
101
|
+
resolve();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this.node.is_open = true;
|
|
106
|
+
|
|
107
|
+
if (!this.isRendered()) {
|
|
108
|
+
// The folder is rendered open when its parent is opened
|
|
109
|
+
this.triggerEvent("tree.open", { node: this.node });
|
|
110
|
+
resolve();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const button = this.getButton();
|
|
115
|
+
button.classList.remove(this.classNames.closed);
|
|
116
|
+
button.innerHTML = "";
|
|
117
|
+
|
|
118
|
+
const openedIconElement = this.openedIconElement;
|
|
119
|
+
|
|
120
|
+
if (openedIconElement) {
|
|
121
|
+
const icon = openedIconElement.cloneNode(true);
|
|
122
|
+
button.appendChild(icon);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const doOpen = (): void => {
|
|
126
|
+
this.element.classList.remove(this.classNames.closed);
|
|
127
|
+
|
|
128
|
+
const titleSpan = this.getTitleSpan();
|
|
129
|
+
titleSpan.setAttribute("aria-expanded", "true");
|
|
130
|
+
|
|
131
|
+
this.triggerEvent("tree.open", {
|
|
132
|
+
node: this.node,
|
|
133
|
+
});
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
resolve();
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// The children are rendered the first time the folder is opened
|
|
139
|
+
const ul = this.getUl() ?? this.renderChildren(this.node);
|
|
140
|
+
|
|
141
|
+
if (!ul) {
|
|
142
|
+
doOpen();
|
|
143
|
+
} else if (slide) {
|
|
144
|
+
slideDown(ul, animationSpeed, doOpen);
|
|
145
|
+
} else {
|
|
146
|
+
ul.style.display = "block";
|
|
147
|
+
doOpen();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
protected mustShowBorderDropHint(position: Position): boolean {
|
|
153
|
+
return !this.node.is_open && position === "inside";
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private getButton(): HTMLLinkElement {
|
|
157
|
+
return this.element.querySelector(
|
|
158
|
+
`:scope > .${this.classNames.element} > a.${this.classNames.toggler}`,
|
|
159
|
+
) as HTMLLinkElement;
|
|
160
|
+
}
|
|
138
161
|
}
|
|
139
162
|
|
|
140
163
|
export default FolderElement;
|
|
@@ -3,82 +3,82 @@ import type { DropHint } from "../dragAndDropHandler/types";
|
|
|
3
3
|
import type { Node, Position } from "../node";
|
|
4
4
|
|
|
5
5
|
class GhostDropHint implements DropHint {
|
|
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
|
-
}
|
|
6
|
+
private classNames: ClassNames;
|
|
7
|
+
private element: HTMLElement;
|
|
8
|
+
private ghost: HTMLElement;
|
|
9
|
+
private node: Node;
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
node: Node,
|
|
13
|
+
element: HTMLElement,
|
|
14
|
+
position: Position,
|
|
15
|
+
classNames: ClassNames,
|
|
16
|
+
) {
|
|
17
|
+
this.classNames = classNames;
|
|
18
|
+
this.element = element;
|
|
19
|
+
this.node = node;
|
|
20
|
+
this.ghost = this.createGhostElement();
|
|
21
|
+
|
|
22
|
+
switch (position) {
|
|
23
|
+
case "after":
|
|
24
|
+
this.moveAfter();
|
|
25
|
+
break;
|
|
26
|
+
|
|
27
|
+
case "before":
|
|
28
|
+
this.moveBefore();
|
|
29
|
+
break;
|
|
30
|
+
|
|
31
|
+
case "inside": {
|
|
32
|
+
if (node.isFolder() && node.is_open) {
|
|
33
|
+
this.moveInsideOpenFolder();
|
|
34
|
+
} else {
|
|
35
|
+
this.moveInside();
|
|
38
36
|
}
|
|
37
|
+
}
|
|
39
38
|
}
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
public remove(): void {
|
|
42
|
+
this.ghost.remove();
|
|
43
|
+
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
private createGhostElement() {
|
|
46
|
+
const { circle, common, ghost: ghostClass, line } = this.classNames;
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const ghost = document.createElement("li");
|
|
49
|
+
ghost.className = `${common} ${ghostClass}`;
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
const circleSpan = document.createElement("span");
|
|
52
|
+
circleSpan.className = `${common} ${circle}`;
|
|
53
|
+
ghost.append(circleSpan);
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const lineSpan = document.createElement("span");
|
|
56
|
+
lineSpan.className = `${common} ${line}`;
|
|
57
|
+
ghost.append(lineSpan);
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
return ghost;
|
|
60
|
+
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
private moveAfter(): void {
|
|
63
|
+
this.element.after(this.ghost);
|
|
64
|
+
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
private moveBefore(): void {
|
|
67
|
+
this.element.before(this.ghost);
|
|
68
|
+
}
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
private moveInside(): void {
|
|
71
|
+
this.element.after(this.ghost);
|
|
72
|
+
this.ghost.classList.add(this.classNames.inside);
|
|
73
|
+
}
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
private moveInsideOpenFolder(): void {
|
|
76
|
+
const childElement = this.node.children[0]?.element;
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
78
|
+
if (childElement) {
|
|
79
|
+
childElement.before(this.ghost);
|
|
81
80
|
}
|
|
81
|
+
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
export default GhostDropHint;
|
package/src/nodeElement/index.ts
CHANGED
|
@@ -7,97 +7,111 @@ import BorderDropHint from "./borderDropHint";
|
|
|
7
7
|
import GhostDropHint from "./ghostDropHint";
|
|
8
8
|
|
|
9
9
|
export interface NodeElementParams {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
classNames: ClassNames;
|
|
11
|
+
getScrollLeft: GetScrollLeft;
|
|
12
|
+
node: Node;
|
|
13
|
+
tabIndex?: number;
|
|
14
|
+
treeElement: HTMLElement;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
class NodeElement {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
18
|
+
public element: HTMLElement;
|
|
19
|
+
public node: Node;
|
|
20
|
+
protected classNames: ClassNames;
|
|
21
|
+
private getScrollLeft: GetScrollLeft;
|
|
22
|
+
private tabIndex?: number;
|
|
23
|
+
private treeElement: HTMLElement;
|
|
24
|
+
|
|
25
|
+
constructor({
|
|
26
|
+
classNames,
|
|
27
|
+
getScrollLeft,
|
|
28
|
+
node,
|
|
29
|
+
tabIndex,
|
|
30
|
+
treeElement,
|
|
31
|
+
}: NodeElementParams) {
|
|
32
|
+
this.classNames = classNames;
|
|
33
|
+
this.getScrollLeft = getScrollLeft;
|
|
34
|
+
this.node = node;
|
|
35
|
+
this.tabIndex = tabIndex;
|
|
36
|
+
this.treeElement = treeElement;
|
|
37
|
+
|
|
38
|
+
// The root node has no element of its own; it uses the tree element.
|
|
39
|
+
this.element = node.element ?? this.treeElement;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public addDropHint(position: Position): DropHint {
|
|
43
|
+
if (this.mustShowBorderDropHint(position)) {
|
|
44
|
+
return new BorderDropHint(
|
|
45
|
+
this.element,
|
|
46
|
+
this.getScrollLeft(),
|
|
47
|
+
this.classNames,
|
|
48
|
+
);
|
|
49
|
+
} else {
|
|
50
|
+
return new GhostDropHint(
|
|
51
|
+
this.node,
|
|
52
|
+
this.element,
|
|
53
|
+
position,
|
|
54
|
+
this.classNames,
|
|
55
|
+
);
|
|
41
56
|
}
|
|
57
|
+
}
|
|
42
58
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.element,
|
|
47
|
-
this.getScrollLeft(),
|
|
48
|
-
this.classNames,
|
|
49
|
-
);
|
|
50
|
-
} else {
|
|
51
|
-
return new GhostDropHint(
|
|
52
|
-
this.node,
|
|
53
|
-
this.element,
|
|
54
|
-
position,
|
|
55
|
-
this.classNames,
|
|
56
|
-
);
|
|
57
|
-
}
|
|
59
|
+
public deselect(): void {
|
|
60
|
+
if (!this.isRendered()) {
|
|
61
|
+
return;
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
this.element.classList.remove(this.classNames.selected);
|
|
62
|
-
|
|
63
|
-
const titleSpan = this.getTitleSpan();
|
|
64
|
-
titleSpan.removeAttribute("tabindex");
|
|
65
|
-
titleSpan.setAttribute("aria-selected", "false");
|
|
66
|
-
|
|
67
|
-
titleSpan.blur();
|
|
68
|
-
}
|
|
64
|
+
this.element.classList.remove(this.classNames.selected);
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
const titleSpan = this.getTitleSpan();
|
|
67
|
+
titleSpan.removeAttribute("tabindex");
|
|
68
|
+
titleSpan.setAttribute("aria-selected", "false");
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
titleSpan.blur();
|
|
71
|
+
}
|
|
75
72
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
public select(mustSetFocus: boolean): void {
|
|
74
|
+
if (!this.isRendered()) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
80
77
|
|
|
81
|
-
|
|
78
|
+
this.element.classList.add(this.classNames.selected);
|
|
82
79
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
}
|
|
80
|
+
const titleSpan = this.getTitleSpan();
|
|
81
|
+
const tabIndex = this.tabIndex;
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
) as HTMLSpanElement;
|
|
83
|
+
// Check for null or undefined
|
|
84
|
+
if (tabIndex != null) {
|
|
85
|
+
titleSpan.setAttribute("tabindex", tabIndex.toString());
|
|
92
86
|
}
|
|
93
87
|
|
|
94
|
-
|
|
95
|
-
return this.element.querySelector(":scope > ul") as HTMLUListElement;
|
|
96
|
-
}
|
|
88
|
+
titleSpan.setAttribute("aria-selected", "true");
|
|
97
89
|
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
if (mustSetFocus) {
|
|
91
|
+
titleSpan.focus();
|
|
100
92
|
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
protected getTitleSpan(): HTMLSpanElement {
|
|
96
|
+
return this.element.querySelector(
|
|
97
|
+
`:scope > .${this.classNames.element} > span.${this.classNames.title}`,
|
|
98
|
+
) as HTMLSpanElement;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected getUl(): HTMLUListElement | null {
|
|
102
|
+
return this.element.querySelector(":scope > ul");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* A node inside a closed folder is not rendered. Its selected and open
|
|
106
|
+
* state is applied when it is rendered.
|
|
107
|
+
*/
|
|
108
|
+
protected isRendered(): boolean {
|
|
109
|
+
return Boolean(this.node.element);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected mustShowBorderDropHint(position: Position): boolean {
|
|
113
|
+
return position === "inside";
|
|
114
|
+
}
|
|
101
115
|
}
|
|
102
116
|
|
|
103
117
|
export default NodeElement;
|