praxis-kit 5.0.0 → 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/{chunk-SKAY22CZ.js → chunk-P5ZJBPAR.js} +81 -20
- package/dist/contract/index.d.ts +27 -1
- package/dist/lit/index.d.ts +27 -1
- package/dist/lit/index.js +92 -26
- package/dist/preact/index.d.ts +27 -1
- package/dist/preact/index.js +81 -20
- 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-D6rRB2gJ.d.ts → react-options-AitAOrje.d.ts} +27 -1
- package/dist/solid/index.d.ts +27 -1
- package/dist/solid/index.js +72 -17
- package/dist/svelte/Polymorphic.svelte +1 -1
- package/dist/svelte/index.d.ts +32 -2
- package/dist/svelte/index.js +68 -16
- package/dist/tailwind/index.d.ts +89 -54
- package/dist/tailwind/index.js +85 -46
- package/dist/vue/index.d.ts +27 -1
- package/dist/vue/index.js +70 -17
- package/dist/web/index.d.ts +27 -1
- package/dist/web/index.js +92 -31
- package/package.json +4 -4
|
@@ -420,6 +420,19 @@ function makeResolveTag(defaultTag) {
|
|
|
420
420
|
};
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
424
|
+
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
425
|
+
|
|
426
|
+
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
427
|
+
function isDynamicRule(rule) {
|
|
428
|
+
return isObject(rule, true) && rule[RULE_BRAND] === true;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
432
|
+
function resolveRule(rule, context) {
|
|
433
|
+
return isDynamicRule(rule) ? rule.resolve(context) : rule;
|
|
434
|
+
}
|
|
435
|
+
|
|
423
436
|
// ../../lib/primitive/src/utils/assert-never.ts
|
|
424
437
|
function assertNever(value) {
|
|
425
438
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
@@ -1885,10 +1898,22 @@ var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
|
1885
1898
|
|
|
1886
1899
|
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1887
1900
|
var isTextLike = (child) => isString(child) || isNumber(child);
|
|
1901
|
+
function checkPositionCardinalityInvariant(rules, context) {
|
|
1902
|
+
iterate.forEach(rules, (rule) => {
|
|
1903
|
+
const { name, position, cardinality } = rule;
|
|
1904
|
+
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1905
|
+
throw new RangeError(
|
|
1906
|
+
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1888
1911
|
var ChildrenEvaluator = class extends InvariantBase {
|
|
1889
1912
|
#context;
|
|
1890
|
-
|
|
1891
|
-
#
|
|
1913
|
+
/** Rules with a static cardinality — normalized once, reused on every evaluate() call. */
|
|
1914
|
+
#staticRules;
|
|
1915
|
+
/** Rules whose cardinality is `dynamic(...)` — re-resolved against a ChildRuleContext per call. */
|
|
1916
|
+
#dynamicRuleInputs;
|
|
1892
1917
|
#matcher;
|
|
1893
1918
|
#ruleValidator;
|
|
1894
1919
|
#exclusiveChildren;
|
|
@@ -1896,29 +1921,39 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1896
1921
|
constructor(rules, diagnostics, context = "Component", options = {}) {
|
|
1897
1922
|
super(diagnostics);
|
|
1898
1923
|
this.#context = context;
|
|
1899
|
-
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1900
|
-
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1901
1924
|
this.#exclusiveChildren = options.exclusiveChildren ?? false;
|
|
1902
1925
|
this.#allowText = options.allowText ?? true;
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
);
|
|
1909
|
-
}
|
|
1926
|
+
const staticRuleInputs = [];
|
|
1927
|
+
const dynamicRuleInputs = [];
|
|
1928
|
+
iterate.forEach(rules, (rule) => {
|
|
1929
|
+
if (isDynamicRule(rule.cardinality)) dynamicRuleInputs.push(rule);
|
|
1930
|
+
else staticRuleInputs.push(rule);
|
|
1910
1931
|
});
|
|
1911
|
-
this.#
|
|
1932
|
+
this.#dynamicRuleInputs = dynamicRuleInputs;
|
|
1933
|
+
this.#staticRules = staticRuleInputs.map(
|
|
1934
|
+
(r) => normalizeChildRule(r)
|
|
1935
|
+
);
|
|
1912
1936
|
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1937
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1938
|
+
checkPositionCardinalityInvariant(this.#staticRules, context);
|
|
1939
|
+
this.#matcher = new RuleMatcher(this.#staticRules);
|
|
1940
|
+
} else {
|
|
1941
|
+
this.#matcher = void 0;
|
|
1942
|
+
}
|
|
1913
1943
|
}
|
|
1914
|
-
|
|
1944
|
+
/**
|
|
1945
|
+
* @param context Required when any rule has a `dynamic(...)` cardinality —
|
|
1946
|
+
* supplies the resolved tag/props those rules are evaluated against.
|
|
1947
|
+
*/
|
|
1948
|
+
evaluate(children, context) {
|
|
1915
1949
|
if (!this.active) return;
|
|
1950
|
+
const { rules, matcher } = this.#resolveRules(context);
|
|
1916
1951
|
const {
|
|
1917
1952
|
matrix,
|
|
1918
1953
|
unexpectedIndices: rawUnexpectedIndices,
|
|
1919
1954
|
ambiguousIndices
|
|
1920
|
-
} =
|
|
1921
|
-
this.#ruleValidator.validate(
|
|
1955
|
+
} = matcher.match(children);
|
|
1956
|
+
this.#ruleValidator.validate(rules, matrix, children.length);
|
|
1922
1957
|
const unexpectedIndices = new Set(
|
|
1923
1958
|
[...rawUnexpectedIndices].filter(
|
|
1924
1959
|
(ci) => isTextLike(children[ci]) ? this.#allowText === false : this.#exclusiveChildren
|
|
@@ -1932,11 +1967,28 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1932
1967
|
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1933
1968
|
} else {
|
|
1934
1969
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1935
|
-
const names = [...matches].map((ri) =>
|
|
1970
|
+
const names = [...matches].map((ri) => rules[ri]?.name ?? `#${ri}`);
|
|
1936
1971
|
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1937
1972
|
}
|
|
1938
1973
|
});
|
|
1939
1974
|
}
|
|
1975
|
+
#resolveRules(context) {
|
|
1976
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1977
|
+
return { rules: this.#staticRules, matcher: this.#matcher };
|
|
1978
|
+
}
|
|
1979
|
+
if (context === void 0) {
|
|
1980
|
+
throw new RangeError(
|
|
1981
|
+
`ChildrenEvaluator [${this.#context}]: rule(s) have a dynamic(...) cardinality \u2014 evaluate() requires a context argument to resolve them.`
|
|
1982
|
+
);
|
|
1983
|
+
}
|
|
1984
|
+
const resolvedDynamicRules = this.#dynamicRuleInputs.map((r) => {
|
|
1985
|
+
const cardinality = resolveRule(r.cardinality, context);
|
|
1986
|
+
return normalizeChildRule({ ...r, cardinality });
|
|
1987
|
+
});
|
|
1988
|
+
checkPositionCardinalityInvariant(resolvedDynamicRules, this.#context);
|
|
1989
|
+
const rules = [...this.#staticRules, ...resolvedDynamicRules];
|
|
1990
|
+
return { rules, matcher: new RuleMatcher(rules) };
|
|
1991
|
+
}
|
|
1940
1992
|
};
|
|
1941
1993
|
|
|
1942
1994
|
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
@@ -2846,8 +2898,14 @@ function applyDisplayName(component, name) {
|
|
|
2846
2898
|
// ../../adapters/react/src/shared/render.ts
|
|
2847
2899
|
import { createElement as createElement2 } from "react";
|
|
2848
2900
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
2849
|
-
function buildRenderState(tag, directives, props, className, children) {
|
|
2850
|
-
const state = {
|
|
2901
|
+
function buildRenderState(tag, directives, props, normalizedProps, className, children) {
|
|
2902
|
+
const state = {
|
|
2903
|
+
tag,
|
|
2904
|
+
directives,
|
|
2905
|
+
props,
|
|
2906
|
+
normalizedProps,
|
|
2907
|
+
className
|
|
2908
|
+
};
|
|
2851
2909
|
if (children !== void 0) state.children = children;
|
|
2852
2910
|
return state;
|
|
2853
2911
|
}
|
|
@@ -2872,7 +2930,7 @@ function prepareRenderState(runtime, props, filterProps) {
|
|
|
2872
2930
|
...as !== void 0 && { as },
|
|
2873
2931
|
...asChild !== void 0 && { asChild }
|
|
2874
2932
|
};
|
|
2875
|
-
return buildRenderState(tag, directives, filteredProps, resolvedClass, children);
|
|
2933
|
+
return buildRenderState(tag, directives, filteredProps, normalizedProps, resolvedClass, children);
|
|
2876
2934
|
}
|
|
2877
2935
|
function warnDiscardedChildren(originalChildren, normalizedChildren, validator) {
|
|
2878
2936
|
if (!Array.isArray(originalChildren)) return;
|
|
@@ -2950,7 +3008,10 @@ function render({
|
|
|
2950
3008
|
let cached;
|
|
2951
3009
|
const getNormalizedChildren = () => cached ??= normalizeChildren(state.children);
|
|
2952
3010
|
if (process.env.NODE_ENV !== "production") {
|
|
2953
|
-
childrenEvaluator?.evaluate(getNormalizedChildren()
|
|
3011
|
+
childrenEvaluator?.evaluate(getNormalizedChildren(), {
|
|
3012
|
+
tag: state.tag,
|
|
3013
|
+
props: state.normalizedProps
|
|
3014
|
+
});
|
|
2954
3015
|
runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren());
|
|
2955
3016
|
}
|
|
2956
3017
|
if (typeof props.render === "function") {
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -29,6 +29,26 @@ type MinMax = {
|
|
|
29
29
|
};
|
|
30
30
|
type CardinalityInput = Partial<MinMax>;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Resolved per-instance state available to a dynamic (`dynamic(...)`) child
|
|
34
|
+
* rule field — the same tag/props every adapter already computes before
|
|
35
|
+
* evaluating children, exposed so a rule can vary by them (e.g. cardinality
|
|
36
|
+
* that depends on the resolved `as` tag).
|
|
37
|
+
*/
|
|
38
|
+
type ChildRuleContext = {
|
|
39
|
+
readonly tag: unknown;
|
|
40
|
+
readonly props: Readonly<AnyRecord>;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
declare const RULE_BRAND: unique symbol;
|
|
44
|
+
|
|
45
|
+
type DynamicRule<T, C = unknown> = {
|
|
46
|
+
readonly [RULE_BRAND]: true;
|
|
47
|
+
resolve(context: C): T;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type Rule<T, C = unknown> = T | DynamicRule<T, C>;
|
|
51
|
+
|
|
32
52
|
type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
|
|
33
53
|
|
|
34
54
|
type ChildRulePosition = 'first' | 'last' | 'any';
|
|
@@ -36,7 +56,13 @@ type ChildRulePosition = 'first' | 'last' | 'any';
|
|
|
36
56
|
type ChildRuleInput<T = unknown, U extends T = T> = {
|
|
37
57
|
name: string;
|
|
38
58
|
match: ChildRuleMatch<T, U>;
|
|
39
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Either a static cardinality, or `dynamic((ctx) => ...)` to derive it from
|
|
61
|
+
* the resolved tag/props (e.g. a different max depending on `as`). `match`
|
|
62
|
+
* stays static-only — it's already a function, so a dynamic wrapper would
|
|
63
|
+
* be indistinguishable from the predicate itself without one.
|
|
64
|
+
*/
|
|
65
|
+
cardinality?: Rule<CardinalityInput, ChildRuleContext>;
|
|
40
66
|
position?: ChildRulePosition;
|
|
41
67
|
/**
|
|
42
68
|
* Optional component-type reference for O(1) dispatch index.
|
package/dist/lit/index.d.ts
CHANGED
|
@@ -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.
|
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)}`);
|
|
@@ -1715,10 +1728,22 @@ var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
|
1715
1728
|
|
|
1716
1729
|
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1717
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
|
+
}
|
|
1718
1741
|
var ChildrenEvaluator = class extends InvariantBase {
|
|
1719
1742
|
#context;
|
|
1720
|
-
|
|
1721
|
-
#
|
|
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;
|
|
1722
1747
|
#matcher;
|
|
1723
1748
|
#ruleValidator;
|
|
1724
1749
|
#exclusiveChildren;
|
|
@@ -1726,29 +1751,39 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1726
1751
|
constructor(rules, diagnostics, context = "Component", options = {}) {
|
|
1727
1752
|
super(diagnostics);
|
|
1728
1753
|
this.#context = context;
|
|
1729
|
-
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1730
|
-
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1731
1754
|
this.#exclusiveChildren = options.exclusiveChildren ?? false;
|
|
1732
1755
|
this.#allowText = options.allowText ?? true;
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
);
|
|
1739
|
-
}
|
|
1756
|
+
const staticRuleInputs = [];
|
|
1757
|
+
const dynamicRuleInputs = [];
|
|
1758
|
+
iterate.forEach(rules, (rule) => {
|
|
1759
|
+
if (isDynamicRule(rule.cardinality)) dynamicRuleInputs.push(rule);
|
|
1760
|
+
else staticRuleInputs.push(rule);
|
|
1740
1761
|
});
|
|
1741
|
-
this.#
|
|
1762
|
+
this.#dynamicRuleInputs = dynamicRuleInputs;
|
|
1763
|
+
this.#staticRules = staticRuleInputs.map(
|
|
1764
|
+
(r) => normalizeChildRule(r)
|
|
1765
|
+
);
|
|
1742
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
|
+
}
|
|
1743
1773
|
}
|
|
1744
|
-
|
|
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) {
|
|
1745
1779
|
if (!this.active) return;
|
|
1780
|
+
const { rules, matcher } = this.#resolveRules(context);
|
|
1746
1781
|
const {
|
|
1747
1782
|
matrix,
|
|
1748
1783
|
unexpectedIndices: rawUnexpectedIndices,
|
|
1749
1784
|
ambiguousIndices
|
|
1750
|
-
} =
|
|
1751
|
-
this.#ruleValidator.validate(
|
|
1785
|
+
} = matcher.match(children);
|
|
1786
|
+
this.#ruleValidator.validate(rules, matrix, children.length);
|
|
1752
1787
|
const unexpectedIndices = new Set(
|
|
1753
1788
|
[...rawUnexpectedIndices].filter(
|
|
1754
1789
|
(ci) => isTextLike(children[ci]) ? this.#allowText === false : this.#exclusiveChildren
|
|
@@ -1762,11 +1797,28 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1762
1797
|
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1763
1798
|
} else {
|
|
1764
1799
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1765
|
-
const names = [...matches].map((ri) =>
|
|
1800
|
+
const names = [...matches].map((ri) => rules[ri]?.name ?? `#${ri}`);
|
|
1766
1801
|
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1767
1802
|
}
|
|
1768
1803
|
});
|
|
1769
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
|
+
}
|
|
1770
1822
|
};
|
|
1771
1823
|
|
|
1772
1824
|
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
@@ -2558,13 +2610,10 @@ function toLooseBundle(bundle) {
|
|
|
2558
2610
|
}
|
|
2559
2611
|
return bundle;
|
|
2560
2612
|
}
|
|
2561
|
-
function
|
|
2562
|
-
const { as, className, recipe, ...rest } = props;
|
|
2563
|
-
const { options,
|
|
2613
|
+
function resolveTagAndNormalizedProps(bundle, props) {
|
|
2614
|
+
const { as, className: _className, recipe: _recipe, ...rest } = props;
|
|
2615
|
+
const { options, resolveProps, resolveTag: resolveTag2 } = bundle.runtime;
|
|
2564
2616
|
const tag = resolveTag2(as);
|
|
2565
|
-
if (options.allowedAs !== void 0) {
|
|
2566
|
-
enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
|
|
2567
|
-
}
|
|
2568
2617
|
const mergedProps = resolveProps(rest);
|
|
2569
2618
|
const normalizedProps = typeof options.normalizeFn === "function" ? options.normalizeFn(mergedProps) : mergedProps;
|
|
2570
2619
|
const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
|
|
@@ -2574,6 +2623,15 @@ function resolveHostState(bundle, props) {
|
|
|
2574
2623
|
Object.assign(finalProps, normalize(finalProps));
|
|
2575
2624
|
}
|
|
2576
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
|
+
}
|
|
2577
2635
|
const resolvedClass = resolveClasses(
|
|
2578
2636
|
tag,
|
|
2579
2637
|
finalProps,
|
|
@@ -2582,7 +2640,7 @@ function resolveHostState(bundle, props) {
|
|
|
2582
2640
|
);
|
|
2583
2641
|
const ariaResult = resolveAria(tag, finalProps);
|
|
2584
2642
|
const attributes = applyFilter(ariaResult.props, bundle.filterProps, options.variantKeys);
|
|
2585
|
-
return { className: resolvedClass, attributes };
|
|
2643
|
+
return { className: resolvedClass, attributes, tag, normalizedProps: finalProps };
|
|
2586
2644
|
}
|
|
2587
2645
|
function diffAndApplyAttributes(host, state, prevPipelineAttrs, incomingProps) {
|
|
2588
2646
|
const hasOwn2 = Object.hasOwn;
|
|
@@ -2721,7 +2779,11 @@ function createContractComponent(options) {
|
|
|
2721
2779
|
get _self() {
|
|
2722
2780
|
return this;
|
|
2723
2781
|
}
|
|
2724
|
-
|
|
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() {
|
|
2725
2787
|
const self = this._self;
|
|
2726
2788
|
const props = {};
|
|
2727
2789
|
iterate.forEach(iterate.items(this.attributes), (attr) => {
|
|
@@ -2735,14 +2797,18 @@ function createContractComponent(options) {
|
|
|
2735
2797
|
const val = self[key];
|
|
2736
2798
|
if (val != null) props[key] = val;
|
|
2737
2799
|
});
|
|
2800
|
+
return props;
|
|
2801
|
+
}
|
|
2802
|
+
_applyPraxis() {
|
|
2803
|
+
const props = this._buildProps();
|
|
2738
2804
|
diffAndApplyAttributes(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
|
|
2739
2805
|
}
|
|
2740
2806
|
render() {
|
|
2741
2807
|
const children = Array.from(this.childNodes);
|
|
2808
|
+
const { tag, normalizedProps } = resolveTagAndNormalizedProps(looseBundle, this._buildProps());
|
|
2742
2809
|
if (bundle.childrenEvaluator) {
|
|
2743
|
-
bundle.childrenEvaluator.evaluate(children);
|
|
2810
|
+
bundle.childrenEvaluator.evaluate(children, { tag, props: normalizedProps });
|
|
2744
2811
|
}
|
|
2745
|
-
const tag = bundle.runtime.resolveTag(this._self.as);
|
|
2746
2812
|
bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children);
|
|
2747
2813
|
return html`<slot></slot>`;
|
|
2748
2814
|
}
|
package/dist/preact/index.d.ts
CHANGED
|
@@ -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.
|
package/dist/preact/index.js
CHANGED
|
@@ -472,6 +472,19 @@ function makeResolveTag(defaultTag) {
|
|
|
472
472
|
};
|
|
473
473
|
}
|
|
474
474
|
|
|
475
|
+
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
476
|
+
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
477
|
+
|
|
478
|
+
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
479
|
+
function isDynamicRule(rule) {
|
|
480
|
+
return isObject(rule, true) && rule[RULE_BRAND] === true;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
484
|
+
function resolveRule(rule, context) {
|
|
485
|
+
return isDynamicRule(rule) ? rule.resolve(context) : rule;
|
|
486
|
+
}
|
|
487
|
+
|
|
475
488
|
// ../../lib/primitive/src/utils/assert-never.ts
|
|
476
489
|
function assertNever(value) {
|
|
477
490
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
@@ -1900,10 +1913,22 @@ var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
|
1900
1913
|
|
|
1901
1914
|
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1902
1915
|
var isTextLike = (child) => isString(child) || isNumber(child);
|
|
1916
|
+
function checkPositionCardinalityInvariant(rules, context) {
|
|
1917
|
+
iterate.forEach(rules, (rule) => {
|
|
1918
|
+
const { name, position, cardinality } = rule;
|
|
1919
|
+
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1920
|
+
throw new RangeError(
|
|
1921
|
+
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1922
|
+
);
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1903
1926
|
var ChildrenEvaluator = class extends InvariantBase {
|
|
1904
1927
|
#context;
|
|
1905
|
-
|
|
1906
|
-
#
|
|
1928
|
+
/** Rules with a static cardinality — normalized once, reused on every evaluate() call. */
|
|
1929
|
+
#staticRules;
|
|
1930
|
+
/** Rules whose cardinality is `dynamic(...)` — re-resolved against a ChildRuleContext per call. */
|
|
1931
|
+
#dynamicRuleInputs;
|
|
1907
1932
|
#matcher;
|
|
1908
1933
|
#ruleValidator;
|
|
1909
1934
|
#exclusiveChildren;
|
|
@@ -1911,29 +1936,39 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1911
1936
|
constructor(rules, diagnostics, context = "Component", options = {}) {
|
|
1912
1937
|
super(diagnostics);
|
|
1913
1938
|
this.#context = context;
|
|
1914
|
-
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1915
|
-
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1916
1939
|
this.#exclusiveChildren = options.exclusiveChildren ?? false;
|
|
1917
1940
|
this.#allowText = options.allowText ?? true;
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
);
|
|
1924
|
-
}
|
|
1941
|
+
const staticRuleInputs = [];
|
|
1942
|
+
const dynamicRuleInputs = [];
|
|
1943
|
+
iterate.forEach(rules, (rule) => {
|
|
1944
|
+
if (isDynamicRule(rule.cardinality)) dynamicRuleInputs.push(rule);
|
|
1945
|
+
else staticRuleInputs.push(rule);
|
|
1925
1946
|
});
|
|
1926
|
-
this.#
|
|
1947
|
+
this.#dynamicRuleInputs = dynamicRuleInputs;
|
|
1948
|
+
this.#staticRules = staticRuleInputs.map(
|
|
1949
|
+
(r) => normalizeChildRule(r)
|
|
1950
|
+
);
|
|
1927
1951
|
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1952
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1953
|
+
checkPositionCardinalityInvariant(this.#staticRules, context);
|
|
1954
|
+
this.#matcher = new RuleMatcher(this.#staticRules);
|
|
1955
|
+
} else {
|
|
1956
|
+
this.#matcher = void 0;
|
|
1957
|
+
}
|
|
1928
1958
|
}
|
|
1929
|
-
|
|
1959
|
+
/**
|
|
1960
|
+
* @param context Required when any rule has a `dynamic(...)` cardinality —
|
|
1961
|
+
* supplies the resolved tag/props those rules are evaluated against.
|
|
1962
|
+
*/
|
|
1963
|
+
evaluate(children, context) {
|
|
1930
1964
|
if (!this.active) return;
|
|
1965
|
+
const { rules, matcher } = this.#resolveRules(context);
|
|
1931
1966
|
const {
|
|
1932
1967
|
matrix,
|
|
1933
1968
|
unexpectedIndices: rawUnexpectedIndices,
|
|
1934
1969
|
ambiguousIndices
|
|
1935
|
-
} =
|
|
1936
|
-
this.#ruleValidator.validate(
|
|
1970
|
+
} = matcher.match(children);
|
|
1971
|
+
this.#ruleValidator.validate(rules, matrix, children.length);
|
|
1937
1972
|
const unexpectedIndices = new Set(
|
|
1938
1973
|
[...rawUnexpectedIndices].filter(
|
|
1939
1974
|
(ci) => isTextLike(children[ci]) ? this.#allowText === false : this.#exclusiveChildren
|
|
@@ -1947,11 +1982,28 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1947
1982
|
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1948
1983
|
} else {
|
|
1949
1984
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1950
|
-
const names = [...matches].map((ri) =>
|
|
1985
|
+
const names = [...matches].map((ri) => rules[ri]?.name ?? `#${ri}`);
|
|
1951
1986
|
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1952
1987
|
}
|
|
1953
1988
|
});
|
|
1954
1989
|
}
|
|
1990
|
+
#resolveRules(context) {
|
|
1991
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1992
|
+
return { rules: this.#staticRules, matcher: this.#matcher };
|
|
1993
|
+
}
|
|
1994
|
+
if (context === void 0) {
|
|
1995
|
+
throw new RangeError(
|
|
1996
|
+
`ChildrenEvaluator [${this.#context}]: rule(s) have a dynamic(...) cardinality \u2014 evaluate() requires a context argument to resolve them.`
|
|
1997
|
+
);
|
|
1998
|
+
}
|
|
1999
|
+
const resolvedDynamicRules = this.#dynamicRuleInputs.map((r) => {
|
|
2000
|
+
const cardinality = resolveRule(r.cardinality, context);
|
|
2001
|
+
return normalizeChildRule({ ...r, cardinality });
|
|
2002
|
+
});
|
|
2003
|
+
checkPositionCardinalityInvariant(resolvedDynamicRules, this.#context);
|
|
2004
|
+
const rules = [...this.#staticRules, ...resolvedDynamicRules];
|
|
2005
|
+
return { rules, matcher: new RuleMatcher(rules) };
|
|
2006
|
+
}
|
|
1955
2007
|
};
|
|
1956
2008
|
|
|
1957
2009
|
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
@@ -2837,8 +2889,14 @@ var Slot = forwardRef(function Slot2({ children, ...slotProps }, ref) {
|
|
|
2837
2889
|
Object.assign(Slot, { displayName: SLOT_NAME });
|
|
2838
2890
|
|
|
2839
2891
|
// ../../adapters/preact/src/render.tsx
|
|
2840
|
-
function buildRenderState(tag, directives, props, className, children) {
|
|
2841
|
-
const state = {
|
|
2892
|
+
function buildRenderState(tag, directives, props, normalizedProps, className, children) {
|
|
2893
|
+
const state = {
|
|
2894
|
+
tag,
|
|
2895
|
+
directives,
|
|
2896
|
+
props,
|
|
2897
|
+
normalizedProps,
|
|
2898
|
+
className
|
|
2899
|
+
};
|
|
2842
2900
|
if (children !== void 0) state.children = children;
|
|
2843
2901
|
return state;
|
|
2844
2902
|
}
|
|
@@ -2863,7 +2921,7 @@ function prepareRenderState(runtime, props, filterProps) {
|
|
|
2863
2921
|
...as !== void 0 && { as },
|
|
2864
2922
|
...asChild !== void 0 && { asChild }
|
|
2865
2923
|
};
|
|
2866
|
-
return buildRenderState(tag, directives, filteredProps, resolvedClass, children);
|
|
2924
|
+
return buildRenderState(tag, directives, filteredProps, normalizedProps, resolvedClass, children);
|
|
2867
2925
|
}
|
|
2868
2926
|
function warnDiscardedChildren(originalChildren, normalizedChildren, validator) {
|
|
2869
2927
|
if (!Array.isArray(originalChildren)) return;
|
|
@@ -2941,7 +2999,10 @@ function render({
|
|
|
2941
2999
|
let normalizedChildren;
|
|
2942
3000
|
const getNormalizedChildren = () => normalizedChildren ??= normalizeChildren2(state.children);
|
|
2943
3001
|
if (process.env.NODE_ENV !== "production") {
|
|
2944
|
-
childrenEvaluator?.evaluate(getNormalizedChildren()
|
|
3002
|
+
childrenEvaluator?.evaluate(getNormalizedChildren(), {
|
|
3003
|
+
tag: state.tag,
|
|
3004
|
+
props: state.normalizedProps
|
|
3005
|
+
});
|
|
2945
3006
|
runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren());
|
|
2946
3007
|
}
|
|
2947
3008
|
const slotResult = tryRenderAsChild(
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-
|
|
2
|
-
export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, m as composeRefs, l as defineContractComponent, m as mergeRefs } from '../react-options-
|
|
1
|
+
import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory, b as ReactFactoryOptions, P as PolymorphicComponent, c as PolymorphicGenerics, d as ExtractPluginProps } from '../react-options-AitAOrje.js';
|
|
2
|
+
export { e as AnyFactoryOptions, f as ElementRef, F as FactoryOptions, g as PolymorphicProps, h as PolymorphicWithAsChild, i as PolymorphicWithRender, j as RenderCallbackProps, S as Slottable, k as SlottableProps, m as composeRefs, l as defineContractComponent, m as mergeRefs } from '../react-options-AitAOrje.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactElement, Ref } from 'react';
|
|
5
5
|
import 'type-fest';
|