@y14e/disclosure-css 2.0.1 → 2.0.3
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 +6 -6
- package/dist/index.bundle.cjs +188 -92
- package/dist/index.bundle.js +188 -92
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -10,14 +10,14 @@ npm i @y14e/disclosure-css
|
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
// npm
|
|
13
|
-
import Disclosure from
|
|
13
|
+
import Disclosure from "@y14e/disclosure-css";
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import Disclosure from
|
|
16
|
+
import Disclosure from "https://esm.sh/@y14e/disclosure-css@2.0.3";
|
|
17
17
|
// or
|
|
18
|
-
import Disclosure from
|
|
18
|
+
import Disclosure from "https://cdn.jsdelivr.net/npm/@y14e/disclosure-css@2.0.3/+esm";
|
|
19
19
|
// or
|
|
20
|
-
import Disclosure from
|
|
20
|
+
import Disclosure from "https://esm.unpkg.com/@y14e/disclosure-css@2.0.3";
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
@@ -34,7 +34,7 @@ new Disclosure(root, options);
|
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
36
|
interface DisclosureOptions {
|
|
37
|
-
collapsible
|
|
37
|
+
collapsible: boolean; // default: true
|
|
38
38
|
}
|
|
39
39
|
```
|
|
40
40
|
|
|
@@ -43,7 +43,7 @@ interface DisclosureOptions {
|
|
|
43
43
|
Override the global default settings applied to all disclosure instances.
|
|
44
44
|
|
|
45
45
|
```ts
|
|
46
|
-
import Disclosure from
|
|
46
|
+
import Disclosure from "@y14e/disclosure-css";
|
|
47
47
|
|
|
48
48
|
Disclosure.defaults = {
|
|
49
49
|
collapsible: false,
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -1,10 +1,38 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// node_modules/@y14e/attributes-utils/dist/index.js
|
|
4
|
+
var snapshots = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
function restoreAttributes(element_or_elements) {
|
|
6
|
+
for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
|
|
7
|
+
const snapshot = snapshots.get(element);
|
|
8
|
+
if (!snapshot) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
for (const [name, value] of snapshot.entries()) {
|
|
12
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
13
|
+
}
|
|
14
|
+
snapshots.delete(element);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function saveAttributes(element_or_elements, name_or_names) {
|
|
18
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
19
|
+
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
20
|
+
let snapshot = snapshots.get(element);
|
|
21
|
+
if (!snapshot) {
|
|
22
|
+
snapshot = /* @__PURE__ */ new Map();
|
|
23
|
+
snapshots.set(element, snapshot);
|
|
24
|
+
}
|
|
25
|
+
names.forEach((name) => {
|
|
26
|
+
snapshot.set(name, element.getAttribute(name));
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// node_modules/@y14e/roving-tabindex/node_modules/@y14e/attributes-utils/dist/index.js
|
|
4
32
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
5
33
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
6
|
-
function addTokenToAttribute(element,
|
|
7
|
-
const value = element.getAttribute(
|
|
34
|
+
function addTokenToAttribute(element, name, token, options = {}) {
|
|
35
|
+
const value = element.getAttribute(name)?.trim();
|
|
8
36
|
const {
|
|
9
37
|
caseInsensitive = false,
|
|
10
38
|
parse = DEFAULT_PARSER,
|
|
@@ -15,42 +43,47 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
15
43
|
const lower = token.toLowerCase();
|
|
16
44
|
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
17
45
|
tokens.push(token);
|
|
18
|
-
element.setAttribute(
|
|
46
|
+
element.setAttribute(name, serialize(tokens));
|
|
19
47
|
}
|
|
20
48
|
} else {
|
|
21
49
|
const set = new Set(tokens);
|
|
22
50
|
set.add(token);
|
|
23
|
-
element.setAttribute(
|
|
51
|
+
element.setAttribute(name, serialize([...set]));
|
|
24
52
|
}
|
|
25
53
|
}
|
|
26
|
-
var
|
|
27
|
-
function
|
|
28
|
-
for (const element of
|
|
29
|
-
const snapshot =
|
|
54
|
+
var snapshots2 = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
function restoreAttributes2(element_or_elements) {
|
|
56
|
+
for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
|
|
57
|
+
const snapshot = snapshots2.get(element);
|
|
30
58
|
if (!snapshot) {
|
|
31
59
|
continue;
|
|
32
60
|
}
|
|
33
|
-
for (const [
|
|
34
|
-
value === null ? element.removeAttribute(
|
|
61
|
+
for (const [name, value] of snapshot.entries()) {
|
|
62
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
35
63
|
}
|
|
36
|
-
|
|
64
|
+
snapshots2.delete(element);
|
|
37
65
|
}
|
|
38
66
|
}
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
67
|
+
function saveAttributes2(element_or_elements, name_or_names) {
|
|
68
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
69
|
+
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
70
|
+
let snapshot = snapshots2.get(element);
|
|
42
71
|
if (!snapshot) {
|
|
43
72
|
snapshot = /* @__PURE__ */ new Map();
|
|
44
|
-
|
|
73
|
+
snapshots2.set(element, snapshot);
|
|
45
74
|
}
|
|
46
|
-
|
|
47
|
-
snapshot.set(
|
|
75
|
+
names.forEach((name) => {
|
|
76
|
+
snapshot.set(name, element.getAttribute(name));
|
|
48
77
|
});
|
|
49
78
|
});
|
|
50
79
|
}
|
|
51
80
|
|
|
52
81
|
// node_modules/power-focusable/dist/index.js
|
|
53
82
|
var FOCUSABLE_SELECTOR = `:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`;
|
|
83
|
+
var FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX = FOCUSABLE_SELECTOR.replace(
|
|
84
|
+
/(,\s*)?\[tabindex="-1"\]/g,
|
|
85
|
+
""
|
|
86
|
+
);
|
|
54
87
|
function getFocusables(container = document.body, options = {}) {
|
|
55
88
|
if (!(container instanceof Element)) {
|
|
56
89
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
@@ -87,36 +120,43 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
87
120
|
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
88
121
|
skipVisibilityCheck = false;
|
|
89
122
|
}
|
|
90
|
-
const
|
|
123
|
+
const candidates = [];
|
|
91
124
|
if (composed || include) {
|
|
92
125
|
let traverse2 = function(node) {
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
126
|
+
if (isFocusable(node, {
|
|
127
|
+
skipNegativeTabIndexCheck,
|
|
128
|
+
skipVisibilityCheck
|
|
129
|
+
}) || include?.(node)) {
|
|
130
|
+
candidates[candidates.length] = node;
|
|
98
131
|
}
|
|
99
|
-
const
|
|
100
|
-
for (let i = 0, l =
|
|
101
|
-
const child =
|
|
132
|
+
const children2 = composed ? getComposedChildren(node) : getChildren(node);
|
|
133
|
+
for (let i = 0, l = children2.length; i < l; i++) {
|
|
134
|
+
const child = children2[i];
|
|
102
135
|
child && traverse2(child);
|
|
103
136
|
}
|
|
104
137
|
};
|
|
105
|
-
|
|
138
|
+
const children = composed ? getComposedChildren(container) : getChildren(container);
|
|
139
|
+
for (let i = 0, l = children.length; i < l; i++) {
|
|
140
|
+
const child = children[i];
|
|
141
|
+
child && traverse2(child);
|
|
142
|
+
}
|
|
106
143
|
} else {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
144
|
+
const matches = container.querySelectorAll(
|
|
145
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
146
|
+
);
|
|
147
|
+
for (let i = 0, l = matches.length; i < l; i++) {
|
|
148
|
+
const matched = matches[i];
|
|
149
|
+
if (matched && isFocusable(matched, {
|
|
111
150
|
skipNegativeTabIndexCheck,
|
|
112
151
|
skipVisibilityCheck
|
|
113
152
|
})) {
|
|
114
|
-
|
|
153
|
+
candidates[candidates.length] = matched;
|
|
115
154
|
}
|
|
116
155
|
}
|
|
117
156
|
}
|
|
118
|
-
|
|
119
|
-
|
|
157
|
+
return normalizeRadioGroup(
|
|
158
|
+
sortByTabIndex(filter ? candidates.filter(filter) : candidates)
|
|
159
|
+
);
|
|
120
160
|
}
|
|
121
161
|
function isFocusable(element, options = {}) {
|
|
122
162
|
if (!(element instanceof Element)) {
|
|
@@ -139,7 +179,7 @@ function isFocusable(element, options = {}) {
|
|
|
139
179
|
return false;
|
|
140
180
|
}
|
|
141
181
|
if (!element.matches(
|
|
142
|
-
skipNegativeTabIndexCheck ?
|
|
182
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
143
183
|
)) {
|
|
144
184
|
return false;
|
|
145
185
|
}
|
|
@@ -197,22 +237,42 @@ function normalizeRadioGroup(elements) {
|
|
|
197
237
|
if (!map) {
|
|
198
238
|
map = /* @__PURE__ */ new Map();
|
|
199
239
|
}
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
|
|
240
|
+
const root = element.getRootNode();
|
|
241
|
+
let value = map.get(root);
|
|
242
|
+
if (!value) {
|
|
243
|
+
value = /* @__PURE__ */ new Map();
|
|
244
|
+
map.set(root, value);
|
|
245
|
+
}
|
|
246
|
+
let v = value.get(element.form);
|
|
247
|
+
if (!v) {
|
|
248
|
+
v = /* @__PURE__ */ new Map();
|
|
249
|
+
value.set(element.form, v);
|
|
204
250
|
}
|
|
251
|
+
let vv = v.get(element.name);
|
|
252
|
+
if (!vv) {
|
|
253
|
+
vv = [];
|
|
254
|
+
v.set(element.name, vv);
|
|
255
|
+
}
|
|
256
|
+
vv[vv.length] = element;
|
|
205
257
|
}
|
|
206
258
|
if (!map) {
|
|
207
259
|
return elements;
|
|
208
260
|
}
|
|
209
261
|
const placeholder = /* @__PURE__ */ new Set();
|
|
210
|
-
for (const
|
|
211
|
-
|
|
262
|
+
for (const value of map.values()) {
|
|
263
|
+
for (const v of value.values()) {
|
|
264
|
+
for (const vv of v.values()) {
|
|
265
|
+
const radio = vv.find((element) => element.checked) ?? vv[0];
|
|
266
|
+
radio && placeholder.add(radio);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
212
269
|
}
|
|
213
|
-
return elements.filter(
|
|
214
|
-
|
|
215
|
-
|
|
270
|
+
return elements.filter((element) => {
|
|
271
|
+
if (!(element instanceof HTMLInputElement)) {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
return !isUngroupedRadio(element) || placeholder.has(element);
|
|
275
|
+
});
|
|
216
276
|
}
|
|
217
277
|
function sortByTabIndex(elements) {
|
|
218
278
|
const ordered = [];
|
|
@@ -284,7 +344,7 @@ function isInert(element) {
|
|
|
284
344
|
return "inert" in element && !!element.inert;
|
|
285
345
|
}
|
|
286
346
|
function isUngroupedRadio(element) {
|
|
287
|
-
return element
|
|
347
|
+
return element.type === "radio" && !!element.name;
|
|
288
348
|
}
|
|
289
349
|
|
|
290
350
|
// node_modules/@y14e/roving-tabindex/dist/index.js
|
|
@@ -294,14 +354,8 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
294
354
|
return () => {
|
|
295
355
|
};
|
|
296
356
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return () => roving.destroy();
|
|
300
|
-
} catch (error) {
|
|
301
|
-
error instanceof Error && console.warn(error.message || error);
|
|
302
|
-
return () => {
|
|
303
|
-
};
|
|
304
|
-
}
|
|
357
|
+
const roving = new RovingTabIndex(container, options);
|
|
358
|
+
return () => roving.destroy();
|
|
305
359
|
}
|
|
306
360
|
var RovingTabIndex = class _RovingTabIndex {
|
|
307
361
|
static #initialized = /* @__PURE__ */ new Set();
|
|
@@ -315,17 +369,17 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
315
369
|
constructor(container, options = {}) {
|
|
316
370
|
this.#container = container;
|
|
317
371
|
let {
|
|
318
|
-
direction,
|
|
372
|
+
direction = "both",
|
|
319
373
|
navigationOnly = false,
|
|
320
374
|
noMemory = false,
|
|
321
375
|
noStart = false,
|
|
322
|
-
selector,
|
|
376
|
+
selector = "",
|
|
323
377
|
typeahead = false,
|
|
324
378
|
wrap = false
|
|
325
379
|
} = options;
|
|
326
|
-
if (
|
|
327
|
-
console.warn("Invalid direction option. Fallback: both
|
|
328
|
-
direction =
|
|
380
|
+
if (!["both", "horizontal", "vertical"].includes(direction)) {
|
|
381
|
+
console.warn("Invalid direction option. Fallback: 'both'.");
|
|
382
|
+
direction = "both";
|
|
329
383
|
}
|
|
330
384
|
if (typeof navigationOnly !== "boolean") {
|
|
331
385
|
console.warn("Invalid navigationOnly option. Fallback: false.");
|
|
@@ -339,11 +393,21 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
339
393
|
console.warn("Invalid noStart option. Fallback: false.");
|
|
340
394
|
noStart = false;
|
|
341
395
|
}
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
396
|
+
if (selector !== "") {
|
|
397
|
+
let hasError = false;
|
|
398
|
+
if (typeof selector !== "string" || !selector.trim()) {
|
|
399
|
+
hasError = true;
|
|
400
|
+
} else {
|
|
401
|
+
try {
|
|
402
|
+
this.#container.querySelector(selector);
|
|
403
|
+
} catch {
|
|
404
|
+
hasError = true;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (hasError) {
|
|
408
|
+
console.warn("Invalid selector. Fallback: no selector string.");
|
|
409
|
+
selector = "";
|
|
410
|
+
}
|
|
347
411
|
}
|
|
348
412
|
if (typeof typeahead !== "boolean") {
|
|
349
413
|
console.warn("Invalid typeahead option. Fallback: false.");
|
|
@@ -353,9 +417,15 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
353
417
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
354
418
|
wrap = false;
|
|
355
419
|
}
|
|
356
|
-
this.#settings = {
|
|
357
|
-
|
|
358
|
-
|
|
420
|
+
this.#settings = {
|
|
421
|
+
direction,
|
|
422
|
+
navigationOnly,
|
|
423
|
+
noMemory,
|
|
424
|
+
noStart,
|
|
425
|
+
selector,
|
|
426
|
+
typeahead,
|
|
427
|
+
wrap
|
|
428
|
+
};
|
|
359
429
|
this.#selectorFilter = this.#createSelectorFilter();
|
|
360
430
|
this.#initialize();
|
|
361
431
|
}
|
|
@@ -366,7 +436,10 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
366
436
|
this.#isDestroyed = true;
|
|
367
437
|
this.#controller?.abort();
|
|
368
438
|
this.#controller = null;
|
|
369
|
-
|
|
439
|
+
this.#focusables.forEach((focusable) => {
|
|
440
|
+
_RovingTabIndex.#initialized.delete(focusable);
|
|
441
|
+
restoreAttributes2(focusable);
|
|
442
|
+
});
|
|
370
443
|
this.#focusables.clear();
|
|
371
444
|
this.#focusablesByFirstChar.clear();
|
|
372
445
|
}
|
|
@@ -403,7 +476,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
403
476
|
return;
|
|
404
477
|
}
|
|
405
478
|
const { direction, typeahead, wrap } = this.#settings;
|
|
406
|
-
const isBoth =
|
|
479
|
+
const isBoth = direction === "both";
|
|
407
480
|
const isHorizontal = direction === "horizontal";
|
|
408
481
|
if (![
|
|
409
482
|
"End",
|
|
@@ -415,18 +488,20 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
415
488
|
return;
|
|
416
489
|
}
|
|
417
490
|
}
|
|
491
|
+
const candidates = this.#getFocusables().filter(
|
|
492
|
+
(focusable2) => this.#focusables.has(focusable2)
|
|
493
|
+
);
|
|
418
494
|
const active = getActiveElement();
|
|
419
495
|
if (!(active instanceof Element)) {
|
|
420
496
|
return;
|
|
421
497
|
}
|
|
422
|
-
|
|
423
|
-
if (!current.includes(active)) {
|
|
498
|
+
if (!candidates.includes(active)) {
|
|
424
499
|
return;
|
|
425
500
|
}
|
|
426
501
|
event.preventDefault();
|
|
427
|
-
const currentIndex = current.indexOf(active);
|
|
428
502
|
let newIndex;
|
|
429
|
-
|
|
503
|
+
const activeIndex = candidates.indexOf(active);
|
|
504
|
+
let focusables = candidates;
|
|
430
505
|
switch (key) {
|
|
431
506
|
case "End":
|
|
432
507
|
newIndex = -1;
|
|
@@ -436,37 +511,47 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
436
511
|
break;
|
|
437
512
|
case "ArrowLeft":
|
|
438
513
|
case "ArrowUp": {
|
|
439
|
-
const rawIndex =
|
|
514
|
+
const rawIndex = activeIndex - 1;
|
|
440
515
|
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
441
516
|
break;
|
|
442
517
|
}
|
|
443
518
|
case "ArrowRight":
|
|
444
519
|
case "ArrowDown": {
|
|
445
|
-
const rawIndex =
|
|
446
|
-
|
|
520
|
+
const rawIndex = activeIndex + 1;
|
|
521
|
+
const length = focusables.length;
|
|
522
|
+
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
447
523
|
break;
|
|
448
524
|
}
|
|
449
525
|
default: {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
526
|
+
const focusablesByFirstChar = new Set(
|
|
527
|
+
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
528
|
+
);
|
|
529
|
+
focusables = candidates.filter(
|
|
530
|
+
(candidate) => focusablesByFirstChar.has(candidate)
|
|
531
|
+
);
|
|
532
|
+
const afterIndex = focusables.findIndex(
|
|
533
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
453
534
|
);
|
|
454
|
-
newIndex =
|
|
535
|
+
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
455
536
|
}
|
|
456
537
|
}
|
|
457
|
-
const focusable =
|
|
538
|
+
const focusable = focusables.at(newIndex);
|
|
458
539
|
focusable && focusElement(focusable);
|
|
459
540
|
};
|
|
460
541
|
#update(active) {
|
|
461
542
|
const current = new Set(this.#getFocusables());
|
|
462
543
|
for (const focusable of this.#focusables) {
|
|
463
544
|
if (!current.has(focusable)) {
|
|
464
|
-
|
|
545
|
+
_RovingTabIndex.#initialized.delete(focusable);
|
|
546
|
+
restoreAttributes2(focusable);
|
|
465
547
|
this.#focusables.delete(focusable);
|
|
466
|
-
this.#focusablesByFirstChar
|
|
548
|
+
for (const [key, focusables] of this.#focusablesByFirstChar) {
|
|
467
549
|
const index = focusables.indexOf(focusable);
|
|
468
|
-
index >= 0
|
|
469
|
-
|
|
550
|
+
if (index >= 0) {
|
|
551
|
+
focusables.splice(index, 1);
|
|
552
|
+
!focusables.length && this.#focusablesByFirstChar.delete(key);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
470
555
|
}
|
|
471
556
|
}
|
|
472
557
|
const { navigationOnly, noStart, typeahead } = this.#settings;
|
|
@@ -475,12 +560,12 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
475
560
|
continue;
|
|
476
561
|
}
|
|
477
562
|
if (_RovingTabIndex.#initialized.has(focusable)) {
|
|
478
|
-
|
|
563
|
+
continue;
|
|
479
564
|
}
|
|
480
565
|
this.#focusables.add(focusable);
|
|
481
566
|
_RovingTabIndex.#initialized.add(focusable);
|
|
482
567
|
if (!navigationOnly) {
|
|
483
|
-
|
|
568
|
+
saveAttributes2(focusable, "tabindex");
|
|
484
569
|
focusable.setAttribute("tabindex", "-1");
|
|
485
570
|
}
|
|
486
571
|
if (!typeahead) {
|
|
@@ -493,7 +578,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
493
578
|
);
|
|
494
579
|
if (char) {
|
|
495
580
|
keys.add(char);
|
|
496
|
-
|
|
581
|
+
saveAttributes2(focusable, "aria-keyshortcuts");
|
|
497
582
|
addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
|
|
498
583
|
caseInsensitive: true
|
|
499
584
|
});
|
|
@@ -677,7 +762,7 @@ var Disclosure = class _Disclosure {
|
|
|
677
762
|
details.open = isExpand;
|
|
678
763
|
}
|
|
679
764
|
#createBinding(details, summary, content) {
|
|
680
|
-
return { details, summary
|
|
765
|
+
return { content, details, summary };
|
|
681
766
|
}
|
|
682
767
|
#isFocusable(element) {
|
|
683
768
|
return element.tabIndex >= 0;
|
|
@@ -691,7 +776,7 @@ var Disclosure = class _Disclosure {
|
|
|
691
776
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
692
777
|
* Using the <details> and <summary> element.
|
|
693
778
|
*
|
|
694
|
-
* @version 2.0.
|
|
779
|
+
* @version 2.0.3
|
|
695
780
|
* @author Yusuke Kamiyamane
|
|
696
781
|
* @license MIT
|
|
697
782
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -703,7 +788,18 @@ var Disclosure = class _Disclosure {
|
|
|
703
788
|
(**
|
|
704
789
|
* Attributes Utils
|
|
705
790
|
*
|
|
706
|
-
* @version
|
|
791
|
+
* @version 2.0.0
|
|
792
|
+
* @author Yusuke Kamiyamane
|
|
793
|
+
* @license MIT
|
|
794
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
795
|
+
* @see {@link https://github.com/y14e/attributes-utils}
|
|
796
|
+
*)
|
|
797
|
+
|
|
798
|
+
@y14e/attributes-utils/dist/index.js:
|
|
799
|
+
(**
|
|
800
|
+
* Attributes Utils
|
|
801
|
+
*
|
|
802
|
+
* @version 1.1.7
|
|
707
803
|
* @author Yusuke Kamiyamane
|
|
708
804
|
* @license MIT
|
|
709
805
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -716,7 +812,7 @@ power-focusable/dist/index.js:
|
|
|
716
812
|
* High-precision focus management utility with full composed tree support.
|
|
717
813
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
718
814
|
*
|
|
719
|
-
* @version 4.3.
|
|
815
|
+
* @version 4.3.23
|
|
720
816
|
* @author Yusuke Kamiyamane
|
|
721
817
|
* @license MIT
|
|
722
818
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -729,7 +825,7 @@ power-focusable/dist/index.js:
|
|
|
729
825
|
* Lightweight roving tabindex utility with fully focus management.
|
|
730
826
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
731
827
|
*
|
|
732
|
-
* @version 3.1.
|
|
828
|
+
* @version 3.1.20
|
|
733
829
|
* @author Yusuke Kamiyamane
|
|
734
830
|
* @license MIT
|
|
735
831
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
// node_modules/@y14e/attributes-utils/dist/index.js
|
|
2
|
+
var snapshots = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function restoreAttributes(element_or_elements) {
|
|
4
|
+
for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
|
|
5
|
+
const snapshot = snapshots.get(element);
|
|
6
|
+
if (!snapshot) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
for (const [name, value] of snapshot.entries()) {
|
|
10
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
11
|
+
}
|
|
12
|
+
snapshots.delete(element);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function saveAttributes(element_or_elements, name_or_names) {
|
|
16
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
17
|
+
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
18
|
+
let snapshot = snapshots.get(element);
|
|
19
|
+
if (!snapshot) {
|
|
20
|
+
snapshot = /* @__PURE__ */ new Map();
|
|
21
|
+
snapshots.set(element, snapshot);
|
|
22
|
+
}
|
|
23
|
+
names.forEach((name) => {
|
|
24
|
+
snapshot.set(name, element.getAttribute(name));
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// node_modules/@y14e/roving-tabindex/node_modules/@y14e/attributes-utils/dist/index.js
|
|
2
30
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
3
31
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
4
|
-
function addTokenToAttribute(element,
|
|
5
|
-
const value = element.getAttribute(
|
|
32
|
+
function addTokenToAttribute(element, name, token, options = {}) {
|
|
33
|
+
const value = element.getAttribute(name)?.trim();
|
|
6
34
|
const {
|
|
7
35
|
caseInsensitive = false,
|
|
8
36
|
parse = DEFAULT_PARSER,
|
|
@@ -13,42 +41,47 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
13
41
|
const lower = token.toLowerCase();
|
|
14
42
|
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
15
43
|
tokens.push(token);
|
|
16
|
-
element.setAttribute(
|
|
44
|
+
element.setAttribute(name, serialize(tokens));
|
|
17
45
|
}
|
|
18
46
|
} else {
|
|
19
47
|
const set = new Set(tokens);
|
|
20
48
|
set.add(token);
|
|
21
|
-
element.setAttribute(
|
|
49
|
+
element.setAttribute(name, serialize([...set]));
|
|
22
50
|
}
|
|
23
51
|
}
|
|
24
|
-
var
|
|
25
|
-
function
|
|
26
|
-
for (const element of
|
|
27
|
-
const snapshot =
|
|
52
|
+
var snapshots2 = /* @__PURE__ */ new WeakMap();
|
|
53
|
+
function restoreAttributes2(element_or_elements) {
|
|
54
|
+
for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
|
|
55
|
+
const snapshot = snapshots2.get(element);
|
|
28
56
|
if (!snapshot) {
|
|
29
57
|
continue;
|
|
30
58
|
}
|
|
31
|
-
for (const [
|
|
32
|
-
value === null ? element.removeAttribute(
|
|
59
|
+
for (const [name, value] of snapshot.entries()) {
|
|
60
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
33
61
|
}
|
|
34
|
-
|
|
62
|
+
snapshots2.delete(element);
|
|
35
63
|
}
|
|
36
64
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
39
|
-
|
|
65
|
+
function saveAttributes2(element_or_elements, name_or_names) {
|
|
66
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
67
|
+
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
68
|
+
let snapshot = snapshots2.get(element);
|
|
40
69
|
if (!snapshot) {
|
|
41
70
|
snapshot = /* @__PURE__ */ new Map();
|
|
42
|
-
|
|
71
|
+
snapshots2.set(element, snapshot);
|
|
43
72
|
}
|
|
44
|
-
|
|
45
|
-
snapshot.set(
|
|
73
|
+
names.forEach((name) => {
|
|
74
|
+
snapshot.set(name, element.getAttribute(name));
|
|
46
75
|
});
|
|
47
76
|
});
|
|
48
77
|
}
|
|
49
78
|
|
|
50
79
|
// node_modules/power-focusable/dist/index.js
|
|
51
80
|
var FOCUSABLE_SELECTOR = `:is(a[href], area[href], button, embed, iframe, input:not([type="hidden" i]), object, select, details > summary:first-of-type, textarea, [contenteditable]:not([contenteditable="false" i]), [controls], [tabindex]):not(:disabled, [hidden], [inert], [tabindex="-1"])`;
|
|
81
|
+
var FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX = FOCUSABLE_SELECTOR.replace(
|
|
82
|
+
/(,\s*)?\[tabindex="-1"\]/g,
|
|
83
|
+
""
|
|
84
|
+
);
|
|
52
85
|
function getFocusables(container = document.body, options = {}) {
|
|
53
86
|
if (!(container instanceof Element)) {
|
|
54
87
|
console.warn("Invalid container element. Fallback: <body> element.");
|
|
@@ -85,36 +118,43 @@ function getFocusables(container = document.body, options = {}) {
|
|
|
85
118
|
console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
|
|
86
119
|
skipVisibilityCheck = false;
|
|
87
120
|
}
|
|
88
|
-
const
|
|
121
|
+
const candidates = [];
|
|
89
122
|
if (composed || include) {
|
|
90
123
|
let traverse2 = function(node) {
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
124
|
+
if (isFocusable(node, {
|
|
125
|
+
skipNegativeTabIndexCheck,
|
|
126
|
+
skipVisibilityCheck
|
|
127
|
+
}) || include?.(node)) {
|
|
128
|
+
candidates[candidates.length] = node;
|
|
96
129
|
}
|
|
97
|
-
const
|
|
98
|
-
for (let i = 0, l =
|
|
99
|
-
const child =
|
|
130
|
+
const children2 = composed ? getComposedChildren(node) : getChildren(node);
|
|
131
|
+
for (let i = 0, l = children2.length; i < l; i++) {
|
|
132
|
+
const child = children2[i];
|
|
100
133
|
child && traverse2(child);
|
|
101
134
|
}
|
|
102
135
|
};
|
|
103
|
-
|
|
136
|
+
const children = composed ? getComposedChildren(container) : getChildren(container);
|
|
137
|
+
for (let i = 0, l = children.length; i < l; i++) {
|
|
138
|
+
const child = children[i];
|
|
139
|
+
child && traverse2(child);
|
|
140
|
+
}
|
|
104
141
|
} else {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
142
|
+
const matches = container.querySelectorAll(
|
|
143
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
144
|
+
);
|
|
145
|
+
for (let i = 0, l = matches.length; i < l; i++) {
|
|
146
|
+
const matched = matches[i];
|
|
147
|
+
if (matched && isFocusable(matched, {
|
|
109
148
|
skipNegativeTabIndexCheck,
|
|
110
149
|
skipVisibilityCheck
|
|
111
150
|
})) {
|
|
112
|
-
|
|
151
|
+
candidates[candidates.length] = matched;
|
|
113
152
|
}
|
|
114
153
|
}
|
|
115
154
|
}
|
|
116
|
-
|
|
117
|
-
|
|
155
|
+
return normalizeRadioGroup(
|
|
156
|
+
sortByTabIndex(filter ? candidates.filter(filter) : candidates)
|
|
157
|
+
);
|
|
118
158
|
}
|
|
119
159
|
function isFocusable(element, options = {}) {
|
|
120
160
|
if (!(element instanceof Element)) {
|
|
@@ -137,7 +177,7 @@ function isFocusable(element, options = {}) {
|
|
|
137
177
|
return false;
|
|
138
178
|
}
|
|
139
179
|
if (!element.matches(
|
|
140
|
-
skipNegativeTabIndexCheck ?
|
|
180
|
+
skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR_WITH_NEGATIVE_TABINDEX : FOCUSABLE_SELECTOR
|
|
141
181
|
)) {
|
|
142
182
|
return false;
|
|
143
183
|
}
|
|
@@ -195,22 +235,42 @@ function normalizeRadioGroup(elements) {
|
|
|
195
235
|
if (!map) {
|
|
196
236
|
map = /* @__PURE__ */ new Map();
|
|
197
237
|
}
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
if (
|
|
201
|
-
|
|
238
|
+
const root = element.getRootNode();
|
|
239
|
+
let value = map.get(root);
|
|
240
|
+
if (!value) {
|
|
241
|
+
value = /* @__PURE__ */ new Map();
|
|
242
|
+
map.set(root, value);
|
|
243
|
+
}
|
|
244
|
+
let v = value.get(element.form);
|
|
245
|
+
if (!v) {
|
|
246
|
+
v = /* @__PURE__ */ new Map();
|
|
247
|
+
value.set(element.form, v);
|
|
202
248
|
}
|
|
249
|
+
let vv = v.get(element.name);
|
|
250
|
+
if (!vv) {
|
|
251
|
+
vv = [];
|
|
252
|
+
v.set(element.name, vv);
|
|
253
|
+
}
|
|
254
|
+
vv[vv.length] = element;
|
|
203
255
|
}
|
|
204
256
|
if (!map) {
|
|
205
257
|
return elements;
|
|
206
258
|
}
|
|
207
259
|
const placeholder = /* @__PURE__ */ new Set();
|
|
208
|
-
for (const
|
|
209
|
-
|
|
260
|
+
for (const value of map.values()) {
|
|
261
|
+
for (const v of value.values()) {
|
|
262
|
+
for (const vv of v.values()) {
|
|
263
|
+
const radio = vv.find((element) => element.checked) ?? vv[0];
|
|
264
|
+
radio && placeholder.add(radio);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
210
267
|
}
|
|
211
|
-
return elements.filter(
|
|
212
|
-
|
|
213
|
-
|
|
268
|
+
return elements.filter((element) => {
|
|
269
|
+
if (!(element instanceof HTMLInputElement)) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
return !isUngroupedRadio(element) || placeholder.has(element);
|
|
273
|
+
});
|
|
214
274
|
}
|
|
215
275
|
function sortByTabIndex(elements) {
|
|
216
276
|
const ordered = [];
|
|
@@ -282,7 +342,7 @@ function isInert(element) {
|
|
|
282
342
|
return "inert" in element && !!element.inert;
|
|
283
343
|
}
|
|
284
344
|
function isUngroupedRadio(element) {
|
|
285
|
-
return element
|
|
345
|
+
return element.type === "radio" && !!element.name;
|
|
286
346
|
}
|
|
287
347
|
|
|
288
348
|
// node_modules/@y14e/roving-tabindex/dist/index.js
|
|
@@ -292,14 +352,8 @@ function createRovingTabIndex(container, options = {}) {
|
|
|
292
352
|
return () => {
|
|
293
353
|
};
|
|
294
354
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
return () => roving.destroy();
|
|
298
|
-
} catch (error) {
|
|
299
|
-
error instanceof Error && console.warn(error.message || error);
|
|
300
|
-
return () => {
|
|
301
|
-
};
|
|
302
|
-
}
|
|
355
|
+
const roving = new RovingTabIndex(container, options);
|
|
356
|
+
return () => roving.destroy();
|
|
303
357
|
}
|
|
304
358
|
var RovingTabIndex = class _RovingTabIndex {
|
|
305
359
|
static #initialized = /* @__PURE__ */ new Set();
|
|
@@ -313,17 +367,17 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
313
367
|
constructor(container, options = {}) {
|
|
314
368
|
this.#container = container;
|
|
315
369
|
let {
|
|
316
|
-
direction,
|
|
370
|
+
direction = "both",
|
|
317
371
|
navigationOnly = false,
|
|
318
372
|
noMemory = false,
|
|
319
373
|
noStart = false,
|
|
320
|
-
selector,
|
|
374
|
+
selector = "",
|
|
321
375
|
typeahead = false,
|
|
322
376
|
wrap = false
|
|
323
377
|
} = options;
|
|
324
|
-
if (
|
|
325
|
-
console.warn("Invalid direction option. Fallback: both
|
|
326
|
-
direction =
|
|
378
|
+
if (!["both", "horizontal", "vertical"].includes(direction)) {
|
|
379
|
+
console.warn("Invalid direction option. Fallback: 'both'.");
|
|
380
|
+
direction = "both";
|
|
327
381
|
}
|
|
328
382
|
if (typeof navigationOnly !== "boolean") {
|
|
329
383
|
console.warn("Invalid navigationOnly option. Fallback: false.");
|
|
@@ -337,11 +391,21 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
337
391
|
console.warn("Invalid noStart option. Fallback: false.");
|
|
338
392
|
noStart = false;
|
|
339
393
|
}
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
394
|
+
if (selector !== "") {
|
|
395
|
+
let hasError = false;
|
|
396
|
+
if (typeof selector !== "string" || !selector.trim()) {
|
|
397
|
+
hasError = true;
|
|
398
|
+
} else {
|
|
399
|
+
try {
|
|
400
|
+
this.#container.querySelector(selector);
|
|
401
|
+
} catch {
|
|
402
|
+
hasError = true;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (hasError) {
|
|
406
|
+
console.warn("Invalid selector. Fallback: no selector string.");
|
|
407
|
+
selector = "";
|
|
408
|
+
}
|
|
345
409
|
}
|
|
346
410
|
if (typeof typeahead !== "boolean") {
|
|
347
411
|
console.warn("Invalid typeahead option. Fallback: false.");
|
|
@@ -351,9 +415,15 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
351
415
|
console.warn("Invalid wrap option. Fallback: false.");
|
|
352
416
|
wrap = false;
|
|
353
417
|
}
|
|
354
|
-
this.#settings = {
|
|
355
|
-
|
|
356
|
-
|
|
418
|
+
this.#settings = {
|
|
419
|
+
direction,
|
|
420
|
+
navigationOnly,
|
|
421
|
+
noMemory,
|
|
422
|
+
noStart,
|
|
423
|
+
selector,
|
|
424
|
+
typeahead,
|
|
425
|
+
wrap
|
|
426
|
+
};
|
|
357
427
|
this.#selectorFilter = this.#createSelectorFilter();
|
|
358
428
|
this.#initialize();
|
|
359
429
|
}
|
|
@@ -364,7 +434,10 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
364
434
|
this.#isDestroyed = true;
|
|
365
435
|
this.#controller?.abort();
|
|
366
436
|
this.#controller = null;
|
|
367
|
-
|
|
437
|
+
this.#focusables.forEach((focusable) => {
|
|
438
|
+
_RovingTabIndex.#initialized.delete(focusable);
|
|
439
|
+
restoreAttributes2(focusable);
|
|
440
|
+
});
|
|
368
441
|
this.#focusables.clear();
|
|
369
442
|
this.#focusablesByFirstChar.clear();
|
|
370
443
|
}
|
|
@@ -401,7 +474,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
401
474
|
return;
|
|
402
475
|
}
|
|
403
476
|
const { direction, typeahead, wrap } = this.#settings;
|
|
404
|
-
const isBoth =
|
|
477
|
+
const isBoth = direction === "both";
|
|
405
478
|
const isHorizontal = direction === "horizontal";
|
|
406
479
|
if (![
|
|
407
480
|
"End",
|
|
@@ -413,18 +486,20 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
413
486
|
return;
|
|
414
487
|
}
|
|
415
488
|
}
|
|
489
|
+
const candidates = this.#getFocusables().filter(
|
|
490
|
+
(focusable2) => this.#focusables.has(focusable2)
|
|
491
|
+
);
|
|
416
492
|
const active = getActiveElement();
|
|
417
493
|
if (!(active instanceof Element)) {
|
|
418
494
|
return;
|
|
419
495
|
}
|
|
420
|
-
|
|
421
|
-
if (!current.includes(active)) {
|
|
496
|
+
if (!candidates.includes(active)) {
|
|
422
497
|
return;
|
|
423
498
|
}
|
|
424
499
|
event.preventDefault();
|
|
425
|
-
const currentIndex = current.indexOf(active);
|
|
426
500
|
let newIndex;
|
|
427
|
-
|
|
501
|
+
const activeIndex = candidates.indexOf(active);
|
|
502
|
+
let focusables = candidates;
|
|
428
503
|
switch (key) {
|
|
429
504
|
case "End":
|
|
430
505
|
newIndex = -1;
|
|
@@ -434,37 +509,47 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
434
509
|
break;
|
|
435
510
|
case "ArrowLeft":
|
|
436
511
|
case "ArrowUp": {
|
|
437
|
-
const rawIndex =
|
|
512
|
+
const rawIndex = activeIndex - 1;
|
|
438
513
|
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
439
514
|
break;
|
|
440
515
|
}
|
|
441
516
|
case "ArrowRight":
|
|
442
517
|
case "ArrowDown": {
|
|
443
|
-
const rawIndex =
|
|
444
|
-
|
|
518
|
+
const rawIndex = activeIndex + 1;
|
|
519
|
+
const length = focusables.length;
|
|
520
|
+
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
445
521
|
break;
|
|
446
522
|
}
|
|
447
523
|
default: {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
524
|
+
const focusablesByFirstChar = new Set(
|
|
525
|
+
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
526
|
+
);
|
|
527
|
+
focusables = candidates.filter(
|
|
528
|
+
(candidate) => focusablesByFirstChar.has(candidate)
|
|
529
|
+
);
|
|
530
|
+
const afterIndex = focusables.findIndex(
|
|
531
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
451
532
|
);
|
|
452
|
-
newIndex =
|
|
533
|
+
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
453
534
|
}
|
|
454
535
|
}
|
|
455
|
-
const focusable =
|
|
536
|
+
const focusable = focusables.at(newIndex);
|
|
456
537
|
focusable && focusElement(focusable);
|
|
457
538
|
};
|
|
458
539
|
#update(active) {
|
|
459
540
|
const current = new Set(this.#getFocusables());
|
|
460
541
|
for (const focusable of this.#focusables) {
|
|
461
542
|
if (!current.has(focusable)) {
|
|
462
|
-
|
|
543
|
+
_RovingTabIndex.#initialized.delete(focusable);
|
|
544
|
+
restoreAttributes2(focusable);
|
|
463
545
|
this.#focusables.delete(focusable);
|
|
464
|
-
this.#focusablesByFirstChar
|
|
546
|
+
for (const [key, focusables] of this.#focusablesByFirstChar) {
|
|
465
547
|
const index = focusables.indexOf(focusable);
|
|
466
|
-
index >= 0
|
|
467
|
-
|
|
548
|
+
if (index >= 0) {
|
|
549
|
+
focusables.splice(index, 1);
|
|
550
|
+
!focusables.length && this.#focusablesByFirstChar.delete(key);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
468
553
|
}
|
|
469
554
|
}
|
|
470
555
|
const { navigationOnly, noStart, typeahead } = this.#settings;
|
|
@@ -473,12 +558,12 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
473
558
|
continue;
|
|
474
559
|
}
|
|
475
560
|
if (_RovingTabIndex.#initialized.has(focusable)) {
|
|
476
|
-
|
|
561
|
+
continue;
|
|
477
562
|
}
|
|
478
563
|
this.#focusables.add(focusable);
|
|
479
564
|
_RovingTabIndex.#initialized.add(focusable);
|
|
480
565
|
if (!navigationOnly) {
|
|
481
|
-
|
|
566
|
+
saveAttributes2(focusable, "tabindex");
|
|
482
567
|
focusable.setAttribute("tabindex", "-1");
|
|
483
568
|
}
|
|
484
569
|
if (!typeahead) {
|
|
@@ -491,7 +576,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
491
576
|
);
|
|
492
577
|
if (char) {
|
|
493
578
|
keys.add(char);
|
|
494
|
-
|
|
579
|
+
saveAttributes2(focusable, "aria-keyshortcuts");
|
|
495
580
|
addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
|
|
496
581
|
caseInsensitive: true
|
|
497
582
|
});
|
|
@@ -675,7 +760,7 @@ var Disclosure = class _Disclosure {
|
|
|
675
760
|
details.open = isExpand;
|
|
676
761
|
}
|
|
677
762
|
#createBinding(details, summary, content) {
|
|
678
|
-
return { details, summary
|
|
763
|
+
return { content, details, summary };
|
|
679
764
|
}
|
|
680
765
|
#isFocusable(element) {
|
|
681
766
|
return element.tabIndex >= 0;
|
|
@@ -689,7 +774,7 @@ var Disclosure = class _Disclosure {
|
|
|
689
774
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
690
775
|
* Using the <details> and <summary> element.
|
|
691
776
|
*
|
|
692
|
-
* @version 2.0.
|
|
777
|
+
* @version 2.0.3
|
|
693
778
|
* @author Yusuke Kamiyamane
|
|
694
779
|
* @license MIT
|
|
695
780
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -701,7 +786,18 @@ var Disclosure = class _Disclosure {
|
|
|
701
786
|
(**
|
|
702
787
|
* Attributes Utils
|
|
703
788
|
*
|
|
704
|
-
* @version
|
|
789
|
+
* @version 2.0.0
|
|
790
|
+
* @author Yusuke Kamiyamane
|
|
791
|
+
* @license MIT
|
|
792
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
793
|
+
* @see {@link https://github.com/y14e/attributes-utils}
|
|
794
|
+
*)
|
|
795
|
+
|
|
796
|
+
@y14e/attributes-utils/dist/index.js:
|
|
797
|
+
(**
|
|
798
|
+
* Attributes Utils
|
|
799
|
+
*
|
|
800
|
+
* @version 1.1.7
|
|
705
801
|
* @author Yusuke Kamiyamane
|
|
706
802
|
* @license MIT
|
|
707
803
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -714,7 +810,7 @@ power-focusable/dist/index.js:
|
|
|
714
810
|
* High-precision focus management utility with full composed tree support.
|
|
715
811
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
716
812
|
*
|
|
717
|
-
* @version 4.3.
|
|
813
|
+
* @version 4.3.23
|
|
718
814
|
* @author Yusuke Kamiyamane
|
|
719
815
|
* @license MIT
|
|
720
816
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -727,7 +823,7 @@ power-focusable/dist/index.js:
|
|
|
727
823
|
* Lightweight roving tabindex utility with fully focus management.
|
|
728
824
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
729
825
|
*
|
|
730
|
-
* @version 3.1.
|
|
826
|
+
* @version 3.1.20
|
|
731
827
|
* @author Yusuke Kamiyamane
|
|
732
828
|
* @license MIT
|
|
733
829
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -150,7 +150,7 @@ var Disclosure = class _Disclosure {
|
|
|
150
150
|
details.open = isExpand;
|
|
151
151
|
}
|
|
152
152
|
#createBinding(details, summary, content) {
|
|
153
|
-
return { details, summary
|
|
153
|
+
return { content, details, summary };
|
|
154
154
|
}
|
|
155
155
|
#isFocusable(element) {
|
|
156
156
|
return element.tabIndex >= 0;
|
|
@@ -164,7 +164,7 @@ var Disclosure = class _Disclosure {
|
|
|
164
164
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
165
165
|
* Using the <details> and <summary> element.
|
|
166
166
|
*
|
|
167
|
-
* @version 2.0.
|
|
167
|
+
* @version 2.0.3
|
|
168
168
|
* @author Yusuke Kamiyamane
|
|
169
169
|
* @license MIT
|
|
170
170
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
4
4
|
* Using the <details> and <summary> element.
|
|
5
5
|
*
|
|
6
|
-
* @version 2.0.
|
|
6
|
+
* @version 2.0.3
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
10
10
|
* @see {@link https://github.com/y14e/disclosure-css}
|
|
11
11
|
*/
|
|
12
12
|
interface DisclosureOptions {
|
|
13
|
-
|
|
13
|
+
collapsible: boolean;
|
|
14
14
|
}
|
|
15
15
|
declare class Disclosure {
|
|
16
16
|
#private;
|
|
17
|
-
static defaults: DisclosureOptions
|
|
18
|
-
constructor(root: HTMLElement, options?: DisclosureOptions);
|
|
17
|
+
static defaults: Partial<DisclosureOptions>;
|
|
18
|
+
constructor(root: HTMLElement, options?: Partial<DisclosureOptions>);
|
|
19
19
|
collapse(details: HTMLDetailsElement): void;
|
|
20
20
|
destroy(): void;
|
|
21
21
|
expand(details: HTMLDetailsElement): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
4
4
|
* Using the <details> and <summary> element.
|
|
5
5
|
*
|
|
6
|
-
* @version 2.0.
|
|
6
|
+
* @version 2.0.3
|
|
7
7
|
* @author Yusuke Kamiyamane
|
|
8
8
|
* @license MIT
|
|
9
9
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
10
10
|
* @see {@link https://github.com/y14e/disclosure-css}
|
|
11
11
|
*/
|
|
12
12
|
interface DisclosureOptions {
|
|
13
|
-
|
|
13
|
+
collapsible: boolean;
|
|
14
14
|
}
|
|
15
15
|
declare class Disclosure {
|
|
16
16
|
#private;
|
|
17
|
-
static defaults: DisclosureOptions
|
|
18
|
-
constructor(root: HTMLElement, options?: DisclosureOptions);
|
|
17
|
+
static defaults: Partial<DisclosureOptions>;
|
|
18
|
+
constructor(root: HTMLElement, options?: Partial<DisclosureOptions>);
|
|
19
19
|
collapse(details: HTMLDetailsElement): void;
|
|
20
20
|
destroy(): void;
|
|
21
21
|
expand(details: HTMLDetailsElement): void;
|
package/dist/index.js
CHANGED
|
@@ -148,7 +148,7 @@ var Disclosure = class _Disclosure {
|
|
|
148
148
|
details.open = isExpand;
|
|
149
149
|
}
|
|
150
150
|
#createBinding(details, summary, content) {
|
|
151
|
-
return { details, summary
|
|
151
|
+
return { content, details, summary };
|
|
152
152
|
}
|
|
153
153
|
#isFocusable(element) {
|
|
154
154
|
return element.tabIndex >= 0;
|
|
@@ -162,7 +162,7 @@ var Disclosure = class _Disclosure {
|
|
|
162
162
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
163
163
|
* Using the <details> and <summary> element.
|
|
164
164
|
*
|
|
165
|
-
* @version 2.0.
|
|
165
|
+
* @version 2.0.3
|
|
166
166
|
* @author Yusuke Kamiyamane
|
|
167
167
|
* @license MIT
|
|
168
168
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/disclosure-css",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "WAI-ARIA compliant disclosure pattern implementation in TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -45,14 +45,13 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"bun-types": "latest",
|
|
47
47
|
"tsup": "^8.0.0",
|
|
48
|
-
"typescript": "^5.6.0"
|
|
49
|
-
"utility-types": "^3.11.0"
|
|
48
|
+
"typescript": "^5.6.0"
|
|
50
49
|
},
|
|
51
50
|
"engines": {
|
|
52
51
|
"node": ">=18"
|
|
53
52
|
},
|
|
54
53
|
"dependencies": {
|
|
55
|
-
"@y14e/attributes-utils": "^
|
|
56
|
-
"@y14e/roving-tabindex": "^3.1.
|
|
54
|
+
"@y14e/attributes-utils": "^2.0.0",
|
|
55
|
+
"@y14e/roving-tabindex": "^3.1.20"
|
|
57
56
|
}
|
|
58
57
|
}
|