praxis-kit 6.6.1 → 7.0.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.
package/dist/lit/index.js CHANGED
@@ -13,6 +13,11 @@ function makeResolveTag(defaultTag) {
13
13
  // ../../lib/primitive/src/rule/rule-brand.ts
14
14
  var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
15
15
 
16
+ // ../../lib/primitive/src/rule/dynamic.ts
17
+ function dynamic(resolve) {
18
+ return { [RULE_BRAND]: true, resolve };
19
+ }
20
+
16
21
  // ../../lib/primitive/src/guards/foundational/is-defined.ts
17
22
  function isUndefined(value) {
18
23
  return value === void 0;
@@ -26,7 +31,7 @@ function isNonNull(value) {
26
31
  return value != null;
27
32
  }
28
33
  function isNullish(value) {
29
- return isNull(value) || value === void 0;
34
+ return isNull(value) || isUndefined(value);
30
35
  }
31
36
 
32
37
  // ../../lib/primitive/src/utils/type-guards.ts
@@ -517,6 +522,24 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
517
522
  ]
518
523
  ]);
519
524
 
525
+ // ../../lib/primitive/src/constants/html/void-tags.ts
526
+ var VOID_TAGS = [
527
+ "area",
528
+ "base",
529
+ "br",
530
+ "col",
531
+ "embed",
532
+ "hr",
533
+ "img",
534
+ "input",
535
+ "link",
536
+ "meta",
537
+ "param",
538
+ "source",
539
+ "track",
540
+ "wbr"
541
+ ];
542
+
520
543
  // ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
521
544
  function isGlobalAriaAttribute(attr) {
522
545
  return GLOBAL_ARIA_ATTRIBUTES.has(attr);
@@ -1446,7 +1469,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1446
1469
  const cached = _AriaPolicyEngine.#removeAttributeFixCache.get(attr);
1447
1470
  if (cached) return cached;
1448
1471
  const fix = {
1449
- kind: `removeAttribute:${attr}`,
1472
+ kind: "removeAttribute",
1473
+ attribute: attr,
1450
1474
  apply: ({ props }) => {
1451
1475
  if (!(attr in props)) return { applied: false, next: props };
1452
1476
  return { applied: true, next: omitProp(props, attr), previous: props };
@@ -1717,7 +1741,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1717
1741
  if (!impliedLive) return NO_VIOLATIONS2;
1718
1742
  if ("aria-live" in props) return NO_VIOLATIONS2;
1719
1743
  const injectLive = {
1720
- kind: `injectLive:${effectiveRole}`,
1744
+ kind: "injectLive",
1745
+ attribute: "aria-live",
1721
1746
  apply: (ctx) => ({
1722
1747
  applied: true,
1723
1748
  next: { ...ctx.props, "aria-live": impliedLive },
@@ -1786,6 +1811,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1786
1811
  }
1787
1812
  };
1788
1813
 
1814
+ // ../../lib/contract/src/aria/factories.ts
1815
+ function removeProp(props, key) {
1816
+ const next = { ...props };
1817
+ delete next[key];
1818
+ return next;
1819
+ }
1820
+ function removeAttributeFix(attribute) {
1821
+ return Object.freeze({
1822
+ kind: "removeAttribute",
1823
+ attribute,
1824
+ apply: ({ props }) => {
1825
+ if (!(attribute in props)) return { applied: false, next: props };
1826
+ return { applied: true, next: removeProp(props, attribute), previous: props };
1827
+ }
1828
+ });
1829
+ }
1830
+
1789
1831
  // ../../lib/contract/src/children/get-type-name.ts
1790
1832
  function getTypeName(value) {
1791
1833
  if (value === null) return "null";
@@ -2104,22 +2146,6 @@ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
2104
2146
 
2105
2147
  // ../core/src/html/contracts/categories.ts
2106
2148
  var METADATA_TAGS = ["script", "template"];
2107
- var VOID_TAGS = [
2108
- "area",
2109
- "base",
2110
- "br",
2111
- "col",
2112
- "embed",
2113
- "hr",
2114
- "img",
2115
- "input",
2116
- "link",
2117
- "meta",
2118
- "param",
2119
- "source",
2120
- "track",
2121
- "wbr"
2122
- ];
2123
2149
  var TEXT_ONLY_TAGS = [
2124
2150
  "option",
2125
2151
  "script",
@@ -2243,20 +2269,6 @@ var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
2243
2269
 
2244
2270
  // ../core/src/html/spec/validators/attribute-type-validator.ts
2245
2271
  var DEFAULT_INPUT_TYPE = "text";
2246
- function omit(props, key) {
2247
- const next = { ...props };
2248
- delete next[key];
2249
- return next;
2250
- }
2251
- function removeAttributeFix(attribute) {
2252
- return {
2253
- kind: `removeAttribute:${attribute}`,
2254
- apply: ({ props }) => {
2255
- if (!(attribute in props)) return { applied: false, next: props };
2256
- return { applied: true, next: omit(props, attribute), previous: props };
2257
- }
2258
- };
2259
- }
2260
2272
  function createInputAttributeTypeRule({
2261
2273
  attribute,
2262
2274
  allowedTypes
@@ -2762,6 +2774,13 @@ function isLabelableControl(child) {
2762
2774
  const type = getChildProp(child, "type");
2763
2775
  return !isString(type) || type !== "hidden";
2764
2776
  }
2777
+ function hasAccessibleNameProp(props) {
2778
+ return "aria-label" in props || "aria-labelledby" in props;
2779
+ }
2780
+ function isNonEmptyTextChild(child) {
2781
+ if (isNumber(child)) return true;
2782
+ return isString(child) && child.trim().length > 0;
2783
+ }
2765
2784
  var labelContract = contract([
2766
2785
  { name: "control", match: isLabelableControl, cardinality: { max: 1 } },
2767
2786
  { name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
@@ -2769,6 +2788,13 @@ var labelContract = contract([
2769
2788
  name: "other-interactive-content",
2770
2789
  match: isTag(...OTHER_INTERACTIVE_TAGS),
2771
2790
  cardinality: { max: 0 }
2791
+ },
2792
+ {
2793
+ name: "accessible-name",
2794
+ match: isNonEmptyTextChild,
2795
+ cardinality: dynamic(
2796
+ (ctx) => hasAccessibleNameProp(ctx.props) ? { min: 0 } : { min: 1 }
2797
+ )
2772
2798
  }
2773
2799
  ]);
2774
2800
 
@@ -3615,7 +3641,7 @@ function createContractComponent(options) {
3615
3641
  if (bundle.childrenEvaluator) {
3616
3642
  bundle.childrenEvaluator.evaluate(children, { tag, props: normalizedProps });
3617
3643
  }
3618
- bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children);
3644
+ bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children, { tag, props: normalizedProps });
3619
3645
  return html`<slot></slot>`;
3620
3646
  }
3621
3647
  }
@@ -196,8 +196,8 @@ type AriaContext = {
196
196
  readonly props: ReadonlyDeep<IntrinsicProps>;
197
197
  };
198
198
 
199
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
200
- type InjectLiveFixKind = `injectLive:${string}`;
199
+ type RemoveAttributeFixKind = 'removeAttribute';
200
+ type InjectLiveFixKind = 'injectLive';
201
201
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
202
202
 
203
203
  type AriaFixResult = {
@@ -210,6 +210,9 @@ type AriaFixResult = {
210
210
  };
211
211
  type AriaFix = {
212
212
  readonly kind: FixKind;
213
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
214
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
215
+ readonly attribute?: string;
213
216
  readonly priority?: number;
214
217
  readonly source?: string;
215
218
  readonly apply: (context: AriaContext) => AriaFixResult;
@@ -11,6 +11,11 @@ var EVENT_HANDLER_RE = /^on[A-Z]/;
11
11
  // ../../lib/primitive/src/rule/rule-brand.ts
12
12
  var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
13
13
 
14
+ // ../../lib/primitive/src/rule/dynamic.ts
15
+ function dynamic(resolve) {
16
+ return { [RULE_BRAND]: true, resolve };
17
+ }
18
+
14
19
  // ../../lib/primitive/src/guards/foundational/is-defined.ts
15
20
  function isUndefined(value) {
16
21
  return value === void 0;
@@ -24,7 +29,7 @@ function isNonNull(value) {
24
29
  return value != null;
25
30
  }
26
31
  function isNullish(value) {
27
- return isNull(value) || value === void 0;
32
+ return isNull(value) || isUndefined(value);
28
33
  }
29
34
 
30
35
  // ../../lib/primitive/src/utils/type-guards.ts
@@ -625,6 +630,24 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
625
630
  ]
626
631
  ]);
627
632
 
633
+ // ../../lib/primitive/src/constants/html/void-tags.ts
634
+ var VOID_TAGS = [
635
+ "area",
636
+ "base",
637
+ "br",
638
+ "col",
639
+ "embed",
640
+ "hr",
641
+ "img",
642
+ "input",
643
+ "link",
644
+ "meta",
645
+ "param",
646
+ "source",
647
+ "track",
648
+ "wbr"
649
+ ];
650
+
628
651
  // ../../lib/primitive/src/constants/primitive/slot-name.ts
629
652
  var SLOT_NAME = "Slot";
630
653
 
@@ -1629,7 +1652,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1629
1652
  const cached = _AriaPolicyEngine.#removeAttributeFixCache.get(attr);
1630
1653
  if (cached) return cached;
1631
1654
  const fix = {
1632
- kind: `removeAttribute:${attr}`,
1655
+ kind: "removeAttribute",
1656
+ attribute: attr,
1633
1657
  apply: ({ props }) => {
1634
1658
  if (!(attr in props)) return { applied: false, next: props };
1635
1659
  return { applied: true, next: omitProp(props, attr), previous: props };
@@ -1900,7 +1924,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1900
1924
  if (!impliedLive) return NO_VIOLATIONS2;
1901
1925
  if ("aria-live" in props) return NO_VIOLATIONS2;
1902
1926
  const injectLive = {
1903
- kind: `injectLive:${effectiveRole}`,
1927
+ kind: "injectLive",
1928
+ attribute: "aria-live",
1904
1929
  apply: (ctx) => ({
1905
1930
  applied: true,
1906
1931
  next: { ...ctx.props, "aria-live": impliedLive },
@@ -1969,6 +1994,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1969
1994
  }
1970
1995
  };
1971
1996
 
1997
+ // ../../lib/contract/src/aria/factories.ts
1998
+ function removeProp(props, key) {
1999
+ const next = { ...props };
2000
+ delete next[key];
2001
+ return next;
2002
+ }
2003
+ function removeAttributeFix(attribute) {
2004
+ return Object.freeze({
2005
+ kind: "removeAttribute",
2006
+ attribute,
2007
+ apply: ({ props }) => {
2008
+ if (!(attribute in props)) return { applied: false, next: props };
2009
+ return { applied: true, next: removeProp(props, attribute), previous: props };
2010
+ }
2011
+ });
2012
+ }
2013
+
1972
2014
  // ../../lib/contract/src/children/get-type-name.ts
1973
2015
  function getTypeName(value) {
1974
2016
  if (value === null) return "null";
@@ -2287,22 +2329,6 @@ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
2287
2329
 
2288
2330
  // ../core/src/html/contracts/categories.ts
2289
2331
  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
2332
  var TEXT_ONLY_TAGS = [
2307
2333
  "option",
2308
2334
  "script",
@@ -2426,20 +2452,6 @@ var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
2426
2452
 
2427
2453
  // ../core/src/html/spec/validators/attribute-type-validator.ts
2428
2454
  var DEFAULT_INPUT_TYPE = "text";
2429
- function omit(props, key) {
2430
- const next = { ...props };
2431
- delete next[key];
2432
- return next;
2433
- }
2434
- function removeAttributeFix(attribute) {
2435
- return {
2436
- kind: `removeAttribute:${attribute}`,
2437
- apply: ({ props }) => {
2438
- if (!(attribute in props)) return { applied: false, next: props };
2439
- return { applied: true, next: omit(props, attribute), previous: props };
2440
- }
2441
- };
2442
- }
2443
2455
  function createInputAttributeTypeRule({
2444
2456
  attribute,
2445
2457
  allowedTypes
@@ -2945,6 +2957,13 @@ function isLabelableControl(child) {
2945
2957
  const type = getChildProp(child, "type");
2946
2958
  return !isString(type) || type !== "hidden";
2947
2959
  }
2960
+ function hasAccessibleNameProp(props) {
2961
+ return "aria-label" in props || "aria-labelledby" in props;
2962
+ }
2963
+ function isNonEmptyTextChild(child) {
2964
+ if (isNumber(child)) return true;
2965
+ return isString(child) && child.trim().length > 0;
2966
+ }
2948
2967
  var labelContract = contract([
2949
2968
  { name: "control", match: isLabelableControl, cardinality: { max: 1 } },
2950
2969
  { name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
@@ -2952,6 +2971,13 @@ var labelContract = contract([
2952
2971
  name: "other-interactive-content",
2953
2972
  match: isTag(...OTHER_INTERACTIVE_TAGS),
2954
2973
  cardinality: { max: 0 }
2974
+ },
2975
+ {
2976
+ name: "accessible-name",
2977
+ match: isNonEmptyTextChild,
2978
+ cardinality: dynamic(
2979
+ (ctx) => hasAccessibleNameProp(ctx.props) ? { min: 0 } : { min: 1 }
2980
+ )
2955
2981
  }
2956
2982
  ]);
2957
2983
 
@@ -3803,7 +3829,10 @@ function render({
3803
3829
  tag: state.tag,
3804
3830
  props: state.normalizedProps
3805
3831
  });
3806
- runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren());
3832
+ runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren(), {
3833
+ tag: state.tag,
3834
+ props: state.normalizedProps
3835
+ });
3807
3836
  }
3808
3837
  const slotResult = tryRenderAsChild(
3809
3838
  state,
@@ -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-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';
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-Cm99IE5J.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-Cm99IE5J.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-6JILZ6GQ.js";
15
+ } from "../chunk-35CJAOJW.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-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';
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-Cm99IE5J.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-Cm99IE5J.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-6JILZ6GQ.js";
16
+ } from "../chunk-35CJAOJW.js";
17
17
 
18
18
  // ../../adapters/react/src/legacy/create-contract-component.ts
19
19
  import { forwardRef as forwardRef2 } from "react";
@@ -197,8 +197,8 @@ type AriaContext = {
197
197
  readonly props: ReadonlyDeep<IntrinsicProps>;
198
198
  };
199
199
 
200
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
201
- type InjectLiveFixKind = `injectLive:${string}`;
200
+ type RemoveAttributeFixKind = 'removeAttribute';
201
+ type InjectLiveFixKind = 'injectLive';
202
202
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
203
203
 
204
204
  type AriaFixResult = {
@@ -211,6 +211,9 @@ type AriaFixResult = {
211
211
  };
212
212
  type AriaFix = {
213
213
  readonly kind: FixKind;
214
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
215
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
216
+ readonly attribute?: string;
214
217
  readonly priority?: number;
215
218
  readonly source?: string;
216
219
  readonly apply: (context: AriaContext) => AriaFixResult;
@@ -196,8 +196,8 @@ type AriaContext = {
196
196
  readonly props: ReadonlyDeep<IntrinsicProps>;
197
197
  };
198
198
 
199
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
200
- type InjectLiveFixKind = `injectLive:${string}`;
199
+ type RemoveAttributeFixKind = 'removeAttribute';
200
+ type InjectLiveFixKind = 'injectLive';
201
201
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
202
202
 
203
203
  type AriaFixResult = {
@@ -210,6 +210,9 @@ type AriaFixResult = {
210
210
  };
211
211
  type AriaFix = {
212
212
  readonly kind: FixKind;
213
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
214
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
215
+ readonly attribute?: string;
213
216
  readonly priority?: number;
214
217
  readonly source?: string;
215
218
  readonly apply: (context: AriaContext) => AriaFixResult;
@@ -8,6 +8,11 @@ function makeResolveTag(defaultTag) {
8
8
  // ../../lib/primitive/src/rule/rule-brand.ts
9
9
  var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
10
10
 
11
+ // ../../lib/primitive/src/rule/dynamic.ts
12
+ function dynamic(resolve) {
13
+ return { [RULE_BRAND]: true, resolve };
14
+ }
15
+
11
16
  // ../../lib/primitive/src/guards/foundational/is-defined.ts
12
17
  function isUndefined(value) {
13
18
  return value === void 0;
@@ -21,7 +26,7 @@ function isNonNull(value) {
21
26
  return value != null;
22
27
  }
23
28
  function isNullish(value) {
24
- return isNull(value) || value === void 0;
29
+ return isNull(value) || isUndefined(value);
25
30
  }
26
31
 
27
32
  // ../../lib/primitive/src/utils/type-guards.ts
@@ -598,6 +603,24 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
598
603
  ]
599
604
  ]);
600
605
 
606
+ // ../../lib/primitive/src/constants/html/void-tags.ts
607
+ var VOID_TAGS = [
608
+ "area",
609
+ "base",
610
+ "br",
611
+ "col",
612
+ "embed",
613
+ "hr",
614
+ "img",
615
+ "input",
616
+ "link",
617
+ "meta",
618
+ "param",
619
+ "source",
620
+ "track",
621
+ "wbr"
622
+ ];
623
+
601
624
  // ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
602
625
  function isGlobalAriaAttribute(attr) {
603
626
  return GLOBAL_ARIA_ATTRIBUTES.has(attr);
@@ -1588,7 +1611,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1588
1611
  const cached = _AriaPolicyEngine.#removeAttributeFixCache.get(attr);
1589
1612
  if (cached) return cached;
1590
1613
  const fix = {
1591
- kind: `removeAttribute:${attr}`,
1614
+ kind: "removeAttribute",
1615
+ attribute: attr,
1592
1616
  apply: ({ props }) => {
1593
1617
  if (!(attr in props)) return { applied: false, next: props };
1594
1618
  return { applied: true, next: omitProp(props, attr), previous: props };
@@ -1859,7 +1883,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1859
1883
  if (!impliedLive) return NO_VIOLATIONS2;
1860
1884
  if ("aria-live" in props) return NO_VIOLATIONS2;
1861
1885
  const injectLive = {
1862
- kind: `injectLive:${effectiveRole}`,
1886
+ kind: "injectLive",
1887
+ attribute: "aria-live",
1863
1888
  apply: (ctx) => ({
1864
1889
  applied: true,
1865
1890
  next: { ...ctx.props, "aria-live": impliedLive },
@@ -1928,6 +1953,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1928
1953
  }
1929
1954
  };
1930
1955
 
1956
+ // ../../lib/contract/src/aria/factories.ts
1957
+ function removeProp(props, key) {
1958
+ const next = { ...props };
1959
+ delete next[key];
1960
+ return next;
1961
+ }
1962
+ function removeAttributeFix(attribute) {
1963
+ return Object.freeze({
1964
+ kind: "removeAttribute",
1965
+ attribute,
1966
+ apply: ({ props }) => {
1967
+ if (!(attribute in props)) return { applied: false, next: props };
1968
+ return { applied: true, next: removeProp(props, attribute), previous: props };
1969
+ }
1970
+ });
1971
+ }
1972
+
1931
1973
  // ../../lib/contract/src/children/get-type-name.ts
1932
1974
  function getTypeName(value) {
1933
1975
  if (value === null) return "null";
@@ -2246,22 +2288,6 @@ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
2246
2288
 
2247
2289
  // ../core/src/html/contracts/categories.ts
2248
2290
  var METADATA_TAGS = ["script", "template"];
2249
- var VOID_TAGS = [
2250
- "area",
2251
- "base",
2252
- "br",
2253
- "col",
2254
- "embed",
2255
- "hr",
2256
- "img",
2257
- "input",
2258
- "link",
2259
- "meta",
2260
- "param",
2261
- "source",
2262
- "track",
2263
- "wbr"
2264
- ];
2265
2291
  var TEXT_ONLY_TAGS = [
2266
2292
  "option",
2267
2293
  "script",
@@ -2385,20 +2411,6 @@ var INPUT_MUTUALLY_EXCLUSIVE_POLICIES = [
2385
2411
 
2386
2412
  // ../core/src/html/spec/validators/attribute-type-validator.ts
2387
2413
  var DEFAULT_INPUT_TYPE = "text";
2388
- function omit(props, key) {
2389
- const next = { ...props };
2390
- delete next[key];
2391
- return next;
2392
- }
2393
- function removeAttributeFix(attribute) {
2394
- return {
2395
- kind: `removeAttribute:${attribute}`,
2396
- apply: ({ props }) => {
2397
- if (!(attribute in props)) return { applied: false, next: props };
2398
- return { applied: true, next: omit(props, attribute), previous: props };
2399
- }
2400
- };
2401
- }
2402
2414
  function createInputAttributeTypeRule({
2403
2415
  attribute,
2404
2416
  allowedTypes
@@ -2904,6 +2916,13 @@ function isLabelableControl(child) {
2904
2916
  const type = getChildProp(child, "type");
2905
2917
  return !isString(type) || type !== "hidden";
2906
2918
  }
2919
+ function hasAccessibleNameProp(props) {
2920
+ return "aria-label" in props || "aria-labelledby" in props;
2921
+ }
2922
+ function isNonEmptyTextChild(child) {
2923
+ if (isNumber(child)) return true;
2924
+ return isString(child) && child.trim().length > 0;
2925
+ }
2907
2926
  var labelContract = contract([
2908
2927
  { name: "control", match: isLabelableControl, cardinality: { max: 1 } },
2909
2928
  { name: "nested-label", match: isTag("label"), cardinality: { max: 0 } },
@@ -2911,6 +2930,13 @@ var labelContract = contract([
2911
2930
  name: "other-interactive-content",
2912
2931
  match: isTag(...OTHER_INTERACTIVE_TAGS),
2913
2932
  cardinality: { max: 0 }
2933
+ },
2934
+ {
2935
+ name: "accessible-name",
2936
+ match: isNonEmptyTextChild,
2937
+ cardinality: dynamic(
2938
+ (ctx) => hasAccessibleNameProp(ctx.props) ? { min: 0 } : { min: 1 }
2939
+ )
2914
2940
  }
2915
2941
  ]);
2916
2942
 
@@ -3629,7 +3655,10 @@ function render({
3629
3655
  }));
3630
3656
  }
3631
3657
  if (process.env.NODE_ENV !== "production") {
3632
- createEffect(() => runtime.options.htmlChildrenEvaluatorFn?.(tag())?.evaluate(toChildArray(known.children)));
3658
+ createEffect(() => runtime.options.htmlChildrenEvaluatorFn?.(tag())?.evaluate(toChildArray(known.children), {
3659
+ tag: tag(),
3660
+ props: normalizedProps()
3661
+ }));
3633
3662
  }
3634
3663
  const slotResult = tryRenderAsChild(known, filteredProps, resolvedClass, slotValidator);
3635
3664
  if (slotResult !== null) return slotResult;
@@ -130,7 +130,9 @@
130
130
  if (process.env.NODE_ENV === 'production' || !hostEl) return
131
131
  const childArray = Array.from(hostEl.childNodes)
132
132
  bundle.childrenEvaluator?.evaluate(childArray, { tag, props: normalizedProps })
133
- bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(childArray)
133
+ bundle.runtime.options.htmlChildrenEvaluatorFn
134
+ ?.(tag)
135
+ ?.evaluate(childArray, { tag, props: normalizedProps })
134
136
  })
135
137
  }
136
138
  </script>
@@ -29,13 +29,6 @@ type MinMax = {
29
29
  };
30
30
  type CardinalityInput = Partial<MinMax>;
31
31
 
32
- /** Structural counterpart to `@praxis-kit/contract`'s `ChildrenEvaluator` class — `lib/primitive`
33
- * may not depend on `lib/contract` (see `primitive-no-upper-layers` in .dependency-cruiser.cjs),
34
- * so this describes only the shape consumers actually call. Mirrors `AriaEngine`'s pattern. */
35
- type ChildrenEvaluator$1 = {
36
- evaluate: (children: unknown[]) => void;
37
- };
38
-
39
32
  /**
40
33
  * Resolved per-instance state available to a dynamic (`dynamic(...)`) child
41
34
  * rule field — the same tag/props every adapter already computes before
@@ -47,6 +40,13 @@ type ChildRuleContext = {
47
40
  readonly props: Readonly<AnyRecord>;
48
41
  };
49
42
 
43
+ /** Structural counterpart to `@praxis-kit/contract`'s `ChildrenEvaluator` class — `lib/primitive`
44
+ * may not depend on `lib/contract` (see `primitive-no-upper-layers` in .dependency-cruiser.cjs),
45
+ * so this describes only the shape consumers actually call. Mirrors `AriaEngine`'s pattern. */
46
+ type ChildrenEvaluator$1 = {
47
+ evaluate: (children: unknown[], context?: ChildRuleContext) => void;
48
+ };
49
+
50
50
  declare const RULE_BRAND: unique symbol;
51
51
 
52
52
  type DynamicRule<T, C = unknown> = {
@@ -200,8 +200,8 @@ type AriaContext = {
200
200
  readonly props: ReadonlyDeep<IntrinsicProps>;
201
201
  };
202
202
 
203
- type RemoveAttributeFixKind = `removeAttribute:${string}`;
204
- type InjectLiveFixKind = `injectLive:${string}`;
203
+ type RemoveAttributeFixKind = 'removeAttribute';
204
+ type InjectLiveFixKind = 'injectLive';
205
205
  type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
206
206
 
207
207
  type AriaFixResult = {
@@ -214,6 +214,9 @@ type AriaFixResult = {
214
214
  };
215
215
  type AriaFix = {
216
216
  readonly kind: FixKind;
217
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
218
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
219
+ readonly attribute?: string;
217
220
  readonly priority?: number;
218
221
  readonly source?: string;
219
222
  readonly apply: (context: AriaContext) => AriaFixResult;