@vertz/ui 0.2.0 → 0.2.2
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 +754 -167
- package/dist/index.js +606 -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 +73 -7
- package/dist/query/public.js +12 -4
- package/dist/router/public.d.ts +199 -26
- package/dist/router/public.js +22 -7
- package/dist/shared/chunk-0xcmwgdb.js +288 -0
- package/dist/shared/{chunk-j8vzvne3.js → chunk-9e92w0wt.js} +4 -1
- package/dist/shared/chunk-g4rch80a.js +33 -0
- package/dist/shared/chunk-hh0dhmb4.js +528 -0
- package/dist/shared/{chunk-pgymxpn1.js → chunk-hrd0mft1.js} +136 -34
- package/dist/shared/chunk-jrtrk5z4.js +125 -0
- package/dist/shared/chunk-ka5ked7n.js +188 -0
- package/dist/shared/chunk-n91rwj2r.js +483 -0
- package/dist/shared/chunk-prj7nm08.js +67 -0
- package/dist/shared/chunk-q6cpe5k7.js +230 -0
- package/dist/shared/{chunk-f1ynwam4.js → chunk-qacth5ah.js} +162 -36
- package/dist/shared/chunk-ryb49346.js +374 -0
- package/dist/shared/chunk-v3yyf79g.js +48 -0
- package/dist/test/index.d.ts +67 -6
- package/dist/test/index.js +4 -3
- package/package.json +14 -9
- 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-xd9d7q5p.js +0 -115
- package/dist/shared/chunk-zbbvx05f.js +0 -202
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** A single child value: DOM node, string, number, null, undefined, or nested array. */
|
|
2
|
-
type ChildValue = Node | string | number | null | undefined | ChildValue[];
|
|
1
|
+
/** A single child value: DOM node, string, number, null, undefined, thunk, or nested array. */
|
|
2
|
+
type ChildValue = Node | string | number | null | undefined | ChildValue[] | (() => ChildValue);
|
|
3
3
|
/** A function that returns children (slot accessor). */
|
|
4
4
|
type ChildrenAccessor = () => ChildValue;
|
|
5
5
|
/**
|
|
@@ -7,18 +7,94 @@ type ChildrenAccessor = () => ChildValue;
|
|
|
7
7
|
* Strings and numbers are converted to Text nodes.
|
|
8
8
|
* Null and undefined are filtered out.
|
|
9
9
|
* Arrays are flattened recursively.
|
|
10
|
+
* Thunks (functions) are called and their results re-resolved.
|
|
10
11
|
*/
|
|
11
|
-
declare function resolveChildren(value: ChildValue): Node[];
|
|
12
|
+
declare function resolveChildren(value: ChildValue, _depth?: number): Node[];
|
|
12
13
|
/**
|
|
13
14
|
* Create a children resolver from a children accessor.
|
|
14
15
|
* Returns a function that, when called, resolves the children
|
|
15
16
|
* to a flat array of DOM nodes.
|
|
16
17
|
*/
|
|
17
18
|
declare function children(accessor: ChildrenAccessor): () => Node[];
|
|
19
|
+
/**
|
|
20
|
+
* A reactive signal that holds a value and notifies subscribers on change.
|
|
21
|
+
*/
|
|
22
|
+
interface Signal<T> {
|
|
23
|
+
/** Get the current value and subscribe to changes (when inside a tracking context). */
|
|
24
|
+
get value(): T;
|
|
25
|
+
/** Set the current value and notify subscribers if changed. */
|
|
26
|
+
set value(newValue: T);
|
|
27
|
+
/** Read the current value without subscribing (no tracking). */
|
|
28
|
+
peek(): T;
|
|
29
|
+
/** Manually notify all subscribers (useful after mutating the value in place). */
|
|
30
|
+
notify(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A read-only reactive value derived from other signals.
|
|
34
|
+
*/
|
|
35
|
+
interface ReadonlySignal<T> {
|
|
36
|
+
/** Get the current value and subscribe to changes. */
|
|
37
|
+
readonly value: T;
|
|
38
|
+
/** Read the current value without subscribing. */
|
|
39
|
+
peek(): T;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Unwraps a ReadonlySignal to its value type.
|
|
43
|
+
* Used by signal APIs (like query()) to expose plain values in TypeScript
|
|
44
|
+
* while the compiler auto-unwraps them at runtime.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* type UnwrappedData = Unwrapped<ReadonlySignal<Task | undefined>>; // → Task | undefined
|
|
48
|
+
*/
|
|
49
|
+
type Unwrapped<T> = T extends ReadonlySignal<infer U> ? U : T;
|
|
50
|
+
/**
|
|
51
|
+
* Unwraps all signal properties of an object type.
|
|
52
|
+
* Properties that are signals become their inner value type.
|
|
53
|
+
* Non-signal properties and primitive types pass through unchanged.
|
|
54
|
+
*
|
|
55
|
+
* Used by `useContext` to present context values without the Signal wrapper.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* type Settings = { theme: Signal<string>; setTheme: (t: string) => void };
|
|
59
|
+
* type Unwrapped = UnwrapSignals<Settings>; // { theme: string; setTheme: (t: string) => void }
|
|
60
|
+
*/
|
|
61
|
+
type UnwrapSignals<T> = T extends object ? { [K in keyof T] : Unwrapped<T[K]> } : T;
|
|
62
|
+
/**
|
|
63
|
+
* A computed signal — lazily evaluated, cached, and automatically re-computed
|
|
64
|
+
* when dependencies change.
|
|
65
|
+
*/
|
|
66
|
+
interface Computed<T> extends ReadonlySignal<T> {
|
|
67
|
+
/** Get the current value, re-computing if dirty. Subscribes in tracking context. */
|
|
68
|
+
readonly value: T;
|
|
69
|
+
/** Read the current value without subscribing. */
|
|
70
|
+
peek(): T;
|
|
71
|
+
}
|
|
72
|
+
/** Dispose function returned by effect(). */
|
|
73
|
+
type DisposeFn = () => void;
|
|
74
|
+
/**
|
|
75
|
+
* A snapshot of context values at a point in time.
|
|
76
|
+
* Each Provider creates a new scope that inherits from the parent.
|
|
77
|
+
* Effects capture this scope so that useContext works in async callbacks.
|
|
78
|
+
*/
|
|
79
|
+
type ContextScope = Map<Context<unknown>, unknown>;
|
|
80
|
+
/**
|
|
81
|
+
* Props for the JSX pattern of Context.Provider.
|
|
82
|
+
*
|
|
83
|
+
* `children` accepts both raw values (what TypeScript sees in JSX) and
|
|
84
|
+
* thunks (what the compiler produces). At compile time the compiler wraps
|
|
85
|
+
* JSX children in `() => ...`, but TypeScript checks the pre-compilation
|
|
86
|
+
* source where children are plain elements.
|
|
87
|
+
*/
|
|
88
|
+
interface ProviderJsxProps<T> {
|
|
89
|
+
value: T;
|
|
90
|
+
children: (() => unknown) | unknown;
|
|
91
|
+
}
|
|
18
92
|
/** A context object created by `createContext`. */
|
|
19
93
|
interface Context<T> {
|
|
20
|
-
/** Provide a value
|
|
21
|
-
Provider
|
|
94
|
+
/** Provide a value via callback pattern. */
|
|
95
|
+
Provider(value: T, fn: () => void): void;
|
|
96
|
+
/** Provide a value via JSX pattern (single-arg object with children thunk). */
|
|
97
|
+
Provider(props: ProviderJsxProps<T>): HTMLElement;
|
|
22
98
|
/** @internal — current value stack */
|
|
23
99
|
_stack: T[];
|
|
24
100
|
/** @internal — default value */
|
|
@@ -27,15 +103,20 @@ interface Context<T> {
|
|
|
27
103
|
/**
|
|
28
104
|
* Create a context with an optional default value.
|
|
29
105
|
* Returns an object with a `Provider` function.
|
|
106
|
+
*
|
|
107
|
+
* The optional `__stableId` parameter is injected by the compiler for HMR
|
|
108
|
+
* support. When provided, the context object is cached in a global registry
|
|
109
|
+
* so that bundle re-evaluation returns the same object — preserving identity
|
|
110
|
+
* for ContextScope Map lookups. Users never pass this parameter directly.
|
|
30
111
|
*/
|
|
31
|
-
declare function createContext<T>(defaultValue?: T): Context<T>;
|
|
112
|
+
declare function createContext<T>(defaultValue?: T, __stableId?: string): Context<T>;
|
|
32
113
|
/**
|
|
33
114
|
* Retrieve the current value from the nearest Provider.
|
|
34
115
|
* Checks the synchronous call stack first, then falls back to
|
|
35
116
|
* the captured context scope (for async callbacks like watch/effect).
|
|
36
117
|
* Returns the default value if no Provider is active.
|
|
37
118
|
*/
|
|
38
|
-
declare function useContext<T>(ctx: Context<T>): T | undefined;
|
|
119
|
+
declare function useContext<T>(ctx: Context<T>): UnwrapSignals<T> | undefined;
|
|
39
120
|
/** Props for the ErrorBoundary component. */
|
|
40
121
|
interface ErrorBoundaryProps {
|
|
41
122
|
/** Function that returns the children to render. */
|
|
@@ -57,16 +138,28 @@ interface ErrorBoundaryProps {
|
|
|
57
138
|
declare function ErrorBoundary(props: ErrorBoundaryProps): Node;
|
|
58
139
|
/**
|
|
59
140
|
* Runs callback once on mount. Never re-executes.
|
|
60
|
-
*
|
|
141
|
+
* Return a function to register cleanup that runs on unmount.
|
|
142
|
+
*
|
|
143
|
+
* ```tsx
|
|
144
|
+
* onMount(() => {
|
|
145
|
+
* const id = setInterval(() => seconds++, 1000);
|
|
146
|
+
* return () => clearInterval(id);
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
61
149
|
*/
|
|
62
|
-
declare function
|
|
150
|
+
declare function onMount2(callback: () => (() => void) | void): void;
|
|
151
|
+
interface PresenceProps {
|
|
152
|
+
when: boolean;
|
|
153
|
+
children: () => HTMLElement;
|
|
154
|
+
}
|
|
63
155
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
156
|
+
* Presence component for mount/unmount animations.
|
|
157
|
+
* Defers unmounting until CSS exit animations complete.
|
|
158
|
+
*
|
|
159
|
+
* Props are accessed as getters (not destructured) so the compiler-generated
|
|
160
|
+
* reactive getters are tracked by domEffect.
|
|
68
161
|
*/
|
|
69
|
-
declare function
|
|
162
|
+
declare function Presence(props: PresenceProps): Node;
|
|
70
163
|
/** A ref container for DOM element access. */
|
|
71
164
|
interface Ref<T> {
|
|
72
165
|
current: T | undefined;
|
|
@@ -96,17 +189,51 @@ interface SuspenseProps {
|
|
|
96
189
|
* globally via queueMicrotask to avoid silent swallowing.
|
|
97
190
|
*/
|
|
98
191
|
declare function Suspense(props: SuspenseProps): Node;
|
|
192
|
+
declare const ANIMATION_DURATION: string;
|
|
193
|
+
declare const ANIMATION_EASING: string;
|
|
194
|
+
declare const fadeIn: string;
|
|
195
|
+
declare const fadeOut: string;
|
|
196
|
+
declare const zoomIn: string;
|
|
197
|
+
declare const zoomOut: string;
|
|
198
|
+
declare const slideInFromTop: string;
|
|
199
|
+
declare const slideInFromBottom: string;
|
|
200
|
+
declare const slideOutToTop: string;
|
|
201
|
+
declare const slideOutToBottom: string;
|
|
202
|
+
declare const slideInFromLeft: string;
|
|
203
|
+
declare const slideInFromRight: string;
|
|
204
|
+
declare const slideOutToLeft: string;
|
|
205
|
+
declare const slideOutToRight: string;
|
|
206
|
+
declare const accordionDown: string;
|
|
207
|
+
declare const accordionUp: string;
|
|
208
|
+
/** A raw CSS declaration: { property, value } for styles that can't be expressed as shorthands. */
|
|
209
|
+
interface RawDeclaration {
|
|
210
|
+
property: string;
|
|
211
|
+
value: string;
|
|
212
|
+
}
|
|
213
|
+
/** A value within a nested selector array: shorthand string or raw declaration. */
|
|
214
|
+
type StyleValue = string | RawDeclaration;
|
|
99
215
|
/** A style entry in the array: either a shorthand string or an object for nested selectors. */
|
|
100
|
-
type StyleEntry = string | Record<string,
|
|
216
|
+
type StyleEntry = string | Record<string, StyleValue[]>;
|
|
101
217
|
/** Input to css(): a record of named style blocks. */
|
|
102
218
|
type CSSInput = Record<string, StyleEntry[]>;
|
|
103
|
-
/** Output of css():
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
219
|
+
/** Output of css(): block names as top-level properties, plus non-enumerable `css`. */
|
|
220
|
+
type CSSOutput<T extends CSSInput = CSSInput> = { readonly [K in keyof T & string] : string } & {
|
|
221
|
+
readonly css: string;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Inject CSS text into the document head via a <style> tag.
|
|
225
|
+
* Only runs in browser environments. Deduplicates by CSS content.
|
|
226
|
+
*
|
|
227
|
+
* In SSR, document.head is freshly created per request by installDomShim().
|
|
228
|
+
* The module-level dedup Set would incorrectly block injection on request 2+
|
|
229
|
+
* since the Set persists across requests while document.head is replaced.
|
|
230
|
+
* We bypass dedup when __SSR_URL__ is set (SSR context).
|
|
231
|
+
*/
|
|
232
|
+
declare function injectCSS(cssText: string): void;
|
|
233
|
+
/** Reset injected styles tracking. Used in tests. */
|
|
234
|
+
declare function resetInjectedStyles(): void;
|
|
235
|
+
/** Get all CSS strings that have been injected. Used by SSR to collect styles. */
|
|
236
|
+
declare function getInjectedCSS(): string[];
|
|
110
237
|
/**
|
|
111
238
|
* Process a css() call and produce class names + extracted CSS.
|
|
112
239
|
*
|
|
@@ -118,9 +245,9 @@ interface CSSOutput {
|
|
|
118
245
|
*
|
|
119
246
|
* @param input - Named style blocks.
|
|
120
247
|
* @param filePath - Source file path for deterministic hashing.
|
|
121
|
-
* @returns
|
|
248
|
+
* @returns Object with block names as keys (class name strings) and non-enumerable `css` property.
|
|
122
249
|
*/
|
|
123
|
-
declare function css(input:
|
|
250
|
+
declare function css<T extends CSSInput>(input: T & { [K in keyof T & "css"]? : never }, filePath?: string): CSSOutput<T>;
|
|
124
251
|
/** Input to globalCss(): selector → property-value map. */
|
|
125
252
|
type GlobalCSSInput = Record<string, Record<string, string>>;
|
|
126
253
|
/** Output of globalCss(): extracted CSS string. */
|
|
@@ -139,6 +266,54 @@ interface GlobalCSSOutput {
|
|
|
139
266
|
*/
|
|
140
267
|
declare function globalCss(input: GlobalCSSInput): GlobalCSSOutput;
|
|
141
268
|
/**
|
|
269
|
+
* Register a CSS @keyframes animation and return its name.
|
|
270
|
+
* The CSS is injected into the DOM (deduped by injectCSS).
|
|
271
|
+
*/
|
|
272
|
+
declare function keyframes(name: string, frames: Record<string, Record<string, string>>): string;
|
|
273
|
+
/**
|
|
274
|
+
* Tailwind v4 oklch color palettes.
|
|
275
|
+
*
|
|
276
|
+
* All 22 palettes with shades 50-950 in oklch format.
|
|
277
|
+
* Sourced from: https://github.com/tailwindlabs/tailwindcss/blob/main/packages/tailwindcss/theme.css
|
|
278
|
+
*/
|
|
279
|
+
interface ColorPalette {
|
|
280
|
+
50: string;
|
|
281
|
+
100: string;
|
|
282
|
+
200: string;
|
|
283
|
+
300: string;
|
|
284
|
+
400: string;
|
|
285
|
+
500: string;
|
|
286
|
+
600: string;
|
|
287
|
+
700: string;
|
|
288
|
+
800: string;
|
|
289
|
+
900: string;
|
|
290
|
+
950: string;
|
|
291
|
+
}
|
|
292
|
+
declare const palettes: Readonly<{
|
|
293
|
+
slate: ColorPalette;
|
|
294
|
+
gray: ColorPalette;
|
|
295
|
+
zinc: ColorPalette;
|
|
296
|
+
neutral: ColorPalette;
|
|
297
|
+
stone: ColorPalette;
|
|
298
|
+
red: ColorPalette;
|
|
299
|
+
orange: ColorPalette;
|
|
300
|
+
amber: ColorPalette;
|
|
301
|
+
yellow: ColorPalette;
|
|
302
|
+
lime: ColorPalette;
|
|
303
|
+
green: ColorPalette;
|
|
304
|
+
emerald: ColorPalette;
|
|
305
|
+
teal: ColorPalette;
|
|
306
|
+
cyan: ColorPalette;
|
|
307
|
+
sky: ColorPalette;
|
|
308
|
+
blue: ColorPalette;
|
|
309
|
+
indigo: ColorPalette;
|
|
310
|
+
violet: ColorPalette;
|
|
311
|
+
purple: ColorPalette;
|
|
312
|
+
fuchsia: ColorPalette;
|
|
313
|
+
pink: ColorPalette;
|
|
314
|
+
rose: ColorPalette;
|
|
315
|
+
}>;
|
|
316
|
+
/**
|
|
142
317
|
* Convert an array of shorthand strings into a CSS properties object
|
|
143
318
|
* suitable for inline styles.
|
|
144
319
|
*
|
|
@@ -192,34 +367,27 @@ declare function defineTheme(input: ThemeInput): Theme;
|
|
|
192
367
|
* @returns Compiled CSS and token list.
|
|
193
368
|
*/
|
|
194
369
|
declare function compileTheme(theme: Theme): CompiledTheme;
|
|
195
|
-
/**
|
|
196
|
-
* ThemeProvider — Sets `data-theme` attribute for contextual token switching.
|
|
197
|
-
*
|
|
198
|
-
* Creates a wrapper div element with the appropriate `data-theme` attribute
|
|
199
|
-
* so that contextual CSS custom properties (generated by compileTheme) resolve
|
|
200
|
-
* to the correct variant values.
|
|
201
|
-
*
|
|
202
|
-
* Usage:
|
|
203
|
-
* ```ts
|
|
204
|
-
* ThemeProvider({ theme: 'dark', children: [myApp] });
|
|
205
|
-
* ```
|
|
206
|
-
*/
|
|
207
370
|
/** A child node: either a DOM Node or a string (text content). */
|
|
208
371
|
type ThemeChild = Node | string;
|
|
209
372
|
/** Props for ThemeProvider. */
|
|
210
373
|
interface ThemeProviderProps {
|
|
211
374
|
/** The theme variant name (e.g., 'light', 'dark'). Defaults to 'light'. */
|
|
212
375
|
theme?: string;
|
|
213
|
-
/**
|
|
214
|
-
|
|
376
|
+
/**
|
|
377
|
+
* Child elements to render inside the provider.
|
|
378
|
+
*
|
|
379
|
+
* Accepts a single child (what TypeScript sees in JSX), an array, or a
|
|
380
|
+
* thunk (what the compiler produces after wrapping JSX children).
|
|
381
|
+
*/
|
|
382
|
+
children: ThemeChild | ThemeChild[] | (() => ThemeChild | ThemeChild[]);
|
|
215
383
|
}
|
|
216
384
|
/**
|
|
217
385
|
* Create a wrapper div with `data-theme` attribute for theme switching.
|
|
218
386
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
387
|
+
* Uses __element() directly (instead of jsx()) so the hydration cursor
|
|
388
|
+
* walker can claim the existing SSR node during mount().
|
|
221
389
|
*/
|
|
222
|
-
declare function ThemeProvider(
|
|
390
|
+
declare function ThemeProvider({ theme, children }: ThemeProviderProps): HTMLElement;
|
|
223
391
|
/** A record of variant names to their possible values (each value maps to style entries). */
|
|
224
392
|
type VariantDefinitions = Record<string, Record<string, StyleEntry[]>>;
|
|
225
393
|
/** Extract the variant props type from a variant definitions object. */
|
|
@@ -252,46 +420,145 @@ interface VariantFunction<V extends VariantDefinitions> {
|
|
|
252
420
|
* @returns A function that accepts variant props and returns a className string.
|
|
253
421
|
*/
|
|
254
422
|
declare function variants<V extends VariantDefinitions>(config: VariantsConfig<V>): VariantFunction<V>;
|
|
423
|
+
declare const DialogStackContext: Context<DialogStack>;
|
|
424
|
+
declare function useDialogStack(): DialogStack;
|
|
425
|
+
interface DialogHandle<TResult> {
|
|
426
|
+
close(...args: void extends TResult ? [] : [result: TResult]): void;
|
|
427
|
+
}
|
|
428
|
+
type DialogComponent<
|
|
429
|
+
TResult,
|
|
430
|
+
TProps = Record<string, never>
|
|
431
|
+
> = (props: TProps & {
|
|
432
|
+
dialog: DialogHandle<TResult>;
|
|
433
|
+
}) => Node;
|
|
434
|
+
declare class DialogDismissedError extends Error {
|
|
435
|
+
constructor();
|
|
436
|
+
}
|
|
437
|
+
interface DialogStack {
|
|
438
|
+
open<
|
|
439
|
+
TResult,
|
|
440
|
+
TProps
|
|
441
|
+
>(component: DialogComponent<TResult, TProps>, props: TProps): Promise<TResult>;
|
|
442
|
+
/** @internal — used by useDialogStack() to pass captured context scope */
|
|
443
|
+
openWithScope<
|
|
444
|
+
TResult,
|
|
445
|
+
TProps
|
|
446
|
+
>(component: DialogComponent<TResult, TProps>, props: TProps, scope: ContextScope | null): Promise<TResult>;
|
|
447
|
+
readonly size: number;
|
|
448
|
+
closeAll(): void;
|
|
449
|
+
}
|
|
450
|
+
declare function createDialogStack(container: HTMLElement): DialogStack;
|
|
255
451
|
/**
|
|
256
|
-
*
|
|
452
|
+
* Brand symbol for render nodes.
|
|
453
|
+
* SSR nodes add this to their prototype for fast identification.
|
|
454
|
+
* Browser DOM nodes use the `instanceof Node` fallback in `isRenderNode`.
|
|
257
455
|
*/
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
456
|
+
declare const RENDER_NODE_BRAND: unique symbol;
|
|
457
|
+
interface RenderNode {}
|
|
458
|
+
interface RenderElement extends RenderNode {
|
|
459
|
+
setAttribute(name: string, value: string): void;
|
|
460
|
+
removeAttribute(name: string): void;
|
|
461
|
+
getAttribute(name: string): string | null;
|
|
462
|
+
style: {
|
|
463
|
+
display: string;
|
|
464
|
+
[key: string]: any;
|
|
465
|
+
};
|
|
466
|
+
classList: {
|
|
467
|
+
add(cls: string): void;
|
|
468
|
+
remove(cls: string): void;
|
|
469
|
+
};
|
|
470
|
+
addEventListener(event: string, handler: EventListener): void;
|
|
471
|
+
removeEventListener(event: string, handler: EventListener): void;
|
|
472
|
+
}
|
|
473
|
+
interface RenderText extends RenderNode {
|
|
474
|
+
data: string;
|
|
475
|
+
}
|
|
476
|
+
interface RenderAdapter {
|
|
477
|
+
createElement(tag: string): RenderElement;
|
|
478
|
+
createElementNS(ns: string, tag: string): RenderElement;
|
|
479
|
+
createTextNode(text: string): RenderText;
|
|
480
|
+
createComment(text: string): RenderNode;
|
|
481
|
+
createDocumentFragment(): RenderNode;
|
|
482
|
+
isNode(value: unknown): value is RenderNode;
|
|
267
483
|
}
|
|
268
484
|
/**
|
|
269
|
-
*
|
|
485
|
+
* Type guard: checks if a value is a RenderNode.
|
|
486
|
+
* Fast path: brand check for SSR nodes.
|
|
487
|
+
* Fallback: instanceof Node for browser DOM nodes.
|
|
270
488
|
*/
|
|
271
|
-
|
|
272
|
-
/** Get the current value and subscribe to changes. */
|
|
273
|
-
readonly value: T;
|
|
274
|
-
/** Read the current value without subscribing. */
|
|
275
|
-
peek(): T;
|
|
276
|
-
}
|
|
489
|
+
declare function isRenderNode(value: unknown): value is RenderNode;
|
|
277
490
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
491
|
+
* Get the current render adapter.
|
|
492
|
+
* Auto-detects DOMAdapter if document exists and no adapter has been set.
|
|
280
493
|
*/
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
494
|
+
declare function getAdapter(): RenderAdapter;
|
|
495
|
+
/**
|
|
496
|
+
* Set the current render adapter.
|
|
497
|
+
* Pass null to reset to auto-detect.
|
|
498
|
+
*/
|
|
499
|
+
declare function setAdapter(adapter: RenderAdapter | null): void;
|
|
500
|
+
/**
|
|
501
|
+
* Create a DOM adapter that delegates to real browser DOM APIs.
|
|
502
|
+
* Zero overhead — no branding, no wrapping.
|
|
503
|
+
* Browser `Node` instances pass `isRenderNode()` via the `instanceof Node` fallback.
|
|
504
|
+
*/
|
|
505
|
+
declare function createDOMAdapter(): RenderAdapter;
|
|
506
|
+
/**
|
|
507
|
+
* Create a DOM element with optional static properties.
|
|
508
|
+
*
|
|
509
|
+
* This is a compiler output target — the compiler generates calls
|
|
510
|
+
* to __element for each JSX element.
|
|
511
|
+
*/
|
|
512
|
+
declare function __element<K extends keyof HTMLElementTagNameMap>(tag: K, props?: Record<string, string>): HTMLElementTagNameMap[K];
|
|
513
|
+
declare function __element(tag: string, props?: Record<string, string>): Element;
|
|
514
|
+
/**
|
|
515
|
+
* Append a child to a parent node.
|
|
516
|
+
* During hydration, this is a no-op — the child is already in the DOM.
|
|
517
|
+
* During CSR, delegates to appendChild.
|
|
518
|
+
*
|
|
519
|
+
* Compiler output target — replaces direct `parent.appendChild(child)`.
|
|
520
|
+
*/
|
|
521
|
+
declare function __append(parent: Node, child: Node): void;
|
|
522
|
+
/**
|
|
523
|
+
* Create a static text node.
|
|
524
|
+
* During hydration, claims an existing text node from the SSR output.
|
|
525
|
+
* During CSR, creates a new text node.
|
|
526
|
+
*
|
|
527
|
+
* Compiler output target — replaces `document.createTextNode(str)`.
|
|
528
|
+
*/
|
|
529
|
+
declare function __staticText(text: string): Text;
|
|
530
|
+
/**
|
|
531
|
+
* Push the hydration cursor into an element's children.
|
|
532
|
+
* Compiler output target — emitted around child construction.
|
|
533
|
+
*/
|
|
534
|
+
declare function __enterChildren(el: Element): void;
|
|
535
|
+
/**
|
|
536
|
+
* Pop the hydration cursor back to the parent scope.
|
|
537
|
+
* Compiler output target — emitted after all children are appended.
|
|
538
|
+
*/
|
|
539
|
+
declare function __exitChildren(): void;
|
|
540
|
+
interface FieldState<T = unknown> {
|
|
541
|
+
error: Signal<string | undefined>;
|
|
542
|
+
dirty: Signal<boolean>;
|
|
543
|
+
touched: Signal<boolean>;
|
|
544
|
+
value: Signal<T>;
|
|
545
|
+
setValue: (value: T) => void;
|
|
546
|
+
reset: () => void;
|
|
286
547
|
}
|
|
287
|
-
|
|
288
|
-
|
|
548
|
+
declare function createFieldState<T>(_name: string, initialValue?: T): FieldState<T>;
|
|
549
|
+
import { Result } from "@vertz/fetch";
|
|
289
550
|
/**
|
|
290
551
|
* Minimal schema interface compatible with @vertz/schema.
|
|
291
|
-
* Any object with a `parse(data: unknown):
|
|
552
|
+
* Any object with a `parse(data: unknown): Result` method satisfies this.
|
|
292
553
|
*/
|
|
293
554
|
interface FormSchema<T> {
|
|
294
|
-
parse(data: unknown):
|
|
555
|
+
parse(data: unknown): {
|
|
556
|
+
ok: true;
|
|
557
|
+
data: T;
|
|
558
|
+
} | {
|
|
559
|
+
ok: false;
|
|
560
|
+
error: unknown;
|
|
561
|
+
};
|
|
295
562
|
}
|
|
296
563
|
/** Result of a validation attempt. */
|
|
297
564
|
type ValidationResult<T> = {
|
|
@@ -319,56 +586,87 @@ interface SdkMethod<
|
|
|
319
586
|
TBody,
|
|
320
587
|
TResult
|
|
321
588
|
> {
|
|
322
|
-
(body: TBody):
|
|
589
|
+
(body: TBody): PromiseLike<Result<TResult, Error>>;
|
|
323
590
|
url: string;
|
|
324
591
|
method: string;
|
|
592
|
+
meta?: {
|
|
593
|
+
bodySchema?: FormSchema<TBody>;
|
|
594
|
+
};
|
|
325
595
|
}
|
|
326
|
-
/**
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
596
|
+
/**
|
|
597
|
+
* An SDK method with embedded schema metadata.
|
|
598
|
+
* Generated by `@vertz/codegen` — carries `.meta.bodySchema` for auto-validation.
|
|
599
|
+
*/
|
|
600
|
+
interface SdkMethodWithMeta<
|
|
601
|
+
TBody,
|
|
602
|
+
TResult
|
|
603
|
+
> extends SdkMethod<TBody, TResult> {
|
|
604
|
+
meta: {
|
|
605
|
+
bodySchema: FormSchema<TBody>;
|
|
606
|
+
};
|
|
330
607
|
}
|
|
331
|
-
/**
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
608
|
+
/** Reserved property names that cannot be used as field names on FormInstance. */
|
|
609
|
+
type ReservedFormNames = "submitting" | "dirty" | "valid" | "action" | "method" | "onSubmit" | "reset" | "setFieldError" | "submit" | "__bindElement";
|
|
610
|
+
/** Mapped type providing FieldState for each field in TBody. */
|
|
611
|
+
type FieldAccessors<TBody> = { [K in keyof TBody] : FieldState<TBody[K]> };
|
|
612
|
+
/** Base properties available on every form instance. */
|
|
613
|
+
interface FormBaseProperties<TBody> {
|
|
614
|
+
action: string;
|
|
615
|
+
method: string;
|
|
616
|
+
onSubmit: (e: Event) => Promise<void>;
|
|
617
|
+
reset: () => void;
|
|
618
|
+
setFieldError: (field: keyof TBody & string, message: string) => void;
|
|
619
|
+
submit: (formData?: FormData) => Promise<void>;
|
|
620
|
+
submitting: Signal<boolean>;
|
|
621
|
+
dirty: ReadonlySignal<boolean>;
|
|
622
|
+
valid: ReadonlySignal<boolean>;
|
|
623
|
+
__bindElement: (el: HTMLFormElement) => void;
|
|
335
624
|
}
|
|
336
|
-
/**
|
|
337
|
-
|
|
625
|
+
/**
|
|
626
|
+
* A form instance bound to an SDK method.
|
|
627
|
+
* Combines base properties with per-field reactive state via Proxy.
|
|
628
|
+
* If TBody has any key that conflicts with ReservedFormNames, it produces a type error.
|
|
629
|
+
* TResult is used by form() overloads for return type inference.
|
|
630
|
+
*/
|
|
631
|
+
type FormInstance<
|
|
632
|
+
TBody,
|
|
633
|
+
_TResult
|
|
634
|
+
> = keyof TBody & ReservedFormNames extends never ? FormBaseProperties<TBody> & FieldAccessors<TBody> : {
|
|
635
|
+
__error: `Field name conflicts with reserved form property: ${keyof TBody & ReservedFormNames & string}`;
|
|
636
|
+
};
|
|
637
|
+
/** Options for creating a form instance. */
|
|
638
|
+
interface FormOptions<
|
|
338
639
|
TBody,
|
|
339
640
|
TResult
|
|
340
641
|
> {
|
|
341
|
-
/**
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
*
|
|
352
|
-
* Can also be called directly with FormData for non-DOM usage:
|
|
353
|
-
* `userForm.handleSubmit({ onSuccess })(formData)`.
|
|
354
|
-
*/
|
|
355
|
-
handleSubmit(callbacks?: SubmitCallbacks<TResult>): (formDataOrEvent: FormData | Event) => Promise<void>;
|
|
356
|
-
/** Returns the error message for a field reactively, or undefined if no error. Type-safe field names. */
|
|
357
|
-
error(field: keyof TBody & string): string | undefined;
|
|
642
|
+
/** Explicit schema for client-side validation before submission. */
|
|
643
|
+
schema?: FormSchema<TBody>;
|
|
644
|
+
/** Initial values for form fields. */
|
|
645
|
+
initial?: Partial<TBody> | (() => Partial<TBody>);
|
|
646
|
+
/** Callback invoked after a successful submission. */
|
|
647
|
+
onSuccess?: (result: TResult) => void;
|
|
648
|
+
/** Callback invoked when validation or submission fails. */
|
|
649
|
+
onError?: (errors: Record<string, string>) => void;
|
|
650
|
+
/** When true, reset the form after a successful submission. */
|
|
651
|
+
resetOnSuccess?: boolean;
|
|
358
652
|
}
|
|
359
653
|
/**
|
|
360
|
-
* Create a form instance bound to an SDK method
|
|
654
|
+
* Create a form instance bound to an SDK method.
|
|
655
|
+
*
|
|
656
|
+
* The form provides direct properties for progressive enhancement (action, method, onSubmit),
|
|
657
|
+
* per-field reactive state via Proxy, and submission handling with validation.
|
|
361
658
|
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
* - `handleSubmit()` returns an event handler for FormData extraction, validation, and SDK submission
|
|
365
|
-
* - `error()` for reactive field-level error access
|
|
366
|
-
* - `submitting` signal for loading state
|
|
659
|
+
* When the SDK method has `.meta.bodySchema` (generated by `@vertz/codegen`),
|
|
660
|
+
* the schema option is optional. When the SDK method lacks `.meta`, the schema option is required.
|
|
367
661
|
*/
|
|
368
662
|
declare function form<
|
|
369
663
|
TBody,
|
|
370
664
|
TResult
|
|
371
|
-
>(sdkMethod:
|
|
665
|
+
>(sdkMethod: SdkMethodWithMeta<TBody, TResult>, options?: FormOptions<TBody, TResult>): FormInstance<TBody, TResult>;
|
|
666
|
+
declare function form<
|
|
667
|
+
TBody,
|
|
668
|
+
TResult
|
|
669
|
+
>(sdkMethod: SdkMethod<TBody, TResult>, options: Required<Pick<FormOptions<TBody, TResult>, "schema">> & FormOptions<TBody, TResult>): FormInstance<TBody, TResult>;
|
|
372
670
|
/** Options for formDataToObject conversion. */
|
|
373
671
|
interface FormDataOptions {
|
|
374
672
|
/** When true, coerces numeric strings to numbers and "true"/"false" to booleans. */
|
|
@@ -395,7 +693,8 @@ type ComponentRegistry = Record<string, ComponentLoader>;
|
|
|
395
693
|
* Client entry point for atomic per-component hydration.
|
|
396
694
|
*
|
|
397
695
|
* Scans the DOM for elements with `data-v-id` markers placed by the SSR pass,
|
|
398
|
-
* deserializes their props, and applies
|
|
696
|
+
* deserializes their props, and applies automatic hydration based on viewport
|
|
697
|
+
* proximity (IntersectionObserver with 200px rootMargin).
|
|
399
698
|
*
|
|
400
699
|
* Components without `data-v-id` markers are static and ship zero JS.
|
|
401
700
|
*
|
|
@@ -405,30 +704,40 @@ type ComponentRegistry = Record<string, ComponentLoader>;
|
|
|
405
704
|
*/
|
|
406
705
|
declare function hydrate(registry: ComponentRegistry): void;
|
|
407
706
|
/**
|
|
408
|
-
*
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
707
|
+
* Options for mounting an app to the DOM.
|
|
708
|
+
*/
|
|
709
|
+
interface MountOptions {
|
|
710
|
+
/** Theme definition for CSS vars */
|
|
711
|
+
theme?: Theme;
|
|
712
|
+
/** Global CSS strings to inject */
|
|
713
|
+
styles?: string[];
|
|
714
|
+
/** Callback after mount completes */
|
|
715
|
+
onMount?: (root: HTMLElement) => void;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Handle returned from mount() for controlling the mounted app.
|
|
416
719
|
*/
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
/** Idle -- hydrate during browser idle time via requestIdleCallback. Falls back to setTimeout(fn, 0). */
|
|
424
|
-
declare function idleStrategy(el: Element, hydrateFn: () => void): void;
|
|
720
|
+
interface MountHandle {
|
|
721
|
+
/** Unmount the app and cleanup */
|
|
722
|
+
unmount: () => void;
|
|
723
|
+
/** Root HTMLElement */
|
|
724
|
+
root: HTMLElement;
|
|
725
|
+
}
|
|
425
726
|
/**
|
|
426
|
-
*
|
|
427
|
-
*
|
|
727
|
+
* Mount an app to a DOM element.
|
|
728
|
+
*
|
|
729
|
+
* Uses tolerant hydration automatically: if the root element has SSR content,
|
|
730
|
+
* it walks the existing DOM and attaches reactivity without re-creating nodes.
|
|
731
|
+
* If the root is empty (CSR), it renders from scratch.
|
|
732
|
+
*
|
|
733
|
+
* @param app - App function that returns an HTMLElement
|
|
734
|
+
* @param selector - CSS selector string or HTMLElement
|
|
735
|
+
* @param options - Mount options (theme, styles, onMount, etc.)
|
|
736
|
+
* @returns MountHandle with unmount function and root element
|
|
428
737
|
*/
|
|
429
|
-
declare function
|
|
430
|
-
|
|
431
|
-
|
|
738
|
+
declare function mount<AppFn extends () => Element>(app: AppFn, selector: string | HTMLElement, options?: MountOptions): MountHandle;
|
|
739
|
+
import { QueryDescriptor as QueryDescriptor2 } from "@vertz/fetch";
|
|
740
|
+
import { isQueryDescriptor } from "@vertz/fetch";
|
|
432
741
|
/**
|
|
433
742
|
* Interface for cache stores used by query().
|
|
434
743
|
* Consumers can provide custom implementations (e.g. LRU, persistent storage).
|
|
@@ -437,7 +746,9 @@ interface CacheStore<T = unknown> {
|
|
|
437
746
|
get(key: string): T | undefined;
|
|
438
747
|
set(key: string, value: T): void;
|
|
439
748
|
delete(key: string): void;
|
|
749
|
+
clear?(): void;
|
|
440
750
|
}
|
|
751
|
+
import { QueryDescriptor } from "@vertz/fetch";
|
|
441
752
|
/** Options for query(). */
|
|
442
753
|
interface QueryOptions<T> {
|
|
443
754
|
/** Pre-populated data — skips the initial fetch when provided. */
|
|
@@ -450,15 +761,33 @@ interface QueryOptions<T> {
|
|
|
450
761
|
key?: string;
|
|
451
762
|
/** Custom cache store. Defaults to a shared in-memory Map. */
|
|
452
763
|
cache?: CacheStore<T>;
|
|
764
|
+
/** Timeout in ms for SSR data loading. Default: 300. Set to 0 to disable. */
|
|
765
|
+
ssrTimeout?: number;
|
|
766
|
+
/**
|
|
767
|
+
* Polling interval in ms, or a function for dynamic intervals.
|
|
768
|
+
*
|
|
769
|
+
* - `number` — fixed interval in ms
|
|
770
|
+
* - `false` or `0` — disabled
|
|
771
|
+
* - `(data, iteration) => number | false` — called after each fetch to
|
|
772
|
+
* determine the next interval. Return `false` to stop polling.
|
|
773
|
+
* `iteration` counts polls since the last start/restart (resets to 0
|
|
774
|
+
* when the function returns `false`).
|
|
775
|
+
*/
|
|
776
|
+
refetchInterval?: number | false | ((data: T | undefined, iteration: number) => number | false);
|
|
453
777
|
}
|
|
454
778
|
/** The reactive object returned by query(). */
|
|
455
|
-
interface QueryResult<
|
|
779
|
+
interface QueryResult<
|
|
780
|
+
T,
|
|
781
|
+
E = unknown
|
|
782
|
+
> {
|
|
456
783
|
/** The fetched data, or undefined while loading. */
|
|
457
|
-
readonly data: ReadonlySignal<T | undefined
|
|
458
|
-
/** True
|
|
459
|
-
readonly loading: ReadonlySignal<boolean
|
|
784
|
+
readonly data: Unwrapped<ReadonlySignal<T | undefined>>;
|
|
785
|
+
/** True only on the initial load (no data yet). False during revalidation. */
|
|
786
|
+
readonly loading: Unwrapped<ReadonlySignal<boolean>>;
|
|
787
|
+
/** True when refetching while stale data is already available. */
|
|
788
|
+
readonly revalidating: Unwrapped<ReadonlySignal<boolean>>;
|
|
460
789
|
/** The error from the latest failed fetch, or undefined. */
|
|
461
|
-
readonly error: ReadonlySignal<
|
|
790
|
+
readonly error: Unwrapped<ReadonlySignal<E | undefined>>;
|
|
462
791
|
/** Manually trigger a refetch (clears cache for this key). */
|
|
463
792
|
refetch: () => void;
|
|
464
793
|
/** Alias for refetch — revalidate the cached data. */
|
|
@@ -472,11 +801,44 @@ interface QueryResult<T> {
|
|
|
472
801
|
* The thunk is wrapped in an effect so that when reactive dependencies
|
|
473
802
|
* used *before* the async call change, the query automatically re-fetches.
|
|
474
803
|
*
|
|
475
|
-
* @param
|
|
804
|
+
* @param source - A QueryDescriptor or an async function that returns the data.
|
|
476
805
|
* @param options - Optional configuration.
|
|
477
806
|
* @returns A QueryResult with reactive signals for data, loading, and error.
|
|
478
807
|
*/
|
|
808
|
+
declare function query<
|
|
809
|
+
T,
|
|
810
|
+
E
|
|
811
|
+
>(descriptor: QueryDescriptor<T, E>, options?: Omit<QueryOptions<T>, "key">): QueryResult<T, E>;
|
|
479
812
|
declare function query<T>(thunk: () => Promise<T>, options?: QueryOptions<T>): QueryResult<T>;
|
|
813
|
+
interface QueryMatchHandlers<
|
|
814
|
+
T,
|
|
815
|
+
E
|
|
816
|
+
> {
|
|
817
|
+
loading: () => Node | null;
|
|
818
|
+
error: (error: E) => Node | null;
|
|
819
|
+
data: (data: T) => Node | null;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Pattern-match on a QueryResult's exclusive state.
|
|
823
|
+
*
|
|
824
|
+
* Returns a stable `<span style="display:contents">` wrapper that internally
|
|
825
|
+
* manages branch switching (loading/error/data) via a reactive effect.
|
|
826
|
+
* The same wrapper is returned for repeated calls with the same queryResult
|
|
827
|
+
* (cached via WeakMap), enabling __child's stable-node optimization.
|
|
828
|
+
*
|
|
829
|
+
* Priority: loading → error → data.
|
|
830
|
+
*
|
|
831
|
+
* `loading` only fires on the initial load (no data yet).
|
|
832
|
+
* When revalidating with existing data, the `data` handler receives the
|
|
833
|
+
* current data. Access `query.revalidating` from the component scope for
|
|
834
|
+
* revalidation state.
|
|
835
|
+
*/
|
|
836
|
+
declare function queryMatch<
|
|
837
|
+
T,
|
|
838
|
+
E
|
|
839
|
+
>(queryResult: QueryResult<T, E>, handlers: QueryMatchHandlers<T, E>): HTMLElement & {
|
|
840
|
+
dispose: DisposeFn;
|
|
841
|
+
};
|
|
480
842
|
/**
|
|
481
843
|
* Template literal type utility that extracts route parameter names from a path pattern.
|
|
482
844
|
*
|
|
@@ -504,9 +866,34 @@ type ExtractParams<T extends string> = [ExtractParamsFromSegments<WithoutWildcar
|
|
|
504
866
|
} : Record<string, never> : HasWildcard<T> extends true ? { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string } & {
|
|
505
867
|
"*": string;
|
|
506
868
|
} : { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string };
|
|
869
|
+
/**
|
|
870
|
+
* Convert a route pattern to the union of URL shapes it accepts.
|
|
871
|
+
* - Static: `'/'` → `'/'`
|
|
872
|
+
* - Param: `'/tasks/:id'` → `` `/tasks/${string}` ``
|
|
873
|
+
* - Wildcard: `'/files/*'` → `` `/files/${string}` ``
|
|
874
|
+
* - Multi: `'/users/:id/posts/:postId'` → `` `/users/${string}/posts/${string}` ``
|
|
875
|
+
* - Fallback: `string` → `string` (backward compat)
|
|
876
|
+
*/
|
|
877
|
+
type PathWithParams<T extends string> = T extends `${infer Before}*` ? `${PathWithParams<Before>}${string}` : T extends `${infer Before}:${string}/${infer After}` ? `${Before}${string}/${PathWithParams<`${After}`>}` : T extends `${infer Before}:${string}` ? `${Before}${string}` : T;
|
|
878
|
+
/**
|
|
879
|
+
* Union of all valid URL shapes for a route map.
|
|
880
|
+
* Maps each route pattern key through `PathWithParams` to produce the accepted URL shapes.
|
|
881
|
+
*
|
|
882
|
+
* Example:
|
|
883
|
+
* ```
|
|
884
|
+
* RoutePaths<{ '/': ..., '/tasks/:id': ... }> = '/' | `/tasks/${string}`
|
|
885
|
+
* ```
|
|
886
|
+
*/
|
|
887
|
+
type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in keyof TRouteMap & string] : PathWithParams<K> }[keyof TRouteMap & string];
|
|
507
888
|
/** Simple schema interface for search param parsing. */
|
|
508
889
|
interface SearchParamSchema<T> {
|
|
509
|
-
parse(data: unknown):
|
|
890
|
+
parse(data: unknown): {
|
|
891
|
+
ok: true;
|
|
892
|
+
data: T;
|
|
893
|
+
} | {
|
|
894
|
+
ok: false;
|
|
895
|
+
error: unknown;
|
|
896
|
+
};
|
|
510
897
|
}
|
|
511
898
|
/** A route configuration for a single path. */
|
|
512
899
|
interface RouteConfig<
|
|
@@ -534,6 +921,46 @@ interface RouteConfig<
|
|
|
534
921
|
interface RouteDefinitionMap {
|
|
535
922
|
[pattern: string]: RouteConfig;
|
|
536
923
|
}
|
|
924
|
+
/**
|
|
925
|
+
* Loose route config used as the generic constraint for `defineRoutes`.
|
|
926
|
+
* Uses `Record<string, string>` for loader params so any concrete loader
|
|
927
|
+
* that accesses string params (e.g., `params.id`) satisfies the constraint.
|
|
928
|
+
*/
|
|
929
|
+
interface RouteConfigLike {
|
|
930
|
+
component: () => Node | Promise<{
|
|
931
|
+
default: () => Node;
|
|
932
|
+
}>;
|
|
933
|
+
/**
|
|
934
|
+
* Method syntax (`loader?(ctx): R`) is intentional — it enables **bivariant**
|
|
935
|
+
* parameter checking under `strictFunctionTypes`. Property syntax
|
|
936
|
+
* (`loader?: (ctx) => R`) would be contravariant, causing `RouteConfig<string>`
|
|
937
|
+
* (whose loader has `params: Record<string, never>`) to fail assignability
|
|
938
|
+
* against this constraint's `params: Record<string, string>`.
|
|
939
|
+
*/
|
|
940
|
+
loader?(ctx: {
|
|
941
|
+
params: Record<string, string>;
|
|
942
|
+
signal: AbortSignal;
|
|
943
|
+
}): unknown;
|
|
944
|
+
errorComponent?: (error: Error) => Node;
|
|
945
|
+
searchParams?: SearchParamSchema<unknown>;
|
|
946
|
+
children?: Record<string, RouteConfigLike>;
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Phantom branded array that carries the route map type `T`.
|
|
950
|
+
* The `__routes` property never exists at runtime — it is a type-level
|
|
951
|
+
* marker used to thread the developer's literal route keys through
|
|
952
|
+
* `createRouter`, `useRouter`, etc.
|
|
953
|
+
*/
|
|
954
|
+
type TypedRoutes<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> = CompiledRoute[] & {
|
|
955
|
+
readonly __routes: T;
|
|
956
|
+
};
|
|
957
|
+
/**
|
|
958
|
+
* Extract the route map type from `TypedRoutes<T>`.
|
|
959
|
+
* If `T` is not a `TypedRoutes`, returns `T` as-is (passthrough).
|
|
960
|
+
*
|
|
961
|
+
* Usage: `useRouter<InferRouteMap<typeof routes>>()`
|
|
962
|
+
*/
|
|
963
|
+
type InferRouteMap<T> = T extends TypedRoutes<infer R> ? R : T;
|
|
537
964
|
/** Internal compiled route. */
|
|
538
965
|
interface CompiledRoute {
|
|
539
966
|
/** The original path pattern. */
|
|
@@ -579,17 +1006,30 @@ type LoaderData<T> = T extends {
|
|
|
579
1006
|
* Define routes from a configuration map.
|
|
580
1007
|
* Returns an array of compiled routes preserving definition order.
|
|
581
1008
|
*/
|
|
582
|
-
declare function defineRoutes(map:
|
|
583
|
-
/**
|
|
584
|
-
|
|
1009
|
+
declare function defineRoutes<const T extends Record<string, RouteConfigLike>>(map: T): TypedRoutes<T>;
|
|
1010
|
+
/**
|
|
1011
|
+
* Props for the Link component.
|
|
1012
|
+
*
|
|
1013
|
+
* Generic over the route map `T`. Defaults to `RouteDefinitionMap` (string
|
|
1014
|
+
* index signature) for backward compatibility — unparameterized `LinkProps`
|
|
1015
|
+
* accepts any string href.
|
|
1016
|
+
*/
|
|
1017
|
+
interface LinkProps<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
|
|
585
1018
|
/** The target URL path. */
|
|
586
|
-
href:
|
|
587
|
-
/** Text or content for the link. */
|
|
588
|
-
children: string;
|
|
1019
|
+
href: RoutePaths<T>;
|
|
1020
|
+
/** Text or content for the link. Thunk may return string or Text node. */
|
|
1021
|
+
children: string | (() => string | Node);
|
|
589
1022
|
/** Class applied when the link's href matches the current path. */
|
|
590
1023
|
activeClass?: string;
|
|
591
1024
|
/** Static class name for the anchor element. */
|
|
592
1025
|
className?: string;
|
|
1026
|
+
/** Prefetch strategy. 'hover' triggers server pre-fetch on mouseenter/focus. */
|
|
1027
|
+
prefetch?: "hover";
|
|
1028
|
+
}
|
|
1029
|
+
/** Options for createLink(). */
|
|
1030
|
+
interface LinkFactoryOptions {
|
|
1031
|
+
/** Callback fired when a link wants to prefetch its target URL. */
|
|
1032
|
+
onPrefetch?: (url: string) => void;
|
|
593
1033
|
}
|
|
594
1034
|
/**
|
|
595
1035
|
* Create a Link component factory bound to the router's state.
|
|
@@ -598,14 +1038,45 @@ interface LinkProps {
|
|
|
598
1038
|
* @param navigate - Navigation function from the router
|
|
599
1039
|
* @returns A Link component function
|
|
600
1040
|
*/
|
|
601
|
-
declare function createLink(currentPath: ReadonlySignal<string>, navigate: (url: string) => void): (props: LinkProps) => HTMLAnchorElement;
|
|
1041
|
+
declare function createLink(currentPath: ReadonlySignal<string>, navigate: (url: string) => void, factoryOptions?: LinkFactoryOptions): (props: LinkProps) => HTMLAnchorElement;
|
|
602
1042
|
/** Options for router.navigate(). */
|
|
603
1043
|
interface NavigateOptions {
|
|
604
1044
|
/** Use history.replaceState instead of pushState. */
|
|
605
1045
|
replace?: boolean;
|
|
606
1046
|
}
|
|
607
|
-
/**
|
|
608
|
-
interface
|
|
1047
|
+
/** Handle returned by prefetchNavData for cancellation. */
|
|
1048
|
+
interface PrefetchHandle {
|
|
1049
|
+
abort: () => void;
|
|
1050
|
+
/** Resolves when SSE stream completes (data or done event). */
|
|
1051
|
+
done?: Promise<void>;
|
|
1052
|
+
/** Resolves when the first SSE event of any type arrives. */
|
|
1053
|
+
firstEvent?: Promise<void>;
|
|
1054
|
+
}
|
|
1055
|
+
/** Options for createRouter(). */
|
|
1056
|
+
interface RouterOptions {
|
|
1057
|
+
/** Enable server-side navigation pre-fetch. When true, uses default timeout. */
|
|
1058
|
+
serverNav?: boolean | {
|
|
1059
|
+
timeout?: number;
|
|
1060
|
+
};
|
|
1061
|
+
/** @internal — injected for testing. Production uses the real module. */
|
|
1062
|
+
_prefetchNavData?: (url: string, options?: {
|
|
1063
|
+
timeout?: number;
|
|
1064
|
+
}) => PrefetchHandle;
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* The router instance returned by createRouter.
|
|
1068
|
+
*
|
|
1069
|
+
* Generic over the route map `T`. Defaults to `RouteDefinitionMap` (string
|
|
1070
|
+
* index signature) for backward compatibility — unparameterized `Router`
|
|
1071
|
+
* accepts any string in `navigate()`.
|
|
1072
|
+
*
|
|
1073
|
+
* Method syntax on `navigate`, `revalidate`, and `dispose` enables bivariant
|
|
1074
|
+
* parameter checking under `strictFunctionTypes`. This means `Router<T>` is
|
|
1075
|
+
* assignable to `Router` (the unparameterized default), which is required for
|
|
1076
|
+
* storing typed routers in the `RouterContext` without contravariance errors.
|
|
1077
|
+
* At call sites, TypeScript still enforces the `RoutePaths<T>` constraint.
|
|
1078
|
+
*/
|
|
1079
|
+
interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
|
|
609
1080
|
/** Current matched route (reactive signal). */
|
|
610
1081
|
current: Signal<RouteMatch | null>;
|
|
611
1082
|
/** Loader data from the current route's loaders (reactive signal). */
|
|
@@ -615,34 +1086,63 @@ interface Router {
|
|
|
615
1086
|
/** Parsed search params from the current route (reactive signal). */
|
|
616
1087
|
searchParams: Signal<Record<string, unknown>>;
|
|
617
1088
|
/** Navigate to a new URL path. */
|
|
618
|
-
navigate
|
|
1089
|
+
navigate(url: RoutePaths<T>, options?: NavigateOptions): Promise<void>;
|
|
619
1090
|
/** Re-run all loaders for the current route. */
|
|
620
|
-
revalidate
|
|
1091
|
+
revalidate(): Promise<void>;
|
|
621
1092
|
/** Remove popstate listener and clean up the router. */
|
|
622
|
-
dispose
|
|
1093
|
+
dispose(): void;
|
|
623
1094
|
}
|
|
624
1095
|
/**
|
|
1096
|
+
* Convenience alias for a typed router.
|
|
1097
|
+
* `TypedRouter<T>` is identical to `Router<T>` — it exists for readability
|
|
1098
|
+
* when the generic parameter makes the intent clearer.
|
|
1099
|
+
*/
|
|
1100
|
+
type TypedRouter<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> = Router<T>;
|
|
1101
|
+
/**
|
|
625
1102
|
* Create a router instance.
|
|
626
1103
|
*
|
|
627
1104
|
* @param routes - Compiled route list from defineRoutes()
|
|
628
1105
|
* @param initialUrl - The initial URL to match (optional; auto-detects from window.location or __SSR_URL__)
|
|
629
1106
|
* @returns Router instance with reactive state and navigation methods
|
|
630
1107
|
*/
|
|
631
|
-
declare function createRouter(routes:
|
|
1108
|
+
declare function createRouter<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>(routes: TypedRoutes<T>, initialUrl?: string, options?: RouterOptions): Router<T>;
|
|
632
1109
|
/** Context value for the Outlet. */
|
|
633
|
-
interface
|
|
634
|
-
/**
|
|
635
|
-
childComponent: (() => Node
|
|
636
|
-
|
|
637
|
-
|
|
1110
|
+
interface OutletContextValue {
|
|
1111
|
+
/** Reactive child component factory (may return async module). */
|
|
1112
|
+
childComponent: Signal<(() => Node | Promise<{
|
|
1113
|
+
default: () => Node;
|
|
1114
|
+
}>) | undefined>;
|
|
1115
|
+
/** Router instance for restoring context in async resolution. */
|
|
1116
|
+
router: Router;
|
|
1117
|
+
}
|
|
1118
|
+
/** Shared context used by RouterView and Outlet. */
|
|
1119
|
+
declare const OutletContext: Context<OutletContextValue>;
|
|
1120
|
+
/**
|
|
1121
|
+
* Outlet component — renders the nested child route.
|
|
1122
|
+
*
|
|
1123
|
+
* Must be called inside a layout component rendered by RouterView.
|
|
1124
|
+
* Reads from OutletContext to determine which child to render.
|
|
1125
|
+
*/
|
|
1126
|
+
declare function Outlet(): Node;
|
|
1127
|
+
declare const RouterContext: Context<Router>;
|
|
1128
|
+
declare function useRouter<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>(): UnwrapSignals<Router<T>>;
|
|
1129
|
+
declare function useParams<TPath extends string = string>(): ExtractParams<TPath>;
|
|
1130
|
+
interface RouterViewProps {
|
|
1131
|
+
router: Router;
|
|
1132
|
+
fallback?: () => Node;
|
|
638
1133
|
}
|
|
639
1134
|
/**
|
|
640
|
-
*
|
|
1135
|
+
* Renders the matched route's component inside a container div.
|
|
1136
|
+
*
|
|
1137
|
+
* Handles sync and async (lazy-loaded) components, stale resolution guards,
|
|
1138
|
+
* page cleanup on navigation, and RouterContext propagation.
|
|
641
1139
|
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
1140
|
+
* Uses __element() so the container is claimed from SSR during hydration.
|
|
1141
|
+
* On the first hydration render, children are already in the DOM — the
|
|
1142
|
+
* domEffect runs the component factory (to attach reactivity/event handlers)
|
|
1143
|
+
* but skips clearing the container.
|
|
644
1144
|
*/
|
|
645
|
-
declare function
|
|
1145
|
+
declare function RouterView({ router, fallback }: RouterViewProps): HTMLElement;
|
|
646
1146
|
/**
|
|
647
1147
|
* Parse URLSearchParams into a typed object, optionally through a schema.
|
|
648
1148
|
*
|
|
@@ -668,12 +1168,6 @@ declare class DisposalScopeError extends Error {
|
|
|
668
1168
|
constructor();
|
|
669
1169
|
}
|
|
670
1170
|
/**
|
|
671
|
-
* Register a cleanup function with the current disposal scope.
|
|
672
|
-
* Throws `DisposalScopeError` if no scope is active — fail-fast
|
|
673
|
-
* so developers know their cleanup callback was not registered.
|
|
674
|
-
*/
|
|
675
|
-
declare function onCleanup(fn: DisposeFn): void;
|
|
676
|
-
/**
|
|
677
1171
|
* Group multiple signal writes into a single update flush.
|
|
678
1172
|
* Nested batches are supported — only the outermost batch triggers the flush.
|
|
679
1173
|
*/
|
|
@@ -688,13 +1182,106 @@ declare function signal<T>(initial: T): Signal<T>;
|
|
|
688
1182
|
*/
|
|
689
1183
|
declare function computed<T>(fn: () => T): Computed<T>;
|
|
690
1184
|
/**
|
|
691
|
-
* Create a reactive effect that re-runs whenever its dependencies change.
|
|
692
|
-
* Returns a dispose function to stop the effect.
|
|
693
|
-
*/
|
|
694
|
-
declare function effect(fn: () => void): DisposeFn;
|
|
695
|
-
/**
|
|
696
1185
|
* Execute a function without tracking any signal reads.
|
|
697
1186
|
* Useful for reading signals without creating subscriptions.
|
|
698
1187
|
*/
|
|
699
1188
|
declare function untrack<T>(fn: () => T): T;
|
|
700
|
-
|
|
1189
|
+
/**
|
|
1190
|
+
* Serialized format for EntityStore - used for SSR transfer and hydration.
|
|
1191
|
+
*/
|
|
1192
|
+
interface SerializedStore {
|
|
1193
|
+
/** Entity data keyed by type → id → entity */
|
|
1194
|
+
entities: Record<string, Record<string, unknown>>;
|
|
1195
|
+
/** Query result indices (optional) */
|
|
1196
|
+
queries?: Record<string, {
|
|
1197
|
+
ids: string[];
|
|
1198
|
+
nextCursor?: string | null;
|
|
1199
|
+
}>;
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Options for EntityStore constructor.
|
|
1203
|
+
*/
|
|
1204
|
+
interface EntityStoreOptions {
|
|
1205
|
+
/** Initial data to hydrate from (SSR). */
|
|
1206
|
+
initialData?: SerializedStore;
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* EntityStore - Normalized, signal-backed entity cache for @vertz/ui.
|
|
1210
|
+
*
|
|
1211
|
+
* Stores entities by type and ID, with signal-per-entity reactivity.
|
|
1212
|
+
* Supports field-level merge, SSR hydration, and query result indices.
|
|
1213
|
+
*/
|
|
1214
|
+
declare class EntityStore {
|
|
1215
|
+
private _entities;
|
|
1216
|
+
private _typeListeners;
|
|
1217
|
+
private _queryIndices;
|
|
1218
|
+
constructor(options?: EntityStoreOptions);
|
|
1219
|
+
/**
|
|
1220
|
+
* Read a single entity. Returns a signal that updates on merge.
|
|
1221
|
+
* Returns the same signal instance on repeated calls (identity stability).
|
|
1222
|
+
*/
|
|
1223
|
+
get<T>(type: string, id: string): ReadonlySignal<T | undefined>;
|
|
1224
|
+
/**
|
|
1225
|
+
* Read multiple entities by IDs. Returns a computed signal of the array.
|
|
1226
|
+
* Returns a NEW computed signal each call (not cached).
|
|
1227
|
+
*/
|
|
1228
|
+
getMany<T>(type: string, ids: string[]): ReadonlySignal<(T | undefined)[]>;
|
|
1229
|
+
/**
|
|
1230
|
+
* Merge one or more entities into the store.
|
|
1231
|
+
* Field-level merge with shallow diff - only updates signals if data changed.
|
|
1232
|
+
* Uses batch() to coalesce multiple updates into single reactive flush.
|
|
1233
|
+
* Uses untrack() to prevent circular re-triggering when called from effects.
|
|
1234
|
+
*/
|
|
1235
|
+
merge<T extends {
|
|
1236
|
+
id: string;
|
|
1237
|
+
}>(type: string, data: T | T[]): void;
|
|
1238
|
+
/**
|
|
1239
|
+
* Remove an entity from the store.
|
|
1240
|
+
* Triggers type change listeners and removes from query indices.
|
|
1241
|
+
*/
|
|
1242
|
+
remove(type: string, id: string): void;
|
|
1243
|
+
/**
|
|
1244
|
+
* Subscribe to type-level changes (create/delete, not field updates).
|
|
1245
|
+
* Returns an unsubscribe function.
|
|
1246
|
+
*/
|
|
1247
|
+
onTypeChange(type: string, callback: () => void): () => void;
|
|
1248
|
+
/**
|
|
1249
|
+
* Check if an entity exists in the store.
|
|
1250
|
+
*/
|
|
1251
|
+
has(type: string, id: string): boolean;
|
|
1252
|
+
/**
|
|
1253
|
+
* Get count of entities for a type.
|
|
1254
|
+
*/
|
|
1255
|
+
size(type: string): number;
|
|
1256
|
+
/**
|
|
1257
|
+
* Serialize the store for SSR transfer.
|
|
1258
|
+
*/
|
|
1259
|
+
dehydrate(): SerializedStore;
|
|
1260
|
+
/**
|
|
1261
|
+
* Hydrate from serialized data. Merges into existing store (doesn't replace).
|
|
1262
|
+
*/
|
|
1263
|
+
hydrate(data: SerializedStore): void;
|
|
1264
|
+
private _getOrCreateTypeMap;
|
|
1265
|
+
private _getOrCreateListeners;
|
|
1266
|
+
private _notifyTypeChange;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Create a pre-populated EntityStore for testing.
|
|
1270
|
+
*
|
|
1271
|
+
* @param data - Entity data keyed by type → id → entity
|
|
1272
|
+
* @returns A new EntityStore with the data already merged
|
|
1273
|
+
*
|
|
1274
|
+
* @example
|
|
1275
|
+
* ```ts
|
|
1276
|
+
* const store = createTestStore({
|
|
1277
|
+
* User: {
|
|
1278
|
+
* '1': { id: '1', name: 'Alice' },
|
|
1279
|
+
* '2': { id: '2', name: 'Bob' }
|
|
1280
|
+
* }
|
|
1281
|
+
* });
|
|
1282
|
+
*
|
|
1283
|
+
* expect(store.get('User', '1').value).toEqual({ id: '1', name: 'Alice' });
|
|
1284
|
+
* ```
|
|
1285
|
+
*/
|
|
1286
|
+
declare function createTestStore(data: Record<string, Record<string, unknown>>): EntityStore;
|
|
1287
|
+
export { zoomOut, zoomIn, variants, validate, useSearchParams, useRouter, useParams, useDialogStack, useContext, untrack, slideOutToTop, slideOutToRight, slideOutToLeft, slideOutToBottom, slideInFromTop, slideInFromRight, slideInFromLeft, slideInFromBottom, signal, setAdapter, s, resolveChildren, resetInjectedStyles, ref, queryMatch, query, parseSearchParams, palettes, onMount2 as onMount, mount, keyframes, isRenderNode, isQueryDescriptor, injectCSS, hydrate, globalCss, getInjectedCSS, getAdapter, formDataToObject, form, fadeOut, fadeIn, defineTheme, defineRoutes, css, createTestStore, createRouter, createLink, createFieldState, createDialogStack, createDOMAdapter, createContext, computed, compileTheme, children, batch, accordionUp, accordionDown, __staticText, __exitChildren, __enterChildren, __element, __append, VariantsConfig, VariantProps, VariantFunction, ValidationResult, UnwrapSignals, TypedRoutes, TypedRouter, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, SuspenseProps, Suspense, StyleValue, StyleEntry, Signal, SerializedStore, SearchParamSchema, SdkMethodWithMeta, SdkMethod, RouterViewProps, RouterView, RouterOptions, RouterContext, Router, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, RenderText, RenderNode, RenderElement, RenderAdapter, Ref, ReadonlySignal, RawDeclaration, RENDER_NODE_BRAND, QueryResult, QueryOptions, QueryMatchHandlers, QueryDescriptor2 as QueryDescriptor, PresenceProps, Presence, PathWithParams, OutletContextValue, OutletContext, Outlet, NavigateOptions, MountOptions, MountHandle, MatchedRoute, LoaderData, LinkProps, LinkFactoryOptions, InferRouteMap, GlobalCSSOutput, GlobalCSSInput, FormSchema, FormOptions, FormInstance, FormDataOptions, FieldState, ExtractParams, ErrorBoundaryProps, ErrorBoundary, EntityStoreOptions, EntityStore, DisposeFn, DisposalScopeError, DialogStackContext, DialogStack, DialogHandle, DialogDismissedError, DialogComponent, Context, Computed, ComponentRegistry, ComponentLoader, ComponentFunction, CompiledTheme, CompiledRoute, ColorPalette, ChildrenAccessor, ChildValue, CacheStore, CSSOutput, CSSInput, ANIMATION_EASING, ANIMATION_DURATION };
|