praxis-kit 6.0.0 → 6.1.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.
@@ -12,8 +12,11 @@ function isUndefined(value) {
12
12
  function isNull(value) {
13
13
  return value === null;
14
14
  }
15
+ function isNonNull(value) {
16
+ return value != null;
17
+ }
15
18
 
16
- // ../../lib/primitive/src/utils/is-object.ts
19
+ // ../../lib/primitive/src/utils/type-guards.ts
17
20
  function isObject(value, excludeArrays = false) {
18
21
  if (value === null || typeof value !== "object") return false;
19
22
  return excludeArrays ? !Array.isArray(value) : true;
@@ -507,6 +510,45 @@ var iterate = Object.freeze({
507
510
  values
508
511
  });
509
512
 
513
+ // ../../lib/primitive/src/utils/lru-cache.ts
514
+ var LRUCache = class {
515
+ #maxSize;
516
+ #store = /* @__PURE__ */ new Map();
517
+ constructor(maxSize) {
518
+ if (!Number.isInteger(maxSize) || maxSize < 1) {
519
+ throw new RangeError("LRUCache maxSize must be a positive integer.");
520
+ }
521
+ this.#maxSize = maxSize;
522
+ }
523
+ get(key) {
524
+ if (!this.#store.has(key)) return void 0;
525
+ const value = this.#store.get(key);
526
+ this.#store.delete(key);
527
+ this.#store.set(key, value);
528
+ return value;
529
+ }
530
+ set(key, value) {
531
+ this.#store.delete(key);
532
+ this.#store.set(key, value);
533
+ if (this.#store.size > this.#maxSize) {
534
+ const lru = this.#store.keys().next().value;
535
+ if (lru !== void 0) this.#store.delete(lru);
536
+ }
537
+ }
538
+ has(key) {
539
+ return this.#store.has(key);
540
+ }
541
+ delete(key) {
542
+ return this.#store.delete(key);
543
+ }
544
+ get size() {
545
+ return this.#store.size;
546
+ }
547
+ clear() {
548
+ this.#store.clear();
549
+ }
550
+ };
551
+
510
552
  // ../../lib/primitive/src/utils/merge-props.ts
511
553
  function mergeProps(defaultProps, props) {
512
554
  return {
@@ -551,28 +593,6 @@ function isTag(...args) {
551
593
  return tag !== void 0 && set2.has(tag);
552
594
  }
553
595
 
554
- // ../../lib/contract/src/strict/invariant-base.ts
555
- var InvariantBase = class {
556
- diagnostics;
557
- constructor(diagnostics) {
558
- this.diagnostics = diagnostics;
559
- }
560
- get active() {
561
- return this.diagnostics.active;
562
- }
563
- violate(input) {
564
- this.diagnostics.error(input);
565
- }
566
- // Always caps at warn — never throws. ARIA 'warning' violations route here
567
- // so they surface even in strict='throw' mode without aborting a render.
568
- warn(input) {
569
- this.diagnostics.warn(input);
570
- }
571
- invariant(condition, input) {
572
- if (!condition) this.violate(input);
573
- }
574
- };
575
-
576
596
  // ../../lib/contract/src/diagnostics/aria.ts
577
597
  import { DiagnosticCategory, DiagnosticCode } from "../_shared/diagnostics.js";
578
598
  var AriaDiagnostics = {
@@ -929,8 +949,30 @@ var SlotDiagnostics = {
929
949
  }
930
950
  };
931
951
 
952
+ // ../../lib/contract/src/strict/invariant-base.ts
953
+ var InvariantBase = class {
954
+ diagnostics;
955
+ constructor(diagnostics) {
956
+ this.diagnostics = diagnostics;
957
+ }
958
+ get active() {
959
+ return this.diagnostics.active;
960
+ }
961
+ violate(input) {
962
+ this.diagnostics.error(input);
963
+ }
964
+ // Always caps at warn — never throws. ARIA 'warning' violations route here
965
+ // so they surface even in strict='throw' mode without aborting a render.
966
+ warn(input) {
967
+ this.diagnostics.warn(input);
968
+ }
969
+ invariant(condition, input) {
970
+ if (!condition) this.violate(input);
971
+ }
972
+ };
973
+
932
974
  // ../../lib/contract/src/aria/polymorphic-validator.ts
933
- var VALID = [{ valid: true }];
975
+ var NO_VIOLATIONS = [{ valid: true }];
934
976
  function isIntrinsicTag(tag) {
935
977
  return isString(tag);
936
978
  }
@@ -940,8 +982,7 @@ function omitProp(obj, key) {
940
982
  }
941
983
  var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
942
984
  #extraRules;
943
- #planCache = /* @__PURE__ */ new Map();
944
- static #MAX_CACHE = 100;
985
+ #planCache = new LRUCache(100);
945
986
  // Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
946
987
  // finite so this Map is bounded and avoids recreating closures on every cache miss.
947
988
  static #removeAttributeFixCache = /* @__PURE__ */ new Map();
@@ -973,17 +1014,20 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
973
1014
  static #deriveContext(tag, props) {
974
1015
  if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
975
1016
  const implicitRole = getImplicitRole(tag, props);
976
- const hasRole = implicitRole != null || isString(props.role) && props.role.length > 0;
1017
+ const hasRole = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
977
1018
  if (!hasRole) return { proceed: false, result: { props, violations: [] } };
978
1019
  const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
979
- if (normalized.normalized) return { proceed: false, result: normalized.result };
980
- const effectiveRole = props.role ?? implicitRole;
1020
+ const workingProps = normalized.normalized ? normalized.result.props : props;
1021
+ const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
1022
+ const effectiveRole = workingProps.role ?? implicitRole;
981
1023
  return {
982
1024
  proceed: true,
983
1025
  tag,
984
1026
  implicitRole,
985
1027
  effectiveRole,
986
- context: { tag, props, implicitRole, effectiveRole }
1028
+ props: workingProps,
1029
+ preExistingViolations,
1030
+ context: { tag, props: workingProps, implicitRole, effectiveRole }
987
1031
  };
988
1032
  }
989
1033
  static #runRules(rules, context) {
@@ -998,7 +1042,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
998
1042
  } = context;
999
1043
  const { message, attribute, severity } = result;
1000
1044
  const resolvedMessage = message ?? result.diagnostic?.message;
1001
- const fallbackDiag = resolvedMessage == null ? AriaDiagnostics.invalidRole(role, tag) : void 0;
1045
+ const fallbackDiag = isNonNull(resolvedMessage) ? void 0 : AriaDiagnostics.invalidRole(role, tag);
1002
1046
  violations.push({
1003
1047
  message: resolvedMessage ?? fallbackDiag.message,
1004
1048
  tag,
@@ -1006,8 +1050,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1006
1050
  attribute,
1007
1051
  severity,
1008
1052
  phase: "evaluate",
1009
- ...result.diagnostic != null && { diagnostic: result.diagnostic },
1010
- ...fallbackDiag != null && { diagnostic: fallbackDiag }
1053
+ ...isNonNull(result.diagnostic) && { diagnostic: result.diagnostic },
1054
+ ...isNonNull(fallbackDiag) && { diagnostic: fallbackDiag }
1011
1055
  });
1012
1056
  if (result.fixable) fixes.push(result.fix);
1013
1057
  });
@@ -1015,7 +1059,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1015
1059
  return { violations, fixes };
1016
1060
  }
1017
1061
  static #getRules(context) {
1018
- if (_AriaPolicyEngine.#hasRole(context.props) || context.effectiveRole != null && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(context.effectiveRole)) {
1062
+ if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(context.effectiveRole)) {
1019
1063
  return _AriaPolicyEngine.#pipeline;
1020
1064
  }
1021
1065
  return _AriaPolicyEngine.#implicitOnlyRules;
@@ -1023,24 +1067,36 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1023
1067
  static evaluate(tag, props) {
1024
1068
  const derived = _AriaPolicyEngine.#deriveContext(tag, props);
1025
1069
  if (!derived.proceed) return derived.result;
1026
- const { tag: narrowedTag, implicitRole, context } = derived;
1070
+ const {
1071
+ tag: narrowedTag,
1072
+ implicitRole,
1073
+ context,
1074
+ props: workingProps,
1075
+ preExistingViolations
1076
+ } = derived;
1027
1077
  const { violations, fixes } = _AriaPolicyEngine.#runRules(
1028
1078
  _AriaPolicyEngine.#getRules(context),
1029
1079
  context
1030
1080
  );
1031
- const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, props, fixes);
1032
- return { props: next, violations };
1081
+ const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
1082
+ return { props: next, violations: [...preExistingViolations, ...violations] };
1033
1083
  }
1034
1084
  static #evaluateWithRules(tag, props, extraRules) {
1035
1085
  const derived = _AriaPolicyEngine.#deriveContext(tag, props);
1036
1086
  if (!derived.proceed) return derived.result;
1037
- const { tag: narrowedTag, implicitRole, context } = derived;
1087
+ const {
1088
+ tag: narrowedTag,
1089
+ implicitRole,
1090
+ context,
1091
+ props: workingProps,
1092
+ preExistingViolations
1093
+ } = derived;
1038
1094
  const { violations, fixes } = _AriaPolicyEngine.#runRules(
1039
1095
  [..._AriaPolicyEngine.#getRules(context), ...extraRules],
1040
1096
  context
1041
1097
  );
1042
- const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, props, fixes);
1043
- return { props: next, violations };
1098
+ const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
1099
+ return { props: next, violations: [...preExistingViolations, ...violations] };
1044
1100
  }
1045
1101
  report(violations) {
1046
1102
  iterate.forEach(violations, (v) => {
@@ -1049,12 +1105,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1049
1105
  else this.warn(d);
1050
1106
  });
1051
1107
  }
1052
- // Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs).
1053
- // Non-aria props (className, onClick, etc.) do not affect ARIA decisions and are excluded
1054
- // so cache hits survive re-renders that only change non-aria props.
1055
- // Note: #extraRules are NOT included in the key each engine instance has its own Map,
1056
- // so two engines with different rules never share cache entries. If caching ever becomes
1057
- // static/shared, rule identity would need to be folded into the key.
1108
+ // Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs)
1109
+ // exactly what the built-in pipeline reads. Non-aria props (className, onClick, etc.) do
1110
+ // not affect built-in ARIA decisions and are excluded so cache hits survive re-renders
1111
+ // that only change non-aria props. This key alone is unsound for #extraRules, which may
1112
+ // read arbitrary props outside this set validate() extends it with #extraRulesKeySuffix,
1113
+ // or bypasses the cache, to account for that.
1058
1114
  static #createPlanKey(tag, props) {
1059
1115
  if (!isIntrinsicTag(tag)) return null;
1060
1116
  const parts = [tag];
@@ -1070,6 +1126,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1070
1126
  if (ariaEntries.length > 0) parts.push(...ariaEntries.sort());
1071
1127
  return parts.join("|");
1072
1128
  }
1129
+ // Extends the base cache key with the props each extra rule declares it reads (`readsProps`).
1130
+ // Returns null — meaning "don't cache" — if any extra rule omits `readsProps` (it may read
1131
+ // arbitrary props the key can't account for) or if a declared prop's value isn't a primitive
1132
+ // (object/array identity isn't stably representable in a string key).
1133
+ static #extraRulesKeySuffix(extraRules, props) {
1134
+ const parts = [];
1135
+ for (const rule of extraRules) {
1136
+ const readsProps = rule.readsProps;
1137
+ if (!isNonNull(readsProps)) return null;
1138
+ for (const propKey of readsProps) {
1139
+ const v = props[propKey];
1140
+ if (v !== void 0 && !isString(v) && !isNumber(v) && typeof v !== "boolean") return null;
1141
+ parts.push(`x:${propKey}:${String(v)}`);
1142
+ }
1143
+ }
1144
+ return parts.sort().join("|");
1145
+ }
1073
1146
  static #computePlan(inputProps, resultProps) {
1074
1147
  const removals = /* @__PURE__ */ new Set();
1075
1148
  const updates = {};
@@ -1093,12 +1166,15 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1093
1166
  return next;
1094
1167
  }
1095
1168
  validate(tag, props) {
1096
- const key = _AriaPolicyEngine.#createPlanKey(tag, props);
1169
+ const baseKey = _AriaPolicyEngine.#createPlanKey(tag, props);
1170
+ let key = baseKey;
1171
+ if (this.#extraRules.length > 0) {
1172
+ const suffix = _AriaPolicyEngine.#extraRulesKeySuffix(this.#extraRules, props);
1173
+ key = isNonNull(baseKey) && isNonNull(suffix) ? `${baseKey}|${suffix}` : null;
1174
+ }
1097
1175
  if (!isNull(key)) {
1098
1176
  const cached = this.#planCache.get(key);
1099
1177
  if (cached !== void 0) {
1100
- this.#planCache.delete(key);
1101
- this.#planCache.set(key, cached);
1102
1178
  if (cached.violations.length > 0) this.report(cached.violations);
1103
1179
  return {
1104
1180
  props: _AriaPolicyEngine.#applyPlan(props, cached.removals, cached.updates),
@@ -1115,10 +1191,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1115
1191
  );
1116
1192
  const plan = { removals, updates, violations: result.violations };
1117
1193
  this.#planCache.set(key, plan);
1118
- if (this.#planCache.size > _AriaPolicyEngine.#MAX_CACHE) {
1119
- const lru = this.#planCache.keys().next().value;
1120
- if (lru !== void 0) this.#planCache.delete(lru);
1121
- }
1122
1194
  }
1123
1195
  return result;
1124
1196
  }
@@ -1189,7 +1261,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1189
1261
  implicitRole
1190
1262
  }) {
1191
1263
  const role = props.role;
1192
- if (!implicitRole || !role || role === implicitRole) return VALID;
1264
+ if (!implicitRole || !role || role === implicitRole) return NO_VIOLATIONS;
1193
1265
  if (isStrongImplicitRole(tag) && role === "region") {
1194
1266
  return [
1195
1267
  {
@@ -1201,11 +1273,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1201
1273
  }
1202
1274
  ];
1203
1275
  }
1204
- return VALID;
1276
+ return NO_VIOLATIONS;
1205
1277
  }
1206
1278
  static #checkRedundantRole({ tag, props, implicitRole }) {
1207
1279
  const role = props.role;
1208
- if (!implicitRole || !role || role !== implicitRole) return VALID;
1280
+ if (!implicitRole || !role || role !== implicitRole) return NO_VIOLATIONS;
1209
1281
  return [
1210
1282
  {
1211
1283
  valid: false,
@@ -1218,8 +1290,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1218
1290
  }
1219
1291
  static #checkStandaloneRegion({ tag, props, implicitRole }) {
1220
1292
  const role = props.role;
1221
- if (role !== "region") return VALID;
1222
- if (!isStandaloneTag(tag)) return VALID;
1293
+ if (role !== "region") return NO_VIOLATIONS;
1294
+ if (!isStandaloneTag(tag)) return NO_VIOLATIONS;
1223
1295
  return [
1224
1296
  {
1225
1297
  valid: false,
@@ -1235,7 +1307,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1235
1307
  props,
1236
1308
  effectiveRole
1237
1309
  }) {
1238
- if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
1310
+ if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS;
1239
1311
  const results = [];
1240
1312
  iterate.forEachEntry(props, (key) => {
1241
1313
  if (!key.startsWith("aria-")) return;
@@ -1353,12 +1425,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1353
1425
  }
1354
1426
  }
1355
1427
  static #checkAriaAttributeValues({ props, effectiveRole }) {
1356
- if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
1428
+ if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS;
1357
1429
  const results = [];
1358
1430
  iterate.forEachEntry(props, (key, value) => {
1359
1431
  if (!key.startsWith("aria-")) return;
1360
1432
  const type = _AriaPolicyEngine.#ARIA_VALUE_TYPES.get(key);
1361
- if (type == null) return;
1433
+ if (!isNonNull(type)) return;
1362
1434
  if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
1363
1435
  results.push({
1364
1436
  valid: false,
@@ -1389,13 +1461,13 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1389
1461
  props,
1390
1462
  effectiveRole
1391
1463
  }) {
1392
- if (effectiveRole === "none" || effectiveRole === "presentation") return VALID;
1464
+ if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS;
1393
1465
  const implicitLevel = _AriaPolicyEngine.#HEADING_IMPLICIT_LEVELS.get(tag);
1394
- if (implicitLevel == null) return VALID;
1466
+ if (!isNonNull(implicitLevel)) return NO_VIOLATIONS;
1395
1467
  const raw = props["aria-level"];
1396
- if (raw == null) return VALID;
1468
+ if (!isNonNull(raw)) return NO_VIOLATIONS;
1397
1469
  const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
1398
- if (!Number.isFinite(n) || n !== implicitLevel) return VALID;
1470
+ if (!Number.isFinite(n) || n !== implicitLevel) return NO_VIOLATIONS;
1399
1471
  return [
1400
1472
  {
1401
1473
  valid: false,
@@ -1418,9 +1490,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1418
1490
  props,
1419
1491
  effectiveRole
1420
1492
  }) {
1421
- if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole)) return VALID;
1422
- if ("aria-label" in props || "aria-labelledby" in props) return VALID;
1423
- if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return VALID;
1493
+ if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole))
1494
+ return NO_VIOLATIONS;
1495
+ if ("aria-label" in props || "aria-labelledby" in props) return NO_VIOLATIONS;
1496
+ if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS;
1424
1497
  return [
1425
1498
  {
1426
1499
  valid: false,
@@ -1443,9 +1516,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1443
1516
  props,
1444
1517
  effectiveRole
1445
1518
  }) {
1446
- if (!effectiveRole) return VALID;
1519
+ if (!effectiveRole) return NO_VIOLATIONS;
1447
1520
  const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
1448
- if (required == null) return VALID;
1521
+ if (!isNonNull(required)) return NO_VIOLATIONS;
1449
1522
  const results = [];
1450
1523
  iterate.forEach(required, (attr) => {
1451
1524
  if (attr in props) return;
@@ -1469,12 +1542,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1469
1542
  ]);
1470
1543
  // WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
1471
1544
  static #checkAriaHiddenOnFocusable({ tag, props }) {
1472
- if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return VALID;
1545
+ if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return NO_VIOLATIONS;
1473
1546
  const isInteractive = _AriaPolicyEngine.#INTERACTIVE_TAGS.has(tag);
1474
1547
  if (!isInteractive) {
1475
1548
  const tabindex = props.tabindex;
1476
1549
  const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
1477
- if (!Number.isFinite(n) || n < 0) return VALID;
1550
+ if (!Number.isFinite(n) || n < 0) return NO_VIOLATIONS;
1478
1551
  }
1479
1552
  return [
1480
1553
  {
@@ -1493,7 +1566,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1493
1566
  props,
1494
1567
  effectiveRole
1495
1568
  }) {
1496
- if (effectiveRole !== "none" && effectiveRole !== "presentation") return VALID;
1569
+ if (effectiveRole !== "none" && effectiveRole !== "presentation") return NO_VIOLATIONS;
1497
1570
  const results = [];
1498
1571
  iterate.forEachEntry(props, (key) => {
1499
1572
  if (!key.startsWith("aria-")) return;
@@ -1517,10 +1590,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1517
1590
  ["timer", "off"]
1518
1591
  ]);
1519
1592
  static #checkMissingLiveRegion({ effectiveRole, props }) {
1520
- if (!effectiveRole) return VALID;
1593
+ if (!effectiveRole) return NO_VIOLATIONS;
1521
1594
  const impliedLive = _AriaPolicyEngine.#LIVE_REGION_ROLES.get(effectiveRole);
1522
- if (!impliedLive) return VALID;
1523
- if ("aria-live" in props) return VALID;
1595
+ if (!impliedLive) return NO_VIOLATIONS;
1596
+ if ("aria-live" in props) return NO_VIOLATIONS;
1524
1597
  const injectLive = {
1525
1598
  kind: `injectLive:${effectiveRole}`,
1526
1599
  apply: (ctx) => ({
@@ -1540,8 +1613,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1540
1613
  ];
1541
1614
  }
1542
1615
  static #checkMissingAtomic({ effectiveRole, props }) {
1543
- if (!effectiveRole || !_AriaPolicyEngine.#LIVE_REGION_ROLES.has(effectiveRole)) return VALID;
1544
- if ("aria-atomic" in props) return VALID;
1616
+ if (!effectiveRole || !_AriaPolicyEngine.#LIVE_REGION_ROLES.has(effectiveRole))
1617
+ return NO_VIOLATIONS;
1618
+ if ("aria-atomic" in props) return NO_VIOLATIONS;
1545
1619
  return [
1546
1620
  {
1547
1621
  valid: false,
@@ -1565,8 +1639,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1565
1639
  };
1566
1640
  static #checkInvalidAriaRelevant({ props }) {
1567
1641
  const relevant = props["aria-relevant"];
1568
- if (relevant === void 0) return VALID;
1569
- if (typeof relevant !== "string") return VALID;
1642
+ if (relevant === void 0) return NO_VIOLATIONS;
1643
+ if (typeof relevant !== "string") return NO_VIOLATIONS;
1570
1644
  const tokens = relevant.trim().split(/\s+/);
1571
1645
  const invalid = tokens.filter((t) => !_AriaPolicyEngine.#VALID_RELEVANT_TOKENS.has(t));
1572
1646
  if (invalid.length > 0) {
@@ -1593,7 +1667,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
1593
1667
  }
1594
1668
  ];
1595
1669
  }
1596
- return VALID;
1670
+ return NO_VIOLATIONS;
1597
1671
  }
1598
1672
  };
1599
1673
 
@@ -2193,7 +2267,7 @@ function cva2(base, config) {
2193
2267
  // ../../lib/styling/src/static-class-resolver.ts
2194
2268
  var StaticClassResolver = class {
2195
2269
  #baseClass;
2196
- #cache = /* @__PURE__ */ new Map();
2270
+ #cache = new LRUCache(200);
2197
2271
  #resolveTag;
2198
2272
  constructor(baseClass, tagMap) {
2199
2273
  this.#baseClass = Array.isArray(baseClass) ? baseClass.join(" ") : baseClass;
@@ -2207,17 +2281,9 @@ var StaticClassResolver = class {
2207
2281
  resolve(tag, skipTagMap = false) {
2208
2282
  if (typeof tag !== "string" || skipTagMap) return this.#baseClass;
2209
2283
  const cached = this.#cache.get(tag);
2210
- if (cached !== void 0) {
2211
- this.#cache.delete(tag);
2212
- this.#cache.set(tag, cached);
2213
- return cached;
2214
- }
2284
+ if (cached !== void 0) return cached;
2215
2285
  const result = this.#resolveTag(tag);
2216
2286
  this.#cache.set(tag, result);
2217
- if (this.#cache.size > 200) {
2218
- const lru = this.#cache.keys().next().value;
2219
- if (lru !== void 0) this.#cache.delete(lru);
2220
- }
2221
2287
  return result;
2222
2288
  }
2223
2289
  };
@@ -2228,7 +2294,7 @@ var VariantClassResolver = class _VariantClassResolver {
2228
2294
  #recipeMap;
2229
2295
  #variantKeys;
2230
2296
  #precomputedClasses;
2231
- #cache = /* @__PURE__ */ new Map();
2297
+ #cache = new LRUCache(1e3);
2232
2298
  constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
2233
2299
  this.#cvaFn = cvaFn ?? null;
2234
2300
  this.#recipeMap = Object.freeze(recipeMap ?? {});
@@ -2243,17 +2309,9 @@ var VariantClassResolver = class _VariantClassResolver {
2243
2309
  if (precomputed !== void 0) return precomputed;
2244
2310
  }
2245
2311
  const cached = this.#cache.get(cacheKey);
2246
- if (cached !== void 0) {
2247
- this.#cache.delete(cacheKey);
2248
- this.#cache.set(cacheKey, cached);
2249
- return cached;
2250
- }
2312
+ if (cached !== void 0) return cached;
2251
2313
  const result = this.#compute(props, recipe);
2252
2314
  this.#cache.set(cacheKey, result);
2253
- if (this.#cache.size > 1e3) {
2254
- const lru = this.#cache.keys().next().value;
2255
- if (lru !== void 0) this.#cache.delete(lru);
2256
- }
2257
2315
  return result;
2258
2316
  }
2259
2317
  #compute(props, recipe) {
@@ -2310,7 +2368,7 @@ function createClassPipeline(resolved) {
2310
2368
  const staticClasses = staticResolver.resolve(tag, recipe !== void 0);
2311
2369
  const variantClasses = variantResolver.resolve({ props, recipe });
2312
2370
  if (!className)
2313
- return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
2371
+ return (staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses) || void 0;
2314
2372
  return cn(staticClasses, variantClasses, className);
2315
2373
  };
2316
2374
  }
@@ -2521,7 +2579,7 @@ function createPolymorphic2(options = {}) {
2521
2579
  if (process.env.NODE_ENV !== "production") {
2522
2580
  validateRenderProps(resolved.diagnostics, resolved, props, recipe);
2523
2581
  }
2524
- return classPipeline(tag, props, className, recipe);
2582
+ return classPipeline(tag, props, className, recipe) || void 0;
2525
2583
  },
2526
2584
  resolveAria(tag, props) {
2527
2585
  return resolveAriaFn(tag, props);
@@ -84,7 +84,7 @@ interface BaseClassOptions {
84
84
  baseClassName?: ClassName;
85
85
  }
86
86
 
87
- type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string;
87
+ type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string | undefined;
88
88
 
89
89
  interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
90
90
  recipeMap?: Record<string, RecipeTarget<TVariants>>;
@@ -1,4 +1,4 @@
1
- // ../../lib/primitive/src/utils/is-object.ts
1
+ // ../../lib/primitive/src/utils/type-guards.ts
2
2
  function isString(value) {
3
3
  return typeof value === "string";
4
4
  }
@@ -184,6 +184,45 @@ var iterate = Object.freeze({
184
184
  values
185
185
  });
186
186
 
187
+ // ../../lib/primitive/src/utils/lru-cache.ts
188
+ var LRUCache = class {
189
+ #maxSize;
190
+ #store = /* @__PURE__ */ new Map();
191
+ constructor(maxSize) {
192
+ if (!Number.isInteger(maxSize) || maxSize < 1) {
193
+ throw new RangeError("LRUCache maxSize must be a positive integer.");
194
+ }
195
+ this.#maxSize = maxSize;
196
+ }
197
+ get(key) {
198
+ if (!this.#store.has(key)) return void 0;
199
+ const value = this.#store.get(key);
200
+ this.#store.delete(key);
201
+ this.#store.set(key, value);
202
+ return value;
203
+ }
204
+ set(key, value) {
205
+ this.#store.delete(key);
206
+ this.#store.set(key, value);
207
+ if (this.#store.size > this.#maxSize) {
208
+ const lru = this.#store.keys().next().value;
209
+ if (lru !== void 0) this.#store.delete(lru);
210
+ }
211
+ }
212
+ has(key) {
213
+ return this.#store.has(key);
214
+ }
215
+ delete(key) {
216
+ return this.#store.delete(key);
217
+ }
218
+ get size() {
219
+ return this.#store.size;
220
+ }
221
+ clear() {
222
+ this.#store.clear();
223
+ }
224
+ };
225
+
187
226
  // ../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.mjs
188
227
  import { clsx as clsx2 } from "clsx";
189
228
  var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
@@ -236,7 +275,7 @@ function cva2(base, config) {
236
275
  // ../../lib/styling/src/static-class-resolver.ts
237
276
  var StaticClassResolver = class {
238
277
  #baseClass;
239
- #cache = /* @__PURE__ */ new Map();
278
+ #cache = new LRUCache(200);
240
279
  #resolveTag;
241
280
  constructor(baseClass, tagMap) {
242
281
  this.#baseClass = Array.isArray(baseClass) ? baseClass.join(" ") : baseClass;
@@ -250,17 +289,9 @@ var StaticClassResolver = class {
250
289
  resolve(tag, skipTagMap = false) {
251
290
  if (typeof tag !== "string" || skipTagMap) return this.#baseClass;
252
291
  const cached = this.#cache.get(tag);
253
- if (cached !== void 0) {
254
- this.#cache.delete(tag);
255
- this.#cache.set(tag, cached);
256
- return cached;
257
- }
292
+ if (cached !== void 0) return cached;
258
293
  const result = this.#resolveTag(tag);
259
294
  this.#cache.set(tag, result);
260
- if (this.#cache.size > 200) {
261
- const lru = this.#cache.keys().next().value;
262
- if (lru !== void 0) this.#cache.delete(lru);
263
- }
264
295
  return result;
265
296
  }
266
297
  };
@@ -271,7 +302,7 @@ var VariantClassResolver = class _VariantClassResolver {
271
302
  #recipeMap;
272
303
  #variantKeys;
273
304
  #precomputedClasses;
274
- #cache = /* @__PURE__ */ new Map();
305
+ #cache = new LRUCache(1e3);
275
306
  constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
276
307
  this.#cvaFn = cvaFn ?? null;
277
308
  this.#recipeMap = Object.freeze(recipeMap ?? {});
@@ -286,17 +317,9 @@ var VariantClassResolver = class _VariantClassResolver {
286
317
  if (precomputed !== void 0) return precomputed;
287
318
  }
288
319
  const cached = this.#cache.get(cacheKey);
289
- if (cached !== void 0) {
290
- this.#cache.delete(cacheKey);
291
- this.#cache.set(cacheKey, cached);
292
- return cached;
293
- }
320
+ if (cached !== void 0) return cached;
294
321
  const result = this.#compute(props, recipe);
295
322
  this.#cache.set(cacheKey, result);
296
- if (this.#cache.size > 1e3) {
297
- const lru = this.#cache.keys().next().value;
298
- if (lru !== void 0) this.#cache.delete(lru);
299
- }
300
323
  return result;
301
324
  }
302
325
  #compute(props, recipe) {
@@ -353,7 +376,7 @@ function createClassPipeline(resolved) {
353
376
  const staticClasses = staticResolver.resolve(tag, recipe !== void 0);
354
377
  const variantClasses = variantResolver.resolve({ props, recipe });
355
378
  if (!className)
356
- return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
379
+ return (staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses) || void 0;
357
380
  return cn(staticClasses, variantClasses, className);
358
381
  };
359
382
  }
@@ -678,7 +701,7 @@ function createTailwindPipeline(options, diagnostics) {
678
701
  const compoundDims = compoundDimensions(getCompoundVariants(options));
679
702
  const resolveLayoutContext = (tag, props, className, recipe) => {
680
703
  const mode = resolveLayout(devDiagnostics, props);
681
- const resolvedClasses = innerPipeline(tag, props, className, recipe);
704
+ const resolvedClasses = innerPipeline(tag, props, className, recipe) ?? "";
682
705
  const tokens = classifyTokens(resolvedClasses);
683
706
  const state = new LayoutState(mode);
684
707
  const filtered = tokens.filter((token) => evaluator.evaluate(token, state));