@y14e/tabs 2.0.8 → 2.0.10
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 +19 -19
- package/dist/index.bundle.cjs +106 -39
- package/dist/index.bundle.js +106 -39
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -10,14 +10,14 @@ npm i @y14e/tabs
|
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
// npm
|
|
13
|
-
import Tabs from
|
|
13
|
+
import Tabs from "@y14e/tabs";
|
|
14
14
|
|
|
15
15
|
// CDNs
|
|
16
|
-
import Tabs from
|
|
16
|
+
import Tabs from "https://esm.sh/@y14e/tabs@2.0.10";
|
|
17
17
|
// or
|
|
18
|
-
import Tabs from
|
|
18
|
+
import Tabs from "https://cdn.jsdelivr.net/npm/@y14e/tabs@2.0.10/+esm";
|
|
19
19
|
// or
|
|
20
|
-
import Tabs from
|
|
20
|
+
import Tabs from "https://esm.unpkg.com/@y14e/tabs@2.0.10";
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
@@ -36,26 +36,26 @@ new Tabs(root, options);
|
|
|
36
36
|
interface TabsOptions {
|
|
37
37
|
animation: {
|
|
38
38
|
content: {
|
|
39
|
-
crossFade: boolean;
|
|
40
|
-
duration: number;
|
|
41
|
-
easing: string;
|
|
42
|
-
fade: boolean;
|
|
39
|
+
crossFade: boolean; // default: true
|
|
40
|
+
duration: number; // ms (default: 300)
|
|
41
|
+
easing: string; // <easing-function> (default: 'ease')
|
|
42
|
+
fade: boolean; // default: true
|
|
43
43
|
};
|
|
44
44
|
indicator: {
|
|
45
|
-
duration: number;
|
|
46
|
-
easing: string;
|
|
45
|
+
duration: number; // ms (default: 300)
|
|
46
|
+
easing: string; // <easing-function> (default: 'ease')
|
|
47
47
|
};
|
|
48
48
|
};
|
|
49
49
|
avoidDuplicates: boolean; // default: false
|
|
50
|
-
manual: boolean;
|
|
50
|
+
manual: boolean; // default: false
|
|
51
51
|
selector: {
|
|
52
|
-
content: string;
|
|
53
|
-
indicator: string;
|
|
54
|
-
list: string;
|
|
55
|
-
panel: string;
|
|
56
|
-
tab: string;
|
|
52
|
+
content: string; // default: '[role="tablist"] + *'
|
|
53
|
+
indicator: string; // default: '[data-tabs-indicator]'
|
|
54
|
+
list: string; // default: '[role="tablist"]'
|
|
55
|
+
panel: string; // default: '[role="tabpanel"]'
|
|
56
|
+
tab: string; // default: '[role="tab"]'
|
|
57
57
|
};
|
|
58
|
-
vertical: boolean;
|
|
58
|
+
vertical: boolean; // default: false
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
@@ -68,7 +68,7 @@ If `true`, only the first tab list remains interactive; subsequent duplicates ar
|
|
|
68
68
|
Override the global default settings applied to all accordion instances.
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
|
-
import Tabs from
|
|
71
|
+
import Tabs from "@y14e/tabs";
|
|
72
72
|
|
|
73
73
|
Tabs.defaults = {
|
|
74
74
|
animation: {
|
|
@@ -76,7 +76,7 @@ Tabs.defaults = {
|
|
|
76
76
|
crossFade: false,
|
|
77
77
|
duration: 1000,
|
|
78
78
|
fade: true,
|
|
79
|
-
}
|
|
79
|
+
},
|
|
80
80
|
},
|
|
81
81
|
manual: true,
|
|
82
82
|
};
|
package/dist/index.bundle.cjs
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// node_modules/@y14e/attributes-utils/dist/index.js
|
|
4
4
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
5
5
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
6
|
-
function
|
|
7
|
-
const value = element.getAttribute(
|
|
6
|
+
function addAttributeToken(element, name, token, options = {}) {
|
|
7
|
+
const value = element.getAttribute(name)?.trim();
|
|
8
8
|
const {
|
|
9
9
|
caseInsensitive = false,
|
|
10
10
|
parse = DEFAULT_PARSER,
|
|
@@ -15,12 +15,12 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
15
15
|
const lower = token.toLowerCase();
|
|
16
16
|
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
17
17
|
tokens.push(token);
|
|
18
|
-
element.setAttribute(
|
|
18
|
+
element.setAttribute(name, serialize(tokens));
|
|
19
19
|
}
|
|
20
20
|
} else {
|
|
21
21
|
const set = new Set(tokens);
|
|
22
22
|
set.add(token);
|
|
23
|
-
element.setAttribute(
|
|
23
|
+
element.setAttribute(name, serialize([...set]));
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
var snapshots = /* @__PURE__ */ new WeakMap();
|
|
@@ -30,25 +30,26 @@ function restoreAttributes(element_or_elements) {
|
|
|
30
30
|
if (!snapshot) {
|
|
31
31
|
continue;
|
|
32
32
|
}
|
|
33
|
-
for (const [
|
|
34
|
-
value === null ? element.removeAttribute(
|
|
33
|
+
for (const [name, value] of snapshot.entries()) {
|
|
34
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
35
35
|
}
|
|
36
36
|
snapshots.delete(element);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
function saveAttributes(element_or_elements,
|
|
40
|
-
const
|
|
39
|
+
function saveAttributes(element_or_elements, name_or_names) {
|
|
40
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
41
41
|
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
42
42
|
let snapshot = snapshots.get(element);
|
|
43
43
|
if (!snapshot) {
|
|
44
44
|
snapshot = /* @__PURE__ */ new Map();
|
|
45
45
|
snapshots.set(element, snapshot);
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
snapshot.set(
|
|
47
|
+
names.forEach((name) => {
|
|
48
|
+
snapshot.set(name, element.getAttribute(name));
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
+
var addTokenToAttribute = addAttributeToken;
|
|
52
53
|
|
|
53
54
|
// node_modules/power-focusable/dist/index.js
|
|
54
55
|
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"])`;
|
|
@@ -368,6 +369,56 @@ var Button = class {
|
|
|
368
369
|
};
|
|
369
370
|
};
|
|
370
371
|
|
|
372
|
+
// node_modules/@y14e/roving-tabindex/node_modules/@y14e/attributes-utils/dist/index.js
|
|
373
|
+
var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
|
|
374
|
+
var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
|
|
375
|
+
function addTokenToAttribute2(element, name, token, options = {}) {
|
|
376
|
+
const value = element.getAttribute(name)?.trim();
|
|
377
|
+
const {
|
|
378
|
+
caseInsensitive = false,
|
|
379
|
+
parse = DEFAULT_PARSER2,
|
|
380
|
+
serialize = DEFAULT_SERIALIZER2
|
|
381
|
+
} = options;
|
|
382
|
+
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
383
|
+
if (caseInsensitive) {
|
|
384
|
+
const lower = token.toLowerCase();
|
|
385
|
+
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
386
|
+
tokens.push(token);
|
|
387
|
+
element.setAttribute(name, serialize(tokens));
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
const set = new Set(tokens);
|
|
391
|
+
set.add(token);
|
|
392
|
+
element.setAttribute(name, serialize([...set]));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
var snapshots2 = /* @__PURE__ */ new WeakMap();
|
|
396
|
+
function restoreAttributes2(element_or_elements) {
|
|
397
|
+
for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
|
|
398
|
+
const snapshot = snapshots2.get(element);
|
|
399
|
+
if (!snapshot) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
for (const [name, value] of snapshot.entries()) {
|
|
403
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
404
|
+
}
|
|
405
|
+
snapshots2.delete(element);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function saveAttributes2(element_or_elements, name_or_names) {
|
|
409
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
410
|
+
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
411
|
+
let snapshot = snapshots2.get(element);
|
|
412
|
+
if (!snapshot) {
|
|
413
|
+
snapshot = /* @__PURE__ */ new Map();
|
|
414
|
+
snapshots2.set(element, snapshot);
|
|
415
|
+
}
|
|
416
|
+
names.forEach((name) => {
|
|
417
|
+
snapshot.set(name, element.getAttribute(name));
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
371
422
|
// node_modules/@y14e/roving-tabindex/dist/index.js
|
|
372
423
|
function createRovingTabIndex(container, options = {}) {
|
|
373
424
|
if (!(container instanceof Element)) {
|
|
@@ -415,17 +466,20 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
415
466
|
noStart = false;
|
|
416
467
|
}
|
|
417
468
|
if (selector !== "") {
|
|
469
|
+
let hasError = false;
|
|
418
470
|
if (typeof selector !== "string" || !selector.trim()) {
|
|
419
|
-
|
|
420
|
-
selector = "";
|
|
471
|
+
hasError = true;
|
|
421
472
|
} else {
|
|
422
473
|
try {
|
|
423
|
-
container.querySelector(selector);
|
|
474
|
+
this.#container.querySelector(selector);
|
|
424
475
|
} catch {
|
|
425
|
-
|
|
426
|
-
selector = "";
|
|
476
|
+
hasError = true;
|
|
427
477
|
}
|
|
428
478
|
}
|
|
479
|
+
if (hasError) {
|
|
480
|
+
console.warn("Invalid selector. Fallback: no selector string.");
|
|
481
|
+
selector = "";
|
|
482
|
+
}
|
|
429
483
|
}
|
|
430
484
|
if (typeof typeahead !== "boolean") {
|
|
431
485
|
console.warn("Invalid typeahead option. Fallback: false.");
|
|
@@ -456,7 +510,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
456
510
|
this.#controller = null;
|
|
457
511
|
this.#focusables.forEach((focusable) => {
|
|
458
512
|
_RovingTabIndex.#initialized.delete(focusable);
|
|
459
|
-
|
|
513
|
+
restoreAttributes2(focusable);
|
|
460
514
|
});
|
|
461
515
|
this.#focusables.clear();
|
|
462
516
|
this.#focusablesByFirstChar.clear();
|
|
@@ -506,20 +560,20 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
506
560
|
return;
|
|
507
561
|
}
|
|
508
562
|
}
|
|
563
|
+
const candidates = this.#getFocusables().filter(
|
|
564
|
+
(focusable2) => this.#focusables.has(focusable2)
|
|
565
|
+
);
|
|
509
566
|
const active = getActiveElement();
|
|
510
567
|
if (!(active instanceof Element)) {
|
|
511
568
|
return;
|
|
512
569
|
}
|
|
513
|
-
const candidates = this.#getFocusables().filter(
|
|
514
|
-
(focusable2) => this.#focusables.has(focusable2)
|
|
515
|
-
);
|
|
516
570
|
if (!candidates.includes(active)) {
|
|
517
571
|
return;
|
|
518
572
|
}
|
|
519
573
|
event.preventDefault();
|
|
520
|
-
const activeIndex = candidates.indexOf(active);
|
|
521
574
|
let newIndex;
|
|
522
|
-
|
|
575
|
+
const activeIndex = candidates.indexOf(active);
|
|
576
|
+
let focusables = candidates;
|
|
523
577
|
switch (key) {
|
|
524
578
|
case "End":
|
|
525
579
|
newIndex = -1;
|
|
@@ -536,22 +590,24 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
536
590
|
case "ArrowRight":
|
|
537
591
|
case "ArrowDown": {
|
|
538
592
|
const rawIndex = activeIndex + 1;
|
|
539
|
-
const length =
|
|
593
|
+
const length = focusables.length;
|
|
540
594
|
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
541
595
|
break;
|
|
542
596
|
}
|
|
543
597
|
default: {
|
|
544
|
-
const
|
|
598
|
+
const focusablesByFirstChar = new Set(
|
|
545
599
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
546
600
|
);
|
|
547
|
-
|
|
548
|
-
|
|
601
|
+
focusables = candidates.filter(
|
|
602
|
+
(candidate) => focusablesByFirstChar.has(candidate)
|
|
603
|
+
);
|
|
604
|
+
const afterIndex = focusables.findIndex(
|
|
549
605
|
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
550
606
|
);
|
|
551
607
|
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
552
608
|
}
|
|
553
609
|
}
|
|
554
|
-
const focusable =
|
|
610
|
+
const focusable = focusables.at(newIndex);
|
|
555
611
|
focusable && focusElement(focusable);
|
|
556
612
|
};
|
|
557
613
|
#update(active) {
|
|
@@ -559,7 +615,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
559
615
|
for (const focusable of this.#focusables) {
|
|
560
616
|
if (!current.has(focusable)) {
|
|
561
617
|
_RovingTabIndex.#initialized.delete(focusable);
|
|
562
|
-
|
|
618
|
+
restoreAttributes2(focusable);
|
|
563
619
|
this.#focusables.delete(focusable);
|
|
564
620
|
for (const [key, focusables] of this.#focusablesByFirstChar) {
|
|
565
621
|
const index = focusables.indexOf(focusable);
|
|
@@ -581,7 +637,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
581
637
|
this.#focusables.add(focusable);
|
|
582
638
|
_RovingTabIndex.#initialized.add(focusable);
|
|
583
639
|
if (!navigationOnly) {
|
|
584
|
-
|
|
640
|
+
saveAttributes2(focusable, "tabindex");
|
|
585
641
|
focusable.setAttribute("tabindex", "-1");
|
|
586
642
|
}
|
|
587
643
|
if (!typeahead) {
|
|
@@ -594,8 +650,8 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
594
650
|
);
|
|
595
651
|
if (char) {
|
|
596
652
|
keys.add(char);
|
|
597
|
-
|
|
598
|
-
|
|
653
|
+
saveAttributes2(focusable, "aria-keyshortcuts");
|
|
654
|
+
addTokenToAttribute2(focusable, "aria-keyshortcuts", char, {
|
|
599
655
|
caseInsensitive: true
|
|
600
656
|
});
|
|
601
657
|
}
|
|
@@ -1038,7 +1094,7 @@ var Tabs = class _Tabs {
|
|
|
1038
1094
|
tab && this.activate(tab, true);
|
|
1039
1095
|
};
|
|
1040
1096
|
#createBinding(tabs, panel) {
|
|
1041
|
-
return {
|
|
1097
|
+
return { animation: null, panel, tabs };
|
|
1042
1098
|
}
|
|
1043
1099
|
#hasFocusable(container) {
|
|
1044
1100
|
return !![
|
|
@@ -1116,13 +1172,13 @@ var TabsIndicator = class {
|
|
|
1116
1172
|
if (!tab) {
|
|
1117
1173
|
return;
|
|
1118
1174
|
}
|
|
1119
|
-
const
|
|
1120
|
-
const
|
|
1175
|
+
const tabRect = tab.getBoundingClientRect();
|
|
1176
|
+
const listRect = this.#listElement.getBoundingClientRect();
|
|
1121
1177
|
const { duration, easing } = this.#settings.animation.indicator;
|
|
1122
1178
|
this.#animation = this.#rootElement.animate(
|
|
1123
1179
|
{
|
|
1124
|
-
[position]: `${isHorizontal ?
|
|
1125
|
-
[size]: `${isHorizontal ? width : height}px`
|
|
1180
|
+
[position]: `${isHorizontal ? tabRect.left - listRect.left : tabRect.top - listRect.top}px`,
|
|
1181
|
+
[size]: `${isHorizontal ? tabRect.width : tabRect.height}px`
|
|
1126
1182
|
},
|
|
1127
1183
|
{ duration, easing, fill: "forwards" }
|
|
1128
1184
|
);
|
|
@@ -1150,7 +1206,7 @@ var TabsIndicator = class {
|
|
|
1150
1206
|
* Tabs
|
|
1151
1207
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
1152
1208
|
*
|
|
1153
|
-
* @version 2.0.
|
|
1209
|
+
* @version 2.0.10
|
|
1154
1210
|
* @author Yusuke Kamiyamane
|
|
1155
1211
|
* @license MIT
|
|
1156
1212
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1162,7 +1218,7 @@ var TabsIndicator = class {
|
|
|
1162
1218
|
(**
|
|
1163
1219
|
* Attributes Utils
|
|
1164
1220
|
*
|
|
1165
|
-
* @version
|
|
1221
|
+
* @version 2.0.0
|
|
1166
1222
|
* @author Yusuke Kamiyamane
|
|
1167
1223
|
* @license MIT
|
|
1168
1224
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1175,7 +1231,7 @@ power-focusable/dist/index.js:
|
|
|
1175
1231
|
* High-precision focus management utility with full composed tree support.
|
|
1176
1232
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
1177
1233
|
*
|
|
1178
|
-
* @version 4.3.
|
|
1234
|
+
* @version 4.3.23
|
|
1179
1235
|
* @author Yusuke Kamiyamane
|
|
1180
1236
|
* @license MIT
|
|
1181
1237
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1193,13 +1249,24 @@ power-focusable/dist/index.js:
|
|
|
1193
1249
|
* @see {@link https://github.com/y14e/button}
|
|
1194
1250
|
*)
|
|
1195
1251
|
|
|
1252
|
+
@y14e/attributes-utils/dist/index.js:
|
|
1253
|
+
(**
|
|
1254
|
+
* Attributes Utils
|
|
1255
|
+
*
|
|
1256
|
+
* @version 1.1.7
|
|
1257
|
+
* @author Yusuke Kamiyamane
|
|
1258
|
+
* @license MIT
|
|
1259
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
1260
|
+
* @see {@link https://github.com/y14e/attributes-utils}
|
|
1261
|
+
*)
|
|
1262
|
+
|
|
1196
1263
|
@y14e/roving-tabindex/dist/index.js:
|
|
1197
1264
|
(**
|
|
1198
1265
|
* Roving Tabindex
|
|
1199
1266
|
* Lightweight roving tabindex utility with fully focus management.
|
|
1200
1267
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
1201
1268
|
*
|
|
1202
|
-
* @version 3.1.
|
|
1269
|
+
* @version 3.1.20
|
|
1203
1270
|
* @author Yusuke Kamiyamane
|
|
1204
1271
|
* @license MIT
|
|
1205
1272
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.bundle.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// node_modules/@y14e/attributes-utils/dist/index.js
|
|
2
2
|
var DEFAULT_PARSER = (value) => value.split(/\s+/);
|
|
3
3
|
var DEFAULT_SERIALIZER = (tokens) => tokens.join(" ");
|
|
4
|
-
function
|
|
5
|
-
const value = element.getAttribute(
|
|
4
|
+
function addAttributeToken(element, name, token, options = {}) {
|
|
5
|
+
const value = element.getAttribute(name)?.trim();
|
|
6
6
|
const {
|
|
7
7
|
caseInsensitive = false,
|
|
8
8
|
parse = DEFAULT_PARSER,
|
|
@@ -13,12 +13,12 @@ function addTokenToAttribute(element, attribute, token, options = {}) {
|
|
|
13
13
|
const lower = token.toLowerCase();
|
|
14
14
|
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
15
15
|
tokens.push(token);
|
|
16
|
-
element.setAttribute(
|
|
16
|
+
element.setAttribute(name, serialize(tokens));
|
|
17
17
|
}
|
|
18
18
|
} else {
|
|
19
19
|
const set = new Set(tokens);
|
|
20
20
|
set.add(token);
|
|
21
|
-
element.setAttribute(
|
|
21
|
+
element.setAttribute(name, serialize([...set]));
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
var snapshots = /* @__PURE__ */ new WeakMap();
|
|
@@ -28,25 +28,26 @@ function restoreAttributes(element_or_elements) {
|
|
|
28
28
|
if (!snapshot) {
|
|
29
29
|
continue;
|
|
30
30
|
}
|
|
31
|
-
for (const [
|
|
32
|
-
value === null ? element.removeAttribute(
|
|
31
|
+
for (const [name, value] of snapshot.entries()) {
|
|
32
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
33
33
|
}
|
|
34
34
|
snapshots.delete(element);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
function saveAttributes(element_or_elements,
|
|
38
|
-
const
|
|
37
|
+
function saveAttributes(element_or_elements, name_or_names) {
|
|
38
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
39
39
|
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
40
40
|
let snapshot = snapshots.get(element);
|
|
41
41
|
if (!snapshot) {
|
|
42
42
|
snapshot = /* @__PURE__ */ new Map();
|
|
43
43
|
snapshots.set(element, snapshot);
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
snapshot.set(
|
|
45
|
+
names.forEach((name) => {
|
|
46
|
+
snapshot.set(name, element.getAttribute(name));
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
+
var addTokenToAttribute = addAttributeToken;
|
|
50
51
|
|
|
51
52
|
// node_modules/power-focusable/dist/index.js
|
|
52
53
|
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"])`;
|
|
@@ -366,6 +367,56 @@ var Button = class {
|
|
|
366
367
|
};
|
|
367
368
|
};
|
|
368
369
|
|
|
370
|
+
// node_modules/@y14e/roving-tabindex/node_modules/@y14e/attributes-utils/dist/index.js
|
|
371
|
+
var DEFAULT_PARSER2 = (value) => value.split(/\s+/);
|
|
372
|
+
var DEFAULT_SERIALIZER2 = (tokens) => tokens.join(" ");
|
|
373
|
+
function addTokenToAttribute2(element, name, token, options = {}) {
|
|
374
|
+
const value = element.getAttribute(name)?.trim();
|
|
375
|
+
const {
|
|
376
|
+
caseInsensitive = false,
|
|
377
|
+
parse = DEFAULT_PARSER2,
|
|
378
|
+
serialize = DEFAULT_SERIALIZER2
|
|
379
|
+
} = options;
|
|
380
|
+
const tokens = value ? parse(value).filter(Boolean) : [];
|
|
381
|
+
if (caseInsensitive) {
|
|
382
|
+
const lower = token.toLowerCase();
|
|
383
|
+
if (tokens.every((token2) => token2.toLowerCase() !== lower)) {
|
|
384
|
+
tokens.push(token);
|
|
385
|
+
element.setAttribute(name, serialize(tokens));
|
|
386
|
+
}
|
|
387
|
+
} else {
|
|
388
|
+
const set = new Set(tokens);
|
|
389
|
+
set.add(token);
|
|
390
|
+
element.setAttribute(name, serialize([...set]));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
var snapshots2 = /* @__PURE__ */ new WeakMap();
|
|
394
|
+
function restoreAttributes2(element_or_elements) {
|
|
395
|
+
for (const element of Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]) {
|
|
396
|
+
const snapshot = snapshots2.get(element);
|
|
397
|
+
if (!snapshot) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
for (const [name, value] of snapshot.entries()) {
|
|
401
|
+
value === null ? element.removeAttribute(name) : element.setAttribute(name, value);
|
|
402
|
+
}
|
|
403
|
+
snapshots2.delete(element);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function saveAttributes2(element_or_elements, name_or_names) {
|
|
407
|
+
const names = Array.isArray(name_or_names) ? name_or_names : [name_or_names];
|
|
408
|
+
(Array.isArray(element_or_elements) ? element_or_elements : [element_or_elements]).forEach((element) => {
|
|
409
|
+
let snapshot = snapshots2.get(element);
|
|
410
|
+
if (!snapshot) {
|
|
411
|
+
snapshot = /* @__PURE__ */ new Map();
|
|
412
|
+
snapshots2.set(element, snapshot);
|
|
413
|
+
}
|
|
414
|
+
names.forEach((name) => {
|
|
415
|
+
snapshot.set(name, element.getAttribute(name));
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
369
420
|
// node_modules/@y14e/roving-tabindex/dist/index.js
|
|
370
421
|
function createRovingTabIndex(container, options = {}) {
|
|
371
422
|
if (!(container instanceof Element)) {
|
|
@@ -413,17 +464,20 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
413
464
|
noStart = false;
|
|
414
465
|
}
|
|
415
466
|
if (selector !== "") {
|
|
467
|
+
let hasError = false;
|
|
416
468
|
if (typeof selector !== "string" || !selector.trim()) {
|
|
417
|
-
|
|
418
|
-
selector = "";
|
|
469
|
+
hasError = true;
|
|
419
470
|
} else {
|
|
420
471
|
try {
|
|
421
|
-
container.querySelector(selector);
|
|
472
|
+
this.#container.querySelector(selector);
|
|
422
473
|
} catch {
|
|
423
|
-
|
|
424
|
-
selector = "";
|
|
474
|
+
hasError = true;
|
|
425
475
|
}
|
|
426
476
|
}
|
|
477
|
+
if (hasError) {
|
|
478
|
+
console.warn("Invalid selector. Fallback: no selector string.");
|
|
479
|
+
selector = "";
|
|
480
|
+
}
|
|
427
481
|
}
|
|
428
482
|
if (typeof typeahead !== "boolean") {
|
|
429
483
|
console.warn("Invalid typeahead option. Fallback: false.");
|
|
@@ -454,7 +508,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
454
508
|
this.#controller = null;
|
|
455
509
|
this.#focusables.forEach((focusable) => {
|
|
456
510
|
_RovingTabIndex.#initialized.delete(focusable);
|
|
457
|
-
|
|
511
|
+
restoreAttributes2(focusable);
|
|
458
512
|
});
|
|
459
513
|
this.#focusables.clear();
|
|
460
514
|
this.#focusablesByFirstChar.clear();
|
|
@@ -504,20 +558,20 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
504
558
|
return;
|
|
505
559
|
}
|
|
506
560
|
}
|
|
561
|
+
const candidates = this.#getFocusables().filter(
|
|
562
|
+
(focusable2) => this.#focusables.has(focusable2)
|
|
563
|
+
);
|
|
507
564
|
const active = getActiveElement();
|
|
508
565
|
if (!(active instanceof Element)) {
|
|
509
566
|
return;
|
|
510
567
|
}
|
|
511
|
-
const candidates = this.#getFocusables().filter(
|
|
512
|
-
(focusable2) => this.#focusables.has(focusable2)
|
|
513
|
-
);
|
|
514
568
|
if (!candidates.includes(active)) {
|
|
515
569
|
return;
|
|
516
570
|
}
|
|
517
571
|
event.preventDefault();
|
|
518
|
-
const activeIndex = candidates.indexOf(active);
|
|
519
572
|
let newIndex;
|
|
520
|
-
|
|
573
|
+
const activeIndex = candidates.indexOf(active);
|
|
574
|
+
let focusables = candidates;
|
|
521
575
|
switch (key) {
|
|
522
576
|
case "End":
|
|
523
577
|
newIndex = -1;
|
|
@@ -534,22 +588,24 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
534
588
|
case "ArrowRight":
|
|
535
589
|
case "ArrowDown": {
|
|
536
590
|
const rawIndex = activeIndex + 1;
|
|
537
|
-
const length =
|
|
591
|
+
const length = focusables.length;
|
|
538
592
|
newIndex = wrap ? rawIndex % length : Math.min(rawIndex, length - 1);
|
|
539
593
|
break;
|
|
540
594
|
}
|
|
541
595
|
default: {
|
|
542
|
-
const
|
|
596
|
+
const focusablesByFirstChar = new Set(
|
|
543
597
|
this.#focusablesByFirstChar.get(key.toUpperCase()) ?? []
|
|
544
598
|
);
|
|
545
|
-
|
|
546
|
-
|
|
599
|
+
focusables = candidates.filter(
|
|
600
|
+
(candidate) => focusablesByFirstChar.has(candidate)
|
|
601
|
+
);
|
|
602
|
+
const afterIndex = focusables.findIndex(
|
|
547
603
|
(focusable2) => candidates.indexOf(focusable2) > activeIndex
|
|
548
604
|
);
|
|
549
605
|
newIndex = afterIndex >= 0 ? afterIndex : 0;
|
|
550
606
|
}
|
|
551
607
|
}
|
|
552
|
-
const focusable =
|
|
608
|
+
const focusable = focusables.at(newIndex);
|
|
553
609
|
focusable && focusElement(focusable);
|
|
554
610
|
};
|
|
555
611
|
#update(active) {
|
|
@@ -557,7 +613,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
557
613
|
for (const focusable of this.#focusables) {
|
|
558
614
|
if (!current.has(focusable)) {
|
|
559
615
|
_RovingTabIndex.#initialized.delete(focusable);
|
|
560
|
-
|
|
616
|
+
restoreAttributes2(focusable);
|
|
561
617
|
this.#focusables.delete(focusable);
|
|
562
618
|
for (const [key, focusables] of this.#focusablesByFirstChar) {
|
|
563
619
|
const index = focusables.indexOf(focusable);
|
|
@@ -579,7 +635,7 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
579
635
|
this.#focusables.add(focusable);
|
|
580
636
|
_RovingTabIndex.#initialized.add(focusable);
|
|
581
637
|
if (!navigationOnly) {
|
|
582
|
-
|
|
638
|
+
saveAttributes2(focusable, "tabindex");
|
|
583
639
|
focusable.setAttribute("tabindex", "-1");
|
|
584
640
|
}
|
|
585
641
|
if (!typeahead) {
|
|
@@ -592,8 +648,8 @@ var RovingTabIndex = class _RovingTabIndex {
|
|
|
592
648
|
);
|
|
593
649
|
if (char) {
|
|
594
650
|
keys.add(char);
|
|
595
|
-
|
|
596
|
-
|
|
651
|
+
saveAttributes2(focusable, "aria-keyshortcuts");
|
|
652
|
+
addTokenToAttribute2(focusable, "aria-keyshortcuts", char, {
|
|
597
653
|
caseInsensitive: true
|
|
598
654
|
});
|
|
599
655
|
}
|
|
@@ -1036,7 +1092,7 @@ var Tabs = class _Tabs {
|
|
|
1036
1092
|
tab && this.activate(tab, true);
|
|
1037
1093
|
};
|
|
1038
1094
|
#createBinding(tabs, panel) {
|
|
1039
|
-
return {
|
|
1095
|
+
return { animation: null, panel, tabs };
|
|
1040
1096
|
}
|
|
1041
1097
|
#hasFocusable(container) {
|
|
1042
1098
|
return !![
|
|
@@ -1114,13 +1170,13 @@ var TabsIndicator = class {
|
|
|
1114
1170
|
if (!tab) {
|
|
1115
1171
|
return;
|
|
1116
1172
|
}
|
|
1117
|
-
const
|
|
1118
|
-
const
|
|
1173
|
+
const tabRect = tab.getBoundingClientRect();
|
|
1174
|
+
const listRect = this.#listElement.getBoundingClientRect();
|
|
1119
1175
|
const { duration, easing } = this.#settings.animation.indicator;
|
|
1120
1176
|
this.#animation = this.#rootElement.animate(
|
|
1121
1177
|
{
|
|
1122
|
-
[position]: `${isHorizontal ?
|
|
1123
|
-
[size]: `${isHorizontal ? width : height}px`
|
|
1178
|
+
[position]: `${isHorizontal ? tabRect.left - listRect.left : tabRect.top - listRect.top}px`,
|
|
1179
|
+
[size]: `${isHorizontal ? tabRect.width : tabRect.height}px`
|
|
1124
1180
|
},
|
|
1125
1181
|
{ duration, easing, fill: "forwards" }
|
|
1126
1182
|
);
|
|
@@ -1148,7 +1204,7 @@ var TabsIndicator = class {
|
|
|
1148
1204
|
* Tabs
|
|
1149
1205
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
1150
1206
|
*
|
|
1151
|
-
* @version 2.0.
|
|
1207
|
+
* @version 2.0.10
|
|
1152
1208
|
* @author Yusuke Kamiyamane
|
|
1153
1209
|
* @license MIT
|
|
1154
1210
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1160,7 +1216,7 @@ var TabsIndicator = class {
|
|
|
1160
1216
|
(**
|
|
1161
1217
|
* Attributes Utils
|
|
1162
1218
|
*
|
|
1163
|
-
* @version
|
|
1219
|
+
* @version 2.0.0
|
|
1164
1220
|
* @author Yusuke Kamiyamane
|
|
1165
1221
|
* @license MIT
|
|
1166
1222
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1173,7 +1229,7 @@ power-focusable/dist/index.js:
|
|
|
1173
1229
|
* High-precision focus management utility with full composed tree support.
|
|
1174
1230
|
* Handles complex focus rules including tabindex ordering, radio groups, inert.
|
|
1175
1231
|
*
|
|
1176
|
-
* @version 4.3.
|
|
1232
|
+
* @version 4.3.23
|
|
1177
1233
|
* @author Yusuke Kamiyamane
|
|
1178
1234
|
* @license MIT
|
|
1179
1235
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
@@ -1191,13 +1247,24 @@ power-focusable/dist/index.js:
|
|
|
1191
1247
|
* @see {@link https://github.com/y14e/button}
|
|
1192
1248
|
*)
|
|
1193
1249
|
|
|
1250
|
+
@y14e/attributes-utils/dist/index.js:
|
|
1251
|
+
(**
|
|
1252
|
+
* Attributes Utils
|
|
1253
|
+
*
|
|
1254
|
+
* @version 1.1.7
|
|
1255
|
+
* @author Yusuke Kamiyamane
|
|
1256
|
+
* @license MIT
|
|
1257
|
+
* @copyright Copyright (c) Yusuke Kamiyamane
|
|
1258
|
+
* @see {@link https://github.com/y14e/attributes-utils}
|
|
1259
|
+
*)
|
|
1260
|
+
|
|
1194
1261
|
@y14e/roving-tabindex/dist/index.js:
|
|
1195
1262
|
(**
|
|
1196
1263
|
* Roving Tabindex
|
|
1197
1264
|
* Lightweight roving tabindex utility with fully focus management.
|
|
1198
1265
|
* Designed for accessible menus, tabs, toolbars, and composite widgets.
|
|
1199
1266
|
*
|
|
1200
|
-
* @version 3.1.
|
|
1267
|
+
* @version 3.1.20
|
|
1201
1268
|
* @author Yusuke Kamiyamane
|
|
1202
1269
|
* @license MIT
|
|
1203
1270
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.cjs
CHANGED
|
@@ -415,7 +415,7 @@ var Tabs = class _Tabs {
|
|
|
415
415
|
tab && this.activate(tab, true);
|
|
416
416
|
};
|
|
417
417
|
#createBinding(tabs, panel) {
|
|
418
|
-
return {
|
|
418
|
+
return { animation: null, panel, tabs };
|
|
419
419
|
}
|
|
420
420
|
#hasFocusable(container) {
|
|
421
421
|
return !![
|
|
@@ -493,13 +493,13 @@ var TabsIndicator = class {
|
|
|
493
493
|
if (!tab) {
|
|
494
494
|
return;
|
|
495
495
|
}
|
|
496
|
-
const
|
|
497
|
-
const
|
|
496
|
+
const tabRect = tab.getBoundingClientRect();
|
|
497
|
+
const listRect = this.#listElement.getBoundingClientRect();
|
|
498
498
|
const { duration, easing } = this.#settings.animation.indicator;
|
|
499
499
|
this.#animation = this.#rootElement.animate(
|
|
500
500
|
{
|
|
501
|
-
[position]: `${isHorizontal ?
|
|
502
|
-
[size]: `${isHorizontal ? width : height}px`
|
|
501
|
+
[position]: `${isHorizontal ? tabRect.left - listRect.left : tabRect.top - listRect.top}px`,
|
|
502
|
+
[size]: `${isHorizontal ? tabRect.width : tabRect.height}px`
|
|
503
503
|
},
|
|
504
504
|
{ duration, easing, fill: "forwards" }
|
|
505
505
|
);
|
|
@@ -527,7 +527,7 @@ var TabsIndicator = class {
|
|
|
527
527
|
* Tabs
|
|
528
528
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
529
529
|
*
|
|
530
|
-
* @version 2.0.
|
|
530
|
+
* @version 2.0.10
|
|
531
531
|
* @author Yusuke Kamiyamane
|
|
532
532
|
* @license MIT
|
|
533
533
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -409,7 +409,7 @@ var Tabs = class _Tabs {
|
|
|
409
409
|
tab && this.activate(tab, true);
|
|
410
410
|
};
|
|
411
411
|
#createBinding(tabs, panel) {
|
|
412
|
-
return {
|
|
412
|
+
return { animation: null, panel, tabs };
|
|
413
413
|
}
|
|
414
414
|
#hasFocusable(container) {
|
|
415
415
|
return !![
|
|
@@ -487,13 +487,13 @@ var TabsIndicator = class {
|
|
|
487
487
|
if (!tab) {
|
|
488
488
|
return;
|
|
489
489
|
}
|
|
490
|
-
const
|
|
491
|
-
const
|
|
490
|
+
const tabRect = tab.getBoundingClientRect();
|
|
491
|
+
const listRect = this.#listElement.getBoundingClientRect();
|
|
492
492
|
const { duration, easing } = this.#settings.animation.indicator;
|
|
493
493
|
this.#animation = this.#rootElement.animate(
|
|
494
494
|
{
|
|
495
|
-
[position]: `${isHorizontal ?
|
|
496
|
-
[size]: `${isHorizontal ? width : height}px`
|
|
495
|
+
[position]: `${isHorizontal ? tabRect.left - listRect.left : tabRect.top - listRect.top}px`,
|
|
496
|
+
[size]: `${isHorizontal ? tabRect.width : tabRect.height}px`
|
|
497
497
|
},
|
|
498
498
|
{ duration, easing, fill: "forwards" }
|
|
499
499
|
);
|
|
@@ -521,7 +521,7 @@ var TabsIndicator = class {
|
|
|
521
521
|
* Tabs
|
|
522
522
|
* WAI-ARIA compliant tabs pattern implementation in TypeScript.
|
|
523
523
|
*
|
|
524
|
-
* @version 2.0.
|
|
524
|
+
* @version 2.0.10
|
|
525
525
|
* @author Yusuke Kamiyamane
|
|
526
526
|
* @license MIT
|
|
527
527
|
* @copyright Copyright (c) Yusuke Kamiyamane
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@y14e/tabs",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.10",
|
|
4
4
|
"description": "WAI-ARIA compliant tabs pattern implementation in TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"node": ">=18"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@y14e/attributes-utils": "^
|
|
53
|
+
"@y14e/attributes-utils": "^2.0.0",
|
|
54
54
|
"@y14e/button": "^1.0.6",
|
|
55
|
-
"@y14e/roving-tabindex": "^3.1.
|
|
55
|
+
"@y14e/roving-tabindex": "^3.1.20"
|
|
56
56
|
}
|
|
57
57
|
}
|