@y14e/disclosure 2.0.16 → 2.1.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 +3 -3
- package/dist/index.bundle.cjs +110 -43
- package/dist/index.bundle.js +110 -43
- package/dist/index.cjs +5 -25
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,11 +13,11 @@ npm i @y14e/disclosure
|
|
|
13
13
|
import { Disclosure } from '@y14e/disclosure';
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import { Disclosure } from 'https://esm.sh/@y14e/disclosure@2.
|
|
16
|
+
import { Disclosure } from 'https://esm.sh/@y14e/disclosure@2.1.1';
|
|
17
17
|
// or
|
|
18
|
-
import { Disclosure } from 'https://cdn.jsdelivr.net/npm/@y14e/disclosure@2.
|
|
18
|
+
import { Disclosure } from 'https://cdn.jsdelivr.net/npm/@y14e/disclosure@2.1.1/+esm';
|
|
19
19
|
// or
|
|
20
|
-
import { Disclosure } from 'https://esm.unpkg.com/@y14e/disclosure@2.
|
|
20
|
+
import { Disclosure } from 'https://esm.unpkg.com/@y14e/disclosure@2.1.1';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -207,31 +207,25 @@ function normalizeRadioGroup(elements) {
|
|
|
207
207
|
map = /* @__PURE__ */ new Map();
|
|
208
208
|
}
|
|
209
209
|
const root = element.getRootNode();
|
|
210
|
-
|
|
210
|
+
const groups = map.get(root) ?? map.set(root, /* @__PURE__ */ new Map()).get(root);
|
|
211
211
|
if (!groups) {
|
|
212
|
-
|
|
213
|
-
map.set(root, groups);
|
|
214
|
-
}
|
|
215
|
-
let group = groups.get(element.form);
|
|
216
|
-
if (!group) {
|
|
217
|
-
group = /* @__PURE__ */ new Map();
|
|
218
|
-
groups.set(element.form, group);
|
|
212
|
+
continue;
|
|
219
213
|
}
|
|
220
|
-
|
|
214
|
+
const { form, name } = element;
|
|
215
|
+
const radios = groups.get(form) ?? groups.set(form, /* @__PURE__ */ new Map()).get(form);
|
|
221
216
|
if (!radios) {
|
|
222
|
-
|
|
223
|
-
group.set(element.name, radios);
|
|
217
|
+
continue;
|
|
224
218
|
}
|
|
225
|
-
radios.push(element);
|
|
219
|
+
(radios.get(name) ?? radios.set(name, []).get(name))?.push(element);
|
|
226
220
|
}
|
|
227
221
|
if (!map) {
|
|
228
222
|
return elements;
|
|
229
223
|
}
|
|
230
224
|
const placeholder = /* @__PURE__ */ new Set();
|
|
231
|
-
for (const
|
|
232
|
-
for (const
|
|
233
|
-
for (const
|
|
234
|
-
const radio =
|
|
225
|
+
for (const v of map.values()) {
|
|
226
|
+
for (const w of v.values()) {
|
|
227
|
+
for (const x of w.values()) {
|
|
228
|
+
const radio = x.find((r) => r.checked) ?? x[0];
|
|
235
229
|
radio && placeholder.add(radio);
|
|
236
230
|
}
|
|
237
231
|
}
|
|
@@ -352,14 +346,15 @@ function resolveOptions2(options) {
|
|
|
352
346
|
}
|
|
353
347
|
|
|
354
348
|
// node_modules/@y14e/roving-tabindex/dist/index.js
|
|
349
|
+
var DIRECTIONS = ["both", "grid", "horizontal", "vertical"];
|
|
355
350
|
function createRovingTabIndex(container, options = {}) {
|
|
356
351
|
if (!(container instanceof Element)) {
|
|
357
352
|
console.warn("Invalid container element");
|
|
358
353
|
return () => {
|
|
359
354
|
};
|
|
360
355
|
}
|
|
361
|
-
const
|
|
362
|
-
return () =>
|
|
356
|
+
const rovingTabIndex = new RovingTabIndex(container, options);
|
|
357
|
+
return () => rovingTabIndex.destroy();
|
|
363
358
|
}
|
|
364
359
|
var RovingTabIndex = class _RovingTabIndex {
|
|
365
360
|
static #initialized = /* @__PURE__ */ new Set();
|
|
@@ -418,18 +413,19 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
418
413
|
if (!(event instanceof KeyboardEvent)) {
|
|
419
414
|
return;
|
|
420
415
|
}
|
|
416
|
+
const { direction, typeahead, wrap = false } = this.#settings;
|
|
417
|
+
const isGrid = direction === "grid";
|
|
421
418
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
422
|
-
if (
|
|
419
|
+
if (!(isGrid && ["End", "Home"].includes(key)) && ctrlKey || altKey || metaKey || shiftKey) {
|
|
423
420
|
return;
|
|
424
421
|
}
|
|
425
|
-
const { direction, typeahead, wrap } = this.#settings;
|
|
426
422
|
const isBoth = direction === "both";
|
|
427
423
|
const isHorizontal = direction === "horizontal";
|
|
428
424
|
if (![
|
|
429
425
|
"End",
|
|
430
426
|
"Home",
|
|
431
|
-
...isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
|
|
432
|
-
...isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
|
|
427
|
+
...isGrid || isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
|
|
428
|
+
...isGrid || isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
|
|
433
429
|
].includes(key)) {
|
|
434
430
|
if (!typeahead || !/^\S$/i.test(key) || !this.#focusablesByFirstChar.has(key.toUpperCase())) {
|
|
435
431
|
return;
|
|
@@ -448,39 +444,48 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
448
444
|
event.preventDefault();
|
|
449
445
|
let newIndex;
|
|
450
446
|
const activeIndex = candidates.indexOf(active);
|
|
451
|
-
let
|
|
447
|
+
let target = candidates;
|
|
452
448
|
switch (key) {
|
|
453
449
|
case "End":
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
450
|
+
case "Home": {
|
|
451
|
+
const rawIndex = key === "End" ? -1 : 0;
|
|
452
|
+
if (isGrid && !ctrlKey) {
|
|
453
|
+
const cell = this.#getCellsOfActiveRow().at(rawIndex);
|
|
454
|
+
newIndex = cell ? candidates.indexOf(cell) : activeIndex;
|
|
455
|
+
} else {
|
|
456
|
+
newIndex = rawIndex;
|
|
457
|
+
}
|
|
463
458
|
break;
|
|
464
459
|
}
|
|
460
|
+
case "ArrowLeft":
|
|
461
|
+
case "ArrowUp":
|
|
465
462
|
case "ArrowRight":
|
|
466
463
|
case "ArrowDown": {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
464
|
+
if (["ArrowUp", "ArrowDown"].includes(key) && isGrid) {
|
|
465
|
+
const cell = this.#getNextCell(key, wrap);
|
|
466
|
+
newIndex = cell ? candidates.indexOf(cell) : activeIndex;
|
|
467
|
+
} else {
|
|
468
|
+
if (isGrid) {
|
|
469
|
+
target = this.#getCellsOfActiveRow();
|
|
470
|
+
}
|
|
471
|
+
const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
|
|
472
|
+
const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
|
|
473
|
+
newIndex = isPrevious ? wrap ? rawIndex : Math.max(rawIndex, 0) : wrap ? rawIndex % target.length : Math.min(rawIndex, target.length - 1);
|
|
474
|
+
}
|
|
470
475
|
break;
|
|
471
476
|
}
|
|
472
477
|
default: {
|
|
473
478
|
const focusablesByFirstChar = new Set(
|
|
474
479
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
475
480
|
);
|
|
476
|
-
|
|
477
|
-
const afterIndex =
|
|
481
|
+
target = candidates.filter((c) => focusablesByFirstChar.has(c));
|
|
482
|
+
const afterIndex = target.findIndex(
|
|
478
483
|
(f) => candidates.indexOf(f) > activeIndex
|
|
479
484
|
);
|
|
480
485
|
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
481
486
|
}
|
|
482
487
|
}
|
|
483
|
-
const focusable =
|
|
488
|
+
const focusable = target.at(newIndex);
|
|
484
489
|
focusable && focusElement(focusable);
|
|
485
490
|
};
|
|
486
491
|
#update(active) {
|
|
@@ -550,6 +555,24 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
550
555
|
const { selector } = this.#settings;
|
|
551
556
|
return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
|
|
552
557
|
}
|
|
558
|
+
#getCellCoords(cell) {
|
|
559
|
+
const { height, left, top, width } = cell.getBoundingClientRect();
|
|
560
|
+
return {
|
|
561
|
+
x: left + width / 2,
|
|
562
|
+
y: top + height / 2
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
#getCellsOfActiveRow() {
|
|
566
|
+
const active = getActiveElement();
|
|
567
|
+
if (!(active instanceof Element)) {
|
|
568
|
+
return [];
|
|
569
|
+
}
|
|
570
|
+
const activeRect = active.getBoundingClientRect();
|
|
571
|
+
return this.#getFocusables().filter((cell) => {
|
|
572
|
+
const cellRect = cell.getBoundingClientRect();
|
|
573
|
+
return cellRect.top < activeRect.bottom && cellRect.bottom > activeRect.top;
|
|
574
|
+
});
|
|
575
|
+
}
|
|
553
576
|
#getFocusables() {
|
|
554
577
|
return getFocusables(this.#container, {
|
|
555
578
|
composed: true,
|
|
@@ -558,6 +581,50 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
558
581
|
skipVisibilityCheck: true
|
|
559
582
|
});
|
|
560
583
|
}
|
|
584
|
+
#getNextCell(key, wrap) {
|
|
585
|
+
const cells = this.#getFocusables();
|
|
586
|
+
const active = getActiveElement();
|
|
587
|
+
if (!(active instanceof Element)) {
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
const activeCoords = this.#getCellCoords(active);
|
|
591
|
+
let min = Infinity;
|
|
592
|
+
let result = null;
|
|
593
|
+
for (const cell of cells) {
|
|
594
|
+
if (cell === active) {
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
const cellCoords = this.#getCellCoords(cell);
|
|
598
|
+
const distances = {
|
|
599
|
+
x: Math.abs(cellCoords.x - activeCoords.x),
|
|
600
|
+
y: Math.abs(cellCoords.y - activeCoords.y)
|
|
601
|
+
};
|
|
602
|
+
if (key === "ArrowUp" && cellCoords.y < activeCoords.y && distances.x < distances.y || key === "ArrowDown" && cellCoords.y > activeCoords.y && distances.x < distances.y) {
|
|
603
|
+
const distance = distances.x ** 2 + distances.y ** 2;
|
|
604
|
+
if (distance < min) {
|
|
605
|
+
min = distance;
|
|
606
|
+
result = cell;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (!result && wrap) {
|
|
611
|
+
let max = -Infinity;
|
|
612
|
+
for (const cell of cells) {
|
|
613
|
+
if (cell === active) {
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
const cellCoords = this.#getCellCoords(cell);
|
|
617
|
+
if (Math.abs(cellCoords.x - activeCoords.x) < cell.getBoundingClientRect().width / 2) {
|
|
618
|
+
const distance = key === "ArrowUp" ? cellCoords.y - activeCoords.y : activeCoords.y - cellCoords.y;
|
|
619
|
+
if (distance > max) {
|
|
620
|
+
max = distance;
|
|
621
|
+
result = cell;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return result;
|
|
627
|
+
}
|
|
561
628
|
#resolveOptions(options) {
|
|
562
629
|
let {
|
|
563
630
|
direction = "both",
|
|
@@ -569,7 +636,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
569
636
|
wrap = false
|
|
570
637
|
} = options;
|
|
571
638
|
direction = direction.toLowerCase();
|
|
572
|
-
if (!
|
|
639
|
+
if (!DIRECTIONS.includes(direction)) {
|
|
573
640
|
console.warn("Invalid direction option. Fallback: 'both'.");
|
|
574
641
|
direction = "both";
|
|
575
642
|
}
|
|
@@ -908,7 +975,7 @@ var Disclosure = class _Disclosure {
|
|
|
908
975
|
}
|
|
909
976
|
};
|
|
910
977
|
function waitAnimationFinish(animation) {
|
|
911
|
-
return ["
|
|
978
|
+
return ["finished", "idle"].includes(animation.playState) ? Promise.resolve() : new Promise(
|
|
912
979
|
(resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
|
|
913
980
|
);
|
|
914
981
|
}
|
|
@@ -917,7 +984,7 @@ function waitAnimationFinish(animation) {
|
|
|
917
984
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
918
985
|
* Using the <details> and <summary> element.
|
|
919
986
|
*
|
|
920
|
-
* @version 2.
|
|
987
|
+
* @version 2.1.1
|
|
921
988
|
* @author Yusuke Kamiyamane
|
|
922
989
|
* @license MIT
|
|
923
990
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -942,7 +1009,7 @@ power-focusable/dist/index.js:
|
|
|
942
1009
|
* High-precision focus management utility with full composed tree support.
|
|
943
1010
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
944
1011
|
*
|
|
945
|
-
* @version 4.3
|
|
1012
|
+
* @version 4.4.3
|
|
946
1013
|
* @author Yusuke Kamiyamane
|
|
947
1014
|
* @license MIT
|
|
948
1015
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -955,7 +1022,7 @@ power-focusable/dist/index.js:
|
|
|
955
1022
|
* Lightweight roving tabindex utility with fully focus management.
|
|
956
1023
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
957
1024
|
*
|
|
958
|
-
* @version 3.
|
|
1025
|
+
* @version 3.3.2
|
|
959
1026
|
* @author Yusuke Kamiyamane
|
|
960
1027
|
* @license MIT
|
|
961
1028
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -205,31 +205,25 @@ function normalizeRadioGroup(elements) {
|
|
|
205
205
|
map = /* @__PURE__ */ new Map();
|
|
206
206
|
}
|
|
207
207
|
const root = element.getRootNode();
|
|
208
|
-
|
|
208
|
+
const groups = map.get(root) ?? map.set(root, /* @__PURE__ */ new Map()).get(root);
|
|
209
209
|
if (!groups) {
|
|
210
|
-
|
|
211
|
-
map.set(root, groups);
|
|
212
|
-
}
|
|
213
|
-
let group = groups.get(element.form);
|
|
214
|
-
if (!group) {
|
|
215
|
-
group = /* @__PURE__ */ new Map();
|
|
216
|
-
groups.set(element.form, group);
|
|
210
|
+
continue;
|
|
217
211
|
}
|
|
218
|
-
|
|
212
|
+
const { form, name } = element;
|
|
213
|
+
const radios = groups.get(form) ?? groups.set(form, /* @__PURE__ */ new Map()).get(form);
|
|
219
214
|
if (!radios) {
|
|
220
|
-
|
|
221
|
-
group.set(element.name, radios);
|
|
215
|
+
continue;
|
|
222
216
|
}
|
|
223
|
-
radios.push(element);
|
|
217
|
+
(radios.get(name) ?? radios.set(name, []).get(name))?.push(element);
|
|
224
218
|
}
|
|
225
219
|
if (!map) {
|
|
226
220
|
return elements;
|
|
227
221
|
}
|
|
228
222
|
const placeholder = /* @__PURE__ */ new Set();
|
|
229
|
-
for (const
|
|
230
|
-
for (const
|
|
231
|
-
for (const
|
|
232
|
-
const radio =
|
|
223
|
+
for (const v of map.values()) {
|
|
224
|
+
for (const w of v.values()) {
|
|
225
|
+
for (const x of w.values()) {
|
|
226
|
+
const radio = x.find((r) => r.checked) ?? x[0];
|
|
233
227
|
radio && placeholder.add(radio);
|
|
234
228
|
}
|
|
235
229
|
}
|
|
@@ -350,14 +344,15 @@ function resolveOptions2(options) {
|
|
|
350
344
|
}
|
|
351
345
|
|
|
352
346
|
// node_modules/@y14e/roving-tabindex/dist/index.js
|
|
347
|
+
var DIRECTIONS = ["both", "grid", "horizontal", "vertical"];
|
|
353
348
|
function createRovingTabIndex(container, options = {}) {
|
|
354
349
|
if (!(container instanceof Element)) {
|
|
355
350
|
console.warn("Invalid container element");
|
|
356
351
|
return () => {
|
|
357
352
|
};
|
|
358
353
|
}
|
|
359
|
-
const
|
|
360
|
-
return () =>
|
|
354
|
+
const rovingTabIndex = new RovingTabIndex(container, options);
|
|
355
|
+
return () => rovingTabIndex.destroy();
|
|
361
356
|
}
|
|
362
357
|
var RovingTabIndex = class _RovingTabIndex {
|
|
363
358
|
static #initialized = /* @__PURE__ */ new Set();
|
|
@@ -416,18 +411,19 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
416
411
|
if (!(event instanceof KeyboardEvent)) {
|
|
417
412
|
return;
|
|
418
413
|
}
|
|
414
|
+
const { direction, typeahead, wrap = false } = this.#settings;
|
|
415
|
+
const isGrid = direction === "grid";
|
|
419
416
|
const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
|
|
420
|
-
if (
|
|
417
|
+
if (!(isGrid && ["End", "Home"].includes(key)) && ctrlKey || altKey || metaKey || shiftKey) {
|
|
421
418
|
return;
|
|
422
419
|
}
|
|
423
|
-
const { direction, typeahead, wrap } = this.#settings;
|
|
424
420
|
const isBoth = direction === "both";
|
|
425
421
|
const isHorizontal = direction === "horizontal";
|
|
426
422
|
if (![
|
|
427
423
|
"End",
|
|
428
424
|
"Home",
|
|
429
|
-
...isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
|
|
430
|
-
...isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
|
|
425
|
+
...isGrid || isBoth ? ["ArrowLeft", "ArrowUp"] : [`Arrow${isHorizontal ? "Left" : "Up"}`],
|
|
426
|
+
...isGrid || isBoth ? ["ArrowRight", "ArrowDown"] : [`Arrow${isHorizontal ? "Right" : "Down"}`]
|
|
431
427
|
].includes(key)) {
|
|
432
428
|
if (!typeahead || !/^\S$/i.test(key) || !this.#focusablesByFirstChar.has(key.toUpperCase())) {
|
|
433
429
|
return;
|
|
@@ -446,39 +442,48 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
446
442
|
event.preventDefault();
|
|
447
443
|
let newIndex;
|
|
448
444
|
const activeIndex = candidates.indexOf(active);
|
|
449
|
-
let
|
|
445
|
+
let target = candidates;
|
|
450
446
|
switch (key) {
|
|
451
447
|
case "End":
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
newIndex = wrap ? rawIndex : Math.max(rawIndex, 0);
|
|
448
|
+
case "Home": {
|
|
449
|
+
const rawIndex = key === "End" ? -1 : 0;
|
|
450
|
+
if (isGrid && !ctrlKey) {
|
|
451
|
+
const cell = this.#getCellsOfActiveRow().at(rawIndex);
|
|
452
|
+
newIndex = cell ? candidates.indexOf(cell) : activeIndex;
|
|
453
|
+
} else {
|
|
454
|
+
newIndex = rawIndex;
|
|
455
|
+
}
|
|
461
456
|
break;
|
|
462
457
|
}
|
|
458
|
+
case "ArrowLeft":
|
|
459
|
+
case "ArrowUp":
|
|
463
460
|
case "ArrowRight":
|
|
464
461
|
case "ArrowDown": {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
462
|
+
if (["ArrowUp", "ArrowDown"].includes(key) && isGrid) {
|
|
463
|
+
const cell = this.#getNextCell(key, wrap);
|
|
464
|
+
newIndex = cell ? candidates.indexOf(cell) : activeIndex;
|
|
465
|
+
} else {
|
|
466
|
+
if (isGrid) {
|
|
467
|
+
target = this.#getCellsOfActiveRow();
|
|
468
|
+
}
|
|
469
|
+
const isPrevious = ["ArrowLeft", "ArrowUp"].includes(key);
|
|
470
|
+
const rawIndex = (isGrid ? target.indexOf(active) : activeIndex) + (isPrevious ? -1 : 1);
|
|
471
|
+
newIndex = isPrevious ? wrap ? rawIndex : Math.max(rawIndex, 0) : wrap ? rawIndex % target.length : Math.min(rawIndex, target.length - 1);
|
|
472
|
+
}
|
|
468
473
|
break;
|
|
469
474
|
}
|
|
470
475
|
default: {
|
|
471
476
|
const focusablesByFirstChar = new Set(
|
|
472
477
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
473
478
|
);
|
|
474
|
-
|
|
475
|
-
const afterIndex =
|
|
479
|
+
target = candidates.filter((c) => focusablesByFirstChar.has(c));
|
|
480
|
+
const afterIndex = target.findIndex(
|
|
476
481
|
(f) => candidates.indexOf(f) > activeIndex
|
|
477
482
|
);
|
|
478
483
|
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
479
484
|
}
|
|
480
485
|
}
|
|
481
|
-
const focusable =
|
|
486
|
+
const focusable = target.at(newIndex);
|
|
482
487
|
focusable && focusElement(focusable);
|
|
483
488
|
};
|
|
484
489
|
#update(active) {
|
|
@@ -548,6 +553,24 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
548
553
|
const { selector } = this.#settings;
|
|
549
554
|
return (element) => !selector || [...this.#container.querySelectorAll(selector)].includes(element);
|
|
550
555
|
}
|
|
556
|
+
#getCellCoords(cell) {
|
|
557
|
+
const { height, left, top, width } = cell.getBoundingClientRect();
|
|
558
|
+
return {
|
|
559
|
+
x: left + width / 2,
|
|
560
|
+
y: top + height / 2
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
#getCellsOfActiveRow() {
|
|
564
|
+
const active = getActiveElement();
|
|
565
|
+
if (!(active instanceof Element)) {
|
|
566
|
+
return [];
|
|
567
|
+
}
|
|
568
|
+
const activeRect = active.getBoundingClientRect();
|
|
569
|
+
return this.#getFocusables().filter((cell) => {
|
|
570
|
+
const cellRect = cell.getBoundingClientRect();
|
|
571
|
+
return cellRect.top < activeRect.bottom && cellRect.bottom > activeRect.top;
|
|
572
|
+
});
|
|
573
|
+
}
|
|
551
574
|
#getFocusables() {
|
|
552
575
|
return getFocusables(this.#container, {
|
|
553
576
|
composed: true,
|
|
@@ -556,6 +579,50 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
556
579
|
skipVisibilityCheck: true
|
|
557
580
|
});
|
|
558
581
|
}
|
|
582
|
+
#getNextCell(key, wrap) {
|
|
583
|
+
const cells = this.#getFocusables();
|
|
584
|
+
const active = getActiveElement();
|
|
585
|
+
if (!(active instanceof Element)) {
|
|
586
|
+
return null;
|
|
587
|
+
}
|
|
588
|
+
const activeCoords = this.#getCellCoords(active);
|
|
589
|
+
let min = Infinity;
|
|
590
|
+
let result = null;
|
|
591
|
+
for (const cell of cells) {
|
|
592
|
+
if (cell === active) {
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
const cellCoords = this.#getCellCoords(cell);
|
|
596
|
+
const distances = {
|
|
597
|
+
x: Math.abs(cellCoords.x - activeCoords.x),
|
|
598
|
+
y: Math.abs(cellCoords.y - activeCoords.y)
|
|
599
|
+
};
|
|
600
|
+
if (key === "ArrowUp" && cellCoords.y < activeCoords.y && distances.x < distances.y || key === "ArrowDown" && cellCoords.y > activeCoords.y && distances.x < distances.y) {
|
|
601
|
+
const distance = distances.x ** 2 + distances.y ** 2;
|
|
602
|
+
if (distance < min) {
|
|
603
|
+
min = distance;
|
|
604
|
+
result = cell;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (!result && wrap) {
|
|
609
|
+
let max = -Infinity;
|
|
610
|
+
for (const cell of cells) {
|
|
611
|
+
if (cell === active) {
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
const cellCoords = this.#getCellCoords(cell);
|
|
615
|
+
if (Math.abs(cellCoords.x - activeCoords.x) < cell.getBoundingClientRect().width / 2) {
|
|
616
|
+
const distance = key === "ArrowUp" ? cellCoords.y - activeCoords.y : activeCoords.y - cellCoords.y;
|
|
617
|
+
if (distance > max) {
|
|
618
|
+
max = distance;
|
|
619
|
+
result = cell;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return result;
|
|
625
|
+
}
|
|
559
626
|
#resolveOptions(options) {
|
|
560
627
|
let {
|
|
561
628
|
direction = "both",
|
|
@@ -567,7 +634,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
567
634
|
wrap = false
|
|
568
635
|
} = options;
|
|
569
636
|
direction = direction.toLowerCase();
|
|
570
|
-
if (!
|
|
637
|
+
if (!DIRECTIONS.includes(direction)) {
|
|
571
638
|
console.warn("Invalid direction option. Fallback: 'both'.");
|
|
572
639
|
direction = "both";
|
|
573
640
|
}
|
|
@@ -906,7 +973,7 @@ var Disclosure = class _Disclosure {
|
|
|
906
973
|
}
|
|
907
974
|
};
|
|
908
975
|
function waitAnimationFinish(animation) {
|
|
909
|
-
return ["
|
|
976
|
+
return ["finished", "idle"].includes(animation.playState) ? Promise.resolve() : new Promise(
|
|
910
977
|
(resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
|
|
911
978
|
);
|
|
912
979
|
}
|
|
@@ -915,7 +982,7 @@ function waitAnimationFinish(animation) {
|
|
|
915
982
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
916
983
|
* Using the <details> and <summary> element.
|
|
917
984
|
*
|
|
918
|
-
* @version 2.
|
|
985
|
+
* @version 2.1.1
|
|
919
986
|
* @author Yusuke Kamiyamane
|
|
920
987
|
* @license MIT
|
|
921
988
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -940,7 +1007,7 @@ power-focusable/dist/index.js:
|
|
|
940
1007
|
* High-precision focus management utility with full composed tree support.
|
|
941
1008
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
942
1009
|
*
|
|
943
|
-
* @version 4.3
|
|
1010
|
+
* @version 4.4.3
|
|
944
1011
|
* @author Yusuke Kamiyamane
|
|
945
1012
|
* @license MIT
|
|
946
1013
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -953,7 +1020,7 @@ power-focusable/dist/index.js:
|
|
|
953
1020
|
* Lightweight roving tabindex utility with fully focus management.
|
|
954
1021
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
955
1022
|
*
|
|
956
|
-
* @version 3.
|
|
1023
|
+
* @version 3.3.2
|
|
957
1024
|
* @author Yusuke Kamiyamane
|
|
958
1025
|
* @license MIT
|
|
959
1026
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -1,28 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var attributeUtils = require('@y14e/attribute-utils');
|
|
4
4
|
var rovingTabindex = require('@y14e/roving-tabindex');
|
|
5
5
|
|
|
6
|
-
function _interopNamespace(e) {
|
|
7
|
-
if (e && e.__esModule) return e;
|
|
8
|
-
var n = Object.create(null);
|
|
9
|
-
if (e) {
|
|
10
|
-
Object.keys(e).forEach(function (k) {
|
|
11
|
-
if (k !== 'default') {
|
|
12
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () { return e[k]; }
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
n.default = e;
|
|
21
|
-
return Object.freeze(n);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
var utils__namespace = /*#__PURE__*/_interopNamespace(utils);
|
|
25
|
-
|
|
26
6
|
// src/index.ts
|
|
27
7
|
var Disclosure = class _Disclosure {
|
|
28
8
|
static defaults = {};
|
|
@@ -133,7 +113,7 @@ var Disclosure = class _Disclosure {
|
|
|
133
113
|
}
|
|
134
114
|
}
|
|
135
115
|
this.#detailsElements.length = 0;
|
|
136
|
-
|
|
116
|
+
attributeUtils.restoreAttributes(this.#summaryElements);
|
|
137
117
|
this.#summaryElements.length = 0;
|
|
138
118
|
this.#contentElements.length = 0;
|
|
139
119
|
this.#rootElement.removeAttribute("data-disclosure-initialized");
|
|
@@ -149,7 +129,7 @@ var Disclosure = class _Disclosure {
|
|
|
149
129
|
this.#toggle(details, true);
|
|
150
130
|
}
|
|
151
131
|
#initialize() {
|
|
152
|
-
|
|
132
|
+
attributeUtils.saveAttributes(this.#summaryElements, [
|
|
153
133
|
"aria-disabled",
|
|
154
134
|
"style",
|
|
155
135
|
"tabindex"
|
|
@@ -318,7 +298,7 @@ var Disclosure = class _Disclosure {
|
|
|
318
298
|
}
|
|
319
299
|
};
|
|
320
300
|
function waitAnimationFinish(animation) {
|
|
321
|
-
return ["
|
|
301
|
+
return ["finished", "idle"].includes(animation.playState) ? Promise.resolve() : new Promise(
|
|
322
302
|
(resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
|
|
323
303
|
);
|
|
324
304
|
}
|
|
@@ -327,7 +307,7 @@ function waitAnimationFinish(animation) {
|
|
|
327
307
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
328
308
|
* Using the <details> and <summary> element.
|
|
329
309
|
*
|
|
330
|
-
* @version 2.
|
|
310
|
+
* @version 2.1.1
|
|
331
311
|
* @author Yusuke Kamiyamane
|
|
332
312
|
* @license MIT
|
|
333
313
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { restoreAttributes, saveAttributes } from '@y14e/attribute-utils';
|
|
2
2
|
import { createRovingTabIndex } from '@y14e/roving-tabindex';
|
|
3
3
|
|
|
4
4
|
// src/index.ts
|
|
@@ -111,7 +111,7 @@ var Disclosure = class _Disclosure {
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
this.#detailsElements.length = 0;
|
|
114
|
-
|
|
114
|
+
restoreAttributes(this.#summaryElements);
|
|
115
115
|
this.#summaryElements.length = 0;
|
|
116
116
|
this.#contentElements.length = 0;
|
|
117
117
|
this.#rootElement.removeAttribute("data-disclosure-initialized");
|
|
@@ -127,7 +127,7 @@ var Disclosure = class _Disclosure {
|
|
|
127
127
|
this.#toggle(details, true);
|
|
128
128
|
}
|
|
129
129
|
#initialize() {
|
|
130
|
-
|
|
130
|
+
saveAttributes(this.#summaryElements, [
|
|
131
131
|
"aria-disabled",
|
|
132
132
|
"style",
|
|
133
133
|
"tabindex"
|
|
@@ -296,7 +296,7 @@ var Disclosure = class _Disclosure {
|
|
|
296
296
|
}
|
|
297
297
|
};
|
|
298
298
|
function waitAnimationFinish(animation) {
|
|
299
|
-
return ["
|
|
299
|
+
return ["finished", "idle"].includes(animation.playState) ? Promise.resolve() : new Promise(
|
|
300
300
|
(resolve) => animation.addEventListener("finish", () => resolve(), { once: true })
|
|
301
301
|
);
|
|
302
302
|
}
|
|
@@ -305,7 +305,7 @@ function waitAnimationFinish(animation) {
|
|
|
305
305
|
* WAI-ARIA compliant disclosure pattern implementation in TypeScript.
|
|
306
306
|
* Using the <details> and <summary> element.
|
|
307
307
|
*
|
|
308
|
-
* @version 2.
|
|
308
|
+
* @version 2.1.1
|
|
309
309
|
* @author Yusuke Kamiyamane
|
|
310
310
|
* @license MIT
|
|
311
311
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/disclosure",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "WAI-ARIA compliant disclosure pattern implementation in TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"a11y",
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@y14e/attribute-utils": "^2.0.12",
|
|
58
|
-
"@y14e/roving-tabindex": "^3.
|
|
58
|
+
"@y14e/roving-tabindex": "^3.3.2"
|
|
59
59
|
}
|
|
60
60
|
}
|