@vertz/ui 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +339 -857
- package/dist/css/public.d.ts +24 -27
- package/dist/css/public.js +5 -1
- package/dist/form/public.d.ts +94 -38
- package/dist/form/public.js +5 -3
- package/dist/index.d.ts +696 -167
- package/dist/index.js +461 -84
- package/dist/internals.d.ts +192 -23
- package/dist/internals.js +151 -102
- package/dist/jsx-runtime/index.d.ts +44 -17
- package/dist/jsx-runtime/index.js +26 -7
- package/dist/query/public.d.ts +62 -7
- package/dist/query/public.js +12 -4
- package/dist/router/public.d.ts +186 -26
- package/dist/router/public.js +22 -7
- package/dist/shared/{chunk-f1ynwam4.js → chunk-0p5f7gmg.js} +155 -32
- package/dist/shared/{chunk-j8vzvne3.js → chunk-9e92w0wt.js} +4 -1
- package/dist/shared/{chunk-xd9d7q5p.js → chunk-cq7xg4xe.js} +59 -10
- package/dist/shared/chunk-g4rch80a.js +33 -0
- package/dist/shared/{chunk-pgymxpn1.js → chunk-hrd0mft1.js} +136 -34
- package/dist/shared/chunk-nmjyj8p9.js +290 -0
- package/dist/shared/chunk-pp3a6xbn.js +483 -0
- package/dist/shared/chunk-prj7nm08.js +67 -0
- package/dist/shared/chunk-q6cpe5k7.js +230 -0
- package/dist/shared/chunk-ryb49346.js +374 -0
- package/dist/shared/chunk-v3yyf79g.js +48 -0
- package/dist/shared/chunk-vx0kzack.js +103 -0
- package/dist/shared/chunk-wv6kkj1w.js +464 -0
- package/dist/test/index.d.ts +67 -6
- package/dist/test/index.js +4 -3
- package/package.json +13 -8
- package/dist/shared/chunk-bp3v6s9j.js +0 -62
- package/dist/shared/chunk-d8h2eh8d.js +0 -141
- package/dist/shared/chunk-tsdpgmks.js +0 -98
- package/dist/shared/chunk-zbbvx05f.js +0 -202
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__append,
|
|
3
|
+
__element,
|
|
4
|
+
__enterChildren,
|
|
5
|
+
__exitChildren
|
|
6
|
+
} from "./chunk-ryb49346.js";
|
|
7
|
+
|
|
8
|
+
// src/component/children.ts
|
|
9
|
+
var MAX_RESOLVE_DEPTH = 100;
|
|
10
|
+
function resolveChildren(value, _depth = 0) {
|
|
11
|
+
if (value == null) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
if (typeof value === "function") {
|
|
15
|
+
if (_depth >= MAX_RESOLVE_DEPTH) {
|
|
16
|
+
throw new Error("resolveChildren: max recursion depth exceeded — possible circular thunk");
|
|
17
|
+
}
|
|
18
|
+
return resolveChildren(value(), _depth + 1);
|
|
19
|
+
}
|
|
20
|
+
if (typeof value === "string") {
|
|
21
|
+
return [document.createTextNode(value)];
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === "number") {
|
|
24
|
+
return [document.createTextNode(String(value))];
|
|
25
|
+
}
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
const result = [];
|
|
28
|
+
for (const child of value) {
|
|
29
|
+
const resolved = resolveChildren(child, _depth);
|
|
30
|
+
for (const node of resolved) {
|
|
31
|
+
result.push(node);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
return [value];
|
|
37
|
+
}
|
|
38
|
+
function children(accessor) {
|
|
39
|
+
return () => resolveChildren(accessor());
|
|
40
|
+
}
|
|
41
|
+
|
|
1
42
|
// src/css/token-tables.ts
|
|
2
43
|
var PROPERTY_MAP = {
|
|
3
44
|
p: { properties: ["padding"], valueType: "spacing" },
|
|
@@ -37,6 +78,7 @@ var PROPERTY_MAP = {
|
|
|
37
78
|
weight: { properties: ["font-weight"], valueType: "font-weight" },
|
|
38
79
|
leading: { properties: ["line-height"], valueType: "line-height" },
|
|
39
80
|
tracking: { properties: ["letter-spacing"], valueType: "raw" },
|
|
81
|
+
decoration: { properties: ["text-decoration"], valueType: "raw" },
|
|
40
82
|
ring: { properties: ["outline"], valueType: "ring" },
|
|
41
83
|
cursor: { properties: ["cursor"], valueType: "raw" },
|
|
42
84
|
transition: { properties: ["transition"], valueType: "raw" },
|
|
@@ -65,7 +107,12 @@ var KEYWORD_MAP = {
|
|
|
65
107
|
uppercase: [{ property: "text-transform", value: "uppercase" }],
|
|
66
108
|
lowercase: [{ property: "text-transform", value: "lowercase" }],
|
|
67
109
|
capitalize: [{ property: "text-transform", value: "capitalize" }],
|
|
68
|
-
"outline-none": [{ property: "outline", value: "none" }]
|
|
110
|
+
"outline-none": [{ property: "outline", value: "none" }],
|
|
111
|
+
"overflow-hidden": [{ property: "overflow", value: "hidden" }],
|
|
112
|
+
"select-none": [{ property: "user-select", value: "none" }],
|
|
113
|
+
"pointer-events-none": [{ property: "pointer-events", value: "none" }],
|
|
114
|
+
"whitespace-nowrap": [{ property: "white-space", value: "nowrap" }],
|
|
115
|
+
"shrink-0": [{ property: "flex-shrink", value: "0" }]
|
|
69
116
|
};
|
|
70
117
|
var DISPLAY_MAP = {
|
|
71
118
|
flex: "flex",
|
|
@@ -114,7 +161,8 @@ var SPACING_SCALE = {
|
|
|
114
161
|
};
|
|
115
162
|
var RADIUS_SCALE = {
|
|
116
163
|
none: "0",
|
|
117
|
-
|
|
164
|
+
xs: "0.125rem",
|
|
165
|
+
sm: "0.25rem",
|
|
118
166
|
md: "0.375rem",
|
|
119
167
|
lg: "0.5rem",
|
|
120
168
|
xl: "0.75rem",
|
|
@@ -123,6 +171,7 @@ var RADIUS_SCALE = {
|
|
|
123
171
|
full: "9999px"
|
|
124
172
|
};
|
|
125
173
|
var SHADOW_SCALE = {
|
|
174
|
+
xs: "0 1px 1px 0 rgb(0 0 0 / 0.03)",
|
|
126
175
|
sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
|
|
127
176
|
md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
128
177
|
lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
|
|
@@ -209,7 +258,14 @@ var COLOR_NAMESPACES = new Set([
|
|
|
209
258
|
"input",
|
|
210
259
|
"card",
|
|
211
260
|
"popover",
|
|
212
|
-
"gray"
|
|
261
|
+
"gray",
|
|
262
|
+
"primary-foreground",
|
|
263
|
+
"secondary-foreground",
|
|
264
|
+
"accent-foreground",
|
|
265
|
+
"destructive-foreground",
|
|
266
|
+
"muted-foreground",
|
|
267
|
+
"card-foreground",
|
|
268
|
+
"popover-foreground"
|
|
213
269
|
]);
|
|
214
270
|
var CSS_COLOR_KEYWORDS = new Set([
|
|
215
271
|
"transparent",
|
|
@@ -244,8 +300,8 @@ var PSEUDO_MAP = {
|
|
|
244
300
|
};
|
|
245
301
|
|
|
246
302
|
// src/css/class-generator.ts
|
|
247
|
-
function generateClassName(filePath, blockName) {
|
|
248
|
-
const input = `${filePath}::${blockName}`;
|
|
303
|
+
function generateClassName(filePath, blockName, styleFingerprint = "") {
|
|
304
|
+
const input = styleFingerprint ? `${filePath}::${blockName}::${styleFingerprint}` : `${filePath}::${blockName}`;
|
|
249
305
|
const hash = djb2Hash(input);
|
|
250
306
|
return `_${hash}`;
|
|
251
307
|
}
|
|
@@ -558,20 +614,47 @@ function formatShorthand(parsed) {
|
|
|
558
614
|
// src/css/css.ts
|
|
559
615
|
var DEFAULT_FILE_PATH = "__runtime__";
|
|
560
616
|
var injectedCSS = new Set;
|
|
617
|
+
var vertzSheets = new Set;
|
|
561
618
|
function injectCSS(cssText) {
|
|
562
|
-
if (!cssText
|
|
619
|
+
if (!cssText)
|
|
620
|
+
return;
|
|
621
|
+
const isSSR = typeof globalThis.__SSR_URL__ === "string";
|
|
622
|
+
if (!isSSR && injectedCSS.has(cssText))
|
|
563
623
|
return;
|
|
564
624
|
injectedCSS.add(cssText);
|
|
625
|
+
if (typeof document === "undefined")
|
|
626
|
+
return;
|
|
627
|
+
if (typeof CSSStyleSheet !== "undefined" && document.adoptedStyleSheets !== undefined) {
|
|
628
|
+
const sheet = new CSSStyleSheet;
|
|
629
|
+
sheet.replaceSync(cssText);
|
|
630
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
631
|
+
vertzSheets.add(sheet);
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
565
634
|
const style = document.createElement("style");
|
|
566
635
|
style.setAttribute("data-vertz-css", "");
|
|
567
636
|
style.textContent = cssText;
|
|
568
637
|
document.head.appendChild(style);
|
|
569
638
|
}
|
|
639
|
+
function resetInjectedStyles() {
|
|
640
|
+
injectedCSS.clear();
|
|
641
|
+
if (typeof document !== "undefined" && document.adoptedStyleSheets !== undefined) {
|
|
642
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter((s) => !vertzSheets.has(s));
|
|
643
|
+
}
|
|
644
|
+
vertzSheets.clear();
|
|
645
|
+
}
|
|
646
|
+
function getInjectedCSS() {
|
|
647
|
+
return Array.from(injectedCSS);
|
|
648
|
+
}
|
|
570
649
|
function css(input, filePath = DEFAULT_FILE_PATH) {
|
|
650
|
+
if ("css" in input) {
|
|
651
|
+
throw new Error("css(): block name 'css' is reserved. Rename the block.");
|
|
652
|
+
}
|
|
571
653
|
const classNames = {};
|
|
572
654
|
const cssRules = [];
|
|
573
655
|
for (const [blockName, entries] of Object.entries(input)) {
|
|
574
|
-
const
|
|
656
|
+
const styleFingerprint = serializeEntries(entries);
|
|
657
|
+
const className = generateClassName(filePath, blockName, styleFingerprint);
|
|
575
658
|
classNames[blockName] = className;
|
|
576
659
|
const baseDeclarations = [];
|
|
577
660
|
const pseudoDeclarations = new Map;
|
|
@@ -591,12 +674,20 @@ function css(input, filePath = DEFAULT_FILE_PATH) {
|
|
|
591
674
|
for (const [selector, nestedEntries] of Object.entries(entry)) {
|
|
592
675
|
const nestedDecls = [];
|
|
593
676
|
for (const nestedEntry of nestedEntries) {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
677
|
+
if (typeof nestedEntry === "string") {
|
|
678
|
+
const parsed = parseShorthand(nestedEntry);
|
|
679
|
+
const resolved = resolveToken(parsed);
|
|
680
|
+
nestedDecls.push(...resolved.declarations);
|
|
681
|
+
} else if ("property" in nestedEntry && "value" in nestedEntry) {
|
|
682
|
+
nestedDecls.push({ property: nestedEntry.property, value: nestedEntry.value });
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (selector.startsWith("@")) {
|
|
686
|
+
nestedRules.push(formatAtRule(selector, `.${className}`, nestedDecls));
|
|
687
|
+
} else {
|
|
688
|
+
const resolvedSelector = selector.replaceAll("&", `.${className}`);
|
|
689
|
+
nestedRules.push(formatRule(resolvedSelector, nestedDecls));
|
|
597
690
|
}
|
|
598
|
-
const resolvedSelector = selector.replace("&", `.${className}`);
|
|
599
|
-
nestedRules.push(formatRule(resolvedSelector, nestedDecls));
|
|
600
691
|
}
|
|
601
692
|
}
|
|
602
693
|
}
|
|
@@ -611,10 +702,21 @@ function css(input, filePath = DEFAULT_FILE_PATH) {
|
|
|
611
702
|
const cssText = cssRules.join(`
|
|
612
703
|
`);
|
|
613
704
|
injectCSS(cssText);
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
705
|
+
const result = { ...classNames };
|
|
706
|
+
Object.defineProperty(result, "css", {
|
|
707
|
+
value: cssText,
|
|
708
|
+
enumerable: false,
|
|
709
|
+
configurable: false,
|
|
710
|
+
writable: false
|
|
711
|
+
});
|
|
712
|
+
return result;
|
|
713
|
+
}
|
|
714
|
+
function serializeEntries(entries) {
|
|
715
|
+
return entries.map((entry) => {
|
|
716
|
+
if (typeof entry === "string")
|
|
717
|
+
return entry;
|
|
718
|
+
return Object.entries(entry).map(([sel, vals]) => `${sel}:{${vals.map((v) => typeof v === "string" ? v : `${v.property}=${v.value}`).join(",")}}`).join(";");
|
|
719
|
+
}).join("|");
|
|
618
720
|
}
|
|
619
721
|
function formatRule(selector, declarations) {
|
|
620
722
|
const props = declarations.map((d) => ` ${d.property}: ${d.value};`).join(`
|
|
@@ -623,6 +725,15 @@ function formatRule(selector, declarations) {
|
|
|
623
725
|
${props}
|
|
624
726
|
}`;
|
|
625
727
|
}
|
|
728
|
+
function formatAtRule(atRule, classSelector, declarations) {
|
|
729
|
+
const props = declarations.map((d) => ` ${d.property}: ${d.value};`).join(`
|
|
730
|
+
`);
|
|
731
|
+
return `${atRule} {
|
|
732
|
+
${classSelector} {
|
|
733
|
+
${props}
|
|
734
|
+
}
|
|
735
|
+
}`;
|
|
736
|
+
}
|
|
626
737
|
|
|
627
738
|
// src/css/global-css.ts
|
|
628
739
|
function globalCss(input) {
|
|
@@ -687,6 +798,21 @@ function compileTheme(theme) {
|
|
|
687
798
|
const rootVars = [];
|
|
688
799
|
const darkVars = [];
|
|
689
800
|
const tokenPaths = [];
|
|
801
|
+
for (const name of Object.keys(theme.colors)) {
|
|
802
|
+
if (/[A-Z]/.test(name)) {
|
|
803
|
+
throw new Error(`Color token '${name}' uses camelCase. Use kebab-case to match CSS custom property naming.`);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
for (const [name, values] of Object.entries(theme.colors)) {
|
|
807
|
+
for (const key of Object.keys(values)) {
|
|
808
|
+
if (key === "DEFAULT" || key.startsWith("_"))
|
|
809
|
+
continue;
|
|
810
|
+
const compoundName = `${name}-${key}`;
|
|
811
|
+
if (COLOR_NAMESPACES.has(compoundName)) {
|
|
812
|
+
throw new Error(`Token collision: '${name}.${key}' produces CSS variable '--color-${name}-${key}' ` + `which conflicts with semantic token '${compoundName}'.`);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
690
816
|
for (const [name, values] of Object.entries(theme.colors)) {
|
|
691
817
|
for (const [key, value] of Object.entries(values)) {
|
|
692
818
|
if (key === "DEFAULT") {
|
|
@@ -734,17 +860,14 @@ ${darkVars.join(`
|
|
|
734
860
|
}
|
|
735
861
|
|
|
736
862
|
// src/css/theme-provider.ts
|
|
737
|
-
function ThemeProvider(
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
for (const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
el.appendChild(child);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
863
|
+
function ThemeProvider({ theme = "light", children: children2 }) {
|
|
864
|
+
const el = __element("div", { "data-theme": theme });
|
|
865
|
+
__enterChildren(el);
|
|
866
|
+
const nodes = resolveChildren(children2);
|
|
867
|
+
for (const node of nodes) {
|
|
868
|
+
__append(el, node);
|
|
869
|
+
}
|
|
870
|
+
__exitChildren();
|
|
748
871
|
return el;
|
|
749
872
|
}
|
|
750
873
|
|
|
@@ -772,7 +895,7 @@ function deriveConfigKey(config) {
|
|
|
772
895
|
function variants(config) {
|
|
773
896
|
const { base, variants: variantDefs, defaultVariants, compoundVariants } = config;
|
|
774
897
|
const filePath = deriveConfigKey(config);
|
|
775
|
-
const baseResult =
|
|
898
|
+
const baseResult = css({ base }, filePath);
|
|
776
899
|
const variantResults = {};
|
|
777
900
|
for (const [variantName, options] of Object.entries(variantDefs)) {
|
|
778
901
|
variantResults[variantName] = {};
|
|
@@ -780,7 +903,7 @@ function variants(config) {
|
|
|
780
903
|
if (styles.length > 0) {
|
|
781
904
|
const blockName = `${variantName}_${optionName}`;
|
|
782
905
|
const result = css({ [blockName]: styles }, filePath);
|
|
783
|
-
const className = result
|
|
906
|
+
const className = result[blockName];
|
|
784
907
|
if (className) {
|
|
785
908
|
variantResults[variantName][optionName] = {
|
|
786
909
|
className,
|
|
@@ -800,7 +923,7 @@ function variants(config) {
|
|
|
800
923
|
if (styles.length > 0) {
|
|
801
924
|
const blockName = `compound_${i}`;
|
|
802
925
|
const result = css({ [blockName]: styles }, filePath);
|
|
803
|
-
const className = result
|
|
926
|
+
const className = result[blockName];
|
|
804
927
|
if (className) {
|
|
805
928
|
compoundResults.push({
|
|
806
929
|
conditions,
|
|
@@ -826,7 +949,7 @@ function variants(config) {
|
|
|
826
949
|
}
|
|
827
950
|
const fn = (props) => {
|
|
828
951
|
const classNames = [];
|
|
829
|
-
const baseClassName = baseResult.
|
|
952
|
+
const baseClassName = baseResult.base;
|
|
830
953
|
if (baseClassName) {
|
|
831
954
|
classNames.push(baseClassName);
|
|
832
955
|
}
|
|
@@ -869,4 +992,4 @@ function variants(config) {
|
|
|
869
992
|
return fn;
|
|
870
993
|
}
|
|
871
994
|
|
|
872
|
-
export { 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, css, globalCss, s, defineTheme, compileTheme, ThemeProvider, variants };
|
|
995
|
+
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 };
|
|
@@ -67,7 +67,10 @@ function matchRoute(routes, url) {
|
|
|
67
67
|
for (const [key, value] of searchParams.entries()) {
|
|
68
68
|
raw[key] = value;
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
const parseResult = m.route.searchParams.parse(raw);
|
|
71
|
+
if (parseResult.ok) {
|
|
72
|
+
search = parseResult.data;
|
|
73
|
+
}
|
|
71
74
|
break;
|
|
72
75
|
}
|
|
73
76
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeLoaders,
|
|
3
3
|
matchRoute
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-9e92w0wt.js";
|
|
5
|
+
import {
|
|
6
|
+
prefetchNavData
|
|
7
|
+
} from "./chunk-vx0kzack.js";
|
|
5
8
|
import {
|
|
6
9
|
signal
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-hrd0mft1.js";
|
|
8
11
|
|
|
9
12
|
// src/router/navigate.ts
|
|
10
|
-
|
|
13
|
+
var DEFAULT_NAV_THRESHOLD_MS = 500;
|
|
14
|
+
function createRouter(routes, initialUrl, options) {
|
|
11
15
|
const isSSR = typeof window === "undefined" || typeof globalThis.__SSR_URL__ !== "undefined";
|
|
12
16
|
let url;
|
|
13
17
|
if (initialUrl) {
|
|
@@ -24,6 +28,42 @@ function createRouter(routes, initialUrl) {
|
|
|
24
28
|
const searchParams = signal(initialMatch?.search ?? {});
|
|
25
29
|
let navigationGen = 0;
|
|
26
30
|
let currentAbort = null;
|
|
31
|
+
const serverNavEnabled = !!options?.serverNav;
|
|
32
|
+
const serverNavTimeout = typeof options?.serverNav === "object" ? options.serverNav.timeout : undefined;
|
|
33
|
+
const prefetchFn = options?._prefetchNavData ?? (serverNavEnabled ? prefetchNavData : null);
|
|
34
|
+
let activePrefetch = null;
|
|
35
|
+
function startPrefetch(navUrl) {
|
|
36
|
+
if (!serverNavEnabled || !prefetchFn)
|
|
37
|
+
return null;
|
|
38
|
+
if (activePrefetch) {
|
|
39
|
+
activePrefetch.abort();
|
|
40
|
+
}
|
|
41
|
+
const prefetchOpts = {};
|
|
42
|
+
if (serverNavTimeout !== undefined) {
|
|
43
|
+
prefetchOpts.timeout = serverNavTimeout;
|
|
44
|
+
}
|
|
45
|
+
activePrefetch = prefetchFn(navUrl, prefetchOpts);
|
|
46
|
+
return activePrefetch;
|
|
47
|
+
}
|
|
48
|
+
async function awaitPrefetch(handle) {
|
|
49
|
+
if (!handle?.done)
|
|
50
|
+
return;
|
|
51
|
+
await Promise.race([
|
|
52
|
+
handle.done,
|
|
53
|
+
new Promise((r) => setTimeout(r, DEFAULT_NAV_THRESHOLD_MS))
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
if (isSSR) {
|
|
57
|
+
const g = globalThis;
|
|
58
|
+
const prev = g.__VERTZ_SSR_SYNC_ROUTER__;
|
|
59
|
+
g.__VERTZ_SSR_SYNC_ROUTER__ = (ssrUrl) => {
|
|
60
|
+
if (typeof prev === "function")
|
|
61
|
+
prev(ssrUrl);
|
|
62
|
+
const match = matchRoute(routes, ssrUrl);
|
|
63
|
+
current.value = match;
|
|
64
|
+
searchParams.value = match?.search ?? {};
|
|
65
|
+
};
|
|
66
|
+
}
|
|
27
67
|
if (initialMatch) {
|
|
28
68
|
const gen = ++navigationGen;
|
|
29
69
|
const abort = new AbortController;
|
|
@@ -63,15 +103,19 @@ function createRouter(routes, initialUrl) {
|
|
|
63
103
|
}
|
|
64
104
|
}
|
|
65
105
|
}
|
|
66
|
-
async function navigate(
|
|
106
|
+
async function navigate(navUrl, navOptions) {
|
|
107
|
+
const handle = startPrefetch(navUrl);
|
|
67
108
|
if (!isSSR) {
|
|
68
|
-
if (
|
|
69
|
-
window.history.replaceState(null, "",
|
|
109
|
+
if (navOptions?.replace) {
|
|
110
|
+
window.history.replaceState(null, "", navUrl);
|
|
70
111
|
} else {
|
|
71
|
-
window.history.pushState(null, "",
|
|
112
|
+
window.history.pushState(null, "", navUrl);
|
|
72
113
|
}
|
|
73
114
|
}
|
|
74
|
-
|
|
115
|
+
if (handle?.done) {
|
|
116
|
+
await awaitPrefetch(handle);
|
|
117
|
+
}
|
|
118
|
+
await applyNavigation(navUrl);
|
|
75
119
|
}
|
|
76
120
|
async function revalidate() {
|
|
77
121
|
const match = current.value;
|
|
@@ -88,8 +132,9 @@ function createRouter(routes, initialUrl) {
|
|
|
88
132
|
let onPopState = null;
|
|
89
133
|
if (!isSSR) {
|
|
90
134
|
onPopState = () => {
|
|
91
|
-
const
|
|
92
|
-
|
|
135
|
+
const popUrl = window.location.pathname + window.location.search;
|
|
136
|
+
startPrefetch(popUrl);
|
|
137
|
+
applyNavigation(popUrl).catch(() => {});
|
|
93
138
|
};
|
|
94
139
|
window.addEventListener("popstate", onPopState);
|
|
95
140
|
}
|
|
@@ -100,6 +145,10 @@ function createRouter(routes, initialUrl) {
|
|
|
100
145
|
if (currentAbort) {
|
|
101
146
|
currentAbort.abort();
|
|
102
147
|
}
|
|
148
|
+
if (activePrefetch) {
|
|
149
|
+
activePrefetch.abort();
|
|
150
|
+
activePrefetch = null;
|
|
151
|
+
}
|
|
103
152
|
}
|
|
104
153
|
return {
|
|
105
154
|
current,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/dom/dom-adapter.ts
|
|
2
|
+
function createDOMAdapter() {
|
|
3
|
+
return {
|
|
4
|
+
createElement: (tag) => document.createElement(tag),
|
|
5
|
+
createElementNS: (ns, tag) => document.createElementNS(ns, tag),
|
|
6
|
+
createTextNode: (text) => document.createTextNode(text),
|
|
7
|
+
createComment: (text) => document.createComment(text),
|
|
8
|
+
createDocumentFragment: () => document.createDocumentFragment(),
|
|
9
|
+
isNode: (value) => typeof Node !== "undefined" && value instanceof Node
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/dom/adapter.ts
|
|
14
|
+
var RENDER_NODE_BRAND = Symbol.for("vertz:render-node");
|
|
15
|
+
function isRenderNode(value) {
|
|
16
|
+
if (value == null || typeof value !== "object")
|
|
17
|
+
return false;
|
|
18
|
+
if (RENDER_NODE_BRAND in value)
|
|
19
|
+
return true;
|
|
20
|
+
return typeof Node !== "undefined" && value instanceof Node;
|
|
21
|
+
}
|
|
22
|
+
var currentAdapter = null;
|
|
23
|
+
function getAdapter() {
|
|
24
|
+
if (!currentAdapter) {
|
|
25
|
+
currentAdapter = createDOMAdapter();
|
|
26
|
+
}
|
|
27
|
+
return currentAdapter;
|
|
28
|
+
}
|
|
29
|
+
function setAdapter(adapter) {
|
|
30
|
+
currentAdapter = adapter;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { createDOMAdapter, RENDER_NODE_BRAND, isRenderNode, getAdapter, setAdapter };
|