@y14e/roving-tabindex 1.2.3 → 1.2.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/dist/index.cjs CHANGED
@@ -1,23 +1,28 @@
1
1
  'use strict';
2
2
 
3
3
  // node_modules/@y14e/attributes-utils/dist/index.js
4
+ var defaultParser = (value) => value.split(/\s+/);
5
+ var defaultSerializer = (tokens) => tokens.join(" ");
4
6
  function addTokenToAttribute(element, attribute, token, options = {}) {
5
- const { caseInsensitive = false } = options;
6
- const value = element.getAttribute(attribute)?.trim();
7
- const tokens = value ? value.split(/\s+/) : [];
7
+ const {
8
+ caseInsensitive = false,
9
+ parse = defaultParser,
10
+ serialize = defaultSerializer
11
+ } = options;
12
+ const raw = element.getAttribute(attribute)?.trim();
13
+ const tokens = raw ? parse(raw).filter(Boolean) : [];
8
14
  if (caseInsensitive) {
9
15
  const lower = token.toLowerCase();
10
16
  if (tokens.some((token2) => token2.toLowerCase() === lower)) {
11
17
  return;
12
18
  }
13
19
  tokens.push(token);
14
- element.setAttribute(attribute, tokens.join(" "));
20
+ element.setAttribute(attribute, serialize(tokens));
15
21
  return;
16
22
  }
17
23
  const set = new Set(tokens);
18
24
  set.add(token);
19
- element.setAttribute(attribute, [...set].join(" "));
20
- return;
25
+ element.setAttribute(attribute, serialize([...set]));
21
26
  }
22
27
  var snapshots = /* @__PURE__ */ new WeakMap();
23
28
  function restoreAttributes(elements) {
@@ -27,11 +32,7 @@ function restoreAttributes(elements) {
27
32
  continue;
28
33
  }
29
34
  for (const [attribute, value] of snapshot.entries()) {
30
- if (value === null) {
31
- element.removeAttribute(attribute);
32
- } else {
33
- element.setAttribute(attribute, value);
34
- }
35
+ value === null ? element.removeAttribute(attribute) : element.setAttribute(attribute, value);
35
36
  }
36
37
  snapshots.delete(element);
37
38
  }
@@ -390,7 +391,7 @@ var RovingTabIndex = class {
390
391
  focusElement(focusable);
391
392
  };
392
393
  #update(active) {
393
- const current = /* @__PURE__ */ new Set([
394
+ const focusables = /* @__PURE__ */ new Set([
394
395
  ...this.#getFocusables(),
395
396
  ...getFocusables(this.#container, {
396
397
  composed: true,
@@ -398,46 +399,46 @@ var RovingTabIndex = class {
398
399
  })
399
400
  ]);
400
401
  for (const focusable of this.#focusables) {
401
- if (current.has(focusable)) {
402
+ if (focusables.has(focusable)) {
402
403
  continue;
403
404
  }
404
405
  if (focusable.isConnected) {
405
406
  restoreAttributes([focusable]);
406
407
  }
407
408
  this.#focusables.delete(focusable);
408
- this.#focusablesByFirstChar.forEach((focusables) => {
409
- const index = focusables.indexOf(focusable);
409
+ this.#focusablesByFirstChar.forEach((focusables2) => {
410
+ const index = focusables2.indexOf(focusable);
410
411
  if (index !== -1) {
411
- focusables.splice(index, 1);
412
+ focusables2.splice(index, 1);
412
413
  }
413
414
  });
414
415
  }
415
- for (const c of current) {
416
- if (this.#focusables.has(c)) {
416
+ for (const focusable of focusables) {
417
+ if (this.#focusables.has(focusable)) {
417
418
  continue;
418
419
  }
419
- this.#focusables.add(c);
420
- saveAttributes([c], ["tabindex"]);
421
- c.setAttribute("tabindex", "-1");
420
+ this.#focusables.add(focusable);
421
+ saveAttributes([focusable], ["tabindex"]);
422
+ focusable.setAttribute("tabindex", "-1");
422
423
  if (!this.#options.typeahead) {
423
424
  continue;
424
425
  }
425
- const value = c.ariaKeyShortcuts?.trim();
426
+ const raw = focusable.ariaKeyShortcuts?.trim();
426
427
  const keys = new Set(
427
- value ? value.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toUpperCase()) : []
428
+ raw ? raw.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toUpperCase()) : []
428
429
  );
429
- const char = c.textContent?.trim()?.at(0)?.toUpperCase();
430
+ const char = focusable.textContent?.trim()?.at(0)?.toUpperCase();
430
431
  if (char) {
431
432
  keys.add(char);
432
- saveAttributes([c], ["aria-keyshortcuts"]);
433
- addTokenToAttribute(c, "aria-keyshortcuts", char, {
433
+ saveAttributes([focusable], ["aria-keyshortcuts"]);
434
+ addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
434
435
  caseInsensitive: true
435
436
  });
436
437
  }
437
438
  keys.forEach((key) => {
438
- const focusables = this.#focusablesByFirstChar.get(key) ?? [];
439
- focusables.push(c);
440
- this.#focusablesByFirstChar.set(key, focusables);
439
+ const focusables2 = this.#focusablesByFirstChar.get(key) ?? [];
440
+ focusables2.push(focusable);
441
+ this.#focusablesByFirstChar.set(key, focusables2);
441
442
  });
442
443
  }
443
444
  if (active && this.#focusables.has(active)) {
@@ -477,7 +478,7 @@ function getActiveElement() {
477
478
  * Lightweight roving tabindex utility with fully focus management.
478
479
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
479
480
  *
480
- * @version 1.2.3
481
+ * @version 1.2.4
481
482
  * @author Yusuke Kamiyamane
482
483
  * @license MIT
483
484
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -489,7 +490,7 @@ function getActiveElement() {
489
490
  (**
490
491
  * Attributes Utils
491
492
  *
492
- * @version 1.0.3
493
+ * @version 1.0.4
493
494
  * @author Yusuke Kamiyamane
494
495
  * @license MIT
495
496
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Lightweight roving tabindex utility with fully focus management.
4
4
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
5
5
  *
6
- * @version 1.2.3
6
+ * @version 1.2.4
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Lightweight roving tabindex utility with fully focus management.
4
4
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
5
5
  *
6
- * @version 1.2.3
6
+ * @version 1.2.4
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -1,21 +1,26 @@
1
1
  // node_modules/@y14e/attributes-utils/dist/index.js
2
+ var defaultParser = (value) => value.split(/\s+/);
3
+ var defaultSerializer = (tokens) => tokens.join(" ");
2
4
  function addTokenToAttribute(element, attribute, token, options = {}) {
3
- const { caseInsensitive = false } = options;
4
- const value = element.getAttribute(attribute)?.trim();
5
- const tokens = value ? value.split(/\s+/) : [];
5
+ const {
6
+ caseInsensitive = false,
7
+ parse = defaultParser,
8
+ serialize = defaultSerializer
9
+ } = options;
10
+ const raw = element.getAttribute(attribute)?.trim();
11
+ const tokens = raw ? parse(raw).filter(Boolean) : [];
6
12
  if (caseInsensitive) {
7
13
  const lower = token.toLowerCase();
8
14
  if (tokens.some((token2) => token2.toLowerCase() === lower)) {
9
15
  return;
10
16
  }
11
17
  tokens.push(token);
12
- element.setAttribute(attribute, tokens.join(" "));
18
+ element.setAttribute(attribute, serialize(tokens));
13
19
  return;
14
20
  }
15
21
  const set = new Set(tokens);
16
22
  set.add(token);
17
- element.setAttribute(attribute, [...set].join(" "));
18
- return;
23
+ element.setAttribute(attribute, serialize([...set]));
19
24
  }
20
25
  var snapshots = /* @__PURE__ */ new WeakMap();
21
26
  function restoreAttributes(elements) {
@@ -25,11 +30,7 @@ function restoreAttributes(elements) {
25
30
  continue;
26
31
  }
27
32
  for (const [attribute, value] of snapshot.entries()) {
28
- if (value === null) {
29
- element.removeAttribute(attribute);
30
- } else {
31
- element.setAttribute(attribute, value);
32
- }
33
+ value === null ? element.removeAttribute(attribute) : element.setAttribute(attribute, value);
33
34
  }
34
35
  snapshots.delete(element);
35
36
  }
@@ -388,7 +389,7 @@ var RovingTabIndex = class {
388
389
  focusElement(focusable);
389
390
  };
390
391
  #update(active) {
391
- const current = /* @__PURE__ */ new Set([
392
+ const focusables = /* @__PURE__ */ new Set([
392
393
  ...this.#getFocusables(),
393
394
  ...getFocusables(this.#container, {
394
395
  composed: true,
@@ -396,46 +397,46 @@ var RovingTabIndex = class {
396
397
  })
397
398
  ]);
398
399
  for (const focusable of this.#focusables) {
399
- if (current.has(focusable)) {
400
+ if (focusables.has(focusable)) {
400
401
  continue;
401
402
  }
402
403
  if (focusable.isConnected) {
403
404
  restoreAttributes([focusable]);
404
405
  }
405
406
  this.#focusables.delete(focusable);
406
- this.#focusablesByFirstChar.forEach((focusables) => {
407
- const index = focusables.indexOf(focusable);
407
+ this.#focusablesByFirstChar.forEach((focusables2) => {
408
+ const index = focusables2.indexOf(focusable);
408
409
  if (index !== -1) {
409
- focusables.splice(index, 1);
410
+ focusables2.splice(index, 1);
410
411
  }
411
412
  });
412
413
  }
413
- for (const c of current) {
414
- if (this.#focusables.has(c)) {
414
+ for (const focusable of focusables) {
415
+ if (this.#focusables.has(focusable)) {
415
416
  continue;
416
417
  }
417
- this.#focusables.add(c);
418
- saveAttributes([c], ["tabindex"]);
419
- c.setAttribute("tabindex", "-1");
418
+ this.#focusables.add(focusable);
419
+ saveAttributes([focusable], ["tabindex"]);
420
+ focusable.setAttribute("tabindex", "-1");
420
421
  if (!this.#options.typeahead) {
421
422
  continue;
422
423
  }
423
- const value = c.ariaKeyShortcuts?.trim();
424
+ const raw = focusable.ariaKeyShortcuts?.trim();
424
425
  const keys = new Set(
425
- value ? value.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toUpperCase()) : []
426
+ raw ? raw.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toUpperCase()) : []
426
427
  );
427
- const char = c.textContent?.trim()?.at(0)?.toUpperCase();
428
+ const char = focusable.textContent?.trim()?.at(0)?.toUpperCase();
428
429
  if (char) {
429
430
  keys.add(char);
430
- saveAttributes([c], ["aria-keyshortcuts"]);
431
- addTokenToAttribute(c, "aria-keyshortcuts", char, {
431
+ saveAttributes([focusable], ["aria-keyshortcuts"]);
432
+ addTokenToAttribute(focusable, "aria-keyshortcuts", char, {
432
433
  caseInsensitive: true
433
434
  });
434
435
  }
435
436
  keys.forEach((key) => {
436
- const focusables = this.#focusablesByFirstChar.get(key) ?? [];
437
- focusables.push(c);
438
- this.#focusablesByFirstChar.set(key, focusables);
437
+ const focusables2 = this.#focusablesByFirstChar.get(key) ?? [];
438
+ focusables2.push(focusable);
439
+ this.#focusablesByFirstChar.set(key, focusables2);
439
440
  });
440
441
  }
441
442
  if (active && this.#focusables.has(active)) {
@@ -475,7 +476,7 @@ function getActiveElement() {
475
476
  * Lightweight roving tabindex utility with fully focus management.
476
477
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
477
478
  *
478
- * @version 1.2.3
479
+ * @version 1.2.4
479
480
  * @author Yusuke Kamiyamane
480
481
  * @license MIT
481
482
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -487,7 +488,7 @@ function getActiveElement() {
487
488
  (**
488
489
  * Attributes Utils
489
490
  *
490
- * @version 1.0.3
491
+ * @version 1.0.4
491
492
  * @author Yusuke Kamiyamane
492
493
  * @license MIT
493
494
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/roving-tabindex",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Lightweight roving tabindex utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "homepage": "https://github.com/y14e/roving-tabindex#readme",
50
50
  "devDependencies": {
51
- "@y14e/attributes-utils": "^1.0.3",
51
+ "@y14e/attributes-utils": "^1.0.4",
52
52
  "bun-types": "latest",
53
53
  "power-focusable": "^4.1.7",
54
54
  "tsup": "^8.0.0",