abledom 0.6.0 → 0.6.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/dist/index.d.cts CHANGED
@@ -231,6 +231,52 @@ declare class CustomNotifyRule extends ValidationRule {
231
231
  customNotify(message: string, element?: HTMLElement): void;
232
232
  }
233
233
 
234
+ /*!
235
+ * Copyright (c) Microsoft Corporation. All rights reserved.
236
+ * Licensed under the MIT License.
237
+ */
238
+
239
+ declare class RequiredParentRule extends ValidationRule {
240
+ type: ValidationRuleType;
241
+ name: string;
242
+ anchored: boolean;
243
+ private parentRequirements;
244
+ accept(element: HTMLElement): boolean;
245
+ validate(element: HTMLElement): ValidationResult | null;
246
+ private hasValidParent;
247
+ private createIssue;
248
+ }
249
+
250
+ /*!
251
+ * Copyright (c) Microsoft Corporation. All rights reserved.
252
+ * Licensed under the MIT License.
253
+ */
254
+
255
+ declare class NestedInteractiveElementRule extends ValidationRule {
256
+ type: ValidationRuleType;
257
+ name: string;
258
+ anchored: boolean;
259
+ private _isAriaHidden;
260
+ private _isInteractive;
261
+ private _findNestedInteractive;
262
+ accept(element: HTMLElement): boolean;
263
+ validate(element: HTMLElement): ValidationResult | null;
264
+ }
265
+
266
+ /*!
267
+ * Copyright (c) Microsoft Corporation. All rights reserved.
268
+ * Licensed under the MIT License.
269
+ */
270
+
271
+ declare class TabIndexRule extends ValidationRule {
272
+ type: ValidationRuleType;
273
+ name: string;
274
+ anchored: boolean;
275
+ accept(element: HTMLElement): boolean;
276
+ private isInteractiveElement;
277
+ validate(element: HTMLElement): ValidationResult | null;
278
+ }
279
+
234
280
  interface HTMLElementAttributes {
235
281
  readonly [name: string]: string;
236
282
  }
@@ -240,4 +286,4 @@ declare function matchesSelector(element: HTMLElement, selector: string): boolea
240
286
  declare function isDisplayNone(element: HTMLElement): boolean;
241
287
  declare function isElementVisible(element: HTMLElement): boolean;
242
288
 
243
- export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, ContrastRule, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
289
+ export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, ContrastRule, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, NestedInteractiveElementRule, RequiredParentRule, TabIndexRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
package/dist/index.d.ts CHANGED
@@ -231,6 +231,52 @@ declare class CustomNotifyRule extends ValidationRule {
231
231
  customNotify(message: string, element?: HTMLElement): void;
232
232
  }
233
233
 
234
+ /*!
235
+ * Copyright (c) Microsoft Corporation. All rights reserved.
236
+ * Licensed under the MIT License.
237
+ */
238
+
239
+ declare class RequiredParentRule extends ValidationRule {
240
+ type: ValidationRuleType;
241
+ name: string;
242
+ anchored: boolean;
243
+ private parentRequirements;
244
+ accept(element: HTMLElement): boolean;
245
+ validate(element: HTMLElement): ValidationResult | null;
246
+ private hasValidParent;
247
+ private createIssue;
248
+ }
249
+
250
+ /*!
251
+ * Copyright (c) Microsoft Corporation. All rights reserved.
252
+ * Licensed under the MIT License.
253
+ */
254
+
255
+ declare class NestedInteractiveElementRule extends ValidationRule {
256
+ type: ValidationRuleType;
257
+ name: string;
258
+ anchored: boolean;
259
+ private _isAriaHidden;
260
+ private _isInteractive;
261
+ private _findNestedInteractive;
262
+ accept(element: HTMLElement): boolean;
263
+ validate(element: HTMLElement): ValidationResult | null;
264
+ }
265
+
266
+ /*!
267
+ * Copyright (c) Microsoft Corporation. All rights reserved.
268
+ * Licensed under the MIT License.
269
+ */
270
+
271
+ declare class TabIndexRule extends ValidationRule {
272
+ type: ValidationRuleType;
273
+ name: string;
274
+ anchored: boolean;
275
+ accept(element: HTMLElement): boolean;
276
+ private isInteractiveElement;
277
+ validate(element: HTMLElement): ValidationResult | null;
278
+ }
279
+
234
280
  interface HTMLElementAttributes {
235
281
  readonly [name: string]: string;
236
282
  }
@@ -240,4 +286,4 @@ declare function matchesSelector(element: HTMLElement, selector: string): boolea
240
286
  declare function isDisplayNone(element: HTMLElement): boolean;
241
287
  declare function isElementVisible(element: HTMLElement): boolean;
242
288
 
243
- export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, ContrastRule, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
289
+ export { AbleDOM, type AbleDOMProps, AtomicRule, BadFocusRule, type BlurIssue, ContrastRule, CustomNotifyRule, ExistingIdRule, FindElementRule, FocusLostRule, FocusableElementLabelRule, NestedInteractiveElementRule, RequiredParentRule, TabIndexRule, type ValidationIssue, type ValidationResult, ValidationRule, ValidationRuleType, hasAccessibilityAttribute, isAccessibilityAffectingElement, isDisplayNone, isElementVisible, matchesSelector };
package/dist/index.js CHANGED
@@ -31,6 +31,9 @@ __export(index_exports, {
31
31
  FindElementRule: () => FindElementRule,
32
32
  FocusLostRule: () => FocusLostRule,
33
33
  FocusableElementLabelRule: () => FocusableElementLabelRule,
34
+ NestedInteractiveElementRule: () => NestedInteractiveElementRule,
35
+ RequiredParentRule: () => RequiredParentRule,
36
+ TabIndexRule: () => TabIndexRule,
34
37
  ValidationRule: () => ValidationRule,
35
38
  ValidationRuleType: () => ValidationRuleType,
36
39
  hasAccessibilityAttribute: () => hasAccessibilityAttribute,
@@ -899,10 +902,17 @@ var AccessibilityAffectingElements = {
899
902
  aside: true,
900
903
  body: true,
901
904
  button: true,
905
+ caption: true,
906
+ col: true,
907
+ colgroup: true,
902
908
  datalist: true,
909
+ dd: true,
903
910
  details: true,
904
911
  dialog: true,
905
912
  dl: true,
913
+ dt: true,
914
+ figcaption: true,
915
+ figure: true,
906
916
  form: true,
907
917
  h1: true,
908
918
  h2: true,
@@ -914,6 +924,7 @@ var AccessibilityAffectingElements = {
914
924
  iframe: true,
915
925
  img: true,
916
926
  input: true,
927
+ legend: true,
917
928
  li: true,
918
929
  link: true,
919
930
  main: true,
@@ -923,15 +934,22 @@ var AccessibilityAffectingElements = {
923
934
  nav: true,
924
935
  object: true,
925
936
  ol: true,
937
+ optgroup: true,
926
938
  option: true,
927
939
  progress: true,
928
940
  section: true,
929
941
  select: true,
942
+ source: true,
943
+ summary: true,
944
+ table: true,
930
945
  tbody: true,
946
+ td: true,
931
947
  textarea: true,
932
948
  tfoot: true,
933
949
  th: true,
934
950
  thead: true,
951
+ tr: true,
952
+ track: true,
935
953
  ul: true
936
954
  };
937
955
  var AccessibilityAttributes = {
@@ -2101,6 +2119,475 @@ var CustomNotifyRule = class extends ValidationRule {
2101
2119
  });
2102
2120
  }
2103
2121
  };
2122
+
2123
+ // src/rules/requiredparent.ts
2124
+ var RequiredParentRule = class extends ValidationRule {
2125
+ constructor() {
2126
+ super(...arguments);
2127
+ __publicField(this, "type", 1 /* Error */);
2128
+ __publicField(this, "name", "aria-required-parent");
2129
+ __publicField(this, "anchored", true);
2130
+ __publicField(this, "parentRequirements", /* @__PURE__ */ new Map([
2131
+ [
2132
+ "LI",
2133
+ {
2134
+ allowedParents: ["UL", "OL"],
2135
+ allowedParentRoles: ["list"]
2136
+ }
2137
+ ],
2138
+ [
2139
+ "DT",
2140
+ {
2141
+ allowedParents: ["DL"],
2142
+ allowIntermediateWrappers: true,
2143
+ allowedWrappers: ["DIV"]
2144
+ }
2145
+ ],
2146
+ [
2147
+ "DD",
2148
+ {
2149
+ allowedParents: ["DL"],
2150
+ allowIntermediateWrappers: true,
2151
+ allowedWrappers: ["DIV"]
2152
+ }
2153
+ ],
2154
+ [
2155
+ "TR",
2156
+ {
2157
+ allowedParents: ["TABLE", "THEAD", "TBODY", "TFOOT"],
2158
+ allowedParentRoles: ["table", "grid", "treegrid"]
2159
+ }
2160
+ ],
2161
+ [
2162
+ "TH",
2163
+ {
2164
+ allowedParents: ["TR"],
2165
+ allowedParentRoles: ["row"]
2166
+ }
2167
+ ],
2168
+ [
2169
+ "TD",
2170
+ {
2171
+ allowedParents: ["TR"],
2172
+ allowedParentRoles: ["row"]
2173
+ }
2174
+ ],
2175
+ [
2176
+ "THEAD",
2177
+ {
2178
+ allowedParents: ["TABLE"],
2179
+ allowedParentRoles: ["table", "grid", "treegrid"]
2180
+ }
2181
+ ],
2182
+ [
2183
+ "TBODY",
2184
+ {
2185
+ allowedParents: ["TABLE"],
2186
+ allowedParentRoles: ["table", "grid", "treegrid"]
2187
+ }
2188
+ ],
2189
+ [
2190
+ "TFOOT",
2191
+ {
2192
+ allowedParents: ["TABLE"],
2193
+ allowedParentRoles: ["table", "grid", "treegrid"]
2194
+ }
2195
+ ],
2196
+ [
2197
+ "CAPTION",
2198
+ {
2199
+ allowedParents: ["TABLE"]
2200
+ }
2201
+ ],
2202
+ [
2203
+ "COLGROUP",
2204
+ {
2205
+ allowedParents: ["TABLE"]
2206
+ }
2207
+ ],
2208
+ [
2209
+ "COL",
2210
+ {
2211
+ allowedParents: ["COLGROUP"]
2212
+ }
2213
+ ],
2214
+ [
2215
+ "FIGCAPTION",
2216
+ {
2217
+ allowedParents: ["FIGURE"]
2218
+ }
2219
+ ],
2220
+ [
2221
+ "OPTION",
2222
+ {
2223
+ allowedParents: ["SELECT", "OPTGROUP", "DATALIST"]
2224
+ }
2225
+ ],
2226
+ [
2227
+ "OPTGROUP",
2228
+ {
2229
+ allowedParents: ["SELECT"]
2230
+ }
2231
+ ],
2232
+ [
2233
+ "LEGEND",
2234
+ {
2235
+ allowedParents: ["FIELDSET"]
2236
+ }
2237
+ ],
2238
+ [
2239
+ "SUMMARY",
2240
+ {
2241
+ allowedParents: ["DETAILS"]
2242
+ }
2243
+ ],
2244
+ [
2245
+ "SOURCE",
2246
+ {
2247
+ allowedParents: ["AUDIO", "VIDEO", "PICTURE"]
2248
+ }
2249
+ ],
2250
+ [
2251
+ "TRACK",
2252
+ {
2253
+ allowedParents: ["AUDIO", "VIDEO"]
2254
+ }
2255
+ ],
2256
+ [
2257
+ "role=menuitem",
2258
+ {
2259
+ allowedParentRoles: ["menu", "menubar", "group"]
2260
+ }
2261
+ ],
2262
+ [
2263
+ "role=menuitemcheckbox",
2264
+ {
2265
+ allowedParentRoles: ["menu", "menubar", "group"]
2266
+ }
2267
+ ],
2268
+ [
2269
+ "role=menuitemradio",
2270
+ {
2271
+ allowedParentRoles: ["menu", "menubar", "group"]
2272
+ }
2273
+ ],
2274
+ [
2275
+ "role=listitem",
2276
+ {
2277
+ allowedParentRoles: ["list", "group"]
2278
+ }
2279
+ ],
2280
+ [
2281
+ "role=treeitem",
2282
+ {
2283
+ allowedParentRoles: ["tree", "group"]
2284
+ }
2285
+ ],
2286
+ [
2287
+ "role=tab",
2288
+ {
2289
+ allowedParentRoles: ["tablist"]
2290
+ }
2291
+ ],
2292
+ [
2293
+ "role=row",
2294
+ {
2295
+ allowedParentRoles: ["table", "grid", "treegrid", "rowgroup"]
2296
+ }
2297
+ ],
2298
+ [
2299
+ "role=cell",
2300
+ {
2301
+ allowedParentRoles: ["row"]
2302
+ }
2303
+ ],
2304
+ [
2305
+ "role=gridcell",
2306
+ {
2307
+ allowedParentRoles: ["row"]
2308
+ }
2309
+ ],
2310
+ [
2311
+ "role=columnheader",
2312
+ {
2313
+ allowedParentRoles: ["row"]
2314
+ }
2315
+ ],
2316
+ [
2317
+ "role=rowheader",
2318
+ {
2319
+ allowedParentRoles: ["row"]
2320
+ }
2321
+ ],
2322
+ [
2323
+ "role=rowgroup",
2324
+ {
2325
+ allowedParentRoles: ["table", "grid", "treegrid"]
2326
+ }
2327
+ ],
2328
+ [
2329
+ "role=option",
2330
+ {
2331
+ allowedParentRoles: ["listbox", "group"]
2332
+ }
2333
+ ]
2334
+ ]));
2335
+ }
2336
+ accept(element) {
2337
+ const tagName = element.tagName;
2338
+ const role = element.getAttribute("role");
2339
+ if (this.parentRequirements.has(tagName)) {
2340
+ return true;
2341
+ }
2342
+ if (role && this.parentRequirements.has(`role=${role}`)) {
2343
+ return true;
2344
+ }
2345
+ return false;
2346
+ }
2347
+ validate(element) {
2348
+ const tagName = element.tagName;
2349
+ const role = element.getAttribute("role");
2350
+ let requirement;
2351
+ let identifier = "";
2352
+ if (role && this.parentRequirements.has(`role=${role}`)) {
2353
+ requirement = this.parentRequirements.get(`role=${role}`);
2354
+ identifier = `role="${role}"`;
2355
+ } else if (this.parentRequirements.has(tagName)) {
2356
+ requirement = this.parentRequirements.get(tagName);
2357
+ identifier = `<${tagName.toLowerCase()}>`;
2358
+ }
2359
+ if (!requirement) {
2360
+ return null;
2361
+ }
2362
+ if (requirement.customValidator) {
2363
+ if (requirement.customValidator(element)) {
2364
+ return null;
2365
+ } else {
2366
+ return this.createIssue(element, identifier, requirement);
2367
+ }
2368
+ }
2369
+ if (this.hasValidParent(element, requirement)) {
2370
+ return null;
2371
+ }
2372
+ return this.createIssue(element, identifier, requirement);
2373
+ }
2374
+ hasValidParent(element, requirement) {
2375
+ var _a, _b, _c;
2376
+ let parent = element.parentElement;
2377
+ let depth = 0;
2378
+ const maxDepth = requirement.allowIntermediateWrappers ? 2 : 1;
2379
+ while (parent && depth < maxDepth) {
2380
+ if ((_a = requirement.allowedParents) == null ? void 0 : _a.includes(parent.tagName)) {
2381
+ return true;
2382
+ }
2383
+ const parentRole = parent.getAttribute("role");
2384
+ if (parentRole && ((_b = requirement.allowedParentRoles) == null ? void 0 : _b.includes(parentRole))) {
2385
+ return true;
2386
+ }
2387
+ if (depth === 0 && !requirement.allowIntermediateWrappers) {
2388
+ break;
2389
+ }
2390
+ if (depth === 0 && requirement.allowIntermediateWrappers) {
2391
+ if (!((_c = requirement.allowedWrappers) == null ? void 0 : _c.includes(parent.tagName))) {
2392
+ break;
2393
+ }
2394
+ }
2395
+ parent = parent.parentElement;
2396
+ depth++;
2397
+ }
2398
+ return false;
2399
+ }
2400
+ createIssue(element, identifier, requirement) {
2401
+ var _a, _b;
2402
+ const allowedParentsText = [
2403
+ ...((_a = requirement.allowedParents) == null ? void 0 : _a.map((p) => `<${p.toLowerCase()}>`)) || [],
2404
+ ...((_b = requirement.allowedParentRoles) == null ? void 0 : _b.map((r) => `role="${r}"`)) || []
2405
+ ].join(", ");
2406
+ const message = `${identifier} must be contained by ${allowedParentsText}`;
2407
+ return {
2408
+ issue: {
2409
+ id: "aria-required-parent",
2410
+ message,
2411
+ element,
2412
+ help: "https://dequeuniversity.com/rules/axe/4.2/aria-required-parent"
2413
+ }
2414
+ };
2415
+ }
2416
+ };
2417
+
2418
+ // src/rules/nestedInteractive.ts
2419
+ var interactiveElementSelector = [
2420
+ "a[href]",
2421
+ "button",
2422
+ "input:not([type='hidden'])",
2423
+ "select",
2424
+ "textarea",
2425
+ "details",
2426
+ "audio[controls]",
2427
+ "video[controls]",
2428
+ "*[role='button']",
2429
+ "*[role='link']",
2430
+ "*[role='checkbox']",
2431
+ "*[role='radio']",
2432
+ "*[role='switch']",
2433
+ "*[role='tab']",
2434
+ "*[role='menuitem']",
2435
+ "*[role='menuitemcheckbox']",
2436
+ "*[role='menuitemradio']",
2437
+ "*[role='option']",
2438
+ "*[role='treeitem']"
2439
+ ].join(", ");
2440
+ var NestedInteractiveElementRule = class extends ValidationRule {
2441
+ constructor() {
2442
+ super(...arguments);
2443
+ __publicField(this, "type", 1 /* Error */);
2444
+ __publicField(this, "name", "NestedInteractiveElementRule");
2445
+ __publicField(this, "anchored", true);
2446
+ }
2447
+ _isAriaHidden(element) {
2448
+ return element.ownerDocument.evaluate(
2449
+ `ancestor-or-self::*[@aria-hidden = 'true' or @hidden]`,
2450
+ element,
2451
+ null,
2452
+ XPathResult.BOOLEAN_TYPE,
2453
+ null
2454
+ ).booleanValue;
2455
+ }
2456
+ _isInteractive(element) {
2457
+ return matchesSelector(element, interactiveElementSelector);
2458
+ }
2459
+ _findNestedInteractive(element) {
2460
+ const descendants = element.querySelectorAll(interactiveElementSelector);
2461
+ for (let i = 0; i < descendants.length; i++) {
2462
+ const descendant = descendants[i];
2463
+ if (this._isAriaHidden(descendant)) {
2464
+ continue;
2465
+ }
2466
+ return descendant;
2467
+ }
2468
+ return null;
2469
+ }
2470
+ accept(element) {
2471
+ return this._isInteractive(element);
2472
+ }
2473
+ validate(element) {
2474
+ if (this._isAriaHidden(element)) {
2475
+ return null;
2476
+ }
2477
+ const nestedElement = this._findNestedInteractive(element);
2478
+ if (nestedElement) {
2479
+ const elementTag = element.tagName.toLowerCase();
2480
+ const elementRole = element.getAttribute("role");
2481
+ const nestedTag = nestedElement.tagName.toLowerCase();
2482
+ const nestedRole = nestedElement.getAttribute("role");
2483
+ const elementDesc = elementRole ? `${elementTag}[role="${elementRole}"]` : elementTag;
2484
+ const nestedDesc = nestedRole ? `${nestedTag}[role="${nestedRole}"]` : nestedTag;
2485
+ return {
2486
+ issue: isElementVisible(element) ? {
2487
+ id: "nested-interactive",
2488
+ message: `Interactive element <${elementDesc}> contains a nested interactive element <${nestedDesc}>. This can confuse users and assistive technologies.`,
2489
+ element,
2490
+ rel: nestedElement,
2491
+ help: "https://dequeuniversity.com/rules/axe/4.4/nested-interactive"
2492
+ } : void 0
2493
+ };
2494
+ }
2495
+ return null;
2496
+ }
2497
+ };
2498
+
2499
+ // src/rules/tabindex.ts
2500
+ var INTERACTIVE_ELEMENTS = /* @__PURE__ */ new Set([
2501
+ "A",
2502
+ "BUTTON",
2503
+ "INPUT",
2504
+ "SELECT",
2505
+ "TEXTAREA",
2506
+ "DETAILS",
2507
+ "SUMMARY",
2508
+ "AUDIO",
2509
+ "VIDEO"
2510
+ ]);
2511
+ var INTERACTIVE_ROLES = /* @__PURE__ */ new Set([
2512
+ "button",
2513
+ "link",
2514
+ "checkbox",
2515
+ "radio",
2516
+ "textbox",
2517
+ "combobox",
2518
+ "listbox",
2519
+ "menu",
2520
+ "menubar",
2521
+ "menuitem",
2522
+ "menuitemcheckbox",
2523
+ "menuitemradio",
2524
+ "option",
2525
+ "searchbox",
2526
+ "slider",
2527
+ "spinbutton",
2528
+ "switch",
2529
+ "tab",
2530
+ "tablist",
2531
+ "tree",
2532
+ "treegrid",
2533
+ "treeitem",
2534
+ "grid",
2535
+ "gridcell"
2536
+ ]);
2537
+ var TabIndexRule = class extends ValidationRule {
2538
+ constructor() {
2539
+ super(...arguments);
2540
+ __publicField(this, "type", 2 /* Warning */);
2541
+ __publicField(this, "name", "tabindex");
2542
+ __publicField(this, "anchored", true);
2543
+ }
2544
+ accept(element) {
2545
+ return element.hasAttribute("tabindex");
2546
+ }
2547
+ isInteractiveElement(element) {
2548
+ if (INTERACTIVE_ELEMENTS.has(element.tagName)) {
2549
+ if (element.hasAttribute("disabled")) {
2550
+ return false;
2551
+ }
2552
+ if (element.tagName === "A" && !element.hasAttribute("href")) {
2553
+ return false;
2554
+ }
2555
+ return true;
2556
+ }
2557
+ const role = element.getAttribute("role");
2558
+ if (role && INTERACTIVE_ROLES.has(role)) {
2559
+ return true;
2560
+ }
2561
+ if (element.isContentEditable) {
2562
+ return true;
2563
+ }
2564
+ return false;
2565
+ }
2566
+ validate(element) {
2567
+ const tabindex = parseInt(element.getAttribute("tabindex") || "0", 10);
2568
+ if (tabindex > 0 && this.isInteractiveElement(element)) {
2569
+ return {
2570
+ issue: {
2571
+ id: "tabindex",
2572
+ message: `Avoid positive tabindex values (found: ${tabindex})`,
2573
+ element,
2574
+ help: "https://dequeuniversity.com/rules/axe/4.2/tabindex"
2575
+ }
2576
+ };
2577
+ }
2578
+ if (!this.isInteractiveElement(element)) {
2579
+ return {
2580
+ issue: {
2581
+ id: "tabindex-non-interactive",
2582
+ message: `Avoid using tabindex on non-interactive elements (<${element.tagName.toLowerCase()}>). Consider adding an interactive role or making the element naturally interactive.`,
2583
+ element,
2584
+ help: "https://dequeuniversity.com/rules/axe/4.2/tabindex"
2585
+ }
2586
+ };
2587
+ }
2588
+ return null;
2589
+ }
2590
+ };
2104
2591
  // Annotate the CommonJS export names for ESM import in node:
2105
2592
  0 && (module.exports = {
2106
2593
  AbleDOM,
@@ -2112,6 +2599,9 @@ var CustomNotifyRule = class extends ValidationRule {
2112
2599
  FindElementRule,
2113
2600
  FocusLostRule,
2114
2601
  FocusableElementLabelRule,
2602
+ NestedInteractiveElementRule,
2603
+ RequiredParentRule,
2604
+ TabIndexRule,
2115
2605
  ValidationRule,
2116
2606
  ValidationRuleType,
2117
2607
  hasAccessibilityAttribute,