praxis-kit 6.5.0 → 6.6.0

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.
@@ -253,6 +253,16 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
253
253
  */
254
254
  readonly diagnostics?: Diagnostics | DiagnosticsMode;
255
255
  readonly aria?: readonly AriaRule[];
256
+ /**
257
+ * Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
258
+ * (`AriaRule`'s `readsProps`, fixable `AriaFix` results) but have no
259
+ * relationship to ARIA semantics — an HTML fact or a security check like a
260
+ * dangerous-URL-scheme guard, for example. Evaluated together with `aria`
261
+ * (both run through the same engine, merged into one rule set) — this is a
262
+ * separate bucket purely so a non-ARIA rule doesn't have to sit under the
263
+ * misleading `aria` name to get the machinery it needs.
264
+ */
265
+ readonly rules?: readonly AriaRule[];
256
266
  readonly children?: readonly ChildRuleInput[];
257
267
  /**
258
268
  * When true, only children matching a `children` rule (or text, per `allowText`)
@@ -25,6 +25,9 @@ function isNull(value) {
25
25
  function isNonNull(value) {
26
26
  return value != null;
27
27
  }
28
+ function isNullish(value) {
29
+ return isNull(value) || value === void 0;
30
+ }
28
31
 
29
32
  // ../../lib/primitive/src/utils/type-guards.ts
30
33
  function isObject(value, excludeArrays = false) {
@@ -526,20 +529,29 @@ function isAriaAttributeValidForRole(attr, role) {
526
529
  }
527
530
 
528
531
  // ../../lib/primitive/src/guards/aria/is-aria-role.ts
532
+ function lookupImplicitRole(tag) {
533
+ return IMPLICIT_ROLE_RECORD[tag];
534
+ }
529
535
  function isStrongImplicitRole(tag) {
530
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
531
- return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
536
+ const role = lookupImplicitRole(tag);
537
+ return !isNullish(role) && STRONG_ROLES_SET.has(role);
532
538
  }
533
- function isStandaloneTag(tag) {
534
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
535
- return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
539
+ function hasStandaloneRole(tag) {
540
+ const role = lookupImplicitRole(tag);
541
+ return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
536
542
  }
537
- function getInputImplicitRole(type) {
538
- if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
539
- return INPUT_TYPE_ROLE_MAP[type];
543
+ var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
544
+ function getInputImplicitRole(type, list) {
545
+ if (!isString(type)) return void 0;
546
+ const role = INPUT_TYPE_ROLE_MAP[type];
547
+ if (!role) return void 0;
548
+ if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
549
+ return "combobox";
550
+ }
551
+ return role;
540
552
  }
541
553
  function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
542
- const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
554
+ const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
543
555
  if (!isNamed) return void 0;
544
556
  if (tag === "section") return "region";
545
557
  if (tag === "form") return "form";
@@ -585,7 +597,7 @@ function isTag(...args) {
585
597
  // ../../lib/contract/src/aria/aria-role-policy.ts
586
598
  function getImplicitRole(tag, props) {
587
599
  if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
588
- if (tag === "input") return getInputImplicitRole(props?.type);
600
+ if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
589
601
  if (tag === "img") return props?.alt === "" ? "none" : "img";
590
602
  if (tag === "section" || tag === "form") {
591
603
  return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
@@ -1274,7 +1286,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1274
1286
  if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
1275
1287
  const implicitRole = getImplicitRole(tag, props);
1276
1288
  const hasRole = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
1277
- if (!hasRole) return { proceed: false, result: { props, violations: [] } };
1278
1289
  const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
1279
1290
  const workingProps = normalized.normalized ? normalized.result.props : props;
1280
1291
  const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
@@ -1284,6 +1295,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1284
1295
  tag,
1285
1296
  implicitRole,
1286
1297
  effectiveRole,
1298
+ hasRole,
1287
1299
  props: workingProps,
1288
1300
  preExistingViolations,
1289
1301
  context: { tag, props: workingProps, implicitRole, effectiveRole }
@@ -1327,6 +1339,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1327
1339
  static evaluate(tag, props) {
1328
1340
  const derived = _AriaPolicyEngine.#deriveContext(tag, props);
1329
1341
  if (!derived.proceed) return derived.result;
1342
+ if (!derived.hasRole)
1343
+ return { props: derived.props, violations: [...derived.preExistingViolations] };
1330
1344
  const {
1331
1345
  tag: narrowedTag,
1332
1346
  implicitRole,
@@ -1351,10 +1365,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1351
1365
  props: workingProps,
1352
1366
  preExistingViolations
1353
1367
  } = derived;
1354
- const { violations, fixes } = _AriaPolicyEngine.#runRules(
1355
- [..._AriaPolicyEngine.#getRules(context), ...extraRules],
1356
- context
1357
- );
1368
+ const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
1369
+ const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
1358
1370
  const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
1359
1371
  return { props: next, violations: [...preExistingViolations, ...violations] };
1360
1372
  }
@@ -1553,7 +1565,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1553
1565
  static #checkStandaloneRegion({ tag, props, implicitRole }) {
1554
1566
  const role = props.role;
1555
1567
  if (role !== "region") return NO_VIOLATIONS2;
1556
- if (!isStandaloneTag(tag)) return NO_VIOLATIONS2;
1568
+ if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
1557
1569
  const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
1558
1570
  return [
1559
1571
  {
@@ -3043,6 +3055,11 @@ function composeNormalizers(normalizers, fn) {
3043
3055
  function whenDefined(key, value) {
3044
3056
  return value === void 0 ? {} : { [key]: value };
3045
3057
  }
3058
+ function mergeAriaRules(aria, rules) {
3059
+ if (!aria?.length) return rules;
3060
+ if (!rules?.length) return aria;
3061
+ return [...aria, ...rules];
3062
+ }
3046
3063
  function resolveFactoryOptions(options = {}) {
3047
3064
  const { styling, enforcement } = options;
3048
3065
  const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
@@ -3063,7 +3080,7 @@ function resolveFactoryOptions(options = {}) {
3063
3080
  ...whenDefined("defaultVariants", styling?.defaults),
3064
3081
  ...whenDefined("compoundVariants", styling?.compounds),
3065
3082
  ...whenDefined("normalizeFn", composedNormalizeFn),
3066
- ...whenDefined("ariaRules", enforcement?.aria),
3083
+ ...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
3067
3084
  ...whenDefined("childRules", enforcement?.children),
3068
3085
  ...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
3069
3086
  ...whenDefined("allowText", enforcement?.allowText),
@@ -250,6 +250,16 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
250
250
  */
251
251
  readonly diagnostics?: Diagnostics | DiagnosticsMode;
252
252
  readonly aria?: readonly AriaRule[];
253
+ /**
254
+ * Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
255
+ * (`AriaRule`'s `readsProps`, fixable `AriaFix` results) but have no
256
+ * relationship to ARIA semantics — an HTML fact or a security check like a
257
+ * dangerous-URL-scheme guard, for example. Evaluated together with `aria`
258
+ * (both run through the same engine, merged into one rule set) — this is a
259
+ * separate bucket purely so a non-ARIA rule doesn't have to sit under the
260
+ * misleading `aria` name to get the machinery it needs.
261
+ */
262
+ readonly rules?: readonly AriaRule[];
253
263
  readonly children?: readonly ChildRuleInput[];
254
264
  /**
255
265
  * When true, only children matching a `children` rule (or text, per `allowText`)
package/dist/vue/index.js CHANGED
@@ -23,6 +23,9 @@ function isNull(value) {
23
23
  function isNonNull(value) {
24
24
  return value != null;
25
25
  }
26
+ function isNullish(value) {
27
+ return isNull(value) || value === void 0;
28
+ }
26
29
 
27
30
  // ../../lib/primitive/src/utils/type-guards.ts
28
31
  function isObject(value, excludeArrays = false) {
@@ -610,20 +613,29 @@ function isAriaAttributeValidForRole(attr, role) {
610
613
  }
611
614
 
612
615
  // ../../lib/primitive/src/guards/aria/is-aria-role.ts
616
+ function lookupImplicitRole(tag) {
617
+ return IMPLICIT_ROLE_RECORD[tag];
618
+ }
613
619
  function isStrongImplicitRole(tag) {
614
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
615
- return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
620
+ const role = lookupImplicitRole(tag);
621
+ return !isNullish(role) && STRONG_ROLES_SET.has(role);
616
622
  }
617
- function isStandaloneTag(tag) {
618
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
619
- return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
623
+ function hasStandaloneRole(tag) {
624
+ const role = lookupImplicitRole(tag);
625
+ return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
620
626
  }
621
- function getInputImplicitRole(type) {
622
- if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
623
- return INPUT_TYPE_ROLE_MAP[type];
627
+ var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
628
+ function getInputImplicitRole(type, list) {
629
+ if (!isString(type)) return void 0;
630
+ const role = INPUT_TYPE_ROLE_MAP[type];
631
+ if (!role) return void 0;
632
+ if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
633
+ return "combobox";
634
+ }
635
+ return role;
624
636
  }
625
637
  function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
626
- const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
638
+ const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
627
639
  if (!isNamed) return void 0;
628
640
  if (tag === "section") return "region";
629
641
  if (tag === "form") return "form";
@@ -692,7 +704,7 @@ function defineContractComponent(options) {
692
704
  // ../../lib/contract/src/aria/aria-role-policy.ts
693
705
  function getImplicitRole(tag, props) {
694
706
  if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
695
- if (tag === "input") return getInputImplicitRole(props?.type);
707
+ if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
696
708
  if (tag === "img") return props?.alt === "" ? "none" : "img";
697
709
  if (tag === "section" || tag === "form") {
698
710
  return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
@@ -1381,7 +1393,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1381
1393
  if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
1382
1394
  const implicitRole = getImplicitRole(tag, props);
1383
1395
  const hasRole2 = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
1384
- if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
1385
1396
  const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
1386
1397
  const workingProps = normalized.normalized ? normalized.result.props : props;
1387
1398
  const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
@@ -1391,6 +1402,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1391
1402
  tag,
1392
1403
  implicitRole,
1393
1404
  effectiveRole,
1405
+ hasRole: hasRole2,
1394
1406
  props: workingProps,
1395
1407
  preExistingViolations,
1396
1408
  context: { tag, props: workingProps, implicitRole, effectiveRole }
@@ -1434,6 +1446,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1434
1446
  static evaluate(tag, props) {
1435
1447
  const derived = _AriaPolicyEngine.#deriveContext(tag, props);
1436
1448
  if (!derived.proceed) return derived.result;
1449
+ if (!derived.hasRole)
1450
+ return { props: derived.props, violations: [...derived.preExistingViolations] };
1437
1451
  const {
1438
1452
  tag: narrowedTag,
1439
1453
  implicitRole,
@@ -1458,10 +1472,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1458
1472
  props: workingProps,
1459
1473
  preExistingViolations
1460
1474
  } = derived;
1461
- const { violations, fixes } = _AriaPolicyEngine.#runRules(
1462
- [..._AriaPolicyEngine.#getRules(context), ...extraRules],
1463
- context
1464
- );
1475
+ const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
1476
+ const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
1465
1477
  const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
1466
1478
  return { props: next, violations: [...preExistingViolations, ...violations] };
1467
1479
  }
@@ -1660,7 +1672,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1660
1672
  static #checkStandaloneRegion({ tag, props, implicitRole }) {
1661
1673
  const role = props.role;
1662
1674
  if (role !== "region") return NO_VIOLATIONS2;
1663
- if (!isStandaloneTag(tag)) return NO_VIOLATIONS2;
1675
+ if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
1664
1676
  const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
1665
1677
  return [
1666
1678
  {
@@ -3150,6 +3162,11 @@ function composeNormalizers(normalizers, fn) {
3150
3162
  function whenDefined(key, value) {
3151
3163
  return value === void 0 ? {} : { [key]: value };
3152
3164
  }
3165
+ function mergeAriaRules(aria, rules) {
3166
+ if (!aria?.length) return rules;
3167
+ if (!rules?.length) return aria;
3168
+ return [...aria, ...rules];
3169
+ }
3153
3170
  function resolveFactoryOptions(options = {}) {
3154
3171
  const { styling, enforcement } = options;
3155
3172
  const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
@@ -3170,7 +3187,7 @@ function resolveFactoryOptions(options = {}) {
3170
3187
  ...whenDefined("defaultVariants", styling?.defaults),
3171
3188
  ...whenDefined("compoundVariants", styling?.compounds),
3172
3189
  ...whenDefined("normalizeFn", composedNormalizeFn),
3173
- ...whenDefined("ariaRules", enforcement?.aria),
3190
+ ...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
3174
3191
  ...whenDefined("childRules", enforcement?.children),
3175
3192
  ...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
3176
3193
  ...whenDefined("allowText", enforcement?.allowText),
@@ -231,6 +231,16 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
231
231
  */
232
232
  readonly diagnostics?: Diagnostics | DiagnosticsMode;
233
233
  readonly aria?: readonly AriaRule[];
234
+ /**
235
+ * Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
236
+ * (`AriaRule`'s `readsProps`, fixable `AriaFix` results) but have no
237
+ * relationship to ARIA semantics — an HTML fact or a security check like a
238
+ * dangerous-URL-scheme guard, for example. Evaluated together with `aria`
239
+ * (both run through the same engine, merged into one rule set) — this is a
240
+ * separate bucket purely so a non-ARIA rule doesn't have to sit under the
241
+ * misleading `aria` name to get the machinery it needs.
242
+ */
243
+ readonly rules?: readonly AriaRule[];
234
244
  readonly children?: readonly ChildRuleInput[];
235
245
  /**
236
246
  * When true, only children matching a `children` rule (or text, per `allowText`)
package/dist/web/index.js CHANGED
@@ -25,6 +25,9 @@ function isNull(value) {
25
25
  function isNonNull(value) {
26
26
  return value != null;
27
27
  }
28
+ function isNullish(value) {
29
+ return isNull(value) || value === void 0;
30
+ }
28
31
 
29
32
  // ../../lib/primitive/src/utils/type-guards.ts
30
33
  function isObject(value, excludeArrays = false) {
@@ -526,20 +529,29 @@ function isAriaAttributeValidForRole(attr, role) {
526
529
  }
527
530
 
528
531
  // ../../lib/primitive/src/guards/aria/is-aria-role.ts
532
+ function lookupImplicitRole(tag) {
533
+ return IMPLICIT_ROLE_RECORD[tag];
534
+ }
529
535
  function isStrongImplicitRole(tag) {
530
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
531
- return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
536
+ const role = lookupImplicitRole(tag);
537
+ return !isNullish(role) && STRONG_ROLES_SET.has(role);
532
538
  }
533
- function isStandaloneTag(tag) {
534
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
535
- return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
539
+ function hasStandaloneRole(tag) {
540
+ const role = lookupImplicitRole(tag);
541
+ return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
536
542
  }
537
- function getInputImplicitRole(type) {
538
- if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
539
- return INPUT_TYPE_ROLE_MAP[type];
543
+ var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
544
+ function getInputImplicitRole(type, list) {
545
+ if (!isString(type)) return void 0;
546
+ const role = INPUT_TYPE_ROLE_MAP[type];
547
+ if (!role) return void 0;
548
+ if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
549
+ return "combobox";
550
+ }
551
+ return role;
540
552
  }
541
553
  function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
542
- const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
554
+ const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
543
555
  if (!isNamed) return void 0;
544
556
  if (tag === "section") return "region";
545
557
  if (tag === "form") return "form";
@@ -585,7 +597,7 @@ function isTag(...args) {
585
597
  // ../../lib/contract/src/aria/aria-role-policy.ts
586
598
  function getImplicitRole(tag, props) {
587
599
  if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
588
- if (tag === "input") return getInputImplicitRole(props?.type);
600
+ if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
589
601
  if (tag === "img") return props?.alt === "" ? "none" : "img";
590
602
  if (tag === "section" || tag === "form") {
591
603
  return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
@@ -1228,7 +1240,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1228
1240
  if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
1229
1241
  const implicitRole = getImplicitRole(tag, props);
1230
1242
  const hasRole = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
1231
- if (!hasRole) return { proceed: false, result: { props, violations: [] } };
1232
1243
  const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
1233
1244
  const workingProps = normalized.normalized ? normalized.result.props : props;
1234
1245
  const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
@@ -1238,6 +1249,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1238
1249
  tag,
1239
1250
  implicitRole,
1240
1251
  effectiveRole,
1252
+ hasRole,
1241
1253
  props: workingProps,
1242
1254
  preExistingViolations,
1243
1255
  context: { tag, props: workingProps, implicitRole, effectiveRole }
@@ -1281,6 +1293,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1281
1293
  static evaluate(tag, props) {
1282
1294
  const derived = _AriaPolicyEngine.#deriveContext(tag, props);
1283
1295
  if (!derived.proceed) return derived.result;
1296
+ if (!derived.hasRole)
1297
+ return { props: derived.props, violations: [...derived.preExistingViolations] };
1284
1298
  const {
1285
1299
  tag: narrowedTag,
1286
1300
  implicitRole,
@@ -1305,10 +1319,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1305
1319
  props: workingProps,
1306
1320
  preExistingViolations
1307
1321
  } = derived;
1308
- const { violations, fixes } = _AriaPolicyEngine.#runRules(
1309
- [..._AriaPolicyEngine.#getRules(context), ...extraRules],
1310
- context
1311
- );
1322
+ const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
1323
+ const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
1312
1324
  const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
1313
1325
  return { props: next, violations: [...preExistingViolations, ...violations] };
1314
1326
  }
@@ -1507,7 +1519,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1507
1519
  static #checkStandaloneRegion({ tag, props, implicitRole }) {
1508
1520
  const role = props.role;
1509
1521
  if (role !== "region") return NO_VIOLATIONS2;
1510
- if (!isStandaloneTag(tag)) return NO_VIOLATIONS2;
1522
+ if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
1511
1523
  const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
1512
1524
  return [
1513
1525
  {
@@ -2997,6 +3009,11 @@ function composeNormalizers(normalizers, fn) {
2997
3009
  function whenDefined(key, value) {
2998
3010
  return value === void 0 ? {} : { [key]: value };
2999
3011
  }
3012
+ function mergeAriaRules(aria, rules) {
3013
+ if (!aria?.length) return rules;
3014
+ if (!rules?.length) return aria;
3015
+ return [...aria, ...rules];
3016
+ }
3000
3017
  function resolveFactoryOptions(options = {}) {
3001
3018
  const { styling, enforcement } = options;
3002
3019
  const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
@@ -3017,7 +3034,7 @@ function resolveFactoryOptions(options = {}) {
3017
3034
  ...whenDefined("defaultVariants", styling?.defaults),
3018
3035
  ...whenDefined("compoundVariants", styling?.compounds),
3019
3036
  ...whenDefined("normalizeFn", composedNormalizeFn),
3020
- ...whenDefined("ariaRules", enforcement?.aria),
3037
+ ...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
3021
3038
  ...whenDefined("childRules", enforcement?.children),
3022
3039
  ...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
3023
3040
  ...whenDefined("allowText", enforcement?.allowText),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "praxis-kit",
3
- "version": "6.5.0",
3
+ "version": "6.6.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./react": {
@@ -67,6 +67,10 @@
67
67
  "types": "./dist/guards/index.d.ts",
68
68
  "import": "./dist/guards/index.js"
69
69
  },
70
+ "./html": {
71
+ "types": "./dist/html/index.d.ts",
72
+ "import": "./dist/html/index.js"
73
+ },
70
74
  "./utils": {
71
75
  "types": "./dist/utils/index.d.ts",
72
76
  "import": "./dist/utils/index.js"
@@ -119,6 +123,9 @@
119
123
  "guards": [
120
124
  "./dist/guards/index.d.ts"
121
125
  ],
126
+ "html": [
127
+ "./dist/html/index.d.ts"
128
+ ],
122
129
  "utils": [
123
130
  "./dist/utils/index.d.ts"
124
131
  ]
@@ -197,8 +204,8 @@
197
204
  "vite": "^8.1.5",
198
205
  "vue": "^3.5.38",
199
206
  "@praxis-kit/adapter-utils": "0.0.0",
200
- "@praxis-kit/core": "0.0.0",
201
207
  "@praxis-kit/diagnostics": "0.0.0",
208
+ "@praxis-kit/core": "0.0.0",
202
209
  "@praxis-kit/primitive": "0.0.0",
203
210
  "@praxis-kit/pipeline": "0.0.0",
204
211
  "@praxis-kit/vite-plugin": "0.0.0"