praxis-kit 6.5.0 → 6.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.
@@ -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) {
@@ -637,20 +640,29 @@ function isAriaAttributeValidForRole(attr, role) {
637
640
  }
638
641
 
639
642
  // ../../lib/primitive/src/guards/aria/is-aria-role.ts
643
+ function lookupImplicitRole(tag) {
644
+ return IMPLICIT_ROLE_RECORD[tag];
645
+ }
640
646
  function isStrongImplicitRole(tag) {
641
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
642
- return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
647
+ const role = lookupImplicitRole(tag);
648
+ return !isNullish(role) && STRONG_ROLES_SET.has(role);
643
649
  }
644
- function isStandaloneTag(tag) {
645
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
646
- return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
650
+ function hasStandaloneRole(tag) {
651
+ const role = lookupImplicitRole(tag);
652
+ return !isNullish(role) && STANDALONE_ROLES_SET.has(role);
647
653
  }
648
- function getInputImplicitRole(type) {
649
- if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
650
- return INPUT_TYPE_ROLE_MAP[type];
654
+ var LIST_ELIGIBLE_INPUT_TYPES = /* @__PURE__ */ new Set(["text", "search", "tel", "url", "email"]);
655
+ function getInputImplicitRole(type, list) {
656
+ if (!isString(type)) return void 0;
657
+ const role = INPUT_TYPE_ROLE_MAP[type];
658
+ if (!role) return void 0;
659
+ if (!isNullish(list) && LIST_ELIGIBLE_INPUT_TYPES.has(type)) {
660
+ return "combobox";
661
+ }
662
+ return role;
651
663
  }
652
664
  function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
653
- const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
665
+ const isNamed = isString(ariaLabel) && ariaLabel.trim().length > 0 || isString(ariaLabelledBy) && ariaLabelledBy.trim().length > 0;
654
666
  if (!isNamed) return void 0;
655
667
  if (tag === "section") return "region";
656
668
  if (tag === "form") return "form";
@@ -722,7 +734,7 @@ function defineContractComponent(options) {
722
734
  // ../../lib/contract/src/aria/aria-role-policy.ts
723
735
  function getImplicitRole(tag, props) {
724
736
  if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
725
- if (tag === "input") return getInputImplicitRole(props?.type);
737
+ if (tag === "input") return getInputImplicitRole(props?.type, props?.list);
726
738
  if (tag === "img") return props?.alt === "" ? "none" : "img";
727
739
  if (tag === "section" || tag === "form") {
728
740
  return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
@@ -1411,7 +1423,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1411
1423
  if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
1412
1424
  const implicitRole = getImplicitRole(tag, props);
1413
1425
  const hasRole2 = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
1414
- if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
1415
1426
  const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
1416
1427
  const workingProps = normalized.normalized ? normalized.result.props : props;
1417
1428
  const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
@@ -1421,6 +1432,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1421
1432
  tag,
1422
1433
  implicitRole,
1423
1434
  effectiveRole,
1435
+ hasRole: hasRole2,
1424
1436
  props: workingProps,
1425
1437
  preExistingViolations,
1426
1438
  context: { tag, props: workingProps, implicitRole, effectiveRole }
@@ -1464,6 +1476,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1464
1476
  static evaluate(tag, props) {
1465
1477
  const derived = _AriaPolicyEngine.#deriveContext(tag, props);
1466
1478
  if (!derived.proceed) return derived.result;
1479
+ if (!derived.hasRole)
1480
+ return { props: derived.props, violations: [...derived.preExistingViolations] };
1467
1481
  const {
1468
1482
  tag: narrowedTag,
1469
1483
  implicitRole,
@@ -1488,10 +1502,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1488
1502
  props: workingProps,
1489
1503
  preExistingViolations
1490
1504
  } = derived;
1491
- const { violations, fixes } = _AriaPolicyEngine.#runRules(
1492
- [..._AriaPolicyEngine.#getRules(context), ...extraRules],
1493
- context
1494
- );
1505
+ const rules = derived.hasRole ? [..._AriaPolicyEngine.#getRules(context), ...extraRules] : extraRules;
1506
+ const { violations, fixes } = _AriaPolicyEngine.#runRules(rules, context);
1495
1507
  const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
1496
1508
  return { props: next, violations: [...preExistingViolations, ...violations] };
1497
1509
  }
@@ -1690,7 +1702,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1690
1702
  static #checkStandaloneRegion({ tag, props, implicitRole }) {
1691
1703
  const role = props.role;
1692
1704
  if (role !== "region") return NO_VIOLATIONS2;
1693
- if (!isStandaloneTag(tag)) return NO_VIOLATIONS2;
1705
+ if (!hasStandaloneRole(tag)) return NO_VIOLATIONS2;
1694
1706
  const diagnostic = HtmlDiagnostics.standaloneRegionOverride(tag, implicitRole ?? tag);
1695
1707
  return [
1696
1708
  {
@@ -2273,6 +2285,93 @@ var readonlyProps = ({
2273
2285
  // ../core/src/html/evaluators.ts
2274
2286
  import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
2275
2287
 
2288
+ // ../core/src/html/contracts/categories.ts
2289
+ var METADATA_TAGS = ["script", "template"];
2290
+ var VOID_TAGS = [
2291
+ "area",
2292
+ "base",
2293
+ "br",
2294
+ "col",
2295
+ "embed",
2296
+ "hr",
2297
+ "img",
2298
+ "input",
2299
+ "link",
2300
+ "meta",
2301
+ "param",
2302
+ "source",
2303
+ "track",
2304
+ "wbr"
2305
+ ];
2306
+ var TEXT_ONLY_TAGS = [
2307
+ "option",
2308
+ "script",
2309
+ "style",
2310
+ "textarea",
2311
+ "title"
2312
+ ];
2313
+ var LANDMARK_TAGS = [
2314
+ "article",
2315
+ "aside",
2316
+ "footer",
2317
+ "header",
2318
+ "main",
2319
+ "nav"
2320
+ ];
2321
+ var INTERACTIVE_CONTENT_TAGS = [
2322
+ "a",
2323
+ "button",
2324
+ "input",
2325
+ "select",
2326
+ "textarea",
2327
+ "label"
2328
+ ];
2329
+ var LABELABLE_TAGS = [
2330
+ "button",
2331
+ "input",
2332
+ "meter",
2333
+ "output",
2334
+ "progress",
2335
+ "select",
2336
+ "textarea"
2337
+ ];
2338
+ var OTHER_INTERACTIVE_TAGS = [
2339
+ "a",
2340
+ "details",
2341
+ "embed",
2342
+ "iframe"
2343
+ ];
2344
+ var P_BLOCKED_TAGS = [
2345
+ "address",
2346
+ "article",
2347
+ "aside",
2348
+ "blockquote",
2349
+ "details",
2350
+ "dialog",
2351
+ "div",
2352
+ "dl",
2353
+ "fieldset",
2354
+ "figure",
2355
+ "footer",
2356
+ "form",
2357
+ "h1",
2358
+ "h2",
2359
+ "h3",
2360
+ "h4",
2361
+ "h5",
2362
+ "h6",
2363
+ "header",
2364
+ "hr",
2365
+ "main",
2366
+ "nav",
2367
+ "ol",
2368
+ "p",
2369
+ "pre",
2370
+ "section",
2371
+ "table",
2372
+ "ul"
2373
+ ];
2374
+
2276
2375
  // ../core/src/html/spec/vocabulary/input.ts
2277
2376
  var TEXT_INPUT_TYPES = ["text", "search", "url", "tel", "email", "password"];
2278
2377
  var NUMERIC_INPUT_TYPES = [
@@ -2652,7 +2751,11 @@ var ALLOWED_ROLES = {
2652
2751
  "treeitem"
2653
2752
  ],
2654
2753
  dialog: ["alertdialog"],
2655
- fieldset: ["none", "presentation", "radiogroup"]
2754
+ fieldset: ["none", "presentation", "radiogroup"],
2755
+ // `<label>` has no implicit role and no documented alternates — its native labeling
2756
+ // semantics (control association, accessible-name contribution) aren't reproducible via
2757
+ // ARIA, so any explicit `role` should be avoided rather than substituted.
2758
+ label: []
2656
2759
  };
2657
2760
  var ELEMENT_SPECS = {
2658
2761
  input: inputElementSpec,
@@ -2693,7 +2796,10 @@ var roleNotPermittedRule = Object.assign(
2693
2796
  );
2694
2797
 
2695
2798
  // ../core/src/html/aria-rules.ts
2696
- var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
2799
+ function defineAriaRule(tags, rule) {
2800
+ return Object.assign(rule, { tags });
2801
+ }
2802
+ var LANDMARK_TAG_SET = new Set(LANDMARK_TAGS);
2697
2803
  var removeLandmarkRoleOverride = {
2698
2804
  kind: "removeRole",
2699
2805
  apply: ({ props }) => {
@@ -2702,10 +2808,11 @@ var removeLandmarkRoleOverride = {
2702
2808
  return { applied: true, next: rest, previous: props };
2703
2809
  }
2704
2810
  };
2705
- var landmarkRoleRule = Object.assign(
2811
+ var landmarkRoleRule = defineAriaRule(
2812
+ LANDMARK_TAGS,
2706
2813
  ({ tag, props, implicitRole }) => {
2707
2814
  if (!LANDMARK_TAG_SET.has(tag) || !implicitRole) return [];
2708
- const role = props.role;
2815
+ const { role } = props;
2709
2816
  if (!role || role === implicitRole) return [];
2710
2817
  const diagnostic = HtmlDiagnostics.landmarkRoleOverride(tag, implicitRole, role);
2711
2818
  return [
@@ -2717,8 +2824,7 @@ var landmarkRoleRule = Object.assign(
2717
2824
  diagnostic
2718
2825
  }
2719
2826
  ];
2720
- },
2721
- { tags: [...LANDMARK_TAG_SET] }
2827
+ }
2722
2828
  );
2723
2829
  function requireAccessibleName({ tag, props }) {
2724
2830
  if ("aria-label" in props || "aria-labelledby" in props) return [];
@@ -2731,38 +2837,44 @@ function requireAccessibleName({ tag, props }) {
2731
2837
  }
2732
2838
  ];
2733
2839
  }
2734
- var NAMED_LANDMARK_TAGS = /* @__PURE__ */ new Set(["nav", "aside"]);
2735
- var landmarkNameAdvisory = Object.assign(
2840
+ var NAMED_LANDMARK_TAGS = ["nav", "aside"];
2841
+ var NAMED_LANDMARK_TAG_SET = new Set(NAMED_LANDMARK_TAGS);
2842
+ var landmarkAccessibleNameRule = defineAriaRule(
2843
+ NAMED_LANDMARK_TAGS,
2736
2844
  (ctx) => {
2737
- if (!ctx.implicitRole || !NAMED_LANDMARK_TAGS.has(ctx.tag)) return [];
2845
+ if (!ctx.implicitRole || !NAMED_LANDMARK_TAG_SET.has(ctx.tag)) return [];
2738
2846
  return requireAccessibleName(ctx);
2739
- },
2740
- { tags: [...NAMED_LANDMARK_TAGS] }
2847
+ }
2741
2848
  );
2742
2849
  var HTML_ARIA_RULES = [
2743
2850
  landmarkRoleRule,
2744
- landmarkNameAdvisory,
2851
+ landmarkAccessibleNameRule,
2745
2852
  roleNotPermittedRule,
2746
2853
  ...INPUT_RULES
2747
2854
  ];
2748
2855
 
2749
- // ../core/src/html/contracts.ts
2856
+ // ../core/src/html/contracts/helpers.ts
2750
2857
  import { warnDiagnostics } from "../_shared/diagnostics.js";
2858
+ function isVNodeLike(child) {
2859
+ return isObject(child) && "type" in child;
2860
+ }
2751
2861
  function isOpenContent(...blockedTags) {
2752
2862
  const set2 = new Set(blockedTags);
2753
2863
  return (child) => {
2754
- if (!isObject(child) || !("type" in child)) return false;
2864
+ if (!isVNodeLike(child)) return false;
2755
2865
  const tag = getTag(child);
2756
2866
  return tag === void 0 || !set2.has(tag);
2757
2867
  };
2758
2868
  }
2759
- var METADATA_TAGS = ["script", "template"];
2760
2869
  var metadataMatch = isTag(...METADATA_TAGS);
2761
2870
  function metadata(name = "metadata") {
2762
2871
  return { name, match: metadataMatch };
2763
2872
  }
2873
+ function optional(name, tag) {
2874
+ return { name, match: isTag(tag), cardinality: { max: 1 } };
2875
+ }
2764
2876
  function firstOptional(name, tag) {
2765
- return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
2877
+ return { ...optional(name, tag), position: "first" };
2766
2878
  }
2767
2879
  function contract(children, options) {
2768
2880
  return { diagnostics: warnDiagnostics, children, ...options };
@@ -2776,50 +2888,41 @@ function ariaContract(aria) {
2776
2888
  function firstChildContract(name, tag) {
2777
2889
  return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
2778
2890
  }
2779
- var VOID_TAGS = [
2780
- "area",
2781
- "base",
2782
- "br",
2783
- "col",
2784
- "embed",
2785
- "hr",
2786
- "img",
2787
- "input",
2788
- "link",
2789
- "meta",
2790
- "param",
2791
- "source",
2792
- "track",
2793
- "wbr"
2794
- ];
2795
- var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
2796
- var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
2797
- var listContract = closedContract([
2798
- { name: "list-item", match: isTag("li", ...METADATA_TAGS) }
2799
- ]);
2800
- var tableContract = closedContract([
2801
- firstOptional("caption", "caption"),
2802
- { name: "colgroup", match: isTag("colgroup") },
2803
- { name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
2804
- { name: "tbody", match: isTag("tbody") },
2805
- { name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
2806
- { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
2807
- ]);
2808
- var tableBodyContract = closedContract([
2809
- { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
2810
- ]);
2811
- var tableRowContract = closedContract([
2812
- { name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
2813
- ]);
2814
- var colgroupContract = closedContract([
2815
- { name: "column", match: isTag("col", "template") }
2891
+ function getChildProp(child, key) {
2892
+ if (!isVNodeLike(child)) return void 0;
2893
+ const { props } = child;
2894
+ if (!isObject(props)) return void 0;
2895
+ return props[key];
2896
+ }
2897
+
2898
+ // ../core/src/html/contracts/aria/landmarks.ts
2899
+ var landmarkContract = ariaContract([landmarkRoleRule, landmarkAccessibleNameRule]);
2900
+
2901
+ // ../core/src/html/contracts/aria/widgets.ts
2902
+ var dialogContract = ariaContract([requireAccessibleName]);
2903
+ var menuContract = ariaContract([requireAccessibleName]);
2904
+ var menubarContract = ariaContract([requireAccessibleName]);
2905
+ var treeContract = ariaContract([requireAccessibleName]);
2906
+ var gridContract = ariaContract([requireAccessibleName]);
2907
+ var listboxContract = ariaContract([requireAccessibleName]);
2908
+ var tablistContract = ariaContract([requireAccessibleName]);
2909
+ var radiogroupContract = ariaContract([requireAccessibleName]);
2910
+
2911
+ // ../core/src/html/contracts/html/document.ts
2912
+ var headContract = closedContract([
2913
+ {
2914
+ name: "metadata",
2915
+ match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
2916
+ }
2816
2917
  ]);
2817
- var dlContract = closedContract([
2818
- { name: "term", match: isTag("dt") },
2819
- { name: "description", match: isTag("dd") },
2820
- { name: "group", match: isTag("div") },
2821
- metadata()
2918
+ var htmlContract = closedContract([
2919
+ { name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
2920
+ { name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
2822
2921
  ]);
2922
+ var voidContract = contract([], { exclusiveChildren: true, allowText: false });
2923
+ var textOnlyContract = contract([], { exclusiveChildren: true });
2924
+
2925
+ // ../core/src/html/contracts/html/forms.ts
2823
2926
  var selectContract = closedContract([
2824
2927
  { name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
2825
2928
  ]);
@@ -2829,6 +2932,45 @@ var optgroupContract = closedContract([
2829
2932
  var datalistContract = closedContract([
2830
2933
  { name: "option", match: isTag("option", ...METADATA_TAGS) }
2831
2934
  ]);
2935
+ var buttonContract = closedContract([
2936
+ { name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
2937
+ ]);
2938
+ var anchorContract = closedContract([
2939
+ { name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
2940
+ ]);
2941
+ var labelableTagMatch = isTag(...LABELABLE_TAGS);
2942
+ function isLabelableControl(child) {
2943
+ if (!labelableTagMatch(child)) return false;
2944
+ if (getTag(child) !== "input") return true;
2945
+ const type = getChildProp(child, "type");
2946
+ return !isString(type) || type !== "hidden";
2947
+ }
2948
+ var labelContract = contract([
2949
+ { name: "control", match: isLabelableControl, cardinality: { max: 1 } },
2950
+ { name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
2951
+ {
2952
+ name: "other-interactive-content",
2953
+ match: isTag(...OTHER_INTERACTIVE_TAGS),
2954
+ cardinality: { max: 0 }
2955
+ }
2956
+ ]);
2957
+
2958
+ // ../core/src/html/contracts/html/grouping.ts
2959
+ var detailsContract = firstChildContract("summary", "summary");
2960
+ var fieldsetContract = firstChildContract("legend", "legend");
2961
+
2962
+ // ../core/src/html/contracts/html/lists.ts
2963
+ var listContract = closedContract([
2964
+ { name: "list-item", match: isTag("li", ...METADATA_TAGS) }
2965
+ ]);
2966
+ var dlContract = closedContract([
2967
+ { name: "term", match: isTag("dt") },
2968
+ { name: "description", match: isTag("dd") },
2969
+ { name: "group", match: isTag("div") },
2970
+ metadata()
2971
+ ]);
2972
+
2973
+ // ../core/src/html/contracts/html/media.ts
2832
2974
  var pictureContract = closedContract([
2833
2975
  { name: "source", match: isTag("source", ...METADATA_TAGS) },
2834
2976
  { name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
@@ -2837,91 +2979,49 @@ var figureContract = contract([
2837
2979
  { name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
2838
2980
  { name: "content", match: isOpenContent("figcaption") }
2839
2981
  ]);
2840
- var detailsContract = firstChildContract("summary", "summary");
2841
- var fieldsetContract = firstChildContract("legend", "legend");
2842
2982
  var objectContract = contract([
2843
2983
  { name: "param", match: isTag("param") },
2844
2984
  { name: "content", match: isOpenContent("param") }
2845
2985
  ]);
2846
- var INTERACTIVE_CONTENT_TAGS = ["a", "button", "input", "select", "textarea", "label"];
2847
- var buttonContract = closedContract([
2848
- { name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
2849
- ]);
2850
- var anchorContract = closedContract([
2851
- { name: "content", match: isOpenContent(...INTERACTIVE_CONTENT_TAGS) }
2852
- ]);
2853
- var LABELABLE_TAGS = [
2854
- "button",
2855
- "input",
2856
- "meter",
2857
- "output",
2858
- "progress",
2859
- "select",
2860
- "textarea"
2861
- ];
2862
- var labelContract = contract([
2863
- { name: "control", match: isTag(...LABELABLE_TAGS), cardinality: { max: 1 } }
2864
- ]);
2865
- var P_BLOCKED_TAGS = [
2866
- "address",
2867
- "article",
2868
- "aside",
2869
- "blockquote",
2870
- "details",
2871
- "dialog",
2872
- "div",
2873
- "dl",
2874
- "fieldset",
2875
- "figure",
2876
- "footer",
2877
- "form",
2878
- "h1",
2879
- "h2",
2880
- "h3",
2881
- "h4",
2882
- "h5",
2883
- "h6",
2884
- "header",
2885
- "hr",
2886
- "main",
2887
- "nav",
2888
- "ol",
2889
- "p",
2890
- "pre",
2891
- "section",
2892
- "table",
2893
- "ul"
2894
- ];
2895
- var pContract = closedContract([
2896
- { name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
2897
- ]);
2898
2986
  var mediaContract = contract([
2899
2987
  { name: "source", match: isTag("source") },
2900
2988
  { name: "track", match: isTag("track") },
2901
2989
  metadata(),
2902
2990
  { name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
2903
2991
  ]);
2904
- var headContract = closedContract([
2905
- {
2906
- name: "metadata",
2907
- match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
2908
- }
2992
+
2993
+ // ../core/src/html/contracts/html/tables.ts
2994
+ var tableContract = closedContract([
2995
+ firstOptional("caption", "caption"),
2996
+ { name: "colgroup", match: isTag("colgroup") },
2997
+ { name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
2998
+ { name: "tbody", match: isTag("tbody") },
2999
+ { name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
3000
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
2909
3001
  ]);
2910
- var htmlContract = closedContract([
2911
- { name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
2912
- { name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
3002
+ var tableBodyContract = closedContract([
3003
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
2913
3004
  ]);
2914
- var voidContract = contract([], { exclusiveChildren: true, allowText: false });
2915
- var textOnlyContract = contract([], { exclusiveChildren: true });
2916
- var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
2917
- var dialogContract = ariaContract([requireAccessibleName]);
2918
- var menuContract = ariaContract([requireAccessibleName]);
2919
- var menubarContract = ariaContract([requireAccessibleName]);
2920
- var treeContract = ariaContract([requireAccessibleName]);
2921
- var gridContract = ariaContract([requireAccessibleName]);
2922
- var listboxContract = ariaContract([requireAccessibleName]);
2923
- var tablistContract = ariaContract([requireAccessibleName]);
2924
- var radiogroupContract = ariaContract([requireAccessibleName]);
3005
+ var tableRowContract = closedContract([
3006
+ { name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
3007
+ ]);
3008
+ var colgroupContract = closedContract([
3009
+ { name: "column", match: isTag("col", "template") }
3010
+ ]);
3011
+
3012
+ // ../core/src/html/contracts/html/text.ts
3013
+ var pContract = closedContract([
3014
+ { name: "content", match: isOpenContent(...P_BLOCKED_TAGS) }
3015
+ ]);
3016
+
3017
+ // ../core/src/html/contracts/build-map.ts
3018
+ function buildMap(groups) {
3019
+ return Object.fromEntries(
3020
+ groups.flatMap(([keys2, value]) => keys2.map((key) => [key, value]))
3021
+ );
3022
+ }
3023
+
3024
+ // ../core/src/html/contracts/maps.ts
2925
3025
  var CONTRACT_GROUPS = [
2926
3026
  [VOID_TAGS, voidContract],
2927
3027
  [TEXT_ONLY_TAGS, textOnlyContract],
@@ -2930,13 +3030,8 @@ var CONTRACT_GROUPS = [
2930
3030
  [["audio", "video"], mediaContract],
2931
3031
  [["thead", "tbody", "tfoot"], tableBodyContract]
2932
3032
  ];
2933
- function contractMap(groups) {
2934
- return Object.fromEntries(
2935
- groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
2936
- );
2937
- }
2938
3033
  var htmlContracts = {
2939
- ...contractMap(CONTRACT_GROUPS),
3034
+ ...buildMap(CONTRACT_GROUPS),
2940
3035
  table: tableContract,
2941
3036
  tr: tableRowContract,
2942
3037
  colgroup: colgroupContract,
@@ -3180,6 +3275,11 @@ function composeNormalizers(normalizers, fn) {
3180
3275
  function whenDefined(key, value) {
3181
3276
  return value === void 0 ? {} : { [key]: value };
3182
3277
  }
3278
+ function mergeAriaRules(aria, rules) {
3279
+ if (!aria?.length) return rules;
3280
+ if (!rules?.length) return aria;
3281
+ return [...aria, ...rules];
3282
+ }
3183
3283
  function resolveFactoryOptions(options = {}) {
3184
3284
  const { styling, enforcement } = options;
3185
3285
  const composedNormalizeFn = composeNormalizers(enforcement?.props, options.normalize);
@@ -3200,7 +3300,7 @@ function resolveFactoryOptions(options = {}) {
3200
3300
  ...whenDefined("defaultVariants", styling?.defaults),
3201
3301
  ...whenDefined("compoundVariants", styling?.compounds),
3202
3302
  ...whenDefined("normalizeFn", composedNormalizeFn),
3203
- ...whenDefined("ariaRules", enforcement?.aria),
3303
+ ...whenDefined("ariaRules", mergeAriaRules(enforcement?.aria, enforcement?.rules)),
3204
3304
  ...whenDefined("childRules", enforcement?.children),
3205
3305
  ...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
3206
3306
  ...whenDefined("allowText", enforcement?.allowText),
@@ -1,5 +1,5 @@
1
- import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-DoFNqNdY.js';
2
- export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, m as composeRefs, l as defineContractComponent, m as mergeRefs } from '../react-options-DoFNqNdY.js';
1
+ import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-BUBVohU6.js';
2
+ export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, m as composeRefs, l as defineContractComponent, m as mergeRefs } from '../react-options-BUBVohU6.js';
3
3
  import * as react from 'react';
4
4
  import { ReactElement, Ref } from 'react';
5
5
  import 'type-fest';
@@ -12,7 +12,7 @@ import {
12
12
  makeCloneSlotChild,
13
13
  mergeRefs,
14
14
  render
15
- } from "../chunk-AM5J6PY3.js";
15
+ } from "../chunk-6JILZ6GQ.js";
16
16
 
17
17
  // ../../adapters/react/src/current/slot/composeRefs.ts
18
18
  function getChildRef(element) {
@@ -1,5 +1,5 @@
1
- import { E as ElementType, U as UnknownProps, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-DoFNqNdY.js';
2
- export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, l as defineContractComponent, m as mergeRefs } from '../react-options-DoFNqNdY.js';
1
+ import { E as ElementType, U as UnknownProps, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-BUBVohU6.js';
2
+ export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, l as defineContractComponent, m as mergeRefs } from '../react-options-BUBVohU6.js';
3
3
  import * as react from 'react';
4
4
  import 'type-fest';
5
5
  import '../_shared/diagnostics.js';
@@ -13,7 +13,7 @@ import {
13
13
  makeCloneSlotChild,
14
14
  mergeRefs,
15
15
  render
16
- } from "../chunk-AM5J6PY3.js";
16
+ } from "../chunk-6JILZ6GQ.js";
17
17
 
18
18
  // ../../adapters/react/src/legacy/create-contract-component.ts
19
19
  import { forwardRef as forwardRef2 } from "react";