@y14e/tabs 1.5.0 → 1.5.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
@@ -165,6 +165,7 @@ function getFocusables(container = document.body, options = {}) {
165
165
  composed = false,
166
166
  filter,
167
167
  include,
168
+ skipNegativeTabIndexCheck = false,
168
169
  skipVisibilityCheck = false
169
170
  } = options;
170
171
  if (typeof composed !== "boolean") {
@@ -183,11 +184,22 @@ function getFocusables(container = document.body, options = {}) {
183
184
  );
184
185
  include = void 0;
185
186
  }
187
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
188
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
189
+ skipNegativeTabIndexCheck = false;
190
+ }
191
+ if (typeof skipVisibilityCheck !== "boolean") {
192
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
193
+ skipVisibilityCheck = false;
194
+ }
186
195
  const elements = [];
187
196
  if (composed || include) {
188
197
  let traverse2 = function(node) {
189
198
  if (node instanceof Element) {
190
- if (isFocusable(node, { skipVisibilityCheck }) || include?.(node)) {
199
+ if (isFocusable(node, {
200
+ skipNegativeTabIndexCheck,
201
+ skipVisibilityCheck
202
+ }) || include?.(node)) {
191
203
  elements[elements.length] = node;
192
204
  }
193
205
  }
@@ -208,7 +220,10 @@ function getFocusables(container = document.body, options = {}) {
208
220
  if (!(candidate instanceof Element)) {
209
221
  continue;
210
222
  }
211
- if (isFocusable(candidate, { skipVisibilityCheck })) {
223
+ if (isFocusable(candidate, {
224
+ skipNegativeTabIndexCheck,
225
+ skipVisibilityCheck
226
+ })) {
212
227
  elements[elements.length] = candidate;
213
228
  }
214
229
  }
@@ -221,7 +236,11 @@ function isFocusable(element, options = {}) {
221
236
  console.warn("Invalid element");
222
237
  return false;
223
238
  }
224
- let { skipVisibilityCheck = false } = options;
239
+ let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
240
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
241
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
242
+ skipNegativeTabIndexCheck = false;
243
+ }
225
244
  if (typeof skipVisibilityCheck !== "boolean") {
226
245
  console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
227
246
  skipVisibilityCheck = false;
@@ -229,10 +248,12 @@ function isFocusable(element, options = {}) {
229
248
  if (element.hasAttribute("hidden") || isInert(element)) {
230
249
  return false;
231
250
  }
232
- if (getTabIndex(element) < 0) {
251
+ if (!skipNegativeTabIndexCheck && getTabIndex(element) < 0) {
233
252
  return false;
234
253
  }
235
- if (!element.matches(FOCUSABLE_SELECTOR)) {
254
+ if (!element.matches(
255
+ skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR.replace(/(,\s*)?\[tabindex="-1"\]/g, "") : FOCUSABLE_SELECTOR
256
+ )) {
236
257
  return false;
237
258
  }
238
259
  if (isDisabledDeep(element)) {
@@ -524,7 +545,7 @@ var RovingTabIndex = class {
524
545
  ...getFocusables(this.#container, {
525
546
  composed: true,
526
547
  filter: this.#selectorFilter,
527
- skipVisibilityCheck: true
548
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly
528
549
  })
529
550
  ]);
530
551
  for (const focusable of this.#focusables) {
@@ -590,8 +611,7 @@ var RovingTabIndex = class {
590
611
  return getFocusables(this.#container, {
591
612
  composed: true,
592
613
  filter: this.#selectorFilter,
593
- include: (element) => this.#focusables.has(element),
594
- skipVisibilityCheck: true
614
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly
595
615
  });
596
616
  }
597
617
  };
@@ -1129,7 +1149,7 @@ function isFocusable2(element) {
1129
1149
  * Tabs
1130
1150
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
1131
1151
  *
1132
- * @version 1.5.0
1152
+ * @version 1.5.1
1133
1153
  * @author Yusuke Kamiyamane
1134
1154
  * @license MIT
1135
1155
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1165,7 +1185,7 @@ function isFocusable2(element) {
1165
1185
  * Lightweight roving tabindex utility with fully focus management.
1166
1186
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1167
1187
  *
1168
- * @version 1.3.1
1188
+ * @version 2.0.0
1169
1189
  * @author Yusuke Kamiyamane
1170
1190
  * @license MIT
1171
1191
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1190,7 +1210,7 @@ function isFocusable2(element) {
1190
1210
  * High-precision focus management utility with full composed tree support.
1191
1211
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1192
1212
  *
1193
- * @version 4.2.0
1213
+ * @version 4.3.0
1194
1214
  * @author Yusuke Kamiyamane
1195
1215
  * @license MIT
1196
1216
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Tabs
3
3
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
4
4
  *
5
- * @version 1.5.0
5
+ * @version 1.5.1
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Tabs
3
3
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
4
4
  *
5
- * @version 1.5.0
5
+ * @version 1.5.1
6
6
  * @author Yusuke Kamiyamane
7
7
  * @license MIT
8
8
  * @copyright Copyright (c) Yusuke Kamiyamane
package/dist/index.js CHANGED
@@ -163,6 +163,7 @@ function getFocusables(container = document.body, options = {}) {
163
163
  composed = false,
164
164
  filter,
165
165
  include,
166
+ skipNegativeTabIndexCheck = false,
166
167
  skipVisibilityCheck = false
167
168
  } = options;
168
169
  if (typeof composed !== "boolean") {
@@ -181,11 +182,22 @@ function getFocusables(container = document.body, options = {}) {
181
182
  );
182
183
  include = void 0;
183
184
  }
185
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
186
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
187
+ skipNegativeTabIndexCheck = false;
188
+ }
189
+ if (typeof skipVisibilityCheck !== "boolean") {
190
+ console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
191
+ skipVisibilityCheck = false;
192
+ }
184
193
  const elements = [];
185
194
  if (composed || include) {
186
195
  let traverse2 = function(node) {
187
196
  if (node instanceof Element) {
188
- if (isFocusable(node, { skipVisibilityCheck }) || include?.(node)) {
197
+ if (isFocusable(node, {
198
+ skipNegativeTabIndexCheck,
199
+ skipVisibilityCheck
200
+ }) || include?.(node)) {
189
201
  elements[elements.length] = node;
190
202
  }
191
203
  }
@@ -206,7 +218,10 @@ function getFocusables(container = document.body, options = {}) {
206
218
  if (!(candidate instanceof Element)) {
207
219
  continue;
208
220
  }
209
- if (isFocusable(candidate, { skipVisibilityCheck })) {
221
+ if (isFocusable(candidate, {
222
+ skipNegativeTabIndexCheck,
223
+ skipVisibilityCheck
224
+ })) {
210
225
  elements[elements.length] = candidate;
211
226
  }
212
227
  }
@@ -219,7 +234,11 @@ function isFocusable(element, options = {}) {
219
234
  console.warn("Invalid element");
220
235
  return false;
221
236
  }
222
- let { skipVisibilityCheck = false } = options;
237
+ let { skipNegativeTabIndexCheck = false, skipVisibilityCheck = false } = options;
238
+ if (typeof skipNegativeTabIndexCheck !== "boolean") {
239
+ console.warn("Invalid skipNegativeTabIndexCheck option. Fallback: false.");
240
+ skipNegativeTabIndexCheck = false;
241
+ }
223
242
  if (typeof skipVisibilityCheck !== "boolean") {
224
243
  console.warn("Invalid skipVisibilityCheck option. Fallback: false.");
225
244
  skipVisibilityCheck = false;
@@ -227,10 +246,12 @@ function isFocusable(element, options = {}) {
227
246
  if (element.hasAttribute("hidden") || isInert(element)) {
228
247
  return false;
229
248
  }
230
- if (getTabIndex(element) < 0) {
249
+ if (!skipNegativeTabIndexCheck && getTabIndex(element) < 0) {
231
250
  return false;
232
251
  }
233
- if (!element.matches(FOCUSABLE_SELECTOR)) {
252
+ if (!element.matches(
253
+ skipNegativeTabIndexCheck ? FOCUSABLE_SELECTOR.replace(/(,\s*)?\[tabindex="-1"\]/g, "") : FOCUSABLE_SELECTOR
254
+ )) {
234
255
  return false;
235
256
  }
236
257
  if (isDisabledDeep(element)) {
@@ -522,7 +543,7 @@ var RovingTabIndex = class {
522
543
  ...getFocusables(this.#container, {
523
544
  composed: true,
524
545
  filter: this.#selectorFilter,
525
- skipVisibilityCheck: true
546
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly
526
547
  })
527
548
  ]);
528
549
  for (const focusable of this.#focusables) {
@@ -588,8 +609,7 @@ var RovingTabIndex = class {
588
609
  return getFocusables(this.#container, {
589
610
  composed: true,
590
611
  filter: this.#selectorFilter,
591
- include: (element) => this.#focusables.has(element),
592
- skipVisibilityCheck: true
612
+ skipNegativeTabIndexCheck: !this.#options.navigationOnly
593
613
  });
594
614
  }
595
615
  };
@@ -1127,7 +1147,7 @@ function isFocusable2(element) {
1127
1147
  * Tabs
1128
1148
  * WAI-ARIA compliant tabs pattern implementation in TypeScript.
1129
1149
  *
1130
- * @version 1.5.0
1150
+ * @version 1.5.1
1131
1151
  * @author Yusuke Kamiyamane
1132
1152
  * @license MIT
1133
1153
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1163,7 +1183,7 @@ function isFocusable2(element) {
1163
1183
  * Lightweight roving tabindex utility with fully focus management.
1164
1184
  * Designed for accessible menus, tabs, toolbars, and composite widgets.
1165
1185
  *
1166
- * @version 1.3.1
1186
+ * @version 2.0.0
1167
1187
  * @author Yusuke Kamiyamane
1168
1188
  * @license MIT
1169
1189
  * @copyright Copyright (c) Yusuke Kamiyamane
@@ -1188,7 +1208,7 @@ function isFocusable2(element) {
1188
1208
  * High-precision focus management utility with full composed tree support.
1189
1209
  * Handles complex focus rules including tabindex ordering, radio groups, inert.
1190
1210
  *
1191
- * @version 4.2.0
1211
+ * @version 4.3.0
1192
1212
  * @author Yusuke Kamiyamane
1193
1213
  * @license MIT
1194
1214
  * @copyright Copyright (c) Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@y14e/tabs",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "WAI-ARIA compliant tabs pattern implementation in TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -44,7 +44,7 @@
44
44
  "devDependencies": {
45
45
  "@y14e/attributes-utils": "^1.0.5",
46
46
  "@y14e/button": "^1.0.0",
47
- "@y14e/roving-tabindex": "^1.3.1",
47
+ "@y14e/roving-tabindex": "^2.0.0",
48
48
  "bun-types": "latest",
49
49
  "tsup": "^8.0.0",
50
50
  "typescript": "^5.6.0",