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/solid/index.js
CHANGED
|
@@ -445,6 +445,19 @@ function makeResolveTag(defaultTag) {
|
|
|
445
445
|
};
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
+
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
449
|
+
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
450
|
+
|
|
451
|
+
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
452
|
+
function isDynamicRule(rule) {
|
|
453
|
+
return isObject(rule, true) && rule[RULE_BRAND] === true;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
457
|
+
function resolveRule(rule, context) {
|
|
458
|
+
return isDynamicRule(rule) ? rule.resolve(context) : rule;
|
|
459
|
+
}
|
|
460
|
+
|
|
448
461
|
// ../../lib/primitive/src/utils/assert-never.ts
|
|
449
462
|
function assertNever(value) {
|
|
450
463
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
@@ -1856,32 +1869,68 @@ var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
|
1856
1869
|
};
|
|
1857
1870
|
|
|
1858
1871
|
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1872
|
+
var isTextLike = (child) => isString(child) || isNumber(child);
|
|
1873
|
+
function checkPositionCardinalityInvariant(rules, context) {
|
|
1874
|
+
iterate.forEach(rules, (rule) => {
|
|
1875
|
+
const { name, position, cardinality } = rule;
|
|
1876
|
+
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1877
|
+
throw new RangeError(
|
|
1878
|
+
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1879
|
+
);
|
|
1880
|
+
}
|
|
1881
|
+
});
|
|
1882
|
+
}
|
|
1859
1883
|
var ChildrenEvaluator = class extends InvariantBase {
|
|
1860
1884
|
#context;
|
|
1861
|
-
|
|
1862
|
-
#
|
|
1885
|
+
/** Rules with a static cardinality — normalized once, reused on every evaluate() call. */
|
|
1886
|
+
#staticRules;
|
|
1887
|
+
/** Rules whose cardinality is `dynamic(...)` — re-resolved against a ChildRuleContext per call. */
|
|
1888
|
+
#dynamicRuleInputs;
|
|
1863
1889
|
#matcher;
|
|
1864
1890
|
#ruleValidator;
|
|
1865
|
-
|
|
1891
|
+
#exclusiveChildren;
|
|
1892
|
+
#allowText;
|
|
1893
|
+
constructor(rules, diagnostics, context = "Component", options = {}) {
|
|
1866
1894
|
super(diagnostics);
|
|
1867
1895
|
this.#context = context;
|
|
1868
|
-
this.#
|
|
1869
|
-
this.#
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
);
|
|
1876
|
-
}
|
|
1896
|
+
this.#exclusiveChildren = options.exclusiveChildren ?? false;
|
|
1897
|
+
this.#allowText = options.allowText ?? true;
|
|
1898
|
+
const staticRuleInputs = [];
|
|
1899
|
+
const dynamicRuleInputs = [];
|
|
1900
|
+
iterate.forEach(rules, (rule) => {
|
|
1901
|
+
if (isDynamicRule(rule.cardinality)) dynamicRuleInputs.push(rule);
|
|
1902
|
+
else staticRuleInputs.push(rule);
|
|
1877
1903
|
});
|
|
1878
|
-
this.#
|
|
1904
|
+
this.#dynamicRuleInputs = dynamicRuleInputs;
|
|
1905
|
+
this.#staticRules = staticRuleInputs.map(
|
|
1906
|
+
(r) => normalizeChildRule(r)
|
|
1907
|
+
);
|
|
1879
1908
|
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1909
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1910
|
+
checkPositionCardinalityInvariant(this.#staticRules, context);
|
|
1911
|
+
this.#matcher = new RuleMatcher(this.#staticRules);
|
|
1912
|
+
} else {
|
|
1913
|
+
this.#matcher = void 0;
|
|
1914
|
+
}
|
|
1880
1915
|
}
|
|
1881
|
-
|
|
1916
|
+
/**
|
|
1917
|
+
* @param context Required when any rule has a `dynamic(...)` cardinality —
|
|
1918
|
+
* supplies the resolved tag/props those rules are evaluated against.
|
|
1919
|
+
*/
|
|
1920
|
+
evaluate(children, context) {
|
|
1882
1921
|
if (!this.active) return;
|
|
1883
|
-
const {
|
|
1884
|
-
|
|
1922
|
+
const { rules, matcher } = this.#resolveRules(context);
|
|
1923
|
+
const {
|
|
1924
|
+
matrix,
|
|
1925
|
+
unexpectedIndices: rawUnexpectedIndices,
|
|
1926
|
+
ambiguousIndices
|
|
1927
|
+
} = matcher.match(children);
|
|
1928
|
+
this.#ruleValidator.validate(rules, matrix, children.length);
|
|
1929
|
+
const unexpectedIndices = new Set(
|
|
1930
|
+
[...rawUnexpectedIndices].filter(
|
|
1931
|
+
(ci) => isTextLike(children[ci]) ? this.#allowText === false : this.#exclusiveChildren
|
|
1932
|
+
)
|
|
1933
|
+
);
|
|
1885
1934
|
if (unexpectedIndices.size === 0 && ambiguousIndices.size === 0) return;
|
|
1886
1935
|
const violating = [...unexpectedIndices, ...ambiguousIndices].sort((a, b) => a - b);
|
|
1887
1936
|
iterate.forEach(violating, (ci) => {
|
|
@@ -1890,11 +1939,28 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1890
1939
|
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1891
1940
|
} else {
|
|
1892
1941
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1893
|
-
const names = [...matches].map((ri) =>
|
|
1942
|
+
const names = [...matches].map((ri) => rules[ri]?.name ?? `#${ri}`);
|
|
1894
1943
|
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1895
1944
|
}
|
|
1896
1945
|
});
|
|
1897
1946
|
}
|
|
1947
|
+
#resolveRules(context) {
|
|
1948
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1949
|
+
return { rules: this.#staticRules, matcher: this.#matcher };
|
|
1950
|
+
}
|
|
1951
|
+
if (context === void 0) {
|
|
1952
|
+
throw new RangeError(
|
|
1953
|
+
`ChildrenEvaluator [${this.#context}]: rule(s) have a dynamic(...) cardinality \u2014 evaluate() requires a context argument to resolve them.`
|
|
1954
|
+
);
|
|
1955
|
+
}
|
|
1956
|
+
const resolvedDynamicRules = this.#dynamicRuleInputs.map((r) => {
|
|
1957
|
+
const cardinality = resolveRule(r.cardinality, context);
|
|
1958
|
+
return normalizeChildRule({ ...r, cardinality });
|
|
1959
|
+
});
|
|
1960
|
+
checkPositionCardinalityInvariant(resolvedDynamicRules, this.#context);
|
|
1961
|
+
const rules = [...this.#staticRules, ...resolvedDynamicRules];
|
|
1962
|
+
return { rules, matcher: new RuleMatcher(rules) };
|
|
1963
|
+
}
|
|
1898
1964
|
};
|
|
1899
1965
|
|
|
1900
1966
|
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
@@ -2003,8 +2069,11 @@ function metadata(name = "metadata") {
|
|
|
2003
2069
|
function firstOptional(name, tag) {
|
|
2004
2070
|
return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
|
|
2005
2071
|
}
|
|
2006
|
-
function contract(children) {
|
|
2007
|
-
return { diagnostics: warnDiagnostics, children };
|
|
2072
|
+
function contract(children, options) {
|
|
2073
|
+
return { diagnostics: warnDiagnostics, children, ...options };
|
|
2074
|
+
}
|
|
2075
|
+
function closedContract(children) {
|
|
2076
|
+
return contract(children, { exclusiveChildren: true });
|
|
2008
2077
|
}
|
|
2009
2078
|
function ariaContract(aria) {
|
|
2010
2079
|
return { diagnostics: warnDiagnostics, aria };
|
|
@@ -2030,8 +2099,10 @@ var VOID_TAGS = [
|
|
|
2030
2099
|
];
|
|
2031
2100
|
var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
|
|
2032
2101
|
var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
|
|
2033
|
-
var listContract =
|
|
2034
|
-
|
|
2102
|
+
var listContract = closedContract([
|
|
2103
|
+
{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }
|
|
2104
|
+
]);
|
|
2105
|
+
var tableContract = closedContract([
|
|
2035
2106
|
firstOptional("caption", "caption"),
|
|
2036
2107
|
{ name: "colgroup", match: isTag("colgroup") },
|
|
2037
2108
|
{ name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
|
|
@@ -2039,29 +2110,31 @@ var tableContract = contract([
|
|
|
2039
2110
|
{ name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
|
|
2040
2111
|
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
2041
2112
|
]);
|
|
2042
|
-
var tableBodyContract =
|
|
2113
|
+
var tableBodyContract = closedContract([
|
|
2043
2114
|
{ name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
|
|
2044
2115
|
]);
|
|
2045
|
-
var tableRowContract =
|
|
2116
|
+
var tableRowContract = closedContract([
|
|
2046
2117
|
{ name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
|
|
2047
2118
|
]);
|
|
2048
|
-
var colgroupContract =
|
|
2049
|
-
|
|
2119
|
+
var colgroupContract = closedContract([
|
|
2120
|
+
{ name: "column", match: isTag("col", "template") }
|
|
2121
|
+
]);
|
|
2122
|
+
var dlContract = closedContract([
|
|
2050
2123
|
{ name: "term", match: isTag("dt") },
|
|
2051
2124
|
{ name: "description", match: isTag("dd") },
|
|
2052
2125
|
{ name: "group", match: isTag("div") },
|
|
2053
2126
|
metadata()
|
|
2054
2127
|
]);
|
|
2055
|
-
var selectContract =
|
|
2128
|
+
var selectContract = closedContract([
|
|
2056
2129
|
{ name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
|
|
2057
2130
|
]);
|
|
2058
|
-
var optgroupContract =
|
|
2131
|
+
var optgroupContract = closedContract([
|
|
2059
2132
|
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
2060
2133
|
]);
|
|
2061
|
-
var datalistContract =
|
|
2134
|
+
var datalistContract = closedContract([
|
|
2062
2135
|
{ name: "option", match: isTag("option", ...METADATA_TAGS) }
|
|
2063
2136
|
]);
|
|
2064
|
-
var pictureContract =
|
|
2137
|
+
var pictureContract = closedContract([
|
|
2065
2138
|
{ name: "source", match: isTag("source", ...METADATA_TAGS) },
|
|
2066
2139
|
{ name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
|
|
2067
2140
|
]);
|
|
@@ -2077,23 +2150,18 @@ var mediaContract = contract([
|
|
|
2077
2150
|
metadata(),
|
|
2078
2151
|
{ name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
|
|
2079
2152
|
]);
|
|
2080
|
-
var headContract =
|
|
2153
|
+
var headContract = closedContract([
|
|
2081
2154
|
{
|
|
2082
2155
|
name: "metadata",
|
|
2083
2156
|
match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
|
|
2084
2157
|
}
|
|
2085
2158
|
]);
|
|
2086
|
-
var htmlContract =
|
|
2159
|
+
var htmlContract = closedContract([
|
|
2087
2160
|
{ name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
|
|
2088
2161
|
{ name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
|
|
2089
2162
|
]);
|
|
2090
|
-
var voidContract = contract([]);
|
|
2091
|
-
var textOnlyContract = contract([
|
|
2092
|
-
{
|
|
2093
|
-
name: "text",
|
|
2094
|
-
match: (child) => isString(child) || isNumber(child)
|
|
2095
|
-
}
|
|
2096
|
-
]);
|
|
2163
|
+
var voidContract = contract([], { exclusiveChildren: true, allowText: false });
|
|
2164
|
+
var textOnlyContract = contract([], { exclusiveChildren: true });
|
|
2097
2165
|
var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
|
|
2098
2166
|
var dialogContract = ariaContract([requireAccessibleName]);
|
|
2099
2167
|
var menuContract = ariaContract([requireAccessibleName]);
|
|
@@ -2138,9 +2206,15 @@ var htmlContracts = {
|
|
|
2138
2206
|
var htmlDiagnostics = warnDiagnostics2;
|
|
2139
2207
|
function buildEvaluatorMap() {
|
|
2140
2208
|
const map2 = /* @__PURE__ */ new Map();
|
|
2141
|
-
iterate.forEachEntry(htmlContracts, (tag, { children }) => {
|
|
2142
|
-
if (children?.length) {
|
|
2143
|
-
map2.set(
|
|
2209
|
+
iterate.forEachEntry(htmlContracts, (tag, { children, exclusiveChildren, allowText }) => {
|
|
2210
|
+
if (children?.length || exclusiveChildren || allowText === false) {
|
|
2211
|
+
map2.set(
|
|
2212
|
+
tag,
|
|
2213
|
+
new ChildrenEvaluator(children ?? [], htmlDiagnostics, `<${tag}>`, {
|
|
2214
|
+
exclusiveChildren,
|
|
2215
|
+
allowText
|
|
2216
|
+
})
|
|
2217
|
+
);
|
|
2144
2218
|
}
|
|
2145
2219
|
});
|
|
2146
2220
|
return map2;
|
|
@@ -2351,7 +2425,7 @@ function definePipeline(factory) {
|
|
|
2351
2425
|
}
|
|
2352
2426
|
|
|
2353
2427
|
// ../core/src/options/resolve-factory-options.ts
|
|
2354
|
-
import { silentDiagnostics } from "../_shared/diagnostics.js";
|
|
2428
|
+
import { resolveDiagnostics, silentDiagnostics } from "../_shared/diagnostics.js";
|
|
2355
2429
|
var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
|
|
2356
2430
|
function composeNormalizers(normalizers, fn) {
|
|
2357
2431
|
if (!normalizers?.length) return fn;
|
|
@@ -2372,7 +2446,7 @@ function resolveFactoryOptions(options = {}) {
|
|
|
2372
2446
|
const variantKeys = styling?.variants === void 0 ? EMPTY_VARIANT_KEYS : new Set(Object.keys(styling.variants));
|
|
2373
2447
|
return Object.freeze({
|
|
2374
2448
|
defaultTag: options.tag ?? "div",
|
|
2375
|
-
diagnostics: enforcement?.diagnostics
|
|
2449
|
+
diagnostics: resolveDiagnostics(enforcement?.diagnostics, silentDiagnostics),
|
|
2376
2450
|
variantKeys,
|
|
2377
2451
|
...whenDefined("displayName", options.name),
|
|
2378
2452
|
...whenDefined("defaultProps", options.defaults),
|
|
@@ -2385,6 +2459,8 @@ function resolveFactoryOptions(options = {}) {
|
|
|
2385
2459
|
...whenDefined("normalizeFn", composedNormalizeFn),
|
|
2386
2460
|
...whenDefined("ariaRules", enforcement?.aria),
|
|
2387
2461
|
...whenDefined("childRules", enforcement?.children),
|
|
2462
|
+
...whenDefined("exclusiveChildren", enforcement?.exclusiveChildren),
|
|
2463
|
+
...whenDefined("allowText", enforcement?.allowText),
|
|
2388
2464
|
...whenDefined("allowedAs", enforcement?.allowedAs),
|
|
2389
2465
|
...whenDefined("precomputedClasses", styling?.precomputedClasses)
|
|
2390
2466
|
});
|
|
@@ -2569,16 +2645,22 @@ function buildCoreRuntime(normalized) {
|
|
|
2569
2645
|
}
|
|
2570
2646
|
|
|
2571
2647
|
// ../../lib/adapter-utils/src/runtime/build-engines.ts
|
|
2572
|
-
function buildEngines(diagnostics, childRules, context) {
|
|
2573
|
-
|
|
2648
|
+
function buildEngines(diagnostics, childRules, context, childrenOptions) {
|
|
2649
|
+
const { exclusiveChildren, allowText } = childrenOptions ?? {};
|
|
2650
|
+
return childRules?.length || exclusiveChildren || allowText === false ? {
|
|
2651
|
+
childrenEvaluator: new ChildrenEvaluator(childRules ?? [], diagnostics, context, {
|
|
2652
|
+
exclusiveChildren,
|
|
2653
|
+
allowText
|
|
2654
|
+
})
|
|
2655
|
+
} : {};
|
|
2574
2656
|
}
|
|
2575
2657
|
|
|
2576
2658
|
// ../../lib/adapter-utils/src/runtime/resolve-adapter-common-options.ts
|
|
2577
|
-
import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
|
|
2659
|
+
import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3, resolveDiagnostics as resolveDiagnostics2 } from "../_shared/diagnostics.js";
|
|
2578
2660
|
function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics2) {
|
|
2579
2661
|
return {
|
|
2580
2662
|
name: options.name ?? defaultName,
|
|
2581
|
-
diagnostics: options.enforcement?.diagnostics
|
|
2663
|
+
diagnostics: resolveDiagnostics2(options.enforcement?.diagnostics, defaultDiagnostics)
|
|
2582
2664
|
};
|
|
2583
2665
|
}
|
|
2584
2666
|
|
|
@@ -2633,7 +2715,11 @@ function buildRuntime(options) {
|
|
|
2633
2715
|
const { childrenEvaluator } = buildEngines(
|
|
2634
2716
|
normalized.diagnostics,
|
|
2635
2717
|
normalized.enforcement?.children,
|
|
2636
|
-
normalized.name
|
|
2718
|
+
normalized.name,
|
|
2719
|
+
{
|
|
2720
|
+
exclusiveChildren: normalized.enforcement?.exclusiveChildren,
|
|
2721
|
+
allowText: normalized.enforcement?.allowText
|
|
2722
|
+
}
|
|
2637
2723
|
);
|
|
2638
2724
|
const filterProps = composeFilter(ownedKeys, normalized.filterProps);
|
|
2639
2725
|
const slotValidator = new SlotValidator(normalized.name, normalized.diagnostics);
|
|
@@ -2646,9 +2732,10 @@ function buildRuntime(options) {
|
|
|
2646
2732
|
}
|
|
2647
2733
|
|
|
2648
2734
|
// ../../adapters/solid/src/render.tsx
|
|
2735
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
2736
|
+
import { mergeProps as _$mergeProps } from "solid-js/web";
|
|
2649
2737
|
import { createEffect, createMemo, splitProps } from "solid-js";
|
|
2650
2738
|
import { Dynamic } from "solid-js/web";
|
|
2651
|
-
import { jsx } from "solid-js/jsx-runtime";
|
|
2652
2739
|
var SPLIT_KEYS = ["as", "asChild", "children", "class", "recipe", "ref"];
|
|
2653
2740
|
function toChildArray(children) {
|
|
2654
2741
|
if (children === void 0 || children === null) return [];
|
|
@@ -2656,22 +2743,38 @@ function toChildArray(children) {
|
|
|
2656
2743
|
return [children];
|
|
2657
2744
|
}
|
|
2658
2745
|
function buildElementProps(props, classStr, ref, children) {
|
|
2659
|
-
const {
|
|
2746
|
+
const {
|
|
2747
|
+
role,
|
|
2748
|
+
...rest
|
|
2749
|
+
} = props;
|
|
2660
2750
|
return {
|
|
2661
2751
|
...rest,
|
|
2662
2752
|
class: classStr,
|
|
2663
|
-
...ref !== void 0 && {
|
|
2664
|
-
|
|
2665
|
-
|
|
2753
|
+
...ref !== void 0 && {
|
|
2754
|
+
ref
|
|
2755
|
+
},
|
|
2756
|
+
...children !== void 0 && {
|
|
2757
|
+
children
|
|
2758
|
+
},
|
|
2759
|
+
...isKnownAriaRole(role) && {
|
|
2760
|
+
role
|
|
2761
|
+
}
|
|
2666
2762
|
};
|
|
2667
2763
|
}
|
|
2668
2764
|
function buildSlotProps(props, classStr, ref) {
|
|
2669
|
-
const {
|
|
2765
|
+
const {
|
|
2766
|
+
role,
|
|
2767
|
+
...rest
|
|
2768
|
+
} = props;
|
|
2670
2769
|
return {
|
|
2671
2770
|
...rest,
|
|
2672
2771
|
class: classStr,
|
|
2673
|
-
...ref !== void 0 && {
|
|
2674
|
-
|
|
2772
|
+
...ref !== void 0 && {
|
|
2773
|
+
ref
|
|
2774
|
+
},
|
|
2775
|
+
...isKnownAriaRole(role) && {
|
|
2776
|
+
role
|
|
2777
|
+
}
|
|
2675
2778
|
};
|
|
2676
2779
|
}
|
|
2677
2780
|
function resolveTag2(runtime, as) {
|
|
@@ -2688,9 +2791,7 @@ function tryRenderAsChild(known, filteredProps, resolvedClass, slotValidator) {
|
|
|
2688
2791
|
}
|
|
2689
2792
|
if (!slotValidator.assertRenderFn(known.children)) return null;
|
|
2690
2793
|
const renderFn = known.children;
|
|
2691
|
-
return createMemo(
|
|
2692
|
-
() => renderFn(buildSlotProps(filteredProps(), resolvedClass(), known.ref))
|
|
2693
|
-
);
|
|
2794
|
+
return createMemo(() => renderFn(buildSlotProps(filteredProps(), resolvedClass(), known.ref)));
|
|
2694
2795
|
}
|
|
2695
2796
|
function render({
|
|
2696
2797
|
runtime,
|
|
@@ -2706,32 +2807,27 @@ function render({
|
|
|
2706
2807
|
const normalizedProps = createMemo(() => {
|
|
2707
2808
|
const base = runtime.options.normalizeFn ? runtime.options.normalizeFn(mergedProps()) : mergedProps();
|
|
2708
2809
|
const htmlNormalizers = runtime.options.htmlPropNormalizersFn?.(tag());
|
|
2709
|
-
return htmlNormalizers?.length ? htmlNormalizers.reduce((acc, fn) => ({
|
|
2810
|
+
return htmlNormalizers?.length ? htmlNormalizers.reduce((acc, fn) => ({
|
|
2811
|
+
...acc,
|
|
2812
|
+
...fn(acc)
|
|
2813
|
+
}), base) : base;
|
|
2710
2814
|
});
|
|
2711
|
-
const resolvedClass = createMemo(
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
known.recipe
|
|
2717
|
-
)
|
|
2718
|
-
);
|
|
2719
|
-
const filteredProps = createMemo(
|
|
2720
|
-
() => applyFilter(normalizedProps(), filterProps, runtime.options.variantKeys)
|
|
2721
|
-
);
|
|
2722
|
-
const { allowedAs } = runtime.options;
|
|
2815
|
+
const resolvedClass = createMemo(() => runtime.resolveClasses(tag(), normalizedProps(), known.class, known.recipe));
|
|
2816
|
+
const filteredProps = createMemo(() => applyFilter(normalizedProps(), filterProps, runtime.options.variantKeys));
|
|
2817
|
+
const {
|
|
2818
|
+
allowedAs
|
|
2819
|
+
} = runtime.options;
|
|
2723
2820
|
if (allowedAs !== void 0) {
|
|
2724
|
-
createEffect(
|
|
2725
|
-
() => enforceAllowedAs(tag(), allowedAs, runtime.options.diagnostics, runtime.options.displayName)
|
|
2726
|
-
);
|
|
2821
|
+
createEffect(() => enforceAllowedAs(tag(), allowedAs, runtime.options.diagnostics, runtime.options.displayName));
|
|
2727
2822
|
}
|
|
2728
2823
|
if (process.env.NODE_ENV !== "production" && childrenEvaluator) {
|
|
2729
|
-
createEffect(() => childrenEvaluator.evaluate(toChildArray(known.children)
|
|
2824
|
+
createEffect(() => childrenEvaluator.evaluate(toChildArray(known.children), {
|
|
2825
|
+
tag: tag(),
|
|
2826
|
+
props: normalizedProps()
|
|
2827
|
+
}));
|
|
2730
2828
|
}
|
|
2731
2829
|
if (process.env.NODE_ENV !== "production") {
|
|
2732
|
-
createEffect(
|
|
2733
|
-
() => runtime.options.htmlChildrenEvaluatorFn?.(tag())?.evaluate(toChildArray(known.children))
|
|
2734
|
-
);
|
|
2830
|
+
createEffect(() => runtime.options.htmlChildrenEvaluatorFn?.(tag())?.evaluate(toChildArray(known.children)));
|
|
2735
2831
|
}
|
|
2736
2832
|
const slotResult = tryRenderAsChild(known, filteredProps, resolvedClass, slotValidator);
|
|
2737
2833
|
if (slotResult !== null) return slotResult;
|
|
@@ -2739,7 +2835,11 @@ function render({
|
|
|
2739
2835
|
const ep = buildElementProps(filteredProps(), resolvedClass(), known.ref, known.children);
|
|
2740
2836
|
return resolveDomProps(tag(), ep, runtime);
|
|
2741
2837
|
});
|
|
2742
|
-
return
|
|
2838
|
+
return _$createComponent(Dynamic, _$mergeProps({
|
|
2839
|
+
get component() {
|
|
2840
|
+
return tag();
|
|
2841
|
+
}
|
|
2842
|
+
}, () => domProps()));
|
|
2743
2843
|
}
|
|
2744
2844
|
|
|
2745
2845
|
// ../../adapters/solid/src/create-contract-component.ts
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
declare const process: { env: { NODE_ENV: string } }
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { enforceAllowedAs, isKnownAriaRole } from '@praxis-kit/core'
|
|
7
|
+
import type { ElementType, IntrinsicProps } from '@praxis-kit/core'
|
|
8
|
+
import { isObject, isString } from '@praxis-kit/primitive'
|
|
9
|
+
import { applyFilter } from '@praxis-kit/adapter-utils'
|
|
10
|
+
import type { Snippet } from 'svelte'
|
|
11
|
+
import type {
|
|
12
|
+
PolymorphicComponentProps,
|
|
13
|
+
ResolvedAttributes,
|
|
14
|
+
StyleObject,
|
|
15
|
+
UnknownProps,
|
|
16
|
+
} from './types'
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
bundle,
|
|
20
|
+
as: asProp,
|
|
21
|
+
asChild,
|
|
22
|
+
class: cls,
|
|
23
|
+
recipe,
|
|
24
|
+
children,
|
|
25
|
+
...rest
|
|
26
|
+
}: PolymorphicComponentProps = $props()
|
|
27
|
+
let hostEl: Element | undefined = $state()
|
|
28
|
+
|
|
29
|
+
// Svelte 5 event delegation requires lowercase handler names (onclick, onfocus…).
|
|
30
|
+
// Normalize React-style camelCase handlers so spreads on <svelte:element> work.
|
|
31
|
+
const EVENT_RE = /^on[A-Z]/
|
|
32
|
+
function normalizeEventKeys(props: UnknownProps): UnknownProps {
|
|
33
|
+
const out: ResolvedAttributes = {}
|
|
34
|
+
for (const k in props) {
|
|
35
|
+
out[EVENT_RE.test(k) ? k.toLowerCase() : k] = (props as ResolvedAttributes)[k]
|
|
36
|
+
}
|
|
37
|
+
return out as UnknownProps
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function serializeStyle(style: StyleObject): string {
|
|
41
|
+
let result = ''
|
|
42
|
+
for (const key in style) {
|
|
43
|
+
const value = style[key]
|
|
44
|
+
if (value == null) continue
|
|
45
|
+
if (result) result += ';'
|
|
46
|
+
result += `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}:${value}`
|
|
47
|
+
}
|
|
48
|
+
return result
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function buildDomProps(
|
|
52
|
+
props: UnknownProps,
|
|
53
|
+
classStr: string,
|
|
54
|
+
tag: ElementType,
|
|
55
|
+
): ResolvedAttributes {
|
|
56
|
+
const { role, style, ...r } = normalizeEventKeys(props)
|
|
57
|
+
const styleStr = isObject(style, true)
|
|
58
|
+
? serializeStyle(style as StyleObject)
|
|
59
|
+
: (style as string | undefined)
|
|
60
|
+
const ep: IntrinsicProps = {
|
|
61
|
+
...(r as IntrinsicProps),
|
|
62
|
+
class: classStr,
|
|
63
|
+
...(styleStr !== undefined && { style: styleStr }),
|
|
64
|
+
}
|
|
65
|
+
if (isKnownAriaRole(role)) ep.role = role
|
|
66
|
+
if (!isString(tag)) return ep as ResolvedAttributes
|
|
67
|
+
return bundle.runtime.resolveAria(tag, ep).props as ResolvedAttributes
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function buildSlotProps(props: UnknownProps, classStr: string): UnknownProps {
|
|
71
|
+
const { role, ...r } = props
|
|
72
|
+
return {
|
|
73
|
+
...r,
|
|
74
|
+
class: classStr,
|
|
75
|
+
...(isKnownAriaRole(role) && { role }),
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const tag = $derived(bundle.runtime.resolveTag(asProp as ElementType | undefined))
|
|
80
|
+
const mergedProps = $derived(bundle.runtime.resolveProps(rest as UnknownProps))
|
|
81
|
+
const normalizedProps = $derived.by(() => {
|
|
82
|
+
const { runtime: { options } } = bundle
|
|
83
|
+
// Folded into this derived (rather than a standalone one) so it's guaranteed to run on
|
|
84
|
+
// both SSR and DOM — $derived is lazy in Svelte 5 and only evaluates when read; this one
|
|
85
|
+
// is read downstream by resolvedClass/filteredProps/domProps, which the template renders.
|
|
86
|
+
if (options.allowedAs !== undefined) {
|
|
87
|
+
enforceAllowedAs(
|
|
88
|
+
tag,
|
|
89
|
+
options.allowedAs,
|
|
90
|
+
options.diagnostics,
|
|
91
|
+
options.displayName,
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
const base =
|
|
95
|
+
typeof options.normalizeFn === 'function' ? options.normalizeFn(mergedProps) : mergedProps
|
|
96
|
+
|
|
97
|
+
const htmlNormalizers = options.htmlPropNormalizersFn?.(tag)
|
|
98
|
+
|
|
99
|
+
if (!htmlNormalizers?.length) {
|
|
100
|
+
return base
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return htmlNormalizers.reduce((acc, fn) => ({ ...acc, ...fn(acc) }), base)
|
|
104
|
+
})
|
|
105
|
+
const resolvedClass = $derived(
|
|
106
|
+
bundle.runtime.resolveClasses(tag, normalizedProps, cls as string | undefined, recipe),
|
|
107
|
+
)
|
|
108
|
+
const filteredProps = $derived(
|
|
109
|
+
applyFilter(normalizedProps, bundle.filterProps, bundle.runtime.options.variantKeys),
|
|
110
|
+
)
|
|
111
|
+
const domProps = $derived(buildDomProps(filteredProps, resolvedClass, tag))
|
|
112
|
+
|
|
113
|
+
// Resolves whether to render as child slot; also enforces as+asChild mutual exclusion.
|
|
114
|
+
const useAsChild = $derived.by(() => {
|
|
115
|
+
if (!asChild) return false
|
|
116
|
+
if (asProp !== undefined) {
|
|
117
|
+
bundle.slotValidator.assertExclusive()
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
return true
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// DOM-only (like Lit skipping htmlChildrenEvaluatorFn for its SSR renderToString). Merely
|
|
124
|
+
// *registering* $effect during svelte/server's render() throws ("effect_orphan") — it's not
|
|
125
|
+
// enough to no-op inside the callback, the rune call itself must never happen during SSR.
|
|
126
|
+
// Reads real child nodes off the mounted host, same approach as Lit's Array.from(this.childNodes).
|
|
127
|
+
// Not reachable in the asChild branch — no host element there.
|
|
128
|
+
if (typeof document !== 'undefined') {
|
|
129
|
+
$effect(() => {
|
|
130
|
+
if (process.env.NODE_ENV === 'production' || !hostEl) return
|
|
131
|
+
const childArray = Array.from(hostEl.childNodes)
|
|
132
|
+
bundle.childrenEvaluator?.evaluate(childArray, { tag, props: normalizedProps })
|
|
133
|
+
bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(childArray)
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
</script>
|
|
137
|
+
|
|
138
|
+
{#if useAsChild}
|
|
139
|
+
{#if children}
|
|
140
|
+
{@render (children as Snippet<[UnknownProps]>)(buildSlotProps(filteredProps, resolvedClass))}
|
|
141
|
+
{/if}
|
|
142
|
+
{:else}
|
|
143
|
+
<svelte:element this={tag as string} bind:this={hostEl} {...domProps}>
|
|
144
|
+
{@render (children as Snippet | undefined)?.()}
|
|
145
|
+
</svelte:element>
|
|
146
|
+
{/if}
|