@vertz/ui 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,700 @@
1
+ /** A single child value: DOM node, string, number, null, undefined, or nested array. */
2
+ type ChildValue = Node | string | number | null | undefined | ChildValue[];
3
+ /** A function that returns children (slot accessor). */
4
+ type ChildrenAccessor = () => ChildValue;
5
+ /**
6
+ * Resolve a raw child value into a flat array of DOM nodes.
7
+ * Strings and numbers are converted to Text nodes.
8
+ * Null and undefined are filtered out.
9
+ * Arrays are flattened recursively.
10
+ */
11
+ declare function resolveChildren(value: ChildValue): Node[];
12
+ /**
13
+ * Create a children resolver from a children accessor.
14
+ * Returns a function that, when called, resolves the children
15
+ * to a flat array of DOM nodes.
16
+ */
17
+ declare function children(accessor: ChildrenAccessor): () => Node[];
18
+ /** A context object created by `createContext`. */
19
+ interface Context<T> {
20
+ /** Provide a value to all `useContext` calls within the scope. */
21
+ Provider: (value: T, fn: () => void) => void;
22
+ /** @internal — current value stack */
23
+ _stack: T[];
24
+ /** @internal — default value */
25
+ _default: T | undefined;
26
+ }
27
+ /**
28
+ * Create a context with an optional default value.
29
+ * Returns an object with a `Provider` function.
30
+ */
31
+ declare function createContext<T>(defaultValue?: T): Context<T>;
32
+ /**
33
+ * Retrieve the current value from the nearest Provider.
34
+ * Checks the synchronous call stack first, then falls back to
35
+ * the captured context scope (for async callbacks like watch/effect).
36
+ * Returns the default value if no Provider is active.
37
+ */
38
+ declare function useContext<T>(ctx: Context<T>): T | undefined;
39
+ /** Props for the ErrorBoundary component. */
40
+ interface ErrorBoundaryProps {
41
+ /** Function that returns the children to render. */
42
+ children: () => Node;
43
+ /** Fallback renderer that receives the caught error and a retry function. */
44
+ fallback: (error: Error, retry: () => void) => Node;
45
+ }
46
+ /**
47
+ * ErrorBoundary component.
48
+ * Catches errors thrown by `children()` and renders `fallback` instead.
49
+ * The fallback receives the error and a retry function to re-attempt rendering.
50
+ *
51
+ * When retry is called, children() is re-invoked. If it succeeds, the fallback
52
+ * node in the DOM is replaced with the new children result.
53
+ *
54
+ * Also registers an async error handler so that nested Suspense components
55
+ * can propagate async errors to this boundary.
56
+ */
57
+ declare function ErrorBoundary(props: ErrorBoundaryProps): Node;
58
+ /**
59
+ * Runs callback once on mount. Never re-executes.
60
+ * Supports `onCleanup` inside for teardown on unmount.
61
+ */
62
+ declare function onMount(callback: () => void): void;
63
+ /**
64
+ * Watches a dependency accessor and runs callback whenever it changes.
65
+ * Always takes TWO arguments: a dependency accessor and a callback.
66
+ * Runs callback immediately with current value.
67
+ * Before each re-run, any `onCleanup` from previous run executes first.
68
+ */
69
+ declare function watch<T>(dep: () => T, callback: (value: T) => void): void;
70
+ /** A ref container for DOM element access. */
71
+ interface Ref<T> {
72
+ current: T | undefined;
73
+ }
74
+ /**
75
+ * Create a ref for accessing a DOM element after mount.
76
+ * Returns `{ current: undefined }` initially; after mount,
77
+ * `ref.current` will hold the DOM element.
78
+ */
79
+ declare function ref<T>(): Ref<T>;
80
+ /** Props for the Suspense component. */
81
+ interface SuspenseProps {
82
+ /** Function that returns the children to render (may throw a Promise). */
83
+ children: () => Node;
84
+ /** Fallback renderer shown while children are pending. */
85
+ fallback: () => Node;
86
+ }
87
+ /**
88
+ * Suspense component for async boundaries.
89
+ * Renders children synchronously if possible.
90
+ * If children throw a Promise, renders the fallback and waits for resolution,
91
+ * then replaces the fallback with the children result.
92
+ * If children throw a non-Promise error, it is re-thrown (use ErrorBoundary for error handling).
93
+ *
94
+ * For async errors (promise rejection or retry failure), the error is propagated
95
+ * to the nearest ErrorBoundary. If no ErrorBoundary exists, the error is surfaced
96
+ * globally via queueMicrotask to avoid silent swallowing.
97
+ */
98
+ declare function Suspense(props: SuspenseProps): Node;
99
+ /** A style entry in the array: either a shorthand string or an object for nested selectors. */
100
+ type StyleEntry = string | Record<string, string[]>;
101
+ /** Input to css(): a record of named style blocks. */
102
+ type CSSInput = Record<string, StyleEntry[]>;
103
+ /** Output of css(): a record of block names to class names, plus extracted CSS. */
104
+ interface CSSOutput {
105
+ /** Map of block name → generated class name. */
106
+ classNames: Record<string, string>;
107
+ /** The extracted CSS string. */
108
+ css: string;
109
+ }
110
+ /**
111
+ * Process a css() call and produce class names + extracted CSS.
112
+ *
113
+ * In production, the compiler replaces css() calls at build time.
114
+ * This runtime implementation is used for:
115
+ * - Development mode
116
+ * - Testing
117
+ * - SSR fallback
118
+ *
119
+ * @param input - Named style blocks.
120
+ * @param filePath - Source file path for deterministic hashing.
121
+ * @returns Class names map and extracted CSS.
122
+ */
123
+ declare function css(input: CSSInput, filePath?: string): CSSOutput;
124
+ /** Input to globalCss(): selector → property-value map. */
125
+ type GlobalCSSInput = Record<string, Record<string, string>>;
126
+ /** Output of globalCss(): extracted CSS string. */
127
+ interface GlobalCSSOutput {
128
+ /** The extracted global CSS string. */
129
+ css: string;
130
+ }
131
+ /**
132
+ * Process a globalCss() call and produce global CSS rules.
133
+ *
134
+ * Properties use camelCase and are converted to kebab-case.
135
+ * CSS custom properties (--*) are passed through as-is.
136
+ *
137
+ * @param input - Selector-to-properties map.
138
+ * @returns Extracted CSS.
139
+ */
140
+ declare function globalCss(input: GlobalCSSInput): GlobalCSSOutput;
141
+ /**
142
+ * Convert an array of shorthand strings into a CSS properties object
143
+ * suitable for inline styles.
144
+ *
145
+ * Note: Pseudo-states are not supported in inline styles and will
146
+ * cause an error. Use css() for pseudo-states.
147
+ *
148
+ * @param entries - Array of shorthand strings.
149
+ * @returns A Record of CSS property → value pairs (kebab-case keys).
150
+ */
151
+ declare function s(entries: string[]): Record<string, string>;
152
+ /** Color tokens: a map of color names to their raw/contextual values. */
153
+ type ColorTokens = Record<string, Record<string, string>>;
154
+ /** Spacing tokens: a flat map of names to CSS values. */
155
+ type SpacingTokens = Record<string, string>;
156
+ /** Input to defineTheme(). */
157
+ interface ThemeInput {
158
+ /** Color design tokens (raw shades and contextual variants). */
159
+ colors: ColorTokens;
160
+ /** Spacing scale tokens. */
161
+ spacing?: SpacingTokens;
162
+ }
163
+ /** The structured theme object returned by defineTheme(). */
164
+ interface Theme {
165
+ /** Color design tokens. */
166
+ colors: ColorTokens;
167
+ /** Spacing scale tokens. */
168
+ spacing?: SpacingTokens;
169
+ }
170
+ /** Output of compileTheme(). */
171
+ interface CompiledTheme {
172
+ /** The generated CSS string with :root and [data-theme] blocks. */
173
+ css: string;
174
+ /** Flat list of token dot-paths (e.g., 'primary.500', 'background'). */
175
+ tokens: string[];
176
+ }
177
+ /**
178
+ * Define a theme with raw and contextual design tokens.
179
+ *
180
+ * @param input - Theme token definitions.
181
+ * @returns A structured theme object.
182
+ */
183
+ declare function defineTheme(input: ThemeInput): Theme;
184
+ /**
185
+ * Compile a theme into CSS custom properties.
186
+ *
187
+ * Generates:
188
+ * - `:root { ... }` block with default/raw token values
189
+ * - `[data-theme="dark"] { ... }` block with dark overrides (if any)
190
+ *
191
+ * @param theme - A theme object from defineTheme().
192
+ * @returns Compiled CSS and token list.
193
+ */
194
+ 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
+ /** A child node: either a DOM Node or a string (text content). */
208
+ type ThemeChild = Node | string;
209
+ /** Props for ThemeProvider. */
210
+ interface ThemeProviderProps {
211
+ /** The theme variant name (e.g., 'light', 'dark'). Defaults to 'light'. */
212
+ theme?: string;
213
+ /** Child elements to render inside the provider. */
214
+ children: ThemeChild[];
215
+ }
216
+ /**
217
+ * Create a wrapper div with `data-theme` attribute for theme switching.
218
+ *
219
+ * @param props - Theme and children.
220
+ * @returns A div element with `data-theme` set and children appended.
221
+ */
222
+ declare function ThemeProvider(props: ThemeProviderProps): HTMLDivElement;
223
+ /** A record of variant names to their possible values (each value maps to style entries). */
224
+ type VariantDefinitions = Record<string, Record<string, StyleEntry[]>>;
225
+ /** Extract the variant props type from a variant definitions object. */
226
+ type VariantProps<V extends VariantDefinitions> = { [K in keyof V]? : keyof V[K] };
227
+ /** A compound variant rule: matches when all specified variant values are active. */
228
+ type CompoundVariant<V extends VariantDefinitions> = { [K in keyof V]? : keyof V[K] } & {
229
+ styles: StyleEntry[];
230
+ };
231
+ /** Configuration for the variants() function. */
232
+ interface VariantsConfig<V extends VariantDefinitions> {
233
+ /** Base styles applied to all variants. */
234
+ base: StyleEntry[];
235
+ /** Variant definitions: each key is a variant name, each value is a map of option to styles. */
236
+ variants: V;
237
+ /** Default variant values used when no override is provided. */
238
+ defaultVariants?: { [K in keyof V]? : keyof V[K] };
239
+ /** Compound variants: styles applied when multiple variant values match simultaneously. */
240
+ compoundVariants?: CompoundVariant<V>[];
241
+ }
242
+ /** The function returned by variants(). Takes optional variant props and returns a className string. */
243
+ interface VariantFunction<V extends VariantDefinitions> {
244
+ (props?: VariantProps<V>): string;
245
+ /** The extracted CSS for all variant combinations. */
246
+ css: string;
247
+ }
248
+ /**
249
+ * Create a typed variant function from a config object.
250
+ *
251
+ * @param config - Variant configuration (base, variants, defaultVariants, compoundVariants).
252
+ * @returns A function that accepts variant props and returns a className string.
253
+ */
254
+ declare function variants<V extends VariantDefinitions>(config: VariantsConfig<V>): VariantFunction<V>;
255
+ /**
256
+ * A reactive signal that holds a value and notifies subscribers on change.
257
+ */
258
+ interface Signal<T> {
259
+ /** Get the current value and subscribe to changes (when inside a tracking context). */
260
+ get value(): T;
261
+ /** Set the current value and notify subscribers if changed. */
262
+ set value(newValue: T);
263
+ /** Read the current value without subscribing (no tracking). */
264
+ peek(): T;
265
+ /** Manually notify all subscribers (useful after mutating the value in place). */
266
+ notify(): void;
267
+ }
268
+ /**
269
+ * A read-only reactive value derived from other signals.
270
+ */
271
+ interface ReadonlySignal<T> {
272
+ /** Get the current value and subscribe to changes. */
273
+ readonly value: T;
274
+ /** Read the current value without subscribing. */
275
+ peek(): T;
276
+ }
277
+ /**
278
+ * A computed signal — lazily evaluated, cached, and automatically re-computed
279
+ * when dependencies change.
280
+ */
281
+ interface Computed<T> extends ReadonlySignal<T> {
282
+ /** Get the current value, re-computing if dirty. Subscribes in tracking context. */
283
+ readonly value: T;
284
+ /** Read the current value without subscribing. */
285
+ peek(): T;
286
+ }
287
+ /** Dispose function returned by effect(). */
288
+ type DisposeFn = () => void;
289
+ /**
290
+ * Minimal schema interface compatible with @vertz/schema.
291
+ * Any object with a `parse(data: unknown): T` method satisfies this.
292
+ */
293
+ interface FormSchema<T> {
294
+ parse(data: unknown): T;
295
+ }
296
+ /** Result of a validation attempt. */
297
+ type ValidationResult<T> = {
298
+ success: true;
299
+ data: T;
300
+ errors: Record<string, never>;
301
+ } | {
302
+ success: false;
303
+ data: undefined;
304
+ errors: Record<string, string>;
305
+ };
306
+ /**
307
+ * Validate data against a schema.
308
+ *
309
+ * - On success, returns `{ success: true, data, errors: {} }`.
310
+ * - On failure, extracts field errors from `error.fieldErrors` if present,
311
+ * otherwise falls back to a generic `_form` error.
312
+ */
313
+ declare function validate<T>(schema: FormSchema<T>, data: unknown): ValidationResult<T>;
314
+ /**
315
+ * An SDK method with endpoint metadata attached.
316
+ * Generated SDK methods expose `.url` and `.method` for progressive enhancement.
317
+ */
318
+ interface SdkMethod<
319
+ TBody,
320
+ TResult
321
+ > {
322
+ (body: TBody): Promise<TResult>;
323
+ url: string;
324
+ method: string;
325
+ }
326
+ /** Options for creating a form instance. */
327
+ interface FormOptions<TBody> {
328
+ /** Explicit schema for client-side validation before submission. */
329
+ schema: FormSchema<TBody>;
330
+ }
331
+ /** Callbacks for form submission. Both are optional per spec. */
332
+ interface SubmitCallbacks<TResult> {
333
+ onSuccess?: (result: TResult) => void;
334
+ onError?: (errors: Record<string, string>) => void;
335
+ }
336
+ /** A form instance bound to an SDK method. */
337
+ interface FormInstance<
338
+ TBody,
339
+ TResult
340
+ > {
341
+ /** Returns `{ action, method }` for progressive enhancement in HTML forms. */
342
+ attrs(): {
343
+ action: string;
344
+ method: string;
345
+ };
346
+ /** Reactive signal indicating whether a submission is in progress. */
347
+ submitting: Signal<boolean>;
348
+ /**
349
+ * Returns an event handler that extracts FormData, validates, and submits.
350
+ * Assignable to onSubmit: `onSubmit={userForm.handleSubmit({ onSuccess })}`.
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;
358
+ }
359
+ /**
360
+ * Create a form instance bound to an SDK method with schema validation.
361
+ *
362
+ * The form provides:
363
+ * - `attrs()` for progressive enhancement (returns action/method from SDK metadata)
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
367
+ */
368
+ declare function form<
369
+ TBody,
370
+ TResult
371
+ >(sdkMethod: SdkMethod<TBody, TResult>, options: FormOptions<TBody>): FormInstance<TBody, TResult>;
372
+ /** Options for formDataToObject conversion. */
373
+ interface FormDataOptions {
374
+ /** When true, coerces numeric strings to numbers and "true"/"false" to booleans. */
375
+ coerce?: boolean;
376
+ }
377
+ /**
378
+ * Convert FormData to a plain object.
379
+ *
380
+ * - File entries are skipped (only string values are included).
381
+ * - Duplicate keys use the last value.
382
+ * - When `coerce` is true, numeric strings become numbers and
383
+ * "true"/"false" become booleans.
384
+ */
385
+ declare function formDataToObject(formData: FormData, options?: FormDataOptions): Record<string, unknown>;
386
+ /** A function returning a dynamic import of a component module. */
387
+ type ComponentLoader = () => Promise<{
388
+ default: ComponentFunction;
389
+ }>;
390
+ /** A component function that takes props and an element to mount into. */
391
+ type ComponentFunction = (props: Record<string, unknown>, el: Element) => void;
392
+ /** Maps component IDs to their dynamic import loaders. */
393
+ type ComponentRegistry = Record<string, ComponentLoader>;
394
+ /**
395
+ * Client entry point for atomic per-component hydration.
396
+ *
397
+ * Scans the DOM for elements with `data-v-id` markers placed by the SSR pass,
398
+ * deserializes their props, and applies the appropriate hydration strategy.
399
+ *
400
+ * Components without `data-v-id` markers are static and ship zero JS.
401
+ *
402
+ * Elements that have already been hydrated (marked with `data-v-hydrated`)
403
+ * are skipped to prevent double hydration when `hydrate()` is called
404
+ * multiple times on the same page.
405
+ */
406
+ declare function hydrate(registry: ComponentRegistry): void;
407
+ /**
408
+ * Hydration strategies determine WHEN a component gets hydrated.
409
+ *
410
+ * - eager: immediately on page load
411
+ * - lazy (default): when element becomes visible (IntersectionObserver, 200px rootMargin)
412
+ * - interaction: on first user event (click, focus, pointerenter)
413
+ * - idle: during browser idle time (requestIdleCallback, falls back to setTimeout)
414
+ * - media(query): when a CSS media query matches
415
+ * - visible: when element enters the viewport (IntersectionObserver, no rootMargin)
416
+ */
417
+ /** Eager -- hydrate immediately on page load. */
418
+ declare function eagerStrategy(el: Element, hydrateFn: () => void): void;
419
+ /** Lazy (default) -- hydrate when element becomes visible via IntersectionObserver with 200px rootMargin. */
420
+ declare function lazyStrategy(el: Element, hydrateFn: () => void): void;
421
+ /** Interaction -- hydrate on first user event (click, focus, pointerenter). */
422
+ declare function interactionStrategy(el: Element, hydrateFn: () => void): void;
423
+ /** Idle -- hydrate during browser idle time via requestIdleCallback. Falls back to setTimeout(fn, 0). */
424
+ declare function idleStrategy(el: Element, hydrateFn: () => void): void;
425
+ /**
426
+ * Media -- hydrate when a CSS media query matches.
427
+ * Returns a strategy function bound to the given query string.
428
+ */
429
+ declare function mediaStrategy(query: string): (el: Element, hydrateFn: () => void) => void;
430
+ /** Visible -- hydrate when element enters the viewport via IntersectionObserver (no rootMargin). */
431
+ declare function visibleStrategy(el: Element, hydrateFn: () => void): void;
432
+ /**
433
+ * Interface for cache stores used by query().
434
+ * Consumers can provide custom implementations (e.g. LRU, persistent storage).
435
+ */
436
+ interface CacheStore<T = unknown> {
437
+ get(key: string): T | undefined;
438
+ set(key: string, value: T): void;
439
+ delete(key: string): void;
440
+ }
441
+ /** Options for query(). */
442
+ interface QueryOptions<T> {
443
+ /** Pre-populated data — skips the initial fetch when provided. */
444
+ initialData?: T;
445
+ /** Debounce re-fetches triggered by reactive dependency changes (ms). */
446
+ debounce?: number;
447
+ /** When false, the query will not fetch. Defaults to true. */
448
+ enabled?: boolean;
449
+ /** Explicit cache key. When omitted, derived from the thunk. */
450
+ key?: string;
451
+ /** Custom cache store. Defaults to a shared in-memory Map. */
452
+ cache?: CacheStore<T>;
453
+ }
454
+ /** The reactive object returned by query(). */
455
+ interface QueryResult<T> {
456
+ /** The fetched data, or undefined while loading. */
457
+ readonly data: ReadonlySignal<T | undefined>;
458
+ /** True while a fetch is in progress. */
459
+ readonly loading: ReadonlySignal<boolean>;
460
+ /** The error from the latest failed fetch, or undefined. */
461
+ readonly error: ReadonlySignal<unknown>;
462
+ /** Manually trigger a refetch (clears cache for this key). */
463
+ refetch: () => void;
464
+ /** Alias for refetch — revalidate the cached data. */
465
+ revalidate: () => void;
466
+ /** Dispose the query — stops the reactive effect and cleans up inflight state. */
467
+ dispose: () => void;
468
+ }
469
+ /**
470
+ * Create a reactive data-fetching query.
471
+ *
472
+ * The thunk is wrapped in an effect so that when reactive dependencies
473
+ * used *before* the async call change, the query automatically re-fetches.
474
+ *
475
+ * @param thunk - An async function that returns the data.
476
+ * @param options - Optional configuration.
477
+ * @returns A QueryResult with reactive signals for data, loading, and error.
478
+ */
479
+ declare function query<T>(thunk: () => Promise<T>, options?: QueryOptions<T>): QueryResult<T>;
480
+ /**
481
+ * Template literal type utility that extracts route parameter names from a path pattern.
482
+ *
483
+ * Examples:
484
+ * - `'/users/:id'` -> `{ id: string }`
485
+ * - `'/users/:id/posts/:postId'` -> `{ id: string; postId: string }`
486
+ * - `'/files/*'` -> `{ '*': string }`
487
+ * - `'/users'` -> `Record<string, never>`
488
+ */
489
+ /** Extract param names from a single segment. */
490
+ type ExtractSegmentParam<S extends string> = S extends `:${infer Param}` ? Param : never;
491
+ /** Recursively extract params from path segments separated by '/'. */
492
+ type ExtractParamsFromSegments<T extends string> = T extends `${infer Segment}/${infer Rest}` ? ExtractSegmentParam<Segment> | ExtractParamsFromSegments<Rest> : ExtractSegmentParam<T>;
493
+ /** Check if a path contains a wildcard '*' at the end. */
494
+ type HasWildcard<T extends string> = T extends `${string}*` ? true : false;
495
+ /** Remove trailing wildcard for param extraction. */
496
+ type WithoutWildcard<T extends string> = T extends `${infer Before}*` ? Before : T;
497
+ /**
498
+ * Extract typed params from a route path pattern.
499
+ * `:param` segments become `{ param: string }`.
500
+ * A trailing `*` becomes `{ '*': string }`.
501
+ */
502
+ type ExtractParams<T extends string> = [ExtractParamsFromSegments<WithoutWildcard<T>>] extends [never] ? HasWildcard<T> extends true ? {
503
+ "*": string;
504
+ } : Record<string, never> : HasWildcard<T> extends true ? { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string } & {
505
+ "*": string;
506
+ } : { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string };
507
+ /** Simple schema interface for search param parsing. */
508
+ interface SearchParamSchema<T> {
509
+ parse(data: unknown): T;
510
+ }
511
+ /** A route configuration for a single path. */
512
+ interface RouteConfig<
513
+ TPath extends string = string,
514
+ TLoaderData = unknown,
515
+ TSearch = unknown
516
+ > {
517
+ /** Component factory (lazy for code splitting). */
518
+ component: () => Node | Promise<{
519
+ default: () => Node;
520
+ }>;
521
+ /** Optional loader that runs before render. */
522
+ loader?: (ctx: {
523
+ params: ExtractParams<TPath>;
524
+ signal: AbortSignal;
525
+ }) => Promise<TLoaderData> | TLoaderData;
526
+ /** Optional error component rendered when loader throws. */
527
+ errorComponent?: (error: Error) => Node;
528
+ /** Optional search params schema for validation/coercion. */
529
+ searchParams?: SearchParamSchema<TSearch>;
530
+ /** Nested child routes. */
531
+ children?: RouteDefinitionMap;
532
+ }
533
+ /** A map of path patterns to route configs (user input format). */
534
+ interface RouteDefinitionMap {
535
+ [pattern: string]: RouteConfig;
536
+ }
537
+ /** Internal compiled route. */
538
+ interface CompiledRoute {
539
+ /** The original path pattern. */
540
+ pattern: string;
541
+ /** The route config. */
542
+ component: RouteConfig["component"];
543
+ loader?: (ctx: {
544
+ params: Record<string, string>;
545
+ signal: AbortSignal;
546
+ }) => Promise<unknown> | unknown;
547
+ errorComponent?: RouteConfig["errorComponent"];
548
+ searchParams?: RouteConfig["searchParams"];
549
+ /** Compiled children. */
550
+ children?: CompiledRoute[];
551
+ }
552
+ /** A single matched route entry in the matched chain. */
553
+ interface MatchedRoute {
554
+ route: CompiledRoute;
555
+ params: Record<string, string>;
556
+ }
557
+ /** Result of matching a URL against the route tree. */
558
+ interface RouteMatch {
559
+ /** All params extracted from the full URL path. */
560
+ params: Record<string, string>;
561
+ /** The leaf route config that matched. */
562
+ route: CompiledRoute;
563
+ /** The chain of matched routes from root to leaf (for nested layouts). */
564
+ matched: MatchedRoute[];
565
+ /** URLSearchParams from the URL. */
566
+ searchParams: URLSearchParams;
567
+ /** Parsed/coerced search params if schema is defined. */
568
+ search: Record<string, unknown>;
569
+ }
570
+ /**
571
+ * Type utility to extract loader return type from a route config.
572
+ */
573
+ type LoaderData<T> = T extends {
574
+ loader: (...args: never[]) => Promise<infer R>;
575
+ } ? R : T extends {
576
+ loader: (...args: never[]) => infer R;
577
+ } ? R : never;
578
+ /**
579
+ * Define routes from a configuration map.
580
+ * Returns an array of compiled routes preserving definition order.
581
+ */
582
+ declare function defineRoutes(map: RouteDefinitionMap): CompiledRoute[];
583
+ /** Props for the Link component. */
584
+ interface LinkProps {
585
+ /** The target URL path. */
586
+ href: string;
587
+ /** Text or content for the link. */
588
+ children: string;
589
+ /** Class applied when the link's href matches the current path. */
590
+ activeClass?: string;
591
+ /** Static class name for the anchor element. */
592
+ className?: string;
593
+ }
594
+ /**
595
+ * Create a Link component factory bound to the router's state.
596
+ *
597
+ * @param currentPath - Reactive signal of the current URL path
598
+ * @param navigate - Navigation function from the router
599
+ * @returns A Link component function
600
+ */
601
+ declare function createLink(currentPath: ReadonlySignal<string>, navigate: (url: string) => void): (props: LinkProps) => HTMLAnchorElement;
602
+ /** Options for router.navigate(). */
603
+ interface NavigateOptions {
604
+ /** Use history.replaceState instead of pushState. */
605
+ replace?: boolean;
606
+ }
607
+ /** The router instance returned by createRouter. */
608
+ interface Router {
609
+ /** Current matched route (reactive signal). */
610
+ current: Signal<RouteMatch | null>;
611
+ /** Loader data from the current route's loaders (reactive signal). */
612
+ loaderData: Signal<unknown[]>;
613
+ /** Loader error if any loader threw (reactive signal). */
614
+ loaderError: Signal<Error | null>;
615
+ /** Parsed search params from the current route (reactive signal). */
616
+ searchParams: Signal<Record<string, unknown>>;
617
+ /** Navigate to a new URL path. */
618
+ navigate: (url: string, options?: NavigateOptions) => Promise<void>;
619
+ /** Re-run all loaders for the current route. */
620
+ revalidate: () => Promise<void>;
621
+ /** Remove popstate listener and clean up the router. */
622
+ dispose: () => void;
623
+ }
624
+ /**
625
+ * Create a router instance.
626
+ *
627
+ * @param routes - Compiled route list from defineRoutes()
628
+ * @param initialUrl - The initial URL to match (optional; auto-detects from window.location or __SSR_URL__)
629
+ * @returns Router instance with reactive state and navigation methods
630
+ */
631
+ declare function createRouter(routes: CompiledRoute[], initialUrl?: string): Router;
632
+ /** Context value for the Outlet. */
633
+ interface OutletContext {
634
+ /** The child component factory to render, or undefined if no child. */
635
+ childComponent: (() => Node) | undefined;
636
+ /** The nesting depth (for debugging/tracking). */
637
+ depth: number;
638
+ }
639
+ /**
640
+ * Create an Outlet component bound to a specific outlet context.
641
+ *
642
+ * @param outletCtx - The context that holds the child component
643
+ * @returns An Outlet component function
644
+ */
645
+ declare function createOutlet(outletCtx: Context<OutletContext>): () => Node;
646
+ /**
647
+ * Parse URLSearchParams into a typed object, optionally through a schema.
648
+ *
649
+ * @param urlParams - The raw URLSearchParams
650
+ * @param schema - Optional schema with a `parse` method for validation/coercion
651
+ * @returns Parsed search params object
652
+ */
653
+ declare function parseSearchParams<T = Record<string, string>>(urlParams: URLSearchParams, schema?: SearchParamSchema<T>): T;
654
+ /**
655
+ * Read the current search params from a reactive signal.
656
+ * Intended to be called inside a reactive context (effect/computed).
657
+ *
658
+ * @param searchSignal - Signal holding the current parsed search params
659
+ * @returns The current search params value
660
+ */
661
+ declare function useSearchParams<T>(searchSignal: ReadonlySignal<T>): T;
662
+ /**
663
+ * Error thrown when `onCleanup()` is called outside a disposal scope.
664
+ * Similar to React's invalid hook call error — fail-fast so developers
665
+ * know their cleanup callback was not registered.
666
+ */
667
+ declare class DisposalScopeError extends Error {
668
+ constructor();
669
+ }
670
+ /**
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
+ * Group multiple signal writes into a single update flush.
678
+ * Nested batches are supported — only the outermost batch triggers the flush.
679
+ */
680
+ declare function batch(fn: () => void): void;
681
+ /**
682
+ * Create a reactive signal with an initial value.
683
+ */
684
+ declare function signal<T>(initial: T): Signal<T>;
685
+ /**
686
+ * Create a computed (derived) reactive value.
687
+ * The function is lazily evaluated and cached.
688
+ */
689
+ declare function computed<T>(fn: () => T): Computed<T>;
690
+ /**
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
+ * Execute a function without tracking any signal reads.
697
+ * Useful for reading signals without creating subscriptions.
698
+ */
699
+ declare function untrack<T>(fn: () => T): T;
700
+ export { watch, visibleStrategy, variants, validate, useSearchParams, useContext, untrack, signal, s, resolveChildren, ref, query, parseSearchParams, onMount, onCleanup, mediaStrategy, lazyStrategy, interactionStrategy, idleStrategy, hydrate, globalCss, formDataToObject, form, effect, eagerStrategy, defineTheme, defineRoutes, css, createRouter, createOutlet, createLink, createContext, computed, compileTheme, children, batch, VariantsConfig, VariantProps, VariantFunction, ValidationResult, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, SuspenseProps, Suspense, SubmitCallbacks, StyleEntry, Signal, SearchParamSchema, SdkMethod, Router, RouteMatch, RouteDefinitionMap, RouteConfig, Ref, ReadonlySignal, QueryResult, QueryOptions, OutletContext, NavigateOptions, MatchedRoute, LoaderData, LinkProps, GlobalCSSOutput, GlobalCSSInput, FormSchema, FormOptions, FormInstance, FormDataOptions, ExtractParams, ErrorBoundaryProps, ErrorBoundary, DisposeFn, DisposalScopeError, Context, Computed, ComponentRegistry, ComponentLoader, ComponentFunction, CompiledTheme, CompiledRoute, ChildrenAccessor, ChildValue, CacheStore, CSSOutput, CSSInput };