@y14e/roving-tabindex 1.1.0 → 1.1.2

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,6 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  // node_modules/@y14e/attributes-utils/dist/index.js
4
+ function addTokenToAttribute(element, attribute, token) {
5
+ const tokens = new Set(
6
+ element.getAttribute(attribute)?.trim().split(/\s+/) ?? []
7
+ );
8
+ tokens.add(token);
9
+ element.setAttribute(attribute, [...tokens].join(" "));
10
+ }
4
11
  var snapshots = /* @__PURE__ */ new WeakMap();
5
12
  function restoreAttributes(elements) {
6
13
  elements.forEach((element) => {
@@ -239,12 +246,14 @@ function createRovingTabIndex(container, options = {}) {
239
246
  throw new Error("Invalid container element");
240
247
  }
241
248
  const { direction, selector, typeahead = false, wrap = false } = options;
242
- if (direction && !["horizontal", "vertical"].includes(direction)) {
249
+ if (typeof direction !== "undefined" && !["horizontal", "vertical"].includes(direction)) {
243
250
  console.warn("Invalid direction. Fallback: both (undefined).");
244
251
  Object.assign(options, { direction: void 0 });
245
252
  }
246
- if (typeof selector !== "string") {
247
- console.warn("Invalid selector. Fallback: all focusable elements.");
253
+ if (typeof selector !== "undefined" && typeof selector !== "string") {
254
+ console.warn(
255
+ "Invalid selector. Fallback: all focusable elements (undefined)."
256
+ );
248
257
  Object.assign(options, { selector: void 0 });
249
258
  }
250
259
  if (typeof typeahead !== "boolean") {
@@ -325,7 +334,7 @@ var RovingTabIndex = class {
325
334
  event.preventDefault();
326
335
  event.stopPropagation();
327
336
  const currentIndex = focusables.indexOf(active);
328
- let rawIndex = currentIndex;
337
+ let rawIndex;
329
338
  let newIndex = currentIndex;
330
339
  let target = focusables;
331
340
  switch (key) {
@@ -396,16 +405,21 @@ var RovingTabIndex = class {
396
405
  if (!this.#options.typeahead) {
397
406
  return;
398
407
  }
399
- const shortcuts = c.ariaKeyShortcuts;
400
- const keys = (shortcuts?.split(/\s+/) ?? [c.textContent?.trim()[0] ?? ""]).filter((key) => /^\S$/i.test(key)).map((key) => key.toLowerCase());
408
+ const shortcuts = c.ariaKeyShortcuts?.trim() ?? "";
409
+ const keys = new Set(
410
+ shortcuts ? shortcuts.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toLowerCase()) : []
411
+ );
412
+ const char = c.textContent?.trim()?.at(0)?.toLowerCase();
413
+ if (char) {
414
+ keys.add(char);
415
+ saveAttributes([c], ["aria-keyshortcuts"]);
416
+ addTokenToAttribute(c, "aria-keyshortcuts", char);
417
+ }
401
418
  keys.forEach((key) => {
402
419
  const focusables = this.#focusablesByFirstChar.get(key) ?? [];
403
420
  focusables.push(c);
404
421
  this.#focusablesByFirstChar.set(key, focusables);
405
422
  });
406
- const first = keys[0];
407
- saveAttributes([c], ["aria-keyshortcuts"]);
408
- !shortcuts && first && c.setAttribute("aria-keyshortcuts", first);
409
423
  });
410
424
  if (active && this.#focusables.has(active)) {
411
425
  this.#focusables.forEach((focusable) => {
@@ -444,7 +458,7 @@ function getActiveElement() {
444
458
  * Lightweight roving tabindex utility with fully focus management.
445
459
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
446
460
  *
447
- * @version 1.1.0
461
+ * @version 1.1.2
448
462
  * @author Yusuke Kamiyamane
449
463
  * @license MIT
450
464
  * @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.1.0
6
+ * @version 1.1.2
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.1.0
6
+ * @version 1.1.2
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -1,4 +1,11 @@
1
1
  // node_modules/@y14e/attributes-utils/dist/index.js
2
+ function addTokenToAttribute(element, attribute, token) {
3
+ const tokens = new Set(
4
+ element.getAttribute(attribute)?.trim().split(/\s+/) ?? []
5
+ );
6
+ tokens.add(token);
7
+ element.setAttribute(attribute, [...tokens].join(" "));
8
+ }
2
9
  var snapshots = /* @__PURE__ */ new WeakMap();
3
10
  function restoreAttributes(elements) {
4
11
  elements.forEach((element) => {
@@ -237,12 +244,14 @@ function createRovingTabIndex(container, options = {}) {
237
244
  throw new Error("Invalid container element");
238
245
  }
239
246
  const { direction, selector, typeahead = false, wrap = false } = options;
240
- if (direction && !["horizontal", "vertical"].includes(direction)) {
247
+ if (typeof direction !== "undefined" && !["horizontal", "vertical"].includes(direction)) {
241
248
  console.warn("Invalid direction. Fallback: both (undefined).");
242
249
  Object.assign(options, { direction: void 0 });
243
250
  }
244
- if (typeof selector !== "string") {
245
- console.warn("Invalid selector. Fallback: all focusable elements.");
251
+ if (typeof selector !== "undefined" && typeof selector !== "string") {
252
+ console.warn(
253
+ "Invalid selector. Fallback: all focusable elements (undefined)."
254
+ );
246
255
  Object.assign(options, { selector: void 0 });
247
256
  }
248
257
  if (typeof typeahead !== "boolean") {
@@ -323,7 +332,7 @@ var RovingTabIndex = class {
323
332
  event.preventDefault();
324
333
  event.stopPropagation();
325
334
  const currentIndex = focusables.indexOf(active);
326
- let rawIndex = currentIndex;
335
+ let rawIndex;
327
336
  let newIndex = currentIndex;
328
337
  let target = focusables;
329
338
  switch (key) {
@@ -394,16 +403,21 @@ var RovingTabIndex = class {
394
403
  if (!this.#options.typeahead) {
395
404
  return;
396
405
  }
397
- const shortcuts = c.ariaKeyShortcuts;
398
- const keys = (shortcuts?.split(/\s+/) ?? [c.textContent?.trim()[0] ?? ""]).filter((key) => /^\S$/i.test(key)).map((key) => key.toLowerCase());
406
+ const shortcuts = c.ariaKeyShortcuts?.trim() ?? "";
407
+ const keys = new Set(
408
+ shortcuts ? shortcuts.split(/\s+/).filter((key) => /^\S$/i.test(key)).map((key) => key.toLowerCase()) : []
409
+ );
410
+ const char = c.textContent?.trim()?.at(0)?.toLowerCase();
411
+ if (char) {
412
+ keys.add(char);
413
+ saveAttributes([c], ["aria-keyshortcuts"]);
414
+ addTokenToAttribute(c, "aria-keyshortcuts", char);
415
+ }
399
416
  keys.forEach((key) => {
400
417
  const focusables = this.#focusablesByFirstChar.get(key) ?? [];
401
418
  focusables.push(c);
402
419
  this.#focusablesByFirstChar.set(key, focusables);
403
420
  });
404
- const first = keys[0];
405
- saveAttributes([c], ["aria-keyshortcuts"]);
406
- !shortcuts && first && c.setAttribute("aria-keyshortcuts", first);
407
421
  });
408
422
  if (active && this.#focusables.has(active)) {
409
423
  this.#focusables.forEach((focusable) => {
@@ -442,7 +456,7 @@ function getActiveElement() {
442
456
  * Lightweight roving tabindex utility with fully focus management.
443
457
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
444
458
  *
445
- * @version 1.1.0
459
+ * @version 1.1.2
446
460
  * @author Yusuke Kamiyamane
447
461
  * @license MIT
448
462
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/roving-tabindex",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Lightweight roving tabindex utility with fully focus management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",