praxis-kit 6.6.1 → 7.3.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.
@@ -92,6 +92,7 @@ declare enum DiagnosticCode {
92
92
  TailwindMultipleDisplayProps = "CSS6001",
93
93
  TailwindReservedLayoutLiteral = "CSS6002",
94
94
  TailwindDeadVariantClass = "CSS6003",
95
+ TailwindLayoutOnVoidTag = "CSS6004",
95
96
  PluginInvalidShape = "PLUGIN7001",
96
97
  PluginPipelineReturnType = "PLUGIN7002",
97
98
  InternalError = "INTERNAL9000"
@@ -93,6 +93,7 @@ var DiagnosticCode = /* @__PURE__ */ ((DiagnosticCode2) => {
93
93
  DiagnosticCode2["TailwindMultipleDisplayProps"] = "CSS6001";
94
94
  DiagnosticCode2["TailwindReservedLayoutLiteral"] = "CSS6002";
95
95
  DiagnosticCode2["TailwindDeadVariantClass"] = "CSS6003";
96
+ DiagnosticCode2["TailwindLayoutOnVoidTag"] = "CSS6004";
96
97
  DiagnosticCode2["PluginInvalidShape"] = "PLUGIN7001";
97
98
  DiagnosticCode2["PluginPipelineReturnType"] = "PLUGIN7002";
98
99
  DiagnosticCode2["InternalError"] = "INTERNAL9000";
@@ -3,6 +3,12 @@ function defineContractComponent(options) {
3
3
  return (factory) => factory(options);
4
4
  }
5
5
 
6
+ // ../../lib/adapter-utils/src/runtime/assemble-compound-component.ts
7
+ function assembleCompoundComponent(root, subComponents) {
8
+ if (!subComponents) return root;
9
+ return Object.assign(root, subComponents);
10
+ }
11
+
6
12
  // ../../lib/primitive/src/tag/resolve-tag.ts
7
13
  function makeResolveTag(defaultTag) {
8
14
  return function tag(as) {
@@ -16,6 +22,11 @@ var EVENT_HANDLER_RE = /^on[A-Z]/;
16
22
  // ../../lib/primitive/src/rule/rule-brand.ts
17
23
  var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
18
24
 
25
+ // ../../lib/primitive/src/rule/dynamic.ts
26
+ function dynamic(resolve) {
27
+ return { [RULE_BRAND]: true, resolve };
28
+ }
29
+
19
30
  // ../../lib/primitive/src/guards/foundational/is-defined.ts
20
31
  function isUndefined(value) {
21
32
  return value === void 0;
@@ -29,7 +40,7 @@ function isNonNull(value) {
29
40
  return value != null;
30
41
  }
31
42
  function isNullish(value) {
32
- return isNull(value) || value === void 0;
43
+ return isNull(value) || isUndefined(value);
33
44
  }
34
45
 
35
46
  // ../../lib/primitive/src/utils/type-guards.ts
@@ -54,7 +65,7 @@ function isPlainObject(value) {
54
65
 
55
66
  // ../../lib/primitive/src/rule/is-dynamic-rule.ts
56
67
  function isDynamicRule(rule) {
57
- return isObject(rule, true) && rule[RULE_BRAND] === true;
68
+ return isObject(rule, true) && Reflect.get(rule, RULE_BRAND) === true;
58
69
  }
59
70
 
60
71
  // ../../lib/primitive/src/rule/resolve-rule.ts
@@ -643,6 +654,24 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
643
654
  ]
644
655
  ]);
645
656
 
657
+ // ../../lib/primitive/src/constants/html/void-tags.ts
658
+ var VOID_TAGS = [
659
+ "area",
660
+ "base",
661
+ "br",
662
+ "col",
663
+ "embed",
664
+ "hr",
665
+ "img",
666
+ "input",
667
+ "link",
668
+ "meta",
669
+ "param",
670
+ "source",
671
+ "track",
672
+ "wbr"
673
+ ];
674
+
646
675
  // ../../lib/primitive/src/constants/primitive/slot-name.ts
647
676
  var SLOT_NAME = "Slot";
648
677
 
@@ -699,17 +728,17 @@ var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default
699
728
  // ../../lib/primitive/src/guards/children/is-tag.ts
700
729
  function getAsProp(child) {
701
730
  if (!isObject(child) || !("props" in child)) return void 0;
702
- const props = child.props;
731
+ const { props } = child;
703
732
  if (!isObject(props)) return void 0;
704
- const as = props.as;
733
+ const as = Reflect.get(props, "as");
705
734
  return isString(as) && as !== "" ? as : void 0;
706
735
  }
707
736
  function getTag(child) {
708
737
  if (!isObject(child) || !("type" in child)) return void 0;
709
- const t = child.type;
738
+ const { type: t } = child;
710
739
  if (isString(t)) return t;
711
740
  if (typeof t === "function" || isObject(t)) {
712
- const defaultTag = t[COMPONENT_DEFAULT_TAG];
741
+ const defaultTag = Reflect.get(t, COMPONENT_DEFAULT_TAG);
713
742
  if (!isString(defaultTag)) return void 0;
714
743
  return getAsProp(child) ?? defaultTag;
715
744
  }
@@ -729,6 +758,36 @@ function isTag(...args) {
729
758
  return tag !== void 0 && set2.has(tag);
730
759
  }
731
760
 
761
+ // ../../lib/adapter-utils/src/runtime/finalize-component.ts
762
+ function finalizeComponent(component, defaultTag, subComponents) {
763
+ if (typeof defaultTag === "string") {
764
+ Object.assign(component, { [COMPONENT_DEFAULT_TAG]: defaultTag });
765
+ }
766
+ return assembleCompoundComponent(component, subComponents);
767
+ }
768
+
769
+ // ../../lib/adapter-utils/src/runtime/is-factory-options-like.ts
770
+ var FACTORY_OPTIONS_FIELD_VALIDATORS = {
771
+ tag: (v) => v === void 0 || isString(v),
772
+ name: (v) => v === void 0 || isString(v),
773
+ defaults: (v) => v === void 0 || isObject(v),
774
+ normalize: (v) => v === void 0 || isFunction(v),
775
+ styling: (v) => v === void 0 || isObject(v),
776
+ enforcement: (v) => v === void 0 || isObject(v),
777
+ diagnostics: (v) => v === void 0 || isObject(v),
778
+ subComponents: (v) => v === void 0 || isObject(v),
779
+ onElement: (v) => v === void 0 || isFunction(v)
780
+ };
781
+ function isFactoryOptionsLike(options, extraFieldValidators) {
782
+ if (!isObject(options)) return false;
783
+ const validators = { ...FACTORY_OPTIONS_FIELD_VALIDATORS, ...extraFieldValidators };
784
+ for (const [key, value] of Object.entries(options)) {
785
+ const validate = validators[key];
786
+ if (!validate || !validate(value)) return false;
787
+ }
788
+ return true;
789
+ }
790
+
732
791
  // ../../lib/contract/src/aria/aria-role-policy.ts
733
792
  function getImplicitRole(tag, props) {
734
793
  if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
@@ -1627,7 +1686,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1627
1686
  const cached = _AriaPolicyEngine.#removeAttributeFixCache.get(attr);
1628
1687
  if (cached) return cached;
1629
1688
  const fix = {
1630
- kind: `removeAttribute:${attr}`,
1689
+ kind: "removeAttribute",
1690
+ attribute: attr,
1631
1691
  apply: ({ props }) => {
1632
1692
  if (!(attr in props)) return { applied: false, next: props };
1633
1693
  return { applied: true, next: omitProp(props, attr), previous: props };
@@ -1898,7 +1958,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1898
1958
  if (!impliedLive) return NO_VIOLATIONS2;
1899
1959
  if ("aria-live" in props) return NO_VIOLATIONS2;
1900
1960
  const injectLive = {
1901
- kind: `injectLive:${effectiveRole}`,
1961
+ kind: "injectLive",
1962
+ attribute: "aria-live",
1902
1963
  apply: (ctx) => ({
1903
1964
  applied: true,
1904
1965
  next: { ...ctx.props, "aria-live": impliedLive },
@@ -1967,6 +2028,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1967
2028
  }
1968
2029
  };
1969
2030
 
2031
+ // ../../lib/contract/src/aria/factories.ts
2032
+ function removeProp(props, key) {
2033
+ const next = { ...props };
2034
+ delete next[key];
2035
+ return next;
2036
+ }
2037
+ function removeAttributeFix(attribute) {
2038
+ return Object.freeze({
2039
+ kind: "removeAttribute",
2040
+ attribute,
2041
+ apply: ({ props }) => {
2042
+ if (!(attribute in props)) return { applied: false, next: props };
2043
+ return { applied: true, next: removeProp(props, attribute), previous: props };
2044
+ }
2045
+ });
2046
+ }
2047
+
1970
2048
  // ../../lib/contract/src/children/get-type-name.ts
1971
2049
  function getTypeName(value) {
1972
2050
  if (value === null) return "null";
@@ -2285,22 +2363,6 @@ import { warnDiagnostics as warnDiagnostics2 } from "./_shared/diagnostics.js";
2285
2363
 
2286
2364
  // ../core/src/html/contracts/categories.ts
2287
2365
  var METADATA_TAGS = ["script", "template"];
2288
- var VOID_TAGS = [
2289
- "area",
2290
- "base",
2291
- "br",
2292
- "col",
2293
- "embed",
2294
- "hr",
2295
- "img",
2296
- "input",
2297
- "link",
2298
- "meta",
2299
- "param",
2300
- "source",
2301
- "track",
2302
- "wbr"
2303
- ];
2304
2366
  var TEXT_ONLY_TAGS = [
2305
2367
  "option",
2306
2368
  "script",
@@ -2424,20 +2486,6 @@ var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
2424
2486
 
2425
2487
  // ../core/src/html/spec/validators/attribute-type-validator.ts
2426
2488
  var DEFAULT_INPUT_TYPE = "text";
2427
- function omit(props, key) {
2428
- const next = { ...props };
2429
- delete next[key];
2430
- return next;
2431
- }
2432
- function removeAttributeFix(attribute) {
2433
- return {
2434
- kind: `removeAttribute:${attribute}`,
2435
- apply: ({ props }) => {
2436
- if (!(attribute in props)) return { applied: false, next: props };
2437
- return { applied: true, next: omit(props, attribute), previous: props };
2438
- }
2439
- };
2440
- }
2441
2489
  function createInputAttributeTypeRule({
2442
2490
  attribute,
2443
2491
  allowedTypes
@@ -2890,7 +2938,7 @@ function getChildProp(child, key) {
2890
2938
  if (!isVNodeLike(child)) return void 0;
2891
2939
  const { props } = child;
2892
2940
  if (!isObject(props)) return void 0;
2893
- return props[key];
2941
+ return Reflect.get(props, key);
2894
2942
  }
2895
2943
 
2896
2944
  // ../core/src/html/contracts/aria/landmarks.ts
@@ -2943,6 +2991,13 @@ function isLabelableControl(child) {
2943
2991
  const type = getChildProp(child, "type");
2944
2992
  return !isString(type) || type !== "hidden";
2945
2993
  }
2994
+ function hasAccessibleNameProp(props) {
2995
+ return "aria-label" in props || "aria-labelledby" in props;
2996
+ }
2997
+ function isNonEmptyTextChild(child) {
2998
+ if (isNumber(child)) return true;
2999
+ return isString(child) && child.trim().length > 0;
3000
+ }
2946
3001
  var labelContract = contract([
2947
3002
  { name: "control", match: isLabelableControl, cardinality: { max: 1 } },
2948
3003
  { name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
@@ -2950,6 +3005,13 @@ var labelContract = contract([
2950
3005
  name: "other-interactive-content",
2951
3006
  match: isTag(...OTHER_INTERACTIVE_TAGS),
2952
3007
  cardinality: { max: 0 }
3008
+ },
3009
+ {
3010
+ name: "accessible-name",
3011
+ match: isNonEmptyTextChild,
3012
+ cardinality: dynamic(
3013
+ (ctx) => hasAccessibleNameProp(ctx.props) ? { min: 0 } : { min: 1 }
3014
+ )
2953
3015
  }
2954
3016
  ]);
2955
3017
 
@@ -3699,6 +3761,23 @@ function applySlot(children, slotProps, ref, cloneSlotChild) {
3699
3761
  return cloneSlotChild({ child: children, slotProps, ref });
3700
3762
  }
3701
3763
 
3764
+ // ../../adapters/react/src/shared/to-react-factory-options.ts
3765
+ var REACT_FIELD_VALIDATORS = {
3766
+ slotComponent: (v) => v === void 0 || isFunction(v) || isObject(v),
3767
+ filterProps: (v) => v === void 0 || isFunction(v),
3768
+ artifact: (v) => v === void 0 || isObject(v)
3769
+ };
3770
+ function isReactFactoryOptions(options) {
3771
+ return isFactoryOptionsLike(options, REACT_FIELD_VALIDATORS);
3772
+ }
3773
+
3774
+ // ../../adapters/react/src/shared/is-polymorphic-component.ts
3775
+ function isPolymorphicComponent(value) {
3776
+ if (!isFunction(value)) return false;
3777
+ if (!("displayName" in value)) return true;
3778
+ return value.displayName === void 0 || isString(value.displayName);
3779
+ }
3780
+
3702
3781
  // ../../adapters/react/src/shared/apply-display-name.ts
3703
3782
  function applyDisplayName(component, name) {
3704
3783
  const displayName = name ?? "PolymorphicComponent";
@@ -3824,7 +3903,10 @@ function render({
3824
3903
  tag: state.tag,
3825
3904
  props: state.normalizedProps
3826
3905
  });
3827
- runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren());
3906
+ runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren(), {
3907
+ tag: state.tag,
3908
+ props: state.normalizedProps
3909
+ });
3828
3910
  }
3829
3911
  if (typeof props.render === "function") {
3830
3912
  return props.render({ ...state.props, className: state.className, ref });
@@ -3872,10 +3954,14 @@ function buildRuntime(options, defaultSlotComponent, normalizeChildren) {
3872
3954
  }
3873
3955
 
3874
3956
  export {
3957
+ invariant,
3875
3958
  defineContractComponent,
3876
3959
  isString,
3877
3960
  SLOT_NAME,
3878
3961
  COMPONENT_DEFAULT_TAG,
3962
+ finalizeComponent,
3963
+ isReactFactoryOptions,
3964
+ isPolymorphicComponent,
3879
3965
  mergeRefs,
3880
3966
  applyDisplayName,
3881
3967
  Slottable,
@@ -211608,12 +211608,12 @@ var require_commonjs = __commonJS({
211608
211608
  }
211609
211609
  });
211610
211610
 
211611
- // ../../node_modules/.pnpm/brace-expansion@5.0.7/node_modules/brace-expansion/dist/commonjs/index.js
211611
+ // ../../node_modules/.pnpm/brace-expansion@5.0.9/node_modules/brace-expansion/dist/commonjs/index.js
211612
211612
  var require_commonjs2 = __commonJS({
211613
- "../../node_modules/.pnpm/brace-expansion@5.0.7/node_modules/brace-expansion/dist/commonjs/index.js"(exports) {
211613
+ "../../node_modules/.pnpm/brace-expansion@5.0.9/node_modules/brace-expansion/dist/commonjs/index.js"(exports) {
211614
211614
  "use strict";
211615
211615
  Object.defineProperty(exports, "__esModule", { value: true });
211616
- exports.EXPANSION_MAX = void 0;
211616
+ exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0;
211617
211617
  exports.expand = expand;
211618
211618
  var balanced_match_1 = require_commonjs();
211619
211619
  var escSlash = "\0SLASH" + Math.random() + "\0";
@@ -211632,6 +211632,7 @@ var require_commonjs2 = __commonJS({
211632
211632
  var commaPattern = /\\,/g;
211633
211633
  var periodPattern = /\\\./g;
211634
211634
  exports.EXPANSION_MAX = 1e5;
211635
+ exports.EXPANSION_MAX_LENGTH = 4e6;
211635
211636
  function numeric(str) {
211636
211637
  return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
211637
211638
  }
@@ -211666,11 +211667,11 @@ var require_commonjs2 = __commonJS({
211666
211667
  if (!str) {
211667
211668
  return [];
211668
211669
  }
211669
- const { max = exports.EXPANSION_MAX } = options;
211670
+ const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH } = options;
211670
211671
  if (str.slice(0, 2) === "{}") {
211671
211672
  str = "\\{\\}" + str.slice(2);
211672
211673
  }
211673
- return expand_(escapeBraces(str), max, true).map(unescapeBraces);
211674
+ return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
211674
211675
  }
211675
211676
  function embrace(str) {
211676
211677
  return "{" + str + "}";
@@ -211684,20 +211685,87 @@ var require_commonjs2 = __commonJS({
211684
211685
  function gte(i, y) {
211685
211686
  return i >= y;
211686
211687
  }
211687
- function expand_(str, max, isTop) {
211688
- const expansions = [];
211688
+ function combine(acc, pre, values, max, maxLength, dropEmpties) {
211689
+ const out = [];
211690
+ let length = 0;
211691
+ for (let a = 0; a < acc.length; a++) {
211692
+ for (let v = 0; v < values.length; v++) {
211693
+ if (out.length >= max)
211694
+ return out;
211695
+ const expansion = acc[a] + pre + values[v];
211696
+ if (dropEmpties && !expansion)
211697
+ continue;
211698
+ if (length + expansion.length > maxLength)
211699
+ return out;
211700
+ out.push(expansion);
211701
+ length += expansion.length;
211702
+ }
211703
+ }
211704
+ return out;
211705
+ }
211706
+ function expandSequence(body, isAlphaSequence, max, maxLength) {
211707
+ const n = body.split(/\.\./);
211708
+ const N = [];
211709
+ if (n[0] === void 0 || n[1] === void 0) {
211710
+ return N;
211711
+ }
211712
+ const x = numeric(n[0]);
211713
+ const y = numeric(n[1]);
211714
+ const width = Math.max(n[0].length, n[1].length);
211715
+ let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
211716
+ let test = lte;
211717
+ const reverse = y < x;
211718
+ if (reverse) {
211719
+ incr *= -1;
211720
+ test = gte;
211721
+ }
211722
+ const pad = n.some(isPadded);
211723
+ let length = 0;
211724
+ for (let i = x; test(i, y) && N.length < max; i += incr) {
211725
+ let c;
211726
+ if (isAlphaSequence) {
211727
+ c = String.fromCharCode(i);
211728
+ if (c === "\\") {
211729
+ c = "";
211730
+ }
211731
+ } else {
211732
+ c = String(i);
211733
+ if (pad) {
211734
+ const need = width - c.length;
211735
+ if (need > 0) {
211736
+ const z = new Array(need + 1).join("0");
211737
+ if (i < 0) {
211738
+ c = "-" + z + c.slice(1);
211739
+ } else {
211740
+ c = z + c;
211741
+ }
211742
+ }
211743
+ }
211744
+ }
211745
+ if (length + c.length > maxLength)
211746
+ break;
211747
+ N.push(c);
211748
+ length += c.length;
211749
+ }
211750
+ return N;
211751
+ }
211752
+ function expand_(str, max, maxLength, isTop) {
211753
+ let acc = [""];
211754
+ let dropEmpties = false;
211755
+ let firstGroup = true;
211689
211756
  for (; ; ) {
211690
211757
  const m = (0, balanced_match_1.balanced)("{", "}", str);
211691
- if (!m)
211692
- return [str];
211758
+ if (!m) {
211759
+ return combine(acc, str, [""], max, maxLength, dropEmpties);
211760
+ }
211693
211761
  const pre = m.pre;
211694
- if (/\$$/.test(m.pre)) {
211695
- const post2 = m.post.length ? expand_(m.post, max, false) : [""];
211696
- for (let k = 0; k < post2.length && k < max; k++) {
211697
- const expansion = pre + "{" + m.body + "}" + post2[k];
211698
- expansions.push(expansion);
211699
- }
211700
- return expansions;
211762
+ if (/\$$/.test(pre)) {
211763
+ acc = combine(acc, pre + "{" + m.body + "}", [""], max, maxLength, dropEmpties && !m.post.length);
211764
+ firstGroup = false;
211765
+ if (!m.post.length)
211766
+ break;
211767
+ str = m.post;
211768
+ continue;
211701
211769
  }
211702
211770
  const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
211703
211771
  const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
@@ -211709,74 +211777,55 @@ var require_commonjs2 = __commonJS({
211709
211777
  isTop = true;
211710
211778
  continue;
211711
211779
  }
211712
- return [str];
211780
+ return combine(acc, pre + "{" + m.body + "}" + m.post, [""], max, maxLength, dropEmpties);
211713
211781
  }
211714
- const post = m.post.length ? expand_(m.post, max, false) : [""];
211715
- let n;
211782
+ if (firstGroup) {
211783
+ dropEmpties = isTop && !isSequence;
211784
+ firstGroup = false;
211785
+ }
211786
+ let values;
211716
211787
  if (isSequence) {
211717
- n = m.body.split(/\.\./);
211788
+ values = expandSequence(m.body, isAlphaSequence, max, maxLength);
211718
211789
  } else {
211719
- n = parseCommaParts(m.body);
211790
+ let n = parseCommaParts(m.body);
211720
211791
  if (n.length === 1 && n[0] !== void 0) {
211721
- n = expand_(n[0], max, false).map(embrace);
211792
+ n = expand_(n[0], max, maxLength, false).map(embrace);
211722
211793
  if (n.length === 1) {
211723
- return post.map((p) => m.pre + n[0] + p);
211724
- }
211725
- }
211726
- }
211727
- let N;
211728
- if (isSequence && n[0] !== void 0 && n[1] !== void 0) {
211729
- const x = numeric(n[0]);
211730
- const y = numeric(n[1]);
211731
- const width = Math.max(n[0].length, n[1].length);
211732
- let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
211733
- let test = lte;
211734
- const reverse = y < x;
211735
- if (reverse) {
211736
- incr *= -1;
211737
- test = gte;
211738
- }
211739
- const pad = n.some(isPadded);
211740
- N = [];
211741
- for (let i = x; test(i, y) && N.length < max; i += incr) {
211742
- let c;
211743
- if (isAlphaSequence) {
211744
- c = String.fromCharCode(i);
211745
- if (c === "\\") {
211746
- c = "";
211747
- }
211748
- } else {
211749
- c = String(i);
211750
- if (pad) {
211751
- const need = width - c.length;
211752
- if (need > 0) {
211753
- const z = new Array(need + 1).join("0");
211754
- if (i < 0) {
211755
- c = "-" + z + c.slice(1);
211756
- } else {
211757
- c = z + c;
211758
- }
211759
- }
211760
- }
211794
+ acc = combine(acc, pre + n[0], [""], max, maxLength, dropEmpties && !m.post.length);
211795
+ if (!m.post.length)
211796
+ break;
211797
+ str = m.post;
211798
+ continue;
211761
211799
  }
211762
- N.push(c);
211763
211800
  }
211764
- } else {
211765
- N = [];
211766
- for (let j = 0; j < n.length; j++) {
211767
- N.push.apply(N, expand_(n[j], max, false));
211801
+ let dropsEmpties = dropEmpties && !m.post.length && !pre;
211802
+ for (let d = 0; dropsEmpties && d < acc.length; d++) {
211803
+ if (acc[d]) {
211804
+ dropsEmpties = false;
211805
+ }
211768
211806
  }
211769
- }
211770
- for (let j = 0; j < N.length; j++) {
211771
- for (let k = 0; k < post.length && expansions.length < max; k++) {
211772
- const expansion = pre + N[j] + post[k];
211773
- if (!isTop || isSequence || expansion) {
211774
- expansions.push(expansion);
211807
+ values = [];
211808
+ let valuesLength = 0;
211809
+ outer: for (let j = 0; j < n.length; j++) {
211810
+ const expanded = expand_(n[j], max, maxLength, false);
211811
+ for (let k = 0; k < expanded.length; k++) {
211812
+ const v = expanded[k];
211813
+ if (dropsEmpties && !v)
211814
+ continue;
211815
+ if (values.length >= max || valuesLength + v.length > maxLength) {
211816
+ break outer;
211817
+ }
211818
+ values.push(v);
211819
+ valuesLength += v.length;
211775
211820
  }
211776
211821
  }
211777
211822
  }
211778
- return expansions;
211823
+ acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
211824
+ if (!m.post.length)
211825
+ break;
211826
+ str = m.post;
211779
211827
  }
211828
+ return acc;
211780
211829
  }
211781
211830
  }
211782
211831
  });
@@ -4,6 +4,8 @@ import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
4
4
  type StringMap<T = unknown> = Record<string, T>;
5
5
  type AnyRecord = StringMap<unknown>;
6
6
  type EmptyRecord = Record<never, never>;
7
+ /** A compound component's named sub-components, e.g. `{ Header, Content, Footer }`. */
8
+ type SubComponentMap = Readonly<AnyRecord>;
7
9
 
8
10
  type IntrinsicTag = keyof HTMLElementTagNameMap;
9
11
 
@@ -177,8 +179,8 @@ type AriaContext = {
177
179
  readonly props: ReadonlyDeep<IntrinsicProps>;
178
180
  };
179
181
 
180
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
181
- type InjectLiveFixKind = `injectLive:${string}`;
182
+ type RemoveAttributeFixKind = 'removeAttribute';
183
+ type InjectLiveFixKind = 'injectLive';
182
184
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
183
185
 
184
186
  type AriaFixResult = {
@@ -191,6 +193,9 @@ type AriaFixResult = {
191
193
  };
192
194
  type AriaFix = {
193
195
  readonly kind: FixKind;
196
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
197
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
198
+ readonly attribute?: string;
194
199
  readonly priority?: number;
195
200
  readonly source?: string;
196
201
  readonly apply: (context: AriaContext) => AriaFixResult;
@@ -285,8 +290,82 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
285
290
  * be set directly by component authors — use `enforcement.diagnostics` to override per component.
286
291
  */
287
292
  readonly diagnostics?: Diagnostics$1;
293
+ /**
294
+ * Sub-components to attach to the generated root component, producing a
295
+ * compound component API (for example, `Card.Header`, `Card.Content`,
296
+ * and `Card.Footer`). Purely additive — has no effect on
297
+ * `enforcement.children`; author child rules explicitly if the component
298
+ * needs to validate its children.
299
+ */
300
+ readonly subComponents?: SubComponentMap;
301
+ /**
302
+ * Called once per instance, when the real underlying DOM element first
303
+ * exists, in every adapter — via that adapter's own native mount
304
+ * lifecycle, never through the props/attribute pipeline. Use this for
305
+ * wiring that needs the actual element (native imperative methods like
306
+ * `dialogEl.showModal()`, native events like `close`/`cancel` that have
307
+ * no prop-based equivalent), not for anything expressible as a plain
308
+ * prop.
309
+ *
310
+ * `getProps` returns the instance's *current* resolved props at call
311
+ * time — read it from inside a listener registered once at mount, rather
312
+ * than re-subscribing on every prop change.
313
+ *
314
+ * Return a cleanup function to run when the instance unmounts.
315
+ */
316
+ readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
288
317
  };
289
318
 
319
+ /** Shared input shape for `invalidWithFix`/`invalidWithoutFix`. */
320
+ type InvalidResultInput = {
321
+ readonly severity: Severity;
322
+ readonly attribute?: string;
323
+ readonly message?: string;
324
+ readonly diagnostic?: DiagnosticInput;
325
+ };
326
+
327
+ /** Options for `createRemoveAttributeRule`. */
328
+ type RemoveAttributeRuleOptions = {
329
+ /** Returns true when `attribute` should be stripped for the given render. */
330
+ readonly when: (context: AriaContext) => boolean;
331
+ readonly severity?: Severity;
332
+ readonly message?: string;
333
+ /** Receives the same context `when` did, so the diagnostic can reference the offending value. */
334
+ readonly diagnostic?: (context: AriaContext) => DiagnosticInput;
335
+ readonly readsProps?: readonly string[];
336
+ readonly tags?: readonly string[];
337
+ };
338
+
339
+ /**
340
+ * Builds a correctly-literal-typed `fixable: false` `AriaResult`. Exists so a rule author can
341
+ * extract shared branch logic (severity/attribute/message computed once, reused across multiple
342
+ * `return`s) without TypeScript silently widening `valid: false`/`fixable: false` to `boolean`
343
+ * the moment those values leave an object-literal-in-return-position — the widening only happens
344
+ * on plain object literals; a function's declared return type narrows unconditionally.
345
+ */
346
+ declare function invalidWithoutFix(input: InvalidResultInput): AriaInvalidWithoutFix;
347
+ /** Same as {@link invalidWithoutFix}, for the `fixable: true` branch — requires a `fix`. */
348
+ declare function invalidWithFix(input: InvalidResultInput & {
349
+ readonly fix: AriaFix;
350
+ }): AriaInvalidWithFix;
351
+ /**
352
+ * Builds an `AriaFix` that strips a single attribute — the shape `dangerousHrefRule`-style
353
+ * "strip this attribute when it's dangerous/redundant" rules need. A no-op (`applied: false`) when
354
+ * the attribute isn't present, so applying the fix twice (or applying it when nothing triggered it)
355
+ * is always safe. Frozen — a fix is a value object; nothing should mutate `kind`/`attribute`/`apply`
356
+ * after construction.
357
+ */
358
+ declare function removeAttributeFix(attribute: string): AriaFix;
359
+ /**
360
+ * Convenience factory for the single most common `enforcement.aria`/`enforcement.rules` shape:
361
+ * "strip this attribute when some condition on the element's own props holds" — covers
362
+ * security-style guards (a dangerous URL scheme on `href`) and redundant-attribute rules alike,
363
+ * without hand-writing the rule function, the `AriaFix`, and the `invalidWithFix` call each time.
364
+ * A rule with no fix (a warn-only advisory) still needs the raw `AriaRule` shape directly — this
365
+ * factory is deliberately scoped to the strip-on-match case, not a general rule builder.
366
+ */
367
+ declare function createRemoveAttributeRule(attribute: string, options: RemoveAttributeRuleOptions): AriaRule;
368
+
290
369
  declare const activeProps: PropNormalizer;
291
370
 
292
371
  declare const disabledProps: PropNormalizer;
@@ -316,4 +395,4 @@ declare function mergeContracts(...contracts: readonly EnforcementOptions[]): En
316
395
 
317
396
  type Diagnostics = Diagnostics$1;
318
397
 
319
- export { type AnyFactoryOptions, type AriaContext, type AriaFix, type AriaFixResult, type AriaPhase, type AriaResult, type AriaRule, type Diagnostics, type FixKind, type IntrinsicProps, type AriaInvalidResult as InvalidResult, type AriaInvalidWithFix as InvalidWithFix, type AriaInvalidWithoutFix as InvalidWithoutFix, type NormalizeFn, type PropNormalizer, type RemoveAttributeFixKind, type Severity, type ValidResult, activeContract, activeProps, disabledContract, disabledProps, expandedContract, expandedProps, invalidContract, invalidProps, loadingContract, loadingProps, mergeContracts, pressedContract, pressedProps, readonlyContract, readonlyProps, selectedContract, selectedProps };
398
+ export { type AnyFactoryOptions, type AriaContext, type AriaFix, type AriaFixResult, type AriaPhase, type AriaResult, type AriaRule, type Diagnostics, type FixKind, type IntrinsicProps, type AriaInvalidResult as InvalidResult, type AriaInvalidWithFix as InvalidWithFix, type AriaInvalidWithoutFix as InvalidWithoutFix, type NormalizeFn, type PropNormalizer, type RemoveAttributeFixKind, type Severity, type ValidResult, activeContract, activeProps, createRemoveAttributeRule, disabledContract, disabledProps, expandedContract, expandedProps, invalidContract, invalidProps, invalidWithFix, invalidWithoutFix, loadingContract, loadingProps, mergeContracts, pressedContract, pressedProps, readonlyContract, readonlyProps, removeAttributeFix, selectedContract, selectedProps };