praxis-kit 4.1.3 → 6.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/_shared/diagnostics.d.ts +10 -1
- package/dist/_shared/diagnostics.js +12 -0
- package/dist/{chunk-R2RKHZNX.js → chunk-P5ZJBPAR.js} +147 -52
- package/dist/codemod/index.js +39 -22
- package/dist/contract/index.d.ts +45 -3
- package/dist/eslint/index.js +16 -16
- package/dist/lit/index.d.ts +45 -3
- package/dist/lit/index.js +155 -58
- package/dist/preact/index.d.ts +45 -3
- package/dist/preact/index.js +146 -52
- 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-XrRof248.d.ts → react-options-AitAOrje.d.ts} +45 -3
- package/dist/solid/index.d.ts +45 -3
- package/dist/solid/index.js +180 -80
- package/dist/svelte/Polymorphic.svelte +146 -0
- package/dist/svelte/index.d.ts +66 -5
- package/dist/svelte/index.js +134 -48
- package/dist/tailwind/index.d.ts +89 -54
- package/dist/tailwind/index.js +85 -46
- package/dist/vite-plugin/index.d.ts +31 -0
- package/dist/vite-plugin/index.js +32 -15
- package/dist/vue/index.d.ts +45 -3
- package/dist/vue/index.js +136 -49
- package/dist/web/index.d.ts +45 -3
- package/dist/web/index.js +155 -63
- package/package.json +61 -8
package/dist/eslint/index.js
CHANGED
|
@@ -28,9 +28,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
mod
|
|
29
29
|
));
|
|
30
30
|
|
|
31
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
31
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js
|
|
32
32
|
var require_deepMerge = __commonJS({
|
|
33
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
33
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js"(exports) {
|
|
34
34
|
"use strict";
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.isObjectNotArray = isObjectNotArray;
|
|
@@ -63,9 +63,9 @@ var require_deepMerge = __commonJS({
|
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
66
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js
|
|
67
67
|
var require_applyDefault = __commonJS({
|
|
68
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
68
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js"(exports) {
|
|
69
69
|
"use strict";
|
|
70
70
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
71
|
exports.applyDefault = applyDefault;
|
|
@@ -90,9 +90,9 @@ var require_applyDefault = __commonJS({
|
|
|
90
90
|
}
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
93
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js
|
|
94
94
|
var require_parserSeemsToBeTSESLint = __commonJS({
|
|
95
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
95
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js"(exports) {
|
|
96
96
|
"use strict";
|
|
97
97
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
98
98
|
exports.parserSeemsToBeTSESLint = parserSeemsToBeTSESLint;
|
|
@@ -102,9 +102,9 @@ var require_parserSeemsToBeTSESLint = __commonJS({
|
|
|
102
102
|
}
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
105
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js
|
|
106
106
|
var require_getParserServices = __commonJS({
|
|
107
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
107
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js"(exports) {
|
|
108
108
|
"use strict";
|
|
109
109
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
110
110
|
exports.getParserServices = getParserServices;
|
|
@@ -135,17 +135,17 @@ var require_getParserServices = __commonJS({
|
|
|
135
135
|
}
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
138
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js
|
|
139
139
|
var require_InferTypesFromRule = __commonJS({
|
|
140
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
140
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js"(exports) {
|
|
141
141
|
"use strict";
|
|
142
142
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
143
143
|
}
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
146
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js
|
|
147
147
|
var require_nullThrows = __commonJS({
|
|
148
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
148
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js"(exports) {
|
|
149
149
|
"use strict";
|
|
150
150
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
151
151
|
exports.NullThrowsReasons = void 0;
|
|
@@ -163,9 +163,9 @@ var require_nullThrows = __commonJS({
|
|
|
163
163
|
}
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
166
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js
|
|
167
167
|
var require_RuleCreator = __commonJS({
|
|
168
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
168
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js"(exports) {
|
|
169
169
|
"use strict";
|
|
170
170
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
171
171
|
exports.RuleCreator = RuleCreator8;
|
|
@@ -211,9 +211,9 @@ var require_RuleCreator = __commonJS({
|
|
|
211
211
|
}
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
214
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/index.js
|
|
215
215
|
var require_eslint_utils = __commonJS({
|
|
216
|
-
"../../node_modules/.pnpm/@typescript-eslint+utils@8.
|
|
216
|
+
"../../node_modules/.pnpm/@typescript-eslint+utils@8.63.0_eslint@10.7.0_jiti@2.7.0__typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/index.js"(exports) {
|
|
217
217
|
"use strict";
|
|
218
218
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
219
219
|
if (k2 === void 0) k2 = k;
|
package/dist/lit/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
|
|
2
|
-
import { Diagnostics, DiagnosticInput } from '../_shared/diagnostics.js';
|
|
2
|
+
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from '../_shared/diagnostics.js';
|
|
3
3
|
import { LitElement } from 'lit';
|
|
4
4
|
|
|
5
5
|
type StringMap<T = unknown> = Record<string, T>;
|
|
@@ -30,6 +30,26 @@ type MinMax = {
|
|
|
30
30
|
};
|
|
31
31
|
type CardinalityInput = Partial<MinMax>;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Resolved per-instance state available to a dynamic (`dynamic(...)`) child
|
|
35
|
+
* rule field — the same tag/props every adapter already computes before
|
|
36
|
+
* evaluating children, exposed so a rule can vary by them (e.g. cardinality
|
|
37
|
+
* that depends on the resolved `as` tag).
|
|
38
|
+
*/
|
|
39
|
+
type ChildRuleContext = {
|
|
40
|
+
readonly tag: unknown;
|
|
41
|
+
readonly props: Readonly<AnyRecord>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
declare const RULE_BRAND: unique symbol;
|
|
45
|
+
|
|
46
|
+
type DynamicRule<T, C = unknown> = {
|
|
47
|
+
readonly [RULE_BRAND]: true;
|
|
48
|
+
resolve(context: C): T;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type Rule<T, C = unknown> = T | DynamicRule<T, C>;
|
|
52
|
+
|
|
33
53
|
type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
|
|
34
54
|
|
|
35
55
|
type ChildRulePosition = 'first' | 'last' | 'any';
|
|
@@ -37,7 +57,13 @@ type ChildRulePosition = 'first' | 'last' | 'any';
|
|
|
37
57
|
type ChildRuleInput<T = unknown, U extends T = T> = {
|
|
38
58
|
name: string;
|
|
39
59
|
match: ChildRuleMatch<T, U>;
|
|
40
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Either a static cardinality, or `dynamic((ctx) => ...)` to derive it from
|
|
62
|
+
* the resolved tag/props (e.g. a different max depending on `as`). `match`
|
|
63
|
+
* stays static-only — it's already a function, so a dynamic wrapper would
|
|
64
|
+
* be indistinguishable from the predicate itself without one.
|
|
65
|
+
*/
|
|
66
|
+
cardinality?: Rule<CardinalityInput, ChildRuleContext>;
|
|
41
67
|
position?: ChildRulePosition;
|
|
42
68
|
/**
|
|
43
69
|
* Optional component-type reference for O(1) dispatch index.
|
|
@@ -196,9 +222,25 @@ type AriaRule<C extends AriaContext = AriaContext> = (context: C) => readonly Ar
|
|
|
196
222
|
type PropNormalizer = (props: Readonly<AnyRecord & IntrinsicProps>) => Partial<AnyRecord & IntrinsicProps>;
|
|
197
223
|
|
|
198
224
|
type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
199
|
-
|
|
225
|
+
/**
|
|
226
|
+
* Accepts a preset name (`'warn'`, `'throw'`, `'silent'`) or a full `Diagnostics`
|
|
227
|
+
* instance for custom reporting/policy. The string form needs no import from
|
|
228
|
+
* `@praxis-kit/diagnostics`.
|
|
229
|
+
*/
|
|
230
|
+
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
200
231
|
readonly aria?: readonly AriaRule[];
|
|
201
232
|
readonly children?: readonly ChildRuleInput[];
|
|
233
|
+
/**
|
|
234
|
+
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
235
|
+
* are valid — anything else is rejected. Default: false (open — children not
|
|
236
|
+
* matching any rule are allowed).
|
|
237
|
+
*/
|
|
238
|
+
readonly exclusiveChildren?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* When false, text/number child nodes are rejected regardless of exclusiveChildren
|
|
241
|
+
* or any listed rule. Default: true.
|
|
242
|
+
*/
|
|
243
|
+
readonly allowText?: boolean;
|
|
202
244
|
readonly props?: readonly PropNormalizer[];
|
|
203
245
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
204
246
|
readonly allowedAs?: readonly TAllowed[];
|
package/dist/lit/index.js
CHANGED
|
@@ -313,6 +313,19 @@ function makeResolveTag(defaultTag) {
|
|
|
313
313
|
};
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
+
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
317
|
+
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
318
|
+
|
|
319
|
+
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
320
|
+
function isDynamicRule(rule) {
|
|
321
|
+
return isObject(rule, true) && rule[RULE_BRAND] === true;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
325
|
+
function resolveRule(rule, context) {
|
|
326
|
+
return isDynamicRule(rule) ? rule.resolve(context) : rule;
|
|
327
|
+
}
|
|
328
|
+
|
|
316
329
|
// ../../lib/primitive/src/utils/assert-never.ts
|
|
317
330
|
function assertNever(value) {
|
|
318
331
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
@@ -1714,32 +1727,68 @@ var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
|
1714
1727
|
};
|
|
1715
1728
|
|
|
1716
1729
|
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1730
|
+
var isTextLike = (child) => isString(child) || isNumber(child);
|
|
1731
|
+
function checkPositionCardinalityInvariant(rules, context) {
|
|
1732
|
+
iterate.forEach(rules, (rule) => {
|
|
1733
|
+
const { name, position, cardinality } = rule;
|
|
1734
|
+
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1735
|
+
throw new RangeError(
|
|
1736
|
+
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1737
|
+
);
|
|
1738
|
+
}
|
|
1739
|
+
});
|
|
1740
|
+
}
|
|
1717
1741
|
var ChildrenEvaluator = class extends InvariantBase {
|
|
1718
1742
|
#context;
|
|
1719
|
-
|
|
1720
|
-
#
|
|
1743
|
+
/** Rules with a static cardinality — normalized once, reused on every evaluate() call. */
|
|
1744
|
+
#staticRules;
|
|
1745
|
+
/** Rules whose cardinality is `dynamic(...)` — re-resolved against a ChildRuleContext per call. */
|
|
1746
|
+
#dynamicRuleInputs;
|
|
1721
1747
|
#matcher;
|
|
1722
1748
|
#ruleValidator;
|
|
1723
|
-
|
|
1749
|
+
#exclusiveChildren;
|
|
1750
|
+
#allowText;
|
|
1751
|
+
constructor(rules, diagnostics, context = "Component", options = {}) {
|
|
1724
1752
|
super(diagnostics);
|
|
1725
1753
|
this.#context = context;
|
|
1726
|
-
this.#
|
|
1727
|
-
this.#
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
);
|
|
1734
|
-
}
|
|
1754
|
+
this.#exclusiveChildren = options.exclusiveChildren ?? false;
|
|
1755
|
+
this.#allowText = options.allowText ?? true;
|
|
1756
|
+
const staticRuleInputs = [];
|
|
1757
|
+
const dynamicRuleInputs = [];
|
|
1758
|
+
iterate.forEach(rules, (rule) => {
|
|
1759
|
+
if (isDynamicRule(rule.cardinality)) dynamicRuleInputs.push(rule);
|
|
1760
|
+
else staticRuleInputs.push(rule);
|
|
1735
1761
|
});
|
|
1736
|
-
this.#
|
|
1762
|
+
this.#dynamicRuleInputs = dynamicRuleInputs;
|
|
1763
|
+
this.#staticRules = staticRuleInputs.map(
|
|
1764
|
+
(r) => normalizeChildRule(r)
|
|
1765
|
+
);
|
|
1737
1766
|
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1767
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1768
|
+
checkPositionCardinalityInvariant(this.#staticRules, context);
|
|
1769
|
+
this.#matcher = new RuleMatcher(this.#staticRules);
|
|
1770
|
+
} else {
|
|
1771
|
+
this.#matcher = void 0;
|
|
1772
|
+
}
|
|
1738
1773
|
}
|
|
1739
|
-
|
|
1774
|
+
/**
|
|
1775
|
+
* @param context Required when any rule has a `dynamic(...)` cardinality —
|
|
1776
|
+
* supplies the resolved tag/props those rules are evaluated against.
|
|
1777
|
+
*/
|
|
1778
|
+
evaluate(children, context) {
|
|
1740
1779
|
if (!this.active) return;
|
|
1741
|
-
const {
|
|
1742
|
-
|
|
1780
|
+
const { rules, matcher } = this.#resolveRules(context);
|
|
1781
|
+
const {
|
|
1782
|
+
matrix,
|
|
1783
|
+
unexpectedIndices: rawUnexpectedIndices,
|
|
1784
|
+
ambiguousIndices
|
|
1785
|
+
} = matcher.match(children);
|
|
1786
|
+
this.#ruleValidator.validate(rules, matrix, children.length);
|
|
1787
|
+
const unexpectedIndices = new Set(
|
|
1788
|
+
[...rawUnexpectedIndices].filter(
|
|
1789
|
+
(ci) => isTextLike(children[ci]) ? this.#allowText === false : this.#exclusiveChildren
|
|
1790
|
+
)
|
|
1791
|
+
);
|
|
1743
1792
|
if (unexpectedIndices.size === 0 && ambiguousIndices.size === 0) return;
|
|
1744
1793
|
const violating = [...unexpectedIndices, ...ambiguousIndices].sort((a, b) => a - b);
|
|
1745
1794
|
iterate.forEach(violating, (ci) => {
|
|
@@ -1748,11 +1797,28 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1748
1797
|
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1749
1798
|
} else {
|
|
1750
1799
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1751
|
-
const names = [...matches].map((ri) =>
|
|
1800
|
+
const names = [...matches].map((ri) => rules[ri]?.name ?? `#${ri}`);
|
|
1752
1801
|
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1753
1802
|
}
|
|
1754
1803
|
});
|
|
1755
1804
|
}
|
|
1805
|
+
#resolveRules(context) {
|
|
1806
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1807
|
+
return { rules: this.#staticRules, matcher: this.#matcher };
|
|
1808
|
+
}
|
|
1809
|
+
if (context === void 0) {
|
|
1810
|
+
throw new RangeError(
|
|
1811
|
+
`ChildrenEvaluator [${this.#context}]: rule(s) have a dynamic(...) cardinality \u2014 evaluate() requires a context argument to resolve them.`
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1814
|
+
const resolvedDynamicRules = this.#dynamicRuleInputs.map((r) => {
|
|
1815
|
+
const cardinality = resolveRule(r.cardinality, context);
|
|
1816
|
+
return normalizeChildRule({ ...r, cardinality });
|
|
1817
|
+
});
|
|
1818
|
+
checkPositionCardinalityInvariant(resolvedDynamicRules, this.#context);
|
|
1819
|
+
const rules = [...this.#staticRules, ...resolvedDynamicRules];
|
|
1820
|
+
return { rules, matcher: new RuleMatcher(rules) };
|
|
1821
|
+
}
|
|
1756
1822
|
};
|
|
1757
1823
|
|
|
1758
1824
|
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
@@ -1861,8 +1927,11 @@ function metadata(name = "metadata") {
|
|
|
1861
1927
|
function firstOptional(name, tag) {
|
|
1862
1928
|
return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
|
|
1863
1929
|
}
|
|
1864
|
-
function contract(children) {
|
|
1865
|
-
return { diagnostics: warnDiagnostics, children };
|
|
1930
|
+
function contract(children, options) {
|
|
1931
|
+
return { diagnostics: warnDiagnostics, children, ...options };
|
|
1932
|
+
}
|
|
1933
|
+
function closedContract(children) {
|
|
1934
|
+
return contract(children, { exclusiveChildren: true });
|
|
1866
1935
|
}
|
|
1867
1936
|
function ariaContract(aria) {
|
|
1868
1937
|
return { diagnostics: warnDiagnostics, aria };
|
|
@@ -1888,8 +1957,10 @@ var VOID_TAGS = [
|
|
|
1888
1957
|
];
|
|
1889
1958
|
var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
|
|
1890
1959
|
var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
|
|
1891
|
-
var listContract =
|
|
1892
|
-
|
|
1960
|
+
var listContract = closedContract([
|
|
1961
|
+
{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }
|
|
1962
|
+
]);
|
|
1963
|
+
var tableContract = closedContract([
|
|
1893
1964
|
firstOptional("caption", "caption"),
|
|
1894
1965
|
{ name: "colgroup", match: isTag("colgroup") },
|
|
1895
1966
|
{ name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
|
|
@@ -1897,29 +1968,31 @@ var tableContract = contract([
|
|
|
1897
1968
|
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
1898
1969
|
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
1899
1970
|
]);
|
|
1900
|
-
var tableBodyContract =
|
|
1971
|
+
var tableBodyContract = closedContract([
|
|
1901
1972
|
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
1902
1973
|
]);
|
|
1903
|
-
var tableRowContract =
|
|
1974
|
+
var tableRowContract = closedContract([
|
|
1904
1975
|
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
1905
1976
|
]);
|
|
1906
|
-
var colgroupContract =
|
|
1907
|
-
|
|
1977
|
+
var colgroupContract = closedContract([
|
|
1978
|
+
{ name: "column", match: isTag("col", "template") }
|
|
1979
|
+
]);
|
|
1980
|
+
var dlContract = closedContract([
|
|
1908
1981
|
{ name: "term", match: isTag("dt") },
|
|
1909
1982
|
{ name: "description", match: isTag("dd") },
|
|
1910
1983
|
{ name: "group", match: isTag("div") },
|
|
1911
1984
|
metadata()
|
|
1912
1985
|
]);
|
|
1913
|
-
var selectContract =
|
|
1986
|
+
var selectContract = closedContract([
|
|
1914
1987
|
{ name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
|
|
1915
1988
|
]);
|
|
1916
|
-
var optgroupContract =
|
|
1989
|
+
var optgroupContract = closedContract([
|
|
1917
1990
|
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
1918
1991
|
]);
|
|
1919
|
-
var datalistContract =
|
|
1992
|
+
var datalistContract = closedContract([
|
|
1920
1993
|
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
1921
1994
|
]);
|
|
1922
|
-
var pictureContract =
|
|
1995
|
+
var pictureContract = closedContract([
|
|
1923
1996
|
{ name: "source", match: isTag("source", ...METADATA_TAGS) },
|
|
1924
1997
|
{ name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
|
|
1925
1998
|
]);
|
|
@@ -1935,23 +2008,18 @@ var mediaContract = contract([
|
|
|
1935
2008
|
metadata(),
|
|
1936
2009
|
{ name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
|
|
1937
2010
|
]);
|
|
1938
|
-
var headContract =
|
|
2011
|
+
var headContract = closedContract([
|
|
1939
2012
|
{
|
|
1940
2013
|
name: "metadata",
|
|
1941
2014
|
match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
|
|
1942
2015
|
}
|
|
1943
2016
|
]);
|
|
1944
|
-
var htmlContract =
|
|
2017
|
+
var htmlContract = closedContract([
|
|
1945
2018
|
{ name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
|
|
1946
2019
|
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
1947
2020
|
]);
|
|
1948
|
-
var voidContract = contract([]);
|
|
1949
|
-
var textOnlyContract = contract([
|
|
1950
|
-
{
|
|
1951
|
-
name: "text",
|
|
1952
|
-
match: (child) => isString(child) || isNumber(child)
|
|
1953
|
-
}
|
|
1954
|
-
]);
|
|
2021
|
+
var voidContract = contract([], { exclusiveChildren: true, allowText: false });
|
|
2022
|
+
var textOnlyContract = contract([], { exclusiveChildren: true });
|
|
1955
2023
|
var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
|
|
1956
2024
|
var dialogContract = ariaContract([requireAccessibleName]);
|
|
1957
2025
|
var menuContract = ariaContract([requireAccessibleName]);
|
|
@@ -1996,9 +2064,15 @@ var htmlContracts = {
|
|
|
1996
2064
|
var htmlDiagnostics = warnDiagnostics2;
|
|
1997
2065
|
function buildEvaluatorMap() {
|
|
1998
2066
|
const map2 = /* @__PURE__ */ new Map();
|
|
1999
|
-
iterate.forEachEntry(htmlContracts, (tag, { children }) => {
|
|
2000
|
-
if (children?.length) {
|
|
2001
|
-
map2.set(
|
|
2067
|
+
iterate.forEachEntry(htmlContracts, (tag, { children, exclusiveChildren, allowText }) => {
|
|
2068
|
+
if (children?.length || exclusiveChildren || allowText === false) {
|
|
2069
|
+
map2.set(
|
|
2070
|
+
tag,
|
|
2071
|
+
new ChildrenEvaluator(children ?? [], htmlDiagnostics, `<${tag}>`, {
|
|
2072
|
+
exclusiveChildren,
|
|
2073
|
+
allowText
|
|
2074
|
+
})
|
|
2075
|
+
);
|
|
2002
2076
|
}
|
|
2003
2077
|
});
|
|
2004
2078
|
return map2;
|
|
@@ -2209,7 +2283,7 @@ function definePipeline(factory) {
|
|
|
2209
2283
|
}
|
|
2210
2284
|
|
|
2211
2285
|
// ../core/src/options/resolve-factory-options.ts
|
|
2212
|
-
import { silentDiagnostics } from "../_shared/diagnostics.js";
|
|
2286
|
+
import { resolveDiagnostics, silentDiagnostics } from "../_shared/diagnostics.js";
|
|
2213
2287
|
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
2214
2288
|
function composeNormalizers(normalizers, fn) {
|
|
2215
2289
|
if (!normalizers?.length) return fn;
|
|
@@ -2230,7 +2304,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
2230
2304
|
const variantKeys = styling?.variants === void 0 ? EMPTY_VARIANT_KEYS : new Set(Object.keys(styling.variants));
|
|
2231
2305
|
return Object.freeze({
|
|
2232
2306
|
defaultTag: options.tag ?? "div",
|
|
2233
|
-
diagnostics: enforcement?.diagnostics
|
|
2307
|
+
diagnostics: resolveDiagnostics(enforcement?.diagnostics, silentDiagnostics),
|
|
2234
2308
|
variantKeys,
|
|
2235
2309
|
...whenDefined("displayName", options.name),
|
|
2236
2310
|
...whenDefined("defaultProps", options.defaults),
|
|
@@ -2243,6 +2317,8 @@ function resolveFactoryOptions(options = {}) {
|
|
|
2243
2317
|
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
2244
2318
|
...whenDefined("ariaRules", enforcement?.aria),
|
|
2245
2319
|
...whenDefined("childRules", enforcement?.children),
|
|
2320
|
+
...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
|
|
2321
|
+
...whenDefined("allowText", enforcement?.allowText),
|
|
2246
2322
|
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
2247
2323
|
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
2248
2324
|
});
|
|
@@ -2427,16 +2503,22 @@ function buildCoreRuntime(normalized) {
|
|
|
2427
2503
|
}
|
|
2428
2504
|
|
|
2429
2505
|
// ../../lib/adapter-utils/src/runtime/build-engines.ts
|
|
2430
|
-
function buildEngines(diagnostics, childRules, context) {
|
|
2431
|
-
|
|
2506
|
+
function buildEngines(diagnostics, childRules, context, childrenOptions) {
|
|
2507
|
+
const { exclusiveChildren, allowText } = childrenOptions ?? {};
|
|
2508
|
+
return childRules?.length || exclusiveChildren || allowText === false ? {
|
|
2509
|
+
childrenEvaluator: new ChildrenEvaluator(childRules ?? [], diagnostics, context, {
|
|
2510
|
+
exclusiveChildren,
|
|
2511
|
+
allowText
|
|
2512
|
+
})
|
|
2513
|
+
} : {};
|
|
2432
2514
|
}
|
|
2433
2515
|
|
|
2434
2516
|
// ../../lib/adapter-utils/src/runtime/resolve-adapter-common-options.ts
|
|
2435
|
-
import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
|
|
2517
|
+
import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3, resolveDiagnostics as resolveDiagnostics2 } from "../_shared/diagnostics.js";
|
|
2436
2518
|
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics2) {
|
|
2437
2519
|
return {
|
|
2438
2520
|
name: options.name ?? defaultName,
|
|
2439
|
-
diagnostics: options.enforcement?.diagnostics
|
|
2521
|
+
diagnostics: resolveDiagnostics2(options.enforcement?.diagnostics, defaultDiagnostics)
|
|
2440
2522
|
};
|
|
2441
2523
|
}
|
|
2442
2524
|
|
|
@@ -2528,13 +2610,10 @@ function toLooseBundle(bundle) {
|
|
|
2528
2610
|
}
|
|
2529
2611
|
return bundle;
|
|
2530
2612
|
}
|
|
2531
|
-
function
|
|
2532
|
-
const { as, className, recipe, ...rest } = props;
|
|
2533
|
-
const { options,
|
|
2613
|
+
function resolveTagAndNormalizedProps(bundle, props) {
|
|
2614
|
+
const { as, className: _className, recipe: _recipe, ...rest } = props;
|
|
2615
|
+
const { options, resolveProps, resolveTag: resolveTag2 } = bundle.runtime;
|
|
2534
2616
|
const tag = resolveTag2(as);
|
|
2535
|
-
if (options.allowedAs !== void 0) {
|
|
2536
|
-
enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
|
|
2537
|
-
}
|
|
2538
2617
|
const mergedProps = resolveProps(rest);
|
|
2539
2618
|
const normalizedProps = typeof options.normalizeFn === "function" ? options.normalizeFn(mergedProps) : mergedProps;
|
|
2540
2619
|
const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
|
|
@@ -2544,6 +2623,15 @@ function resolveHostState(bundle, props) {
|
|
|
2544
2623
|
Object.assign(finalProps, normalize(finalProps));
|
|
2545
2624
|
}
|
|
2546
2625
|
}
|
|
2626
|
+
return { tag, normalizedProps: finalProps };
|
|
2627
|
+
}
|
|
2628
|
+
function resolveHostState(bundle, props) {
|
|
2629
|
+
const { className, recipe } = props;
|
|
2630
|
+
const { options, resolveAria, resolveClasses } = bundle.runtime;
|
|
2631
|
+
const { tag, normalizedProps: finalProps } = resolveTagAndNormalizedProps(bundle, props);
|
|
2632
|
+
if (options.allowedAs !== void 0) {
|
|
2633
|
+
enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
|
|
2634
|
+
}
|
|
2547
2635
|
const resolvedClass = resolveClasses(
|
|
2548
2636
|
tag,
|
|
2549
2637
|
finalProps,
|
|
@@ -2552,7 +2640,7 @@ function resolveHostState(bundle, props) {
|
|
|
2552
2640
|
);
|
|
2553
2641
|
const ariaResult = resolveAria(tag, finalProps);
|
|
2554
2642
|
const attributes = applyFilter(ariaResult.props, bundle.filterProps, options.variantKeys);
|
|
2555
|
-
return { className: resolvedClass, attributes };
|
|
2643
|
+
return { className: resolvedClass, attributes, tag, normalizedProps: finalProps };
|
|
2556
2644
|
}
|
|
2557
2645
|
function diffAndApplyAttributes(host, state, prevPipelineAttrs, incomingProps) {
|
|
2558
2646
|
const hasOwn2 = Object.hasOwn;
|
|
@@ -2600,7 +2688,8 @@ function buildRuntime(options) {
|
|
|
2600
2688
|
const { childrenEvaluator } = buildEngines(
|
|
2601
2689
|
normalized.diagnostics,
|
|
2602
2690
|
enforcement?.children,
|
|
2603
|
-
normalized.name
|
|
2691
|
+
normalized.name,
|
|
2692
|
+
{ exclusiveChildren: enforcement?.exclusiveChildren, allowText: enforcement?.allowText }
|
|
2604
2693
|
);
|
|
2605
2694
|
const filterProps = composeFilter(ownedKeys, customFilter);
|
|
2606
2695
|
return {
|
|
@@ -2690,7 +2779,11 @@ function createContractComponent(options) {
|
|
|
2690
2779
|
get _self() {
|
|
2691
2780
|
return this;
|
|
2692
2781
|
}
|
|
2693
|
-
|
|
2782
|
+
// Start with all current DOM attributes so the ARIA engine sees role,
|
|
2783
|
+
// aria-*, and any other pass-through attributes. Shared by render() and
|
|
2784
|
+
// _applyPraxis(), which run at different points in the same update cycle
|
|
2785
|
+
// and can't share a local variable.
|
|
2786
|
+
_buildProps() {
|
|
2694
2787
|
const self = this._self;
|
|
2695
2788
|
const props = {};
|
|
2696
2789
|
iterate.forEach(iterate.items(this.attributes), (attr) => {
|
|
@@ -2704,14 +2797,18 @@ function createContractComponent(options) {
|
|
|
2704
2797
|
const val = self[key];
|
|
2705
2798
|
if (val != null) props[key] = val;
|
|
2706
2799
|
});
|
|
2800
|
+
return props;
|
|
2801
|
+
}
|
|
2802
|
+
_applyPraxis() {
|
|
2803
|
+
const props = this._buildProps();
|
|
2707
2804
|
diffAndApplyAttributes(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
|
|
2708
2805
|
}
|
|
2709
2806
|
render() {
|
|
2710
2807
|
const children = Array.from(this.childNodes);
|
|
2808
|
+
const { tag, normalizedProps } = resolveTagAndNormalizedProps(looseBundle, this._buildProps());
|
|
2711
2809
|
if (bundle.childrenEvaluator) {
|
|
2712
|
-
bundle.childrenEvaluator.evaluate(children);
|
|
2810
|
+
bundle.childrenEvaluator.evaluate(children, { tag, props: normalizedProps });
|
|
2713
2811
|
}
|
|
2714
|
-
const tag = bundle.runtime.resolveTag(this._self.as);
|
|
2715
2812
|
bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children);
|
|
2716
2813
|
return html`<slot></slot>`;
|
|
2717
2814
|
}
|
package/dist/preact/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequireAtLeastOne, Simplify, ReadonlyDeep, OmitIndexSignature } from 'type-fest';
|
|
2
|
-
import { Diagnostics, DiagnosticInput } from '../_shared/diagnostics.js';
|
|
2
|
+
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from '../_shared/diagnostics.js';
|
|
3
3
|
import { ComponentChildren, VNode, ComponentType, JSX, Ref } from 'preact';
|
|
4
4
|
|
|
5
5
|
type StringMap<T = unknown> = Record<string, T>;
|
|
@@ -30,6 +30,26 @@ type MinMax = {
|
|
|
30
30
|
};
|
|
31
31
|
type CardinalityInput = Partial<MinMax>;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Resolved per-instance state available to a dynamic (`dynamic(...)`) child
|
|
35
|
+
* rule field — the same tag/props every adapter already computes before
|
|
36
|
+
* evaluating children, exposed so a rule can vary by them (e.g. cardinality
|
|
37
|
+
* that depends on the resolved `as` tag).
|
|
38
|
+
*/
|
|
39
|
+
type ChildRuleContext = {
|
|
40
|
+
readonly tag: unknown;
|
|
41
|
+
readonly props: Readonly<AnyRecord>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
declare const RULE_BRAND: unique symbol;
|
|
45
|
+
|
|
46
|
+
type DynamicRule<T, C = unknown> = {
|
|
47
|
+
readonly [RULE_BRAND]: true;
|
|
48
|
+
resolve(context: C): T;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type Rule<T, C = unknown> = T | DynamicRule<T, C>;
|
|
52
|
+
|
|
33
53
|
type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
|
|
34
54
|
|
|
35
55
|
type ChildRulePosition = 'first' | 'last' | 'any';
|
|
@@ -37,7 +57,13 @@ type ChildRulePosition = 'first' | 'last' | 'any';
|
|
|
37
57
|
type ChildRuleInput<T = unknown, U extends T = T> = {
|
|
38
58
|
name: string;
|
|
39
59
|
match: ChildRuleMatch<T, U>;
|
|
40
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Either a static cardinality, or `dynamic((ctx) => ...)` to derive it from
|
|
62
|
+
* the resolved tag/props (e.g. a different max depending on `as`). `match`
|
|
63
|
+
* stays static-only — it's already a function, so a dynamic wrapper would
|
|
64
|
+
* be indistinguishable from the predicate itself without one.
|
|
65
|
+
*/
|
|
66
|
+
cardinality?: Rule<CardinalityInput, ChildRuleContext>;
|
|
41
67
|
position?: ChildRulePosition;
|
|
42
68
|
/**
|
|
43
69
|
* Optional component-type reference for O(1) dispatch index.
|
|
@@ -213,9 +239,25 @@ type AriaRule<C extends AriaContext = AriaContext> = (context: C) => readonly Ar
|
|
|
213
239
|
type PropNormalizer = (props: Readonly<AnyRecord & IntrinsicProps>) => Partial<AnyRecord & IntrinsicProps>;
|
|
214
240
|
|
|
215
241
|
type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
216
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Accepts a preset name (`'warn'`, `'throw'`, `'silent'`) or a full `Diagnostics`
|
|
244
|
+
* instance for custom reporting/policy. The string form needs no import from
|
|
245
|
+
* `@praxis-kit/diagnostics`.
|
|
246
|
+
*/
|
|
247
|
+
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
217
248
|
readonly aria?: readonly AriaRule[];
|
|
218
249
|
readonly children?: readonly ChildRuleInput[];
|
|
250
|
+
/**
|
|
251
|
+
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
252
|
+
* are valid — anything else is rejected. Default: false (open — children not
|
|
253
|
+
* matching any rule are allowed).
|
|
254
|
+
*/
|
|
255
|
+
readonly exclusiveChildren?: boolean;
|
|
256
|
+
/**
|
|
257
|
+
* When false, text/number child nodes are rejected regardless of exclusiveChildren
|
|
258
|
+
* or any listed rule. Default: true.
|
|
259
|
+
*/
|
|
260
|
+
readonly allowText?: boolean;
|
|
219
261
|
readonly props?: readonly PropNormalizer[];
|
|
220
262
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
221
263
|
readonly allowedAs?: readonly TAllowed[];
|