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.
- package/dist/{chunk-P5ZJBPAR.js → chunk-OGQ7QKKP.js} +184 -116
- package/dist/contract/index.d.ts +4 -2
- package/dist/eslint/index.js +1 -1
- package/dist/guards/index.d.ts +36 -0
- package/dist/guards/index.js +62 -0
- package/dist/lit/index.d.ts +4 -2
- package/dist/lit/index.js +166 -104
- package/dist/preact/index.d.ts +4 -2
- package/dist/preact/index.js +180 -124
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/dist/react/legacy.d.ts +2 -2
- package/dist/react/legacy.js +1 -1
- package/dist/{react-options-AitAOrje.d.ts → react-options-CjiWrT4q.d.ts} +4 -2
- package/dist/solid/index.d.ts +4 -2
- package/dist/solid/index.js +171 -113
- package/dist/svelte/Polymorphic.svelte +2 -2
- package/dist/svelte/index.d.ts +5 -3
- package/dist/svelte/index.js +161 -103
- package/dist/tailwind/index.d.ts +1 -1
- package/dist/tailwind/index.js +46 -23
- package/dist/vite-plugin/index.js +14 -2
- package/dist/vue/index.d.ts +4 -2
- package/dist/vue/index.js +179 -115
- package/dist/web/index.d.ts +4 -2
- package/dist/web/index.js +166 -104
- package/package.json +12 -5
|
@@ -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/
|
|
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;
|
|
@@ -24,16 +27,11 @@ function isString(value) {
|
|
|
24
27
|
function isNumber(value) {
|
|
25
28
|
return typeof value === "number";
|
|
26
29
|
}
|
|
27
|
-
|
|
28
|
-
// ../../lib/primitive/src/merge/constants.ts
|
|
29
|
-
var EVENT_HANDLER_RE = /^on[A-Z]/;
|
|
30
|
-
|
|
31
|
-
// ../../lib/primitive/src/merge/predicates.ts
|
|
32
30
|
function isFunction(value) {
|
|
33
31
|
return typeof value === "function";
|
|
34
32
|
}
|
|
35
33
|
function isPlainObject(value) {
|
|
36
|
-
if (!isObject(value)) return false;
|
|
34
|
+
if (!isObject(value, true)) return false;
|
|
37
35
|
const proto = Object.getPrototypeOf(value);
|
|
38
36
|
return proto === Object.prototype || proto === null;
|
|
39
37
|
}
|
|
@@ -420,6 +418,9 @@ function makeResolveTag(defaultTag) {
|
|
|
420
418
|
};
|
|
421
419
|
}
|
|
422
420
|
|
|
421
|
+
// ../../lib/primitive/src/merge/constants.ts
|
|
422
|
+
var EVENT_HANDLER_RE = /^on[A-Z]/;
|
|
423
|
+
|
|
423
424
|
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
424
425
|
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
425
426
|
|
|
@@ -614,14 +615,66 @@ var iterate = Object.freeze({
|
|
|
614
615
|
values
|
|
615
616
|
});
|
|
616
617
|
|
|
618
|
+
// ../../lib/primitive/src/utils/lazy.ts
|
|
619
|
+
function lazy(factory) {
|
|
620
|
+
let initialized = false;
|
|
621
|
+
let value;
|
|
622
|
+
return () => {
|
|
623
|
+
if (!initialized) {
|
|
624
|
+
value = factory();
|
|
625
|
+
initialized = true;
|
|
626
|
+
}
|
|
627
|
+
return value;
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// ../../lib/primitive/src/utils/lru-cache.ts
|
|
632
|
+
var LRUCache = class {
|
|
633
|
+
#maxSize;
|
|
634
|
+
#store = /* @__PURE__ */ new Map();
|
|
635
|
+
constructor(maxSize) {
|
|
636
|
+
if (!Number.isInteger(maxSize) || maxSize < 1) {
|
|
637
|
+
throw new RangeError("LRUCache maxSize must be a positive integer.");
|
|
638
|
+
}
|
|
639
|
+
this.#maxSize = maxSize;
|
|
640
|
+
}
|
|
641
|
+
get(key) {
|
|
642
|
+
if (!this.#store.has(key)) return void 0;
|
|
643
|
+
const value = this.#store.get(key);
|
|
644
|
+
this.#store.delete(key);
|
|
645
|
+
this.#store.set(key, value);
|
|
646
|
+
return value;
|
|
647
|
+
}
|
|
648
|
+
set(key, value) {
|
|
649
|
+
this.#store.delete(key);
|
|
650
|
+
this.#store.set(key, value);
|
|
651
|
+
if (this.#store.size > this.#maxSize) {
|
|
652
|
+
const lru = this.#store.keys().next().value;
|
|
653
|
+
if (lru !== void 0) this.#store.delete(lru);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
has(key) {
|
|
657
|
+
return this.#store.has(key);
|
|
658
|
+
}
|
|
659
|
+
delete(key) {
|
|
660
|
+
return this.#store.delete(key);
|
|
661
|
+
}
|
|
662
|
+
get size() {
|
|
663
|
+
return this.#store.size;
|
|
664
|
+
}
|
|
665
|
+
clear() {
|
|
666
|
+
this.#store.clear();
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
|
|
617
670
|
// ../../lib/primitive/src/utils/merge-refs.ts
|
|
618
671
|
function mergeRefsCore(...refs) {
|
|
619
|
-
const
|
|
620
|
-
if (
|
|
621
|
-
if (
|
|
672
|
+
const resolvedRefs = refs.filter((r) => r != null);
|
|
673
|
+
if (resolvedRefs.length === 0) return null;
|
|
674
|
+
if (resolvedRefs.length === 1) return resolvedRefs[0] ?? null;
|
|
622
675
|
return (value) => {
|
|
623
|
-
iterate.forEach(
|
|
624
|
-
if (
|
|
676
|
+
iterate.forEach(resolvedRefs, (ref) => {
|
|
677
|
+
if (isFunction(ref)) {
|
|
625
678
|
ref(value);
|
|
626
679
|
} else {
|
|
627
680
|
ref.current = value;
|
|
@@ -675,28 +728,6 @@ function isTag(...args) {
|
|
|
675
728
|
return tag !== void 0 && set2.has(tag);
|
|
676
729
|
}
|
|
677
730
|
|
|
678
|
-
// ../../lib/contract/src/strict/invariant-base.ts
|
|
679
|
-
var InvariantBase = class {
|
|
680
|
-
diagnostics;
|
|
681
|
-
constructor(diagnostics) {
|
|
682
|
-
this.diagnostics = diagnostics;
|
|
683
|
-
}
|
|
684
|
-
get active() {
|
|
685
|
-
return this.diagnostics.active;
|
|
686
|
-
}
|
|
687
|
-
violate(input) {
|
|
688
|
-
this.diagnostics.error(input);
|
|
689
|
-
}
|
|
690
|
-
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
691
|
-
// so they surface even in strict='throw' mode without aborting a render.
|
|
692
|
-
warn(input) {
|
|
693
|
-
this.diagnostics.warn(input);
|
|
694
|
-
}
|
|
695
|
-
invariant(condition, input) {
|
|
696
|
-
if (!condition) this.violate(input);
|
|
697
|
-
}
|
|
698
|
-
};
|
|
699
|
-
|
|
700
731
|
// ../../lib/contract/src/diagnostics/aria.ts
|
|
701
732
|
import { DiagnosticCategory, DiagnosticCode } from "./_shared/diagnostics.js";
|
|
702
733
|
var AriaDiagnostics = {
|
|
@@ -1053,8 +1084,30 @@ var SlotDiagnostics = {
|
|
|
1053
1084
|
}
|
|
1054
1085
|
};
|
|
1055
1086
|
|
|
1087
|
+
// ../../lib/contract/src/strict/invariant-base.ts
|
|
1088
|
+
var InvariantBase = class {
|
|
1089
|
+
diagnostics;
|
|
1090
|
+
constructor(diagnostics) {
|
|
1091
|
+
this.diagnostics = diagnostics;
|
|
1092
|
+
}
|
|
1093
|
+
get active() {
|
|
1094
|
+
return this.diagnostics.active;
|
|
1095
|
+
}
|
|
1096
|
+
violate(input) {
|
|
1097
|
+
this.diagnostics.error(input);
|
|
1098
|
+
}
|
|
1099
|
+
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
1100
|
+
// so they surface even in strict='throw' mode without aborting a render.
|
|
1101
|
+
warn(input) {
|
|
1102
|
+
this.diagnostics.warn(input);
|
|
1103
|
+
}
|
|
1104
|
+
invariant(condition, input) {
|
|
1105
|
+
if (!condition) this.violate(input);
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1056
1109
|
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
1057
|
-
var
|
|
1110
|
+
var NO_VIOLATIONS = [{ valid: true }];
|
|
1058
1111
|
function isIntrinsicTag(tag) {
|
|
1059
1112
|
return isString(tag);
|
|
1060
1113
|
}
|
|
@@ -1064,8 +1117,7 @@ function omitProp(obj, key) {
|
|
|
1064
1117
|
}
|
|
1065
1118
|
var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
1066
1119
|
#extraRules;
|
|
1067
|
-
#planCache =
|
|
1068
|
-
static #MAX_CACHE = 100;
|
|
1120
|
+
#planCache = new LRUCache(100);
|
|
1069
1121
|
// Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
|
|
1070
1122
|
// finite so this Map is bounded and avoids recreating closures on every cache miss.
|
|
1071
1123
|
static #removeAttributeFixCache = /* @__PURE__ */ new Map();
|
|
@@ -1097,17 +1149,20 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1097
1149
|
static #deriveContext(tag, props) {
|
|
1098
1150
|
if (!isIntrinsicTag(tag)) return { proceed: false, result: { props, violations: [] } };
|
|
1099
1151
|
const implicitRole = getImplicitRole(tag, props);
|
|
1100
|
-
const hasRole2 = implicitRole
|
|
1152
|
+
const hasRole2 = isNonNull(implicitRole) || isString(props.role) && props.role.length > 0;
|
|
1101
1153
|
if (!hasRole2) return { proceed: false, result: { props, violations: [] } };
|
|
1102
1154
|
const normalized = _AriaPolicyEngine.#normalizeEmptyRole(tag, props);
|
|
1103
|
-
|
|
1104
|
-
const
|
|
1155
|
+
const workingProps = normalized.normalized ? normalized.result.props : props;
|
|
1156
|
+
const preExistingViolations = normalized.normalized ? normalized.result.violations : [];
|
|
1157
|
+
const effectiveRole = workingProps.role ?? implicitRole;
|
|
1105
1158
|
return {
|
|
1106
1159
|
proceed: true,
|
|
1107
1160
|
tag,
|
|
1108
1161
|
implicitRole,
|
|
1109
1162
|
effectiveRole,
|
|
1110
|
-
|
|
1163
|
+
props: workingProps,
|
|
1164
|
+
preExistingViolations,
|
|
1165
|
+
context: { tag, props: workingProps, implicitRole, effectiveRole }
|
|
1111
1166
|
};
|
|
1112
1167
|
}
|
|
1113
1168
|
static #runRules(rules, context) {
|
|
@@ -1122,7 +1177,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1122
1177
|
} = context;
|
|
1123
1178
|
const { message, attribute, severity } = result;
|
|
1124
1179
|
const resolvedMessage = message ?? result.diagnostic?.message;
|
|
1125
|
-
const fallbackDiag = resolvedMessage
|
|
1180
|
+
const fallbackDiag = isNonNull(resolvedMessage) ? void 0 : AriaDiagnostics.invalidRole(role, tag);
|
|
1126
1181
|
violations.push({
|
|
1127
1182
|
message: resolvedMessage ?? fallbackDiag.message,
|
|
1128
1183
|
tag,
|
|
@@ -1130,8 +1185,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1130
1185
|
attribute,
|
|
1131
1186
|
severity,
|
|
1132
1187
|
phase: "evaluate",
|
|
1133
|
-
...result.diagnostic
|
|
1134
|
-
...fallbackDiag
|
|
1188
|
+
...isNonNull(result.diagnostic) && { diagnostic: result.diagnostic },
|
|
1189
|
+
...isNonNull(fallbackDiag) && { diagnostic: fallbackDiag }
|
|
1135
1190
|
});
|
|
1136
1191
|
if (result.fixable) fixes.push(result.fix);
|
|
1137
1192
|
});
|
|
@@ -1139,7 +1194,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1139
1194
|
return { violations, fixes };
|
|
1140
1195
|
}
|
|
1141
1196
|
static #getRules(context) {
|
|
1142
|
-
if (_AriaPolicyEngine.#hasRole(context.props) || context.effectiveRole
|
|
1197
|
+
if (_AriaPolicyEngine.#hasRole(context.props) || isNonNull(context.effectiveRole) && _AriaPolicyEngine.#LIVE_REGION_ROLES.has(context.effectiveRole)) {
|
|
1143
1198
|
return _AriaPolicyEngine.#pipeline;
|
|
1144
1199
|
}
|
|
1145
1200
|
return _AriaPolicyEngine.#implicitOnlyRules;
|
|
@@ -1147,24 +1202,36 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1147
1202
|
static evaluate(tag, props) {
|
|
1148
1203
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
1149
1204
|
if (!derived.proceed) return derived.result;
|
|
1150
|
-
const {
|
|
1205
|
+
const {
|
|
1206
|
+
tag: narrowedTag,
|
|
1207
|
+
implicitRole,
|
|
1208
|
+
context,
|
|
1209
|
+
props: workingProps,
|
|
1210
|
+
preExistingViolations
|
|
1211
|
+
} = derived;
|
|
1151
1212
|
const { violations, fixes } = _AriaPolicyEngine.#runRules(
|
|
1152
1213
|
_AriaPolicyEngine.#getRules(context),
|
|
1153
1214
|
context
|
|
1154
1215
|
);
|
|
1155
|
-
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole,
|
|
1156
|
-
return { props: next, violations };
|
|
1216
|
+
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
|
|
1217
|
+
return { props: next, violations: [...preExistingViolations, ...violations] };
|
|
1157
1218
|
}
|
|
1158
1219
|
static #evaluateWithRules(tag, props, extraRules) {
|
|
1159
1220
|
const derived = _AriaPolicyEngine.#deriveContext(tag, props);
|
|
1160
1221
|
if (!derived.proceed) return derived.result;
|
|
1161
|
-
const {
|
|
1222
|
+
const {
|
|
1223
|
+
tag: narrowedTag,
|
|
1224
|
+
implicitRole,
|
|
1225
|
+
context,
|
|
1226
|
+
props: workingProps,
|
|
1227
|
+
preExistingViolations
|
|
1228
|
+
} = derived;
|
|
1162
1229
|
const { violations, fixes } = _AriaPolicyEngine.#runRules(
|
|
1163
1230
|
[..._AriaPolicyEngine.#getRules(context), ...extraRules],
|
|
1164
1231
|
context
|
|
1165
1232
|
);
|
|
1166
|
-
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole,
|
|
1167
|
-
return { props: next, violations };
|
|
1233
|
+
const next = _AriaPolicyEngine.#applyFixes(narrowedTag, implicitRole, workingProps, fixes);
|
|
1234
|
+
return { props: next, violations: [...preExistingViolations, ...violations] };
|
|
1168
1235
|
}
|
|
1169
1236
|
report(violations) {
|
|
1170
1237
|
iterate.forEach(violations, (v) => {
|
|
@@ -1173,12 +1240,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1173
1240
|
else this.warn(d);
|
|
1174
1241
|
});
|
|
1175
1242
|
}
|
|
1176
|
-
// Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs)
|
|
1177
|
-
// Non-aria props (className, onClick, etc.) do
|
|
1178
|
-
// so cache hits survive re-renders
|
|
1179
|
-
//
|
|
1180
|
-
//
|
|
1181
|
-
//
|
|
1243
|
+
// Cache key covers only the aria-relevant subset of props (tag + role + aria-* attrs) —
|
|
1244
|
+
// exactly what the built-in pipeline reads. Non-aria props (className, onClick, etc.) do
|
|
1245
|
+
// not affect built-in ARIA decisions and are excluded so cache hits survive re-renders
|
|
1246
|
+
// that only change non-aria props. This key alone is unsound for #extraRules, which may
|
|
1247
|
+
// read arbitrary props outside this set — validate() extends it with #extraRulesKeySuffix,
|
|
1248
|
+
// or bypasses the cache, to account for that.
|
|
1182
1249
|
static #createPlanKey(tag, props) {
|
|
1183
1250
|
if (!isIntrinsicTag(tag)) return null;
|
|
1184
1251
|
const parts = [tag];
|
|
@@ -1194,6 +1261,23 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1194
1261
|
if (ariaEntries.length > 0) parts.push(...ariaEntries.sort());
|
|
1195
1262
|
return parts.join("|");
|
|
1196
1263
|
}
|
|
1264
|
+
// Extends the base cache key with the props each extra rule declares it reads (`readsProps`).
|
|
1265
|
+
// Returns null — meaning "don't cache" — if any extra rule omits `readsProps` (it may read
|
|
1266
|
+
// arbitrary props the key can't account for) or if a declared prop's value isn't a primitive
|
|
1267
|
+
// (object/array identity isn't stably representable in a string key).
|
|
1268
|
+
static #extraRulesKeySuffix(extraRules, props) {
|
|
1269
|
+
const parts = [];
|
|
1270
|
+
for (const rule of extraRules) {
|
|
1271
|
+
const readsProps = rule.readsProps;
|
|
1272
|
+
if (!isNonNull(readsProps)) return null;
|
|
1273
|
+
for (const propKey of readsProps) {
|
|
1274
|
+
const v = props[propKey];
|
|
1275
|
+
if (v !== void 0 && !isString(v) && !isNumber(v) && typeof v !== "boolean") return null;
|
|
1276
|
+
parts.push(`x:${propKey}:${String(v)}`);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
return parts.sort().join("|");
|
|
1280
|
+
}
|
|
1197
1281
|
static #computePlan(inputProps, resultProps) {
|
|
1198
1282
|
const removals = /* @__PURE__ */ new Set();
|
|
1199
1283
|
const updates = {};
|
|
@@ -1217,12 +1301,15 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1217
1301
|
return next;
|
|
1218
1302
|
}
|
|
1219
1303
|
validate(tag, props) {
|
|
1220
|
-
const
|
|
1304
|
+
const baseKey = _AriaPolicyEngine.#createPlanKey(tag, props);
|
|
1305
|
+
let key = baseKey;
|
|
1306
|
+
if (this.#extraRules.length > 0) {
|
|
1307
|
+
const suffix = _AriaPolicyEngine.#extraRulesKeySuffix(this.#extraRules, props);
|
|
1308
|
+
key = isNonNull(baseKey) && isNonNull(suffix) ? `${baseKey}|${suffix}` : null;
|
|
1309
|
+
}
|
|
1221
1310
|
if (!isNull(key)) {
|
|
1222
1311
|
const cached = this.#planCache.get(key);
|
|
1223
1312
|
if (cached !== void 0) {
|
|
1224
|
-
this.#planCache.delete(key);
|
|
1225
|
-
this.#planCache.set(key, cached);
|
|
1226
1313
|
if (cached.violations.length > 0) this.report(cached.violations);
|
|
1227
1314
|
return {
|
|
1228
1315
|
props: _AriaPolicyEngine.#applyPlan(props, cached.removals, cached.updates),
|
|
@@ -1239,10 +1326,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1239
1326
|
);
|
|
1240
1327
|
const plan = { removals, updates, violations: result.violations };
|
|
1241
1328
|
this.#planCache.set(key, plan);
|
|
1242
|
-
if (this.#planCache.size > _AriaPolicyEngine.#MAX_CACHE) {
|
|
1243
|
-
const lru = this.#planCache.keys().next().value;
|
|
1244
|
-
if (lru !== void 0) this.#planCache.delete(lru);
|
|
1245
|
-
}
|
|
1246
1329
|
}
|
|
1247
1330
|
return result;
|
|
1248
1331
|
}
|
|
@@ -1313,7 +1396,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1313
1396
|
implicitRole
|
|
1314
1397
|
}) {
|
|
1315
1398
|
const role = props.role;
|
|
1316
|
-
if (!implicitRole || !role || role === implicitRole) return
|
|
1399
|
+
if (!implicitRole || !role || role === implicitRole) return NO_VIOLATIONS;
|
|
1317
1400
|
if (isStrongImplicitRole(tag) && role === "region") {
|
|
1318
1401
|
return [
|
|
1319
1402
|
{
|
|
@@ -1325,11 +1408,11 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1325
1408
|
}
|
|
1326
1409
|
];
|
|
1327
1410
|
}
|
|
1328
|
-
return
|
|
1411
|
+
return NO_VIOLATIONS;
|
|
1329
1412
|
}
|
|
1330
1413
|
static #checkRedundantRole({ tag, props, implicitRole }) {
|
|
1331
1414
|
const role = props.role;
|
|
1332
|
-
if (!implicitRole || !role || role !== implicitRole) return
|
|
1415
|
+
if (!implicitRole || !role || role !== implicitRole) return NO_VIOLATIONS;
|
|
1333
1416
|
return [
|
|
1334
1417
|
{
|
|
1335
1418
|
valid: false,
|
|
@@ -1342,8 +1425,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1342
1425
|
}
|
|
1343
1426
|
static #checkStandaloneRegion({ tag, props, implicitRole }) {
|
|
1344
1427
|
const role = props.role;
|
|
1345
|
-
if (role !== "region") return
|
|
1346
|
-
if (!isStandaloneTag(tag)) return
|
|
1428
|
+
if (role !== "region") return NO_VIOLATIONS;
|
|
1429
|
+
if (!isStandaloneTag(tag)) return NO_VIOLATIONS;
|
|
1347
1430
|
return [
|
|
1348
1431
|
{
|
|
1349
1432
|
valid: false,
|
|
@@ -1359,7 +1442,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1359
1442
|
props,
|
|
1360
1443
|
effectiveRole
|
|
1361
1444
|
}) {
|
|
1362
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1445
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS;
|
|
1363
1446
|
const results = [];
|
|
1364
1447
|
iterate.forEachEntry(props, (key) => {
|
|
1365
1448
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1477,12 +1560,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1477
1560
|
}
|
|
1478
1561
|
}
|
|
1479
1562
|
static #checkAriaAttributeValues({ props, effectiveRole }) {
|
|
1480
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1563
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS;
|
|
1481
1564
|
const results = [];
|
|
1482
1565
|
iterate.forEachEntry(props, (key, value) => {
|
|
1483
1566
|
if (!key.startsWith("aria-")) return;
|
|
1484
1567
|
const type = _AriaPolicyEngine.#ARIA_VALUE_TYPES.get(key);
|
|
1485
|
-
if (type
|
|
1568
|
+
if (!isNonNull(type)) return;
|
|
1486
1569
|
if (_AriaPolicyEngine.#isValidAriaValue(value, type)) return;
|
|
1487
1570
|
results.push({
|
|
1488
1571
|
valid: false,
|
|
@@ -1513,13 +1596,13 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1513
1596
|
props,
|
|
1514
1597
|
effectiveRole
|
|
1515
1598
|
}) {
|
|
1516
|
-
if (effectiveRole === "none" || effectiveRole === "presentation") return
|
|
1599
|
+
if (effectiveRole === "none" || effectiveRole === "presentation") return NO_VIOLATIONS;
|
|
1517
1600
|
const implicitLevel = _AriaPolicyEngine.#HEADING_IMPLICIT_LEVELS.get(tag);
|
|
1518
|
-
if (implicitLevel
|
|
1601
|
+
if (!isNonNull(implicitLevel)) return NO_VIOLATIONS;
|
|
1519
1602
|
const raw = props["aria-level"];
|
|
1520
|
-
if (raw
|
|
1603
|
+
if (!isNonNull(raw)) return NO_VIOLATIONS;
|
|
1521
1604
|
const n = typeof raw === "number" ? raw : typeof raw === "string" ? parseInt(raw, 10) : NaN;
|
|
1522
|
-
if (!Number.isFinite(n) || n !== implicitLevel) return
|
|
1605
|
+
if (!Number.isFinite(n) || n !== implicitLevel) return NO_VIOLATIONS;
|
|
1523
1606
|
return [
|
|
1524
1607
|
{
|
|
1525
1608
|
valid: false,
|
|
@@ -1542,9 +1625,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1542
1625
|
props,
|
|
1543
1626
|
effectiveRole
|
|
1544
1627
|
}) {
|
|
1545
|
-
if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole))
|
|
1546
|
-
|
|
1547
|
-
if (
|
|
1628
|
+
if (!effectiveRole || !_AriaPolicyEngine.#NAME_REQUIRED_ROLES.has(effectiveRole))
|
|
1629
|
+
return NO_VIOLATIONS;
|
|
1630
|
+
if ("aria-label" in props || "aria-labelledby" in props) return NO_VIOLATIONS;
|
|
1631
|
+
if (tag === "img" && typeof props.alt === "string" && props.alt.length > 0) return NO_VIOLATIONS;
|
|
1548
1632
|
return [
|
|
1549
1633
|
{
|
|
1550
1634
|
valid: false,
|
|
@@ -1567,9 +1651,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1567
1651
|
props,
|
|
1568
1652
|
effectiveRole
|
|
1569
1653
|
}) {
|
|
1570
|
-
if (!effectiveRole) return
|
|
1654
|
+
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1571
1655
|
const required = _AriaPolicyEngine.#REQUIRED_PROPERTIES.get(effectiveRole);
|
|
1572
|
-
if (required
|
|
1656
|
+
if (!isNonNull(required)) return NO_VIOLATIONS;
|
|
1573
1657
|
const results = [];
|
|
1574
1658
|
iterate.forEach(required, (attr) => {
|
|
1575
1659
|
if (attr in props) return;
|
|
@@ -1593,12 +1677,12 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1593
1677
|
]);
|
|
1594
1678
|
// WAI-ARIA 1.2 §6.6: aria-hidden="true" must not be placed on focusable elements.
|
|
1595
1679
|
static #checkAriaHiddenOnFocusable({ tag, props }) {
|
|
1596
|
-
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return
|
|
1680
|
+
if (props["aria-hidden"] !== "true" && props["aria-hidden"] !== true) return NO_VIOLATIONS;
|
|
1597
1681
|
const isInteractive = _AriaPolicyEngine.#INTERACTIVE_TAGS.has(tag);
|
|
1598
1682
|
if (!isInteractive) {
|
|
1599
1683
|
const tabindex = props.tabindex;
|
|
1600
1684
|
const n = typeof tabindex === "number" ? tabindex : typeof tabindex === "string" ? parseInt(tabindex, 10) : NaN;
|
|
1601
|
-
if (!Number.isFinite(n) || n < 0) return
|
|
1685
|
+
if (!Number.isFinite(n) || n < 0) return NO_VIOLATIONS;
|
|
1602
1686
|
}
|
|
1603
1687
|
return [
|
|
1604
1688
|
{
|
|
@@ -1617,7 +1701,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1617
1701
|
props,
|
|
1618
1702
|
effectiveRole
|
|
1619
1703
|
}) {
|
|
1620
|
-
if (effectiveRole !== "none" && effectiveRole !== "presentation") return
|
|
1704
|
+
if (effectiveRole !== "none" && effectiveRole !== "presentation") return NO_VIOLATIONS;
|
|
1621
1705
|
const results = [];
|
|
1622
1706
|
iterate.forEachEntry(props, (key) => {
|
|
1623
1707
|
if (!key.startsWith("aria-")) return;
|
|
@@ -1641,10 +1725,10 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1641
1725
|
["timer", "off"]
|
|
1642
1726
|
]);
|
|
1643
1727
|
static #checkMissingLiveRegion({ effectiveRole, props }) {
|
|
1644
|
-
if (!effectiveRole) return
|
|
1728
|
+
if (!effectiveRole) return NO_VIOLATIONS;
|
|
1645
1729
|
const impliedLive = _AriaPolicyEngine.#LIVE_REGION_ROLES.get(effectiveRole);
|
|
1646
|
-
if (!impliedLive) return
|
|
1647
|
-
if ("aria-live" in props) return
|
|
1730
|
+
if (!impliedLive) return NO_VIOLATIONS;
|
|
1731
|
+
if ("aria-live" in props) return NO_VIOLATIONS;
|
|
1648
1732
|
const injectLive = {
|
|
1649
1733
|
kind: `injectLive:${effectiveRole}`,
|
|
1650
1734
|
apply: (ctx) => ({
|
|
@@ -1664,8 +1748,9 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1664
1748
|
];
|
|
1665
1749
|
}
|
|
1666
1750
|
static #checkMissingAtomic({ effectiveRole, props }) {
|
|
1667
|
-
if (!effectiveRole || !_AriaPolicyEngine.#LIVE_REGION_ROLES.has(effectiveRole))
|
|
1668
|
-
|
|
1751
|
+
if (!effectiveRole || !_AriaPolicyEngine.#LIVE_REGION_ROLES.has(effectiveRole))
|
|
1752
|
+
return NO_VIOLATIONS;
|
|
1753
|
+
if ("aria-atomic" in props) return NO_VIOLATIONS;
|
|
1669
1754
|
return [
|
|
1670
1755
|
{
|
|
1671
1756
|
valid: false,
|
|
@@ -1689,8 +1774,8 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1689
1774
|
};
|
|
1690
1775
|
static #checkInvalidAriaRelevant({ props }) {
|
|
1691
1776
|
const relevant = props["aria-relevant"];
|
|
1692
|
-
if (relevant === void 0) return
|
|
1693
|
-
if (typeof relevant !== "string") return
|
|
1777
|
+
if (relevant === void 0) return NO_VIOLATIONS;
|
|
1778
|
+
if (typeof relevant !== "string") return NO_VIOLATIONS;
|
|
1694
1779
|
const tokens = relevant.trim().split(/\s+/);
|
|
1695
1780
|
const invalid = tokens.filter((t) => !_AriaPolicyEngine.#VALID_RELEVANT_TOKENS.has(t));
|
|
1696
1781
|
if (invalid.length > 0) {
|
|
@@ -1717,7 +1802,7 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1717
1802
|
}
|
|
1718
1803
|
];
|
|
1719
1804
|
}
|
|
1720
|
-
return
|
|
1805
|
+
return NO_VIOLATIONS;
|
|
1721
1806
|
}
|
|
1722
1807
|
};
|
|
1723
1808
|
|
|
@@ -2317,7 +2402,7 @@ function cva2(base, config) {
|
|
|
2317
2402
|
// ../../lib/styling/src/static-class-resolver.ts
|
|
2318
2403
|
var StaticClassResolver = class {
|
|
2319
2404
|
#baseClass;
|
|
2320
|
-
#cache =
|
|
2405
|
+
#cache = new LRUCache(200);
|
|
2321
2406
|
#resolveTag;
|
|
2322
2407
|
constructor(baseClass, tagMap) {
|
|
2323
2408
|
this.#baseClass = Array.isArray(baseClass) ? baseClass.join(" ") : baseClass;
|
|
@@ -2331,17 +2416,9 @@ var StaticClassResolver = class {
|
|
|
2331
2416
|
resolve(tag, skipTagMap = false) {
|
|
2332
2417
|
if (typeof tag !== "string" || skipTagMap) return this.#baseClass;
|
|
2333
2418
|
const cached = this.#cache.get(tag);
|
|
2334
|
-
if (cached !== void 0)
|
|
2335
|
-
this.#cache.delete(tag);
|
|
2336
|
-
this.#cache.set(tag, cached);
|
|
2337
|
-
return cached;
|
|
2338
|
-
}
|
|
2419
|
+
if (cached !== void 0) return cached;
|
|
2339
2420
|
const result = this.#resolveTag(tag);
|
|
2340
2421
|
this.#cache.set(tag, result);
|
|
2341
|
-
if (this.#cache.size > 200) {
|
|
2342
|
-
const lru = this.#cache.keys().next().value;
|
|
2343
|
-
if (lru !== void 0) this.#cache.delete(lru);
|
|
2344
|
-
}
|
|
2345
2422
|
return result;
|
|
2346
2423
|
}
|
|
2347
2424
|
};
|
|
@@ -2352,7 +2429,7 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
2352
2429
|
#recipeMap;
|
|
2353
2430
|
#variantKeys;
|
|
2354
2431
|
#precomputedClasses;
|
|
2355
|
-
#cache =
|
|
2432
|
+
#cache = new LRUCache(1e3);
|
|
2356
2433
|
constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
|
|
2357
2434
|
this.#cvaFn = cvaFn ?? null;
|
|
2358
2435
|
this.#recipeMap = Object.freeze(recipeMap ?? {});
|
|
@@ -2367,17 +2444,9 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
2367
2444
|
if (precomputed !== void 0) return precomputed;
|
|
2368
2445
|
}
|
|
2369
2446
|
const cached = this.#cache.get(cacheKey);
|
|
2370
|
-
if (cached !== void 0)
|
|
2371
|
-
this.#cache.delete(cacheKey);
|
|
2372
|
-
this.#cache.set(cacheKey, cached);
|
|
2373
|
-
return cached;
|
|
2374
|
-
}
|
|
2447
|
+
if (cached !== void 0) return cached;
|
|
2375
2448
|
const result = this.#compute(props, recipe);
|
|
2376
2449
|
this.#cache.set(cacheKey, result);
|
|
2377
|
-
if (this.#cache.size > 1e3) {
|
|
2378
|
-
const lru = this.#cache.keys().next().value;
|
|
2379
|
-
if (lru !== void 0) this.#cache.delete(lru);
|
|
2380
|
-
}
|
|
2381
2450
|
return result;
|
|
2382
2451
|
}
|
|
2383
2452
|
#compute(props, recipe) {
|
|
@@ -2434,7 +2503,7 @@ function createClassPipeline(resolved) {
|
|
|
2434
2503
|
const staticClasses = staticResolver.resolve(tag, recipe !== void 0);
|
|
2435
2504
|
const variantClasses = variantResolver.resolve({ props, recipe });
|
|
2436
2505
|
if (!className)
|
|
2437
|
-
return staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses;
|
|
2506
|
+
return (staticClasses && variantClasses ? `${staticClasses} ${variantClasses}` : staticClasses || variantClasses) || void 0;
|
|
2438
2507
|
return cn(staticClasses, variantClasses, className);
|
|
2439
2508
|
};
|
|
2440
2509
|
}
|
|
@@ -2645,7 +2714,7 @@ function createPolymorphic2(options = {}) {
|
|
|
2645
2714
|
if (process.env.NODE_ENV !== "production") {
|
|
2646
2715
|
validateRenderProps(resolved.diagnostics, resolved, props, recipe);
|
|
2647
2716
|
}
|
|
2648
|
-
return classPipeline(tag, props, className, recipe);
|
|
2717
|
+
return classPipeline(tag, props, className, recipe) || void 0;
|
|
2649
2718
|
},
|
|
2650
2719
|
resolveAria(tag, props) {
|
|
2651
2720
|
return resolveAriaFn(tag, props);
|
|
@@ -3005,8 +3074,7 @@ function render({
|
|
|
3005
3074
|
childrenEvaluator
|
|
3006
3075
|
}) {
|
|
3007
3076
|
const state = prepareRenderState(runtime, props, filterProps);
|
|
3008
|
-
|
|
3009
|
-
const getNormalizedChildren = () => cached ??= normalizeChildren(state.children);
|
|
3077
|
+
const getNormalizedChildren = lazy(() => normalizeChildren(state.children));
|
|
3010
3078
|
if (process.env.NODE_ENV !== "production") {
|
|
3011
3079
|
childrenEvaluator?.evaluate(getNormalizedChildren(), {
|
|
3012
3080
|
tag: state.tag,
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -138,7 +138,7 @@ interface BaseClassOptions {
|
|
|
138
138
|
baseClassName?: ClassName;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string;
|
|
141
|
+
type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string | undefined;
|
|
142
142
|
|
|
143
143
|
interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
|
|
144
144
|
recipeMap?: Record<string, RecipeTarget<TVariants>>;
|
|
@@ -215,7 +215,9 @@ type AriaInvalidWithoutFix<M extends string = string> = AriaInvalidBase<M> & {
|
|
|
215
215
|
type AriaInvalidResult<M extends string = string> = AriaInvalidWithFix<M> | AriaInvalidWithoutFix<M>;
|
|
216
216
|
type AriaResult = ValidResult | AriaInvalidResult;
|
|
217
217
|
|
|
218
|
-
type AriaRule<C extends AriaContext = AriaContext> = (context: C) => readonly AriaResult[]
|
|
218
|
+
type AriaRule<C extends AriaContext = AriaContext> = ((context: C) => readonly AriaResult[]) & {
|
|
219
|
+
readonly readsProps?: readonly string[];
|
|
220
|
+
};
|
|
219
221
|
|
|
220
222
|
type PropNormalizer = (props: Readonly<AnyRecord & IntrinsicProps>) => Partial<AnyRecord & IntrinsicProps>;
|
|
221
223
|
|
package/dist/eslint/index.js
CHANGED
|
@@ -244,7 +244,7 @@ var require_eslint_utils = __commonJS({
|
|
|
244
244
|
// ../../plugins/eslint/src/rules/no-dead-compound.ts
|
|
245
245
|
var import_eslint_utils = __toESM(require_eslint_utils(), 1);
|
|
246
246
|
|
|
247
|
-
// ../../lib/primitive/src/utils/
|
|
247
|
+
// ../../lib/primitive/src/utils/type-guards.ts
|
|
248
248
|
function isString(value) {
|
|
249
249
|
return typeof value === "string";
|
|
250
250
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
type StringMap<T = unknown> = Record<string, T>;
|
|
2
|
+
type AnyRecord = StringMap<unknown>;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the effective HTML tag for a vnode:
|
|
6
|
+
* - native element: returns its type string directly
|
|
7
|
+
* - praxis-kit component: resolves `as ?? defaultTag`, mirroring render-time logic
|
|
8
|
+
* - anything else: returns undefined
|
|
9
|
+
*/
|
|
10
|
+
declare function getTag(child: unknown): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Checks whether a vnode resolves to one of the given intrinsic tag names.
|
|
13
|
+
* Matches native elements directly, and praxis-kit components by resolving
|
|
14
|
+
* `as ?? defaultTag` — the same logic used at render time.
|
|
15
|
+
*
|
|
16
|
+
* Two call forms are supported:
|
|
17
|
+
* isTag('img')(child) — curried, composable with Array#filter
|
|
18
|
+
* isTag(child, 'img') — direct, reads naturally in if-blocks
|
|
19
|
+
*/
|
|
20
|
+
type TagChild = {
|
|
21
|
+
type: unknown;
|
|
22
|
+
};
|
|
23
|
+
declare function isTag(tag: string, ...tags: readonly string[]): (child: unknown) => child is TagChild;
|
|
24
|
+
declare function isTag(child: unknown, tag: string, ...tags: readonly string[]): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Checks whether a vnode is flow content per the HTML content model: text nodes
|
|
27
|
+
* (string/number) always qualify, and elements/components qualify unless their
|
|
28
|
+
* resolved tag is in the blocked set.
|
|
29
|
+
*/
|
|
30
|
+
declare function isFlowContent(...blockedTags: readonly string[]): (child: unknown) => boolean;
|
|
31
|
+
|
|
32
|
+
declare function isObject(value: unknown, excludeArrays: true): value is AnyRecord;
|
|
33
|
+
declare function isObject(value: unknown, excludeArrays?: false): value is object;
|
|
34
|
+
declare function isString(value: unknown): value is string;
|
|
35
|
+
|
|
36
|
+
export { getTag, isFlowContent, isObject, isString, isTag };
|