@woylie/doggo 0.16.0 → 0.16.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 +1 -1
- package/assets/js/hooks/tree.js +33 -39
- package/package.json +1 -1
package/README.md
CHANGED
package/assets/js/hooks/tree.js
CHANGED
|
@@ -10,7 +10,26 @@ const labelOf = (item) =>
|
|
|
10
10
|
const parentOf = (item) =>
|
|
11
11
|
item.parentElement.closest('[role="treeitem"]') || null;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const labelText = (item) => {
|
|
14
|
+
const label = labelOf(item);
|
|
15
|
+
|
|
16
|
+
if (!label) return "";
|
|
17
|
+
|
|
18
|
+
const copy = label.cloneNode(true);
|
|
19
|
+
|
|
20
|
+
for (const node of copy.querySelectorAll('[aria-hidden="true"], svg')) {
|
|
21
|
+
node.remove();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return copy.textContent;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const domWriter = {
|
|
28
|
+
setAttribute: (el, attr, value) => el.setAttribute(attr, value),
|
|
29
|
+
removeAttribute: (el, attr) => el.removeAttribute(attr),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function initTree(tree, writer = domWriter) {
|
|
14
33
|
// Visible items only. A collapsed branch takes its descendants out of the
|
|
15
34
|
// sequence.
|
|
16
35
|
const getItems = () =>
|
|
@@ -18,22 +37,6 @@ export function initTree(tree) {
|
|
|
18
37
|
(item) => !item.closest('[role="group"][hidden]'),
|
|
19
38
|
);
|
|
20
39
|
|
|
21
|
-
// The hook owns the expanded state. A patch re-renders the server's
|
|
22
|
-
// version, so it is remembered by position and applied again.
|
|
23
|
-
const pathOf = (item) => {
|
|
24
|
-
const path = [];
|
|
25
|
-
|
|
26
|
-
for (let node = item; node; node = parentOf(node)) {
|
|
27
|
-
const siblings = Array.from(
|
|
28
|
-
node.parentElement.querySelectorAll(':scope > [role="treeitem"]'),
|
|
29
|
-
);
|
|
30
|
-
path.unshift(siblings.indexOf(node));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return path.join("-");
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const expandedPaths = new Set();
|
|
37
40
|
let activeIdx = 0;
|
|
38
41
|
let search = "";
|
|
39
42
|
let searchTimeout;
|
|
@@ -46,7 +49,7 @@ export function initTree(tree) {
|
|
|
46
49
|
const active = getItems()[idx];
|
|
47
50
|
|
|
48
51
|
for (const item of tree.querySelectorAll('[role="treeitem"]')) {
|
|
49
|
-
|
|
52
|
+
writer.setAttribute(item, "tabindex", item === active ? "0" : "-1");
|
|
50
53
|
}
|
|
51
54
|
};
|
|
52
55
|
|
|
@@ -56,25 +59,17 @@ export function initTree(tree) {
|
|
|
56
59
|
};
|
|
57
60
|
|
|
58
61
|
const setExpanded = (item, expanded) => {
|
|
59
|
-
|
|
62
|
+
writer.setAttribute(item, "aria-expanded", expanded ? "true" : "false");
|
|
60
63
|
|
|
61
64
|
const group = groupOf(item);
|
|
62
65
|
|
|
63
66
|
if (group) {
|
|
64
67
|
if (expanded) {
|
|
65
|
-
|
|
68
|
+
writer.removeAttribute(group, "hidden");
|
|
66
69
|
} else {
|
|
67
|
-
|
|
70
|
+
writer.setAttribute(group, "hidden", "");
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
|
-
|
|
71
|
-
const path = pathOf(item);
|
|
72
|
-
|
|
73
|
-
if (expanded) {
|
|
74
|
-
expandedPaths.add(path);
|
|
75
|
-
} else {
|
|
76
|
-
expandedPaths.delete(path);
|
|
77
|
-
}
|
|
78
73
|
};
|
|
79
74
|
|
|
80
75
|
// Only the caret toggles. A click on the label is the caller's, for
|
|
@@ -106,8 +101,7 @@ export function initTree(tree) {
|
|
|
106
101
|
|
|
107
102
|
const repeated = [...search].every((char) => char === search[0]);
|
|
108
103
|
const items = getItems();
|
|
109
|
-
|
|
110
|
-
const labels = items.map((item) => labelOf(item)?.textContent ?? "");
|
|
104
|
+
const labels = items.map(labelText);
|
|
111
105
|
const idx = searchIndex(
|
|
112
106
|
labels,
|
|
113
107
|
repeated ? search[0] : search,
|
|
@@ -131,7 +125,7 @@ export function initTree(tree) {
|
|
|
131
125
|
if (isBranch(item) && !isExpanded(item)) {
|
|
132
126
|
setExpanded(item, true);
|
|
133
127
|
} else if (isBranch(item)) {
|
|
134
|
-
const child = groupOf(item)
|
|
128
|
+
const child = groupOf(item)?.querySelector('[role="treeitem"]');
|
|
135
129
|
|
|
136
130
|
if (child) moveTo(getItems().indexOf(child));
|
|
137
131
|
}
|
|
@@ -155,6 +149,7 @@ export function initTree(tree) {
|
|
|
155
149
|
|
|
156
150
|
const nextIdx = targetIndex(e.key, currentIdx, items.length, {
|
|
157
151
|
orientation: "vertical",
|
|
152
|
+
wrap: false,
|
|
158
153
|
});
|
|
159
154
|
|
|
160
155
|
if (nextIdx !== null) {
|
|
@@ -170,12 +165,6 @@ export function initTree(tree) {
|
|
|
170
165
|
});
|
|
171
166
|
|
|
172
167
|
const restore = () => {
|
|
173
|
-
for (const item of tree.querySelectorAll('[role="treeitem"]')) {
|
|
174
|
-
if (isBranch(item) && expandedPaths.has(pathOf(item))) {
|
|
175
|
-
setExpanded(item, true);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
168
|
const items = getItems();
|
|
180
169
|
|
|
181
170
|
if (items.length > 0) setActive(clamp(activeIdx, items.length));
|
|
@@ -188,7 +177,12 @@ export function initTree(tree) {
|
|
|
188
177
|
|
|
189
178
|
export default {
|
|
190
179
|
mounted() {
|
|
191
|
-
|
|
180
|
+
const js = this.js();
|
|
181
|
+
|
|
182
|
+
this.instance = initTree(this.el, {
|
|
183
|
+
setAttribute: (el, attr, value) => js.setAttribute(el, attr, value),
|
|
184
|
+
removeAttribute: (el, attr) => js.removeAttribute(el, attr),
|
|
185
|
+
});
|
|
192
186
|
},
|
|
193
187
|
|
|
194
188
|
updated() {
|