@y14e/disclosure 2.0.2 → 2.0.4
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 +9 -9
- 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 +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +2 -2
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -10,14 +10,14 @@ npm i @y14e/disclosure
|
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
// npm
|
|
13
|
-
import Disclosure from
|
|
13
|
+
import Disclosure from "@y14e/disclosure";
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import Disclosure from
|
|
16
|
+
import Disclosure from "https://esm.sh/@y14e/disclosure@2.0.4";
|
|
17
17
|
// or
|
|
18
|
-
import Disclosure from
|
|
18
|
+
import Disclosure from "https://cdn.jsdelivr.net/npm/@y14e/disclosure@2.0.4/+esm";
|
|
19
19
|
// or
|
|
20
|
-
import Disclosure from
|
|
20
|
+
import Disclosure from "https://esm.unpkg.com/@y14e/disclosure@2.0.4";
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
@@ -34,11 +34,11 @@ new Disclosure(root, options);
|
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
36
|
interface DisclosureOptions {
|
|
37
|
-
animation
|
|
38
|
-
duration
|
|
39
|
-
easing
|
|
37
|
+
animation: {
|
|
38
|
+
duration: number; // ms (default: 300)
|
|
39
|
+
easing: string; // <easing-function> (default: 'ease')
|
|
40
40
|
};
|
|
41
|
-
collapsible
|
|
41
|
+
collapsible: boolean; // default: true
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -47,7 +47,7 @@ interface DisclosureOptions {
|
|
|
47
47
|
Override the global default settings applied to all disclosure instances.
|
|
48
48
|
|
|
49
49
|
```ts
|
|
50
|
-
import Disclosure from
|
|
50
|
+
import Disclosure from "@y14e/disclosure";
|
|
51
51
|
|
|
52
52
|
Disclosure.defaults = {
|
|
53
53
|
animation: {
|
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);
|
|
204
245
|
}
|
|
246
|
+
let v = value.get(element.form);
|
|
247
|
+
if (!v) {
|
|
248
|
+
v = /* @__PURE__ */ new Map();
|
|
249
|
+
value.set(element.form, v);
|
|
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)
|
|
453
531
|
);
|
|
454
|
-
|
|
532
|
+
const afterIndex = focusables.findIndex(
|
|
533
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
534
|
+
);
|
|
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
|
});
|
|
@@ -779,7 +864,7 @@ var Disclosure = class _Disclosure {
|
|
|
779
864
|
);
|
|
780
865
|
}
|
|
781
866
|
#createBinding(details, summary, content) {
|
|
782
|
-
return {
|
|
867
|
+
return { animation: null, content, details, summary };
|
|
783
868
|
}
|
|
784
869
|
#isFocusable(element) {
|
|
785
870
|
return element.tabIndex >= 0;
|
|
@@ -810,7 +895,7 @@ function waitAnimationFinish(animation) {
|
|
|
810
895
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
811
896
|
* Using the <details> and <summary> element.
|
|
812
897
|
*
|
|
813
|
-
* @version 2.0.
|
|
898
|
+
* @version 2.0.4
|
|
814
899
|
* @author Yusuke Kamiyamane
|
|
815
900
|
* @license MIT
|
|
816
901
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -822,7 +907,18 @@ function waitAnimationFinish(animation) {
|
|
|
822
907
|
(**
|
|
823
908
|
* Attributes Utils
|
|
824
909
|
*
|
|
825
|
-
* @version
|
|
910
|
+
* @version 2.0.0
|
|
911
|
+
* @author Yusuke Kamiyamane
|
|
912
|
+
* @license MIT
|
|
913
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
914
|
+
* @see {@link https://github.com/y14e/attributes-utils}
|
|
915
|
+
*)
|
|
916
|
+
|
|
917
|
+
@y14e/attributes-utils/dist/index.js:
|
|
918
|
+
(**
|
|
919
|
+
* Attributes Utils
|
|
920
|
+
*
|
|
921
|
+
* @version 1.1.7
|
|
826
922
|
* @author Yusuke Kamiyamane
|
|
827
923
|
* @license MIT
|
|
828
924
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -835,7 +931,7 @@ power-focusable/dist/index.js:
|
|
|
835
931
|
* High-precision focus management utility with full composed tree support.
|
|
836
932
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
837
933
|
*
|
|
838
|
-
* @version 4.3.
|
|
934
|
+
* @version 4.3.23
|
|
839
935
|
* @author Yusuke Kamiyamane
|
|
840
936
|
* @license MIT
|
|
841
937
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -848,7 +944,7 @@ power-focusable/dist/index.js:
|
|
|
848
944
|
* Lightweight roving tabindex utility with fully focus management.
|
|
849
945
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
850
946
|
*
|
|
851
|
-
* @version 3.1.
|
|
947
|
+
* @version 3.1.20
|
|
852
948
|
* @author Yusuke Kamiyamane
|
|
853
949
|
* @license MIT
|
|
854
950
|
* @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);
|
|
202
243
|
}
|
|
244
|
+
let v = value.get(element.form);
|
|
245
|
+
if (!v) {
|
|
246
|
+
v = /* @__PURE__ */ new Map();
|
|
247
|
+
value.set(element.form, v);
|
|
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)
|
|
451
529
|
);
|
|
452
|
-
|
|
530
|
+
const afterIndex = focusables.findIndex(
|
|
531
|
+
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
532
|
+
);
|
|
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
|
});
|
|
@@ -777,7 +862,7 @@ var Disclosure = class _Disclosure {
|
|
|
777
862
|
);
|
|
778
863
|
}
|
|
779
864
|
#createBinding(details, summary, content) {
|
|
780
|
-
return {
|
|
865
|
+
return { animation: null, content, details, summary };
|
|
781
866
|
}
|
|
782
867
|
#isFocusable(element) {
|
|
783
868
|
return element.tabIndex >= 0;
|
|
@@ -808,7 +893,7 @@ function waitAnimationFinish(animation) {
|
|
|
808
893
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
809
894
|
* Using the <details> and <summary> element.
|
|
810
895
|
*
|
|
811
|
-
* @version 2.0.
|
|
896
|
+
* @version 2.0.4
|
|
812
897
|
* @author Yusuke Kamiyamane
|
|
813
898
|
* @license MIT
|
|
814
899
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -820,7 +905,18 @@ function waitAnimationFinish(animation) {
|
|
|
820
905
|
(**
|
|
821
906
|
* Attributes Utils
|
|
822
907
|
*
|
|
823
|
-
* @version
|
|
908
|
+
* @version 2.0.0
|
|
909
|
+
* @author Yusuke Kamiyamane
|
|
910
|
+
* @license MIT
|
|
911
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
912
|
+
* @see {@link https://github.com/y14e/attributes-utils}
|
|
913
|
+
*)
|
|
914
|
+
|
|
915
|
+
@y14e/attributes-utils/dist/index.js:
|
|
916
|
+
(**
|
|
917
|
+
* Attributes Utils
|
|
918
|
+
*
|
|
919
|
+
* @version 1.1.7
|
|
824
920
|
* @author Yusuke Kamiyamane
|
|
825
921
|
* @license MIT
|
|
826
922
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -833,7 +929,7 @@ power-focusable/dist/index.js:
|
|
|
833
929
|
* High-precision focus management utility with full composed tree support.
|
|
834
930
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
835
931
|
*
|
|
836
|
-
* @version 4.3.
|
|
932
|
+
* @version 4.3.23
|
|
837
933
|
* @author Yusuke Kamiyamane
|
|
838
934
|
* @license MIT
|
|
839
935
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -846,7 +942,7 @@ power-focusable/dist/index.js:
|
|
|
846
942
|
* Lightweight roving tabindex utility with fully focus management.
|
|
847
943
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
848
944
|
*
|
|
849
|
-
* @version 3.1.
|
|
945
|
+
* @version 3.1.20
|
|
850
946
|
* @author Yusuke Kamiyamane
|
|
851
947
|
* @license MIT
|
|
852
948
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -252,7 +252,7 @@ var Disclosure = class _Disclosure {
|
|
|
252
252
|
);
|
|
253
253
|
}
|
|
254
254
|
#createBinding(details, summary, content) {
|
|
255
|
-
return {
|
|
255
|
+
return { animation: null, content, details, summary };
|
|
256
256
|
}
|
|
257
257
|
#isFocusable(element) {
|
|
258
258
|
return element.tabIndex >= 0;
|
|
@@ -283,7 +283,7 @@ function waitAnimationFinish(animation) {
|
|
|
283
283
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
284
284
|
* Using the <details> and <summary> element.
|
|
285
285
|
*
|
|
286
|
-
* @version 2.0.
|
|
286
|
+
* @version 2.0.4
|
|
287
287
|
* @author Yusuke Kamiyamane
|
|
288
288
|
* @license MIT
|
|
289
289
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
|
@@ -3,23 +3,23 @@
|
|
|
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.4
|
|
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}
|
|
11
11
|
*/
|
|
12
12
|
interface DisclosureOptions {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
animation: {
|
|
14
|
+
duration: number;
|
|
15
|
+
easing: string;
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
collapsible: boolean;
|
|
18
18
|
}
|
|
19
19
|
declare class Disclosure {
|
|
20
20
|
#private;
|
|
21
|
-
static defaults: DisclosureOptions
|
|
22
|
-
constructor(root: HTMLElement, options?: DisclosureOptions);
|
|
21
|
+
static defaults: Partial<DisclosureOptions>;
|
|
22
|
+
constructor(root: HTMLElement, options?: Partial<DisclosureOptions>);
|
|
23
23
|
collapse(details: HTMLDetailsElement): void;
|
|
24
24
|
destroy(force?: boolean): Promise<void>;
|
|
25
25
|
expand(details: HTMLDetailsElement): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,23 +3,23 @@
|
|
|
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.4
|
|
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}
|
|
11
11
|
*/
|
|
12
12
|
interface DisclosureOptions {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
animation: {
|
|
14
|
+
duration: number;
|
|
15
|
+
easing: string;
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
collapsible: boolean;
|
|
18
18
|
}
|
|
19
19
|
declare class Disclosure {
|
|
20
20
|
#private;
|
|
21
|
-
static defaults: DisclosureOptions
|
|
22
|
-
constructor(root: HTMLElement, options?: DisclosureOptions);
|
|
21
|
+
static defaults: Partial<DisclosureOptions>;
|
|
22
|
+
constructor(root: HTMLElement, options?: Partial<DisclosureOptions>);
|
|
23
23
|
collapse(details: HTMLDetailsElement): void;
|
|
24
24
|
destroy(force?: boolean): Promise<void>;
|
|
25
25
|
expand(details: HTMLDetailsElement): void;
|
package/dist/index.js
CHANGED
|
@@ -250,7 +250,7 @@ var Disclosure = class _Disclosure {
|
|
|
250
250
|
);
|
|
251
251
|
}
|
|
252
252
|
#createBinding(details, summary, content) {
|
|
253
|
-
return {
|
|
253
|
+
return { animation: null, content, details, summary };
|
|
254
254
|
}
|
|
255
255
|
#isFocusable(element) {
|
|
256
256
|
return element.tabIndex >= 0;
|
|
@@ -281,7 +281,7 @@ function waitAnimationFinish(animation) {
|
|
|
281
281
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
282
282
|
* Using the <details> and <summary> element.
|
|
283
283
|
*
|
|
284
|
-
* @version 2.0.
|
|
284
|
+
* @version 2.0.4
|
|
285
285
|
* @author Yusuke Kamiyamane
|
|
286
286
|
* @license MIT
|
|
287
287
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/disclosure",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
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
|
}
|