@vertz/ui 0.2.15 → 0.2.16
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/README.md +49 -0
- package/dist/shared/chunk-14eqne2a.js +10 -0
- package/dist/shared/{chunk-dksg08fq.js → chunk-1rxa2fz4.js} +2 -8
- package/dist/shared/{chunk-8hsz5y4a.js → chunk-4fwcwxn6.js} +14 -4
- package/dist/shared/{chunk-hw67ckr3.js → chunk-4mtn7af6.js} +230 -19
- package/dist/shared/{chunk-4txc67nd.js → chunk-6jyt4ycw.js} +67 -2
- package/dist/shared/{chunk-83g4h38e.js → chunk-6wd36w21.js} +1 -0
- package/dist/shared/{chunk-h89w580h.js → chunk-afawz764.js} +1 -1
- package/dist/shared/{chunk-nn9v1zmk.js → chunk-b0qqqk03.js} +86 -21
- package/dist/shared/{chunk-1wby7nex.js → chunk-dhehvmj0.js} +161 -9
- package/dist/shared/{chunk-wymw818z.js → chunk-fkbgbf3n.js} +48 -9
- package/dist/shared/{chunk-5dbq8jp9.js → chunk-j09yyh34.js} +72 -6
- package/dist/shared/chunk-mtsvrj9e.js +23 -0
- package/dist/shared/chunk-pnv25zep.js +7 -0
- package/dist/shared/{chunk-j6qyxfdc.js → chunk-vndfjfdy.js} +3 -3
- package/dist/src/auth/public.d.ts +56 -9
- package/dist/src/auth/public.js +189 -13
- package/dist/src/css/public.d.ts +110 -2
- package/dist/src/css/public.js +8 -4
- package/dist/src/form/public.d.ts +29 -6
- package/dist/src/form/public.js +2 -2
- package/dist/src/index.d.ts +284 -13
- package/dist/src/index.js +161 -14
- package/dist/src/internals.d.ts +141 -5
- package/dist/src/internals.js +17 -9
- package/dist/src/query/public.js +4 -3
- package/dist/src/router/public.d.ts +17 -4
- package/dist/src/router/public.js +17 -11
- package/dist/src/test/index.d.ts +5 -0
- package/dist/src/test/index.js +4 -3
- package/package.json +3 -3
- package/reactivity.json +1 -11
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
__classList
|
|
2
|
+
__classList
|
|
3
|
+
} from "./chunk-1rxa2fz4.js";
|
|
4
|
+
import {
|
|
5
|
+
RouterContext
|
|
6
|
+
} from "./chunk-mtsvrj9e.js";
|
|
7
|
+
import {
|
|
3
8
|
__on
|
|
4
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-pnv25zep.js";
|
|
10
|
+
import {
|
|
11
|
+
isBrowser
|
|
12
|
+
} from "./chunk-14eqne2a.js";
|
|
5
13
|
import {
|
|
6
14
|
__append,
|
|
7
15
|
__element,
|
|
@@ -9,18 +17,19 @@ import {
|
|
|
9
17
|
__exitChildren,
|
|
10
18
|
__staticText,
|
|
11
19
|
getIsHydrating
|
|
12
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-vndfjfdy.js";
|
|
13
21
|
import {
|
|
14
22
|
_tryOnCleanup,
|
|
15
23
|
createContext,
|
|
16
24
|
domEffect,
|
|
25
|
+
getSSRContext,
|
|
17
26
|
popScope,
|
|
18
27
|
pushScope,
|
|
19
28
|
runCleanups,
|
|
20
29
|
signal,
|
|
21
30
|
untrack,
|
|
22
31
|
useContext
|
|
23
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-4fwcwxn6.js";
|
|
24
33
|
|
|
25
34
|
// src/router/link.ts
|
|
26
35
|
var DANGEROUS_SCHEMES = ["javascript:", "data:", "vbscript:"];
|
|
@@ -65,8 +74,10 @@ function createLink(currentPath, navigate, factoryOptions) {
|
|
|
65
74
|
} else {
|
|
66
75
|
__append(el, result);
|
|
67
76
|
}
|
|
68
|
-
} else {
|
|
77
|
+
} else if (typeof children === "string") {
|
|
69
78
|
__append(el, __staticText(children));
|
|
79
|
+
} else {
|
|
80
|
+
__append(el, children);
|
|
70
81
|
}
|
|
71
82
|
__exitChildren();
|
|
72
83
|
if (activeClass) {
|
|
@@ -88,22 +99,49 @@ function createLink(currentPath, navigate, factoryOptions) {
|
|
|
88
99
|
return el;
|
|
89
100
|
};
|
|
90
101
|
}
|
|
91
|
-
|
|
92
|
-
// src/router/router-context.ts
|
|
93
|
-
var RouterContext = createContext(undefined, "@vertz/ui::RouterContext");
|
|
94
|
-
function useRouter() {
|
|
102
|
+
function Link({ href, children, activeClass, className }) {
|
|
95
103
|
const router = useContext(RouterContext);
|
|
96
104
|
if (!router) {
|
|
97
|
-
throw new Error("
|
|
105
|
+
throw new Error("Link must be used within a RouterContext.Provider (via createRouter)");
|
|
98
106
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
const safeHref = isSafeUrl(href) ? href : "#";
|
|
108
|
+
const handleClick = (event) => {
|
|
109
|
+
const mouseEvent = event;
|
|
110
|
+
if (mouseEvent.ctrlKey || mouseEvent.metaKey || mouseEvent.shiftKey || mouseEvent.altKey) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
mouseEvent.preventDefault();
|
|
114
|
+
router.navigate({ to: safeHref });
|
|
115
|
+
};
|
|
116
|
+
const props = { href: safeHref };
|
|
117
|
+
if (className) {
|
|
118
|
+
props.class = className;
|
|
105
119
|
}
|
|
106
|
-
|
|
120
|
+
const el = __element("a", props);
|
|
121
|
+
__on(el, "click", handleClick);
|
|
122
|
+
__enterChildren(el);
|
|
123
|
+
if (typeof children === "function") {
|
|
124
|
+
const result = children();
|
|
125
|
+
if (typeof result === "string") {
|
|
126
|
+
__append(el, __staticText(result));
|
|
127
|
+
} else {
|
|
128
|
+
__append(el, result);
|
|
129
|
+
}
|
|
130
|
+
} else if (typeof children === "string") {
|
|
131
|
+
__append(el, __staticText(children));
|
|
132
|
+
} else {
|
|
133
|
+
__append(el, children);
|
|
134
|
+
}
|
|
135
|
+
__exitChildren();
|
|
136
|
+
if (activeClass) {
|
|
137
|
+
__classList(el, {
|
|
138
|
+
[activeClass]: () => {
|
|
139
|
+
router.current;
|
|
140
|
+
return isBrowser() ? window.location.pathname === safeHref : false;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
return el;
|
|
107
145
|
}
|
|
108
146
|
|
|
109
147
|
// src/router/outlet.ts
|
|
@@ -249,17 +287,44 @@ function buildLevels(matched) {
|
|
|
249
287
|
}));
|
|
250
288
|
}
|
|
251
289
|
function buildInsideOutFactory(matched, levels, startAt, router) {
|
|
252
|
-
|
|
290
|
+
const ssrCtx = getSSRContext();
|
|
291
|
+
const wrapForSSR = (route, routeIndex) => {
|
|
292
|
+
if (!ssrCtx)
|
|
293
|
+
return route.component;
|
|
294
|
+
const resolved = ssrCtx.resolvedComponents?.get(route);
|
|
295
|
+
if (resolved)
|
|
296
|
+
return resolved;
|
|
297
|
+
return () => {
|
|
298
|
+
const result = route.component();
|
|
299
|
+
if (result instanceof Promise) {
|
|
300
|
+
if (!ssrCtx.pendingRouteComponents) {
|
|
301
|
+
ssrCtx.pendingRouteComponents = new Map;
|
|
302
|
+
}
|
|
303
|
+
ssrCtx.pendingRouteComponents.set(route, result);
|
|
304
|
+
for (let j = routeIndex + 1;j < matched.length; j++) {
|
|
305
|
+
const childRoute = matched[j].route;
|
|
306
|
+
if (!ssrCtx.pendingRouteComponents.has(childRoute)) {
|
|
307
|
+
const childResult = childRoute.component();
|
|
308
|
+
if (childResult instanceof Promise) {
|
|
309
|
+
ssrCtx.pendingRouteComponents.set(childRoute, childResult);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
let factory = wrapForSSR(matched[matched.length - 1].route, matched.length - 1);
|
|
253
318
|
for (let i = matched.length - 2;i >= startAt; i--) {
|
|
254
319
|
const level = levels[i];
|
|
255
320
|
const childFactory = factory;
|
|
256
321
|
level.childSignal.value = childFactory;
|
|
257
|
-
const
|
|
322
|
+
const parentComponent = wrapForSSR(level.route, i);
|
|
258
323
|
const cs = level.childSignal;
|
|
259
324
|
factory = () => {
|
|
260
325
|
let result;
|
|
261
326
|
OutletContext.Provider({ childComponent: cs, router }, () => {
|
|
262
|
-
result =
|
|
327
|
+
result = parentComponent();
|
|
263
328
|
});
|
|
264
329
|
return result;
|
|
265
330
|
};
|
|
@@ -285,4 +350,4 @@ function useSearchParams(searchSignal) {
|
|
|
285
350
|
return searchSignal.value;
|
|
286
351
|
}
|
|
287
352
|
|
|
288
|
-
export { createLink,
|
|
353
|
+
export { createLink, Link, OutletContext, Outlet, RouterView, parseSearchParams, useSearchParams };
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
__element,
|
|
4
4
|
__enterChildren,
|
|
5
5
|
__exitChildren
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-vndfjfdy.js";
|
|
7
7
|
import {
|
|
8
8
|
getSSRContext
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-4fwcwxn6.js";
|
|
10
10
|
|
|
11
11
|
// src/component/children.ts
|
|
12
12
|
var MAX_RESOLVE_DEPTH = 100;
|
|
@@ -757,6 +757,143 @@ ${props}
|
|
|
757
757
|
}`;
|
|
758
758
|
}
|
|
759
759
|
|
|
760
|
+
// src/css/sanitize.ts
|
|
761
|
+
function sanitizeCssValue(value) {
|
|
762
|
+
return value.replace(/[;{}<>']/g, "").replace(/url\s*\(/gi, "").replace(/expression\s*\(/gi, "").replace(/@import/gi, "");
|
|
763
|
+
}
|
|
764
|
+
function escapeHtmlAttr(value) {
|
|
765
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">").replace(/'/g, "'");
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
// src/css/font.ts
|
|
769
|
+
function font(family, options) {
|
|
770
|
+
return {
|
|
771
|
+
__brand: "FontDescriptor",
|
|
772
|
+
family,
|
|
773
|
+
weight: String(options.weight),
|
|
774
|
+
style: options.style ?? "normal",
|
|
775
|
+
display: options.display ?? "swap",
|
|
776
|
+
src: options.src,
|
|
777
|
+
fallback: options.fallback ?? [],
|
|
778
|
+
subsets: options.subsets ?? ["latin"],
|
|
779
|
+
unicodeRange: options.unicodeRange,
|
|
780
|
+
adjustFontFallback: options.adjustFontFallback ?? true
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
function toCssWeight(weight) {
|
|
784
|
+
return sanitizeCssValue(weight).replace("..", " ");
|
|
785
|
+
}
|
|
786
|
+
function buildFontFace(family, src, weight, style, display, unicodeRange) {
|
|
787
|
+
const safeFamily = sanitizeCssValue(family);
|
|
788
|
+
const safeSrc = sanitizeCssValue(src);
|
|
789
|
+
const safeStyle = sanitizeCssValue(style);
|
|
790
|
+
const safeDisplay = sanitizeCssValue(display);
|
|
791
|
+
const lines = [
|
|
792
|
+
"@font-face {",
|
|
793
|
+
` font-family: '${safeFamily}';`,
|
|
794
|
+
` font-style: ${safeStyle};`,
|
|
795
|
+
` font-weight: ${toCssWeight(weight)};`,
|
|
796
|
+
` font-display: ${safeDisplay};`,
|
|
797
|
+
` src: url(${safeSrc}) format('woff2');`
|
|
798
|
+
];
|
|
799
|
+
if (unicodeRange) {
|
|
800
|
+
lines.push(` unicode-range: ${sanitizeCssValue(unicodeRange)};`);
|
|
801
|
+
}
|
|
802
|
+
lines.push("}");
|
|
803
|
+
return lines.join(`
|
|
804
|
+
`);
|
|
805
|
+
}
|
|
806
|
+
var PERCENT_RE = /^\d+\.\d+%$/;
|
|
807
|
+
function sanitizeMetricValue(value) {
|
|
808
|
+
if (!PERCENT_RE.test(value)) {
|
|
809
|
+
throw new Error(`Invalid font metric override value: "${value}"`);
|
|
810
|
+
}
|
|
811
|
+
return value;
|
|
812
|
+
}
|
|
813
|
+
function buildFallbackFontFace(family, metrics) {
|
|
814
|
+
const safeFamily = sanitizeCssValue(family);
|
|
815
|
+
const lines = [
|
|
816
|
+
"@font-face {",
|
|
817
|
+
` font-family: '${safeFamily} Fallback';`,
|
|
818
|
+
` src: local('${metrics.fallbackFont}');`,
|
|
819
|
+
` ascent-override: ${sanitizeMetricValue(metrics.ascentOverride)};`,
|
|
820
|
+
` descent-override: ${sanitizeMetricValue(metrics.descentOverride)};`,
|
|
821
|
+
` line-gap-override: ${sanitizeMetricValue(metrics.lineGapOverride)};`,
|
|
822
|
+
` size-adjust: ${sanitizeMetricValue(metrics.sizeAdjust)};`,
|
|
823
|
+
"}"
|
|
824
|
+
];
|
|
825
|
+
return lines.join(`
|
|
826
|
+
`);
|
|
827
|
+
}
|
|
828
|
+
function validateWoff2Src(path) {
|
|
829
|
+
if (!path.toLowerCase().endsWith(".woff2")) {
|
|
830
|
+
throw new Error(`Font src "${path}" is not a .woff2 file. Only woff2 format is currently supported.`);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
function compileFonts(fonts, options) {
|
|
834
|
+
const fontFaces = [];
|
|
835
|
+
const cssVars = [];
|
|
836
|
+
const preloadPaths = [];
|
|
837
|
+
const fallbackMetrics = options?.fallbackMetrics;
|
|
838
|
+
for (const [key, descriptor] of Object.entries(fonts)) {
|
|
839
|
+
if (!/^[a-zA-Z0-9-]+$/.test(key)) {
|
|
840
|
+
throw new Error(`Font key "${key}" contains invalid CSS identifier characters. Use only [a-zA-Z0-9-].`);
|
|
841
|
+
}
|
|
842
|
+
const { family, weight, style, display, src, fallback, unicodeRange } = descriptor;
|
|
843
|
+
const adjustFontFallback = descriptor.adjustFontFallback ?? true;
|
|
844
|
+
const metrics = fallbackMetrics?.[key];
|
|
845
|
+
const shouldGenerateFallback = metrics && src && adjustFontFallback !== false;
|
|
846
|
+
const safeFamily = sanitizeCssValue(family);
|
|
847
|
+
const safeFallbacks = fallback.map(sanitizeCssValue);
|
|
848
|
+
const fallbackFontName = shouldGenerateFallback ? `'${safeFamily} Fallback'` : undefined;
|
|
849
|
+
const familyParts = [
|
|
850
|
+
`'${safeFamily}'`,
|
|
851
|
+
...fallbackFontName ? [fallbackFontName] : [],
|
|
852
|
+
...safeFallbacks
|
|
853
|
+
];
|
|
854
|
+
const familyValue = familyParts.join(", ");
|
|
855
|
+
cssVars.push(` --font-${sanitizeCssValue(key)}: ${familyValue};`);
|
|
856
|
+
if (!src)
|
|
857
|
+
continue;
|
|
858
|
+
if (typeof src === "string") {
|
|
859
|
+
validateWoff2Src(src);
|
|
860
|
+
fontFaces.push(buildFontFace(family, src, weight, style, display, unicodeRange));
|
|
861
|
+
preloadPaths.push(src);
|
|
862
|
+
} else {
|
|
863
|
+
for (const entry of src) {
|
|
864
|
+
validateWoff2Src(entry.path);
|
|
865
|
+
const entryWeight = entry.weight != null ? String(entry.weight) : weight;
|
|
866
|
+
const entryStyle = entry.style ?? style;
|
|
867
|
+
fontFaces.push(buildFontFace(family, entry.path, entryWeight, entryStyle, display, unicodeRange));
|
|
868
|
+
}
|
|
869
|
+
const first = src[0];
|
|
870
|
+
if (first) {
|
|
871
|
+
preloadPaths.push(first.path);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
if (shouldGenerateFallback) {
|
|
875
|
+
fontFaces.push(buildFallbackFontFace(family, metrics));
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
const fontFaceCss = fontFaces.join(`
|
|
879
|
+
|
|
880
|
+
`);
|
|
881
|
+
const cssVarLines = cssVars;
|
|
882
|
+
const cssVarsCss = cssVars.length > 0 ? `:root {
|
|
883
|
+
${cssVars.join(`
|
|
884
|
+
`)}
|
|
885
|
+
}` : "";
|
|
886
|
+
const preloadTags = preloadPaths.map((p) => `<link rel="preload" href="${escapeHtmlAttr(p)}" as="font" type="font/woff2" crossorigin>`).join(`
|
|
887
|
+
`);
|
|
888
|
+
const preloadItems = preloadPaths.map((href) => ({
|
|
889
|
+
href,
|
|
890
|
+
as: "font",
|
|
891
|
+
type: "font/woff2",
|
|
892
|
+
crossorigin: true
|
|
893
|
+
}));
|
|
894
|
+
return { fontFaceCss, cssVarsCss, cssVarLines, preloadTags, preloadItems };
|
|
895
|
+
}
|
|
896
|
+
|
|
760
897
|
// src/css/global-css.ts
|
|
761
898
|
function globalCss(input) {
|
|
762
899
|
const rules = [];
|
|
@@ -810,16 +947,14 @@ class InlineStyleError extends Error {
|
|
|
810
947
|
}
|
|
811
948
|
|
|
812
949
|
// src/css/theme.ts
|
|
813
|
-
function sanitizeCssValue(value) {
|
|
814
|
-
return value.replace(/[;{}]/g, "").replace(/url\s*\(/gi, "").replace(/expression\s*\(/gi, "").replace(/@import/gi, "");
|
|
815
|
-
}
|
|
816
950
|
function defineTheme(input) {
|
|
817
951
|
return {
|
|
818
952
|
colors: input.colors,
|
|
819
|
-
spacing: input.spacing
|
|
953
|
+
spacing: input.spacing,
|
|
954
|
+
fonts: input.fonts
|
|
820
955
|
};
|
|
821
956
|
}
|
|
822
|
-
function compileTheme(theme) {
|
|
957
|
+
function compileTheme(theme, options) {
|
|
823
958
|
const rootVars = [];
|
|
824
959
|
const darkVars = [];
|
|
825
960
|
const tokenPaths = [];
|
|
@@ -864,7 +999,22 @@ function compileTheme(theme) {
|
|
|
864
999
|
tokenPaths.push(`spacing.${name}`);
|
|
865
1000
|
}
|
|
866
1001
|
}
|
|
1002
|
+
let fontFaceCss = "";
|
|
1003
|
+
let preloadTags = "";
|
|
1004
|
+
let preloadItems = [];
|
|
1005
|
+
if (theme.fonts) {
|
|
1006
|
+
const compiled = compileFonts(theme.fonts, {
|
|
1007
|
+
fallbackMetrics: options?.fallbackMetrics
|
|
1008
|
+
});
|
|
1009
|
+
fontFaceCss = compiled.fontFaceCss;
|
|
1010
|
+
preloadTags = compiled.preloadTags;
|
|
1011
|
+
preloadItems = compiled.preloadItems;
|
|
1012
|
+
rootVars.push(...compiled.cssVarLines);
|
|
1013
|
+
}
|
|
867
1014
|
const blocks = [];
|
|
1015
|
+
if (fontFaceCss) {
|
|
1016
|
+
blocks.push(fontFaceCss);
|
|
1017
|
+
}
|
|
868
1018
|
if (rootVars.length > 0) {
|
|
869
1019
|
blocks.push(`:root {
|
|
870
1020
|
${rootVars.join(`
|
|
@@ -880,7 +1030,9 @@ ${darkVars.join(`
|
|
|
880
1030
|
return {
|
|
881
1031
|
css: blocks.join(`
|
|
882
1032
|
`),
|
|
883
|
-
tokens: tokenPaths
|
|
1033
|
+
tokens: tokenPaths,
|
|
1034
|
+
preloadTags,
|
|
1035
|
+
preloadItems
|
|
884
1036
|
};
|
|
885
1037
|
}
|
|
886
1038
|
|
|
@@ -1017,4 +1169,4 @@ function variants(config) {
|
|
|
1017
1169
|
return fn;
|
|
1018
1170
|
}
|
|
1019
1171
|
|
|
1020
|
-
export { resolveChildren, children, PROPERTY_MAP, KEYWORD_MAP, DISPLAY_MAP, SPACING_SCALE, RADIUS_SCALE, SHADOW_SCALE, FONT_SIZE_SCALE, FONT_WEIGHT_SCALE, LINE_HEIGHT_SCALE, ALIGNMENT_MAP, SIZE_KEYWORDS, HEIGHT_AXIS_PROPERTIES, COLOR_NAMESPACES, CSS_COLOR_KEYWORDS, CONTENT_MAP, PSEUDO_PREFIXES, PSEUDO_MAP, injectCSS, resetInjectedStyles, getInjectedCSS, css, globalCss, s, defineTheme, compileTheme, ThemeProvider, variants };
|
|
1172
|
+
export { resolveChildren, children, PROPERTY_MAP, KEYWORD_MAP, DISPLAY_MAP, SPACING_SCALE, RADIUS_SCALE, SHADOW_SCALE, FONT_SIZE_SCALE, FONT_WEIGHT_SCALE, LINE_HEIGHT_SCALE, ALIGNMENT_MAP, SIZE_KEYWORDS, HEIGHT_AXIS_PROPERTIES, COLOR_NAMESPACES, CSS_COLOR_KEYWORDS, CONTENT_MAP, PSEUDO_PREFIXES, PSEUDO_MAP, injectCSS, resetInjectedStyles, getInjectedCSS, css, font, compileFonts, globalCss, s, defineTheme, compileTheme, ThemeProvider, variants };
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeLoaders,
|
|
3
3
|
matchRoute
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6wd36w21.js";
|
|
5
5
|
import {
|
|
6
6
|
prefetchNavData
|
|
7
7
|
} from "./chunk-jrtrk5z4.js";
|
|
8
|
+
import {
|
|
9
|
+
isBrowser
|
|
10
|
+
} from "./chunk-14eqne2a.js";
|
|
8
11
|
import {
|
|
9
12
|
getSSRContext,
|
|
10
13
|
signal
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-4fwcwxn6.js";
|
|
12
15
|
|
|
13
16
|
// src/router/navigate.ts
|
|
14
17
|
var DEFAULT_NAV_THRESHOLD_MS = 500;
|
|
@@ -59,24 +62,34 @@ function buildSearch(search) {
|
|
|
59
62
|
function buildNavigationUrl(to, options) {
|
|
60
63
|
return `${interpolatePath(to, options?.params)}${buildSearch(options?.search)}`;
|
|
61
64
|
}
|
|
62
|
-
function createRouter(routes,
|
|
65
|
+
function createRouter(routes, initialUrlOrOptions, maybeOptions) {
|
|
66
|
+
const initialUrl = typeof initialUrlOrOptions === "string" ? initialUrlOrOptions : undefined;
|
|
67
|
+
const options = typeof initialUrlOrOptions === "object" ? initialUrlOrOptions : maybeOptions;
|
|
63
68
|
const ssrCtx = getSSRContext();
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
if (!isBrowser()) {
|
|
70
|
+
let registerRoutesForDiscovery = function(ctx) {
|
|
71
|
+
if (!ctx.discoveredRoutes) {
|
|
72
|
+
ctx.discoveredRoutes = collectRoutePatterns(routes);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
66
75
|
const ssrUrl = initialUrl ?? ssrCtx?.url ?? "/";
|
|
67
76
|
const fallbackMatch = matchRoute(routes, ssrUrl);
|
|
68
77
|
return {
|
|
69
78
|
current: {
|
|
70
79
|
get value() {
|
|
71
80
|
const ctx = getSSRContext();
|
|
72
|
-
if (ctx)
|
|
81
|
+
if (ctx) {
|
|
82
|
+
registerRoutesForDiscovery(ctx);
|
|
73
83
|
return matchRoute(routes, ctx.url);
|
|
84
|
+
}
|
|
74
85
|
return fallbackMatch;
|
|
75
86
|
},
|
|
76
87
|
peek() {
|
|
77
88
|
const ctx = getSSRContext();
|
|
78
|
-
if (ctx)
|
|
89
|
+
if (ctx) {
|
|
90
|
+
registerRoutesForDiscovery(ctx);
|
|
79
91
|
return matchRoute(routes, ctx.url);
|
|
92
|
+
}
|
|
80
93
|
return fallbackMatch;
|
|
81
94
|
},
|
|
82
95
|
notify() {}
|
|
@@ -129,8 +142,12 @@ function createRouter(routes, initialUrl, options) {
|
|
|
129
142
|
const current = {
|
|
130
143
|
get value() {
|
|
131
144
|
const ctx = getSSRContext();
|
|
132
|
-
if (ctx)
|
|
145
|
+
if (ctx) {
|
|
146
|
+
if (!ctx.discoveredRoutes) {
|
|
147
|
+
ctx.discoveredRoutes = collectRoutePatterns(routes);
|
|
148
|
+
}
|
|
133
149
|
return matchRoute(routes, ctx.url);
|
|
150
|
+
}
|
|
134
151
|
return _current.value;
|
|
135
152
|
},
|
|
136
153
|
set value(v) {
|
|
@@ -138,8 +155,12 @@ function createRouter(routes, initialUrl, options) {
|
|
|
138
155
|
},
|
|
139
156
|
peek() {
|
|
140
157
|
const ctx = getSSRContext();
|
|
141
|
-
if (ctx)
|
|
158
|
+
if (ctx) {
|
|
159
|
+
if (!ctx.discoveredRoutes) {
|
|
160
|
+
ctx.discoveredRoutes = collectRoutePatterns(routes);
|
|
161
|
+
}
|
|
142
162
|
return matchRoute(routes, ctx.url);
|
|
163
|
+
}
|
|
143
164
|
return _current.peek();
|
|
144
165
|
},
|
|
145
166
|
notify() {
|
|
@@ -298,5 +319,23 @@ function createRouter(routes, initialUrl, options) {
|
|
|
298
319
|
searchParams
|
|
299
320
|
};
|
|
300
321
|
}
|
|
322
|
+
function collectRoutePatterns(routes, prefix = "") {
|
|
323
|
+
const patterns = [];
|
|
324
|
+
for (const route of routes) {
|
|
325
|
+
const fullPattern = joinPatterns(prefix, route.pattern);
|
|
326
|
+
patterns.push(fullPattern);
|
|
327
|
+
if (route.children) {
|
|
328
|
+
patterns.push(...collectRoutePatterns(route.children, fullPattern));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return patterns;
|
|
332
|
+
}
|
|
333
|
+
function joinPatterns(parent, child) {
|
|
334
|
+
if (!parent || parent === "/")
|
|
335
|
+
return child;
|
|
336
|
+
if (child === "/")
|
|
337
|
+
return parent;
|
|
338
|
+
return `${parent.replace(/\/$/, "")}/${child.replace(/^\//, "")}`;
|
|
339
|
+
}
|
|
301
340
|
|
|
302
341
|
export { createRouter };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
computed,
|
|
3
3
|
signal
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4fwcwxn6.js";
|
|
5
5
|
|
|
6
6
|
// src/form/field-state.ts
|
|
7
7
|
function createFieldState(_name, initialValue) {
|
|
@@ -31,14 +31,40 @@ function createFieldState(_name, initialValue) {
|
|
|
31
31
|
function formDataToObject(formData, options) {
|
|
32
32
|
const result = {};
|
|
33
33
|
const coerce = options?.coerce ?? false;
|
|
34
|
+
const nested = options?.nested ?? false;
|
|
34
35
|
for (const [key, value] of formData.entries()) {
|
|
35
36
|
if (typeof value !== "string") {
|
|
36
37
|
continue;
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
+
const coerced = coerce ? coerceValue(value) : value;
|
|
40
|
+
if (nested && key.includes(".")) {
|
|
41
|
+
setNestedValue(result, key, coerced);
|
|
42
|
+
} else {
|
|
43
|
+
result[key] = coerced;
|
|
44
|
+
}
|
|
39
45
|
}
|
|
40
46
|
return result;
|
|
41
47
|
}
|
|
48
|
+
var DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
49
|
+
function setNestedValue(obj, dotPath, value) {
|
|
50
|
+
const segments = dotPath.split(".");
|
|
51
|
+
let current = obj;
|
|
52
|
+
for (let i = 0;i < segments.length - 1; i++) {
|
|
53
|
+
const segment = segments[i];
|
|
54
|
+
if (DANGEROUS_KEYS.has(segment))
|
|
55
|
+
return;
|
|
56
|
+
const nextSegment = segments[i + 1];
|
|
57
|
+
const isNextArray = /^\d+$/.test(nextSegment);
|
|
58
|
+
if (!(segment in current)) {
|
|
59
|
+
current[segment] = isNextArray ? [] : {};
|
|
60
|
+
}
|
|
61
|
+
current = current[segment];
|
|
62
|
+
}
|
|
63
|
+
const lastSegment = segments[segments.length - 1];
|
|
64
|
+
if (DANGEROUS_KEYS.has(lastSegment))
|
|
65
|
+
return;
|
|
66
|
+
current[lastSegment] = value;
|
|
67
|
+
}
|
|
42
68
|
function coerceValue(value) {
|
|
43
69
|
if (value === "true")
|
|
44
70
|
return true;
|
|
@@ -79,8 +105,11 @@ function validate(schema, data) {
|
|
|
79
105
|
}
|
|
80
106
|
|
|
81
107
|
// src/form/form.ts
|
|
108
|
+
var FIELD_STATE_SIGNALS = new Set(["error", "dirty", "touched", "value"]);
|
|
109
|
+
var FIELD_STATE_METHODS = new Set(["setValue", "reset"]);
|
|
82
110
|
function form(sdkMethod, options) {
|
|
83
111
|
const fieldCache = new Map;
|
|
112
|
+
const chainProxyCache = new Map;
|
|
84
113
|
const submitting = signal(false);
|
|
85
114
|
const fieldGeneration = signal(0);
|
|
86
115
|
const dirty = computed(() => {
|
|
@@ -99,20 +128,57 @@ function form(sdkMethod, options) {
|
|
|
99
128
|
}
|
|
100
129
|
return true;
|
|
101
130
|
});
|
|
131
|
+
function resolveNestedInitial(dotPath) {
|
|
132
|
+
const initialObj = typeof options?.initial === "function" ? options.initial() : options?.initial;
|
|
133
|
+
if (!initialObj)
|
|
134
|
+
return;
|
|
135
|
+
const segments = dotPath.split(".");
|
|
136
|
+
let current = initialObj;
|
|
137
|
+
for (const segment of segments) {
|
|
138
|
+
if (current == null || typeof current !== "object")
|
|
139
|
+
return;
|
|
140
|
+
current = current[segment];
|
|
141
|
+
}
|
|
142
|
+
return current;
|
|
143
|
+
}
|
|
102
144
|
function getOrCreateField(name) {
|
|
103
145
|
let field = fieldCache.get(name);
|
|
104
146
|
if (!field) {
|
|
105
|
-
const
|
|
106
|
-
|
|
147
|
+
const initialValue = name.includes(".") ? resolveNestedInitial(name) : (() => {
|
|
148
|
+
const initialObj = typeof options?.initial === "function" ? options.initial() : options?.initial;
|
|
149
|
+
return initialObj?.[name];
|
|
150
|
+
})();
|
|
107
151
|
field = createFieldState(name, initialValue);
|
|
108
152
|
fieldCache.set(name, field);
|
|
109
153
|
fieldGeneration.value++;
|
|
110
154
|
}
|
|
111
155
|
return field;
|
|
112
156
|
}
|
|
157
|
+
function getOrCreateChainProxy(dotPath) {
|
|
158
|
+
let proxy = chainProxyCache.get(dotPath);
|
|
159
|
+
if (proxy)
|
|
160
|
+
return proxy;
|
|
161
|
+
proxy = new Proxy(Object.create(null), {
|
|
162
|
+
get(_target, prop) {
|
|
163
|
+
if (typeof prop === "string") {
|
|
164
|
+
if (FIELD_STATE_SIGNALS.has(prop)) {
|
|
165
|
+
return getOrCreateField(dotPath)[prop];
|
|
166
|
+
}
|
|
167
|
+
if (FIELD_STATE_METHODS.has(prop)) {
|
|
168
|
+
return getOrCreateField(dotPath)[prop];
|
|
169
|
+
}
|
|
170
|
+
const childPath = `${dotPath}.${prop}`;
|
|
171
|
+
return getOrCreateChainProxy(childPath);
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
chainProxyCache.set(dotPath, proxy);
|
|
177
|
+
return proxy;
|
|
178
|
+
}
|
|
113
179
|
const resolvedSchema = options?.schema ?? sdkMethod.meta?.bodySchema;
|
|
114
180
|
async function submitPipeline(formData) {
|
|
115
|
-
const data = formDataToObject(formData);
|
|
181
|
+
const data = formDataToObject(formData, { nested: true });
|
|
116
182
|
if (resolvedSchema) {
|
|
117
183
|
const result2 = validate(resolvedSchema, data);
|
|
118
184
|
if (!result2.success) {
|
|
@@ -227,7 +293,7 @@ function form(sdkMethod, options) {
|
|
|
227
293
|
if (knownProperties.has(prop)) {
|
|
228
294
|
return target[prop];
|
|
229
295
|
}
|
|
230
|
-
return
|
|
296
|
+
return getOrCreateChainProxy(prop);
|
|
231
297
|
}
|
|
232
298
|
return Reflect.get(target, prop, receiver);
|
|
233
299
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext
|
|
4
|
+
} from "./chunk-4fwcwxn6.js";
|
|
5
|
+
|
|
6
|
+
// src/router/router-context.ts
|
|
7
|
+
var RouterContext = createContext(undefined, "@vertz/ui::RouterContext");
|
|
8
|
+
function useRouter() {
|
|
9
|
+
const router = useContext(RouterContext);
|
|
10
|
+
if (!router) {
|
|
11
|
+
throw new Error("useRouter() must be called within RouterContext.Provider");
|
|
12
|
+
}
|
|
13
|
+
return router;
|
|
14
|
+
}
|
|
15
|
+
function useParams() {
|
|
16
|
+
const router = useContext(RouterContext);
|
|
17
|
+
if (!router) {
|
|
18
|
+
throw new Error("useParams() must be called within RouterContext.Provider");
|
|
19
|
+
}
|
|
20
|
+
return router.current?.parsedParams ?? router.current?.params ?? {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { RouterContext, useRouter, useParams };
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
getAdapter,
|
|
8
8
|
isRenderNode
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-afawz764.js";
|
|
10
10
|
import {
|
|
11
11
|
domEffect
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-4fwcwxn6.js";
|
|
13
13
|
|
|
14
14
|
// src/hydrate/hydration-context.ts
|
|
15
15
|
var isHydrating = false;
|
|
@@ -371,4 +371,4 @@ function __exitChildren() {
|
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
-
export { startHydration, endHydration, getIsHydrating, claimText, claimComment, __text, __child, __insert, __element, __append, __staticText, __enterChildren, __exitChildren };
|
|
374
|
+
export { startHydration, endHydration, getIsHydrating, claimElement, claimText, claimComment, enterChildren, exitChildren, __text, __child, __insert, __element, __append, __staticText, __enterChildren, __exitChildren };
|