@vertz/ui 0.2.13 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/shared/{chunk-c9xxsrat.js → chunk-1wby7nex.js} +18 -1
- package/dist/shared/{chunk-2sth83bd.js → chunk-4txc67nd.js} +1 -1
- package/dist/shared/{chunk-c30eg6wn.js → chunk-5dbq8jp9.js} +7 -0
- package/dist/shared/{chunk-mj7b4t40.js → chunk-wymw818z.js} +50 -2
- package/dist/src/auth/public.d.ts +13 -0
- package/dist/src/auth/public.js +28 -0
- package/dist/src/css/public.js +1 -1
- package/dist/src/form/public.d.ts +5 -2
- package/dist/src/form/public.js +1 -1
- package/dist/src/index.d.ts +28 -8
- package/dist/src/index.js +4 -4
- package/dist/src/internals.js +2 -2
- package/dist/src/router/public.d.ts +23 -6
- package/dist/src/router/public.js +1 -1
- package/dist/src/test/index.d.ts +21 -23
- package/dist/src/test/index.js +2 -2
- package/package.json +3 -3
|
@@ -82,6 +82,7 @@ var PROPERTY_MAP = {
|
|
|
82
82
|
leading: { properties: ["line-height"], valueType: "line-height" },
|
|
83
83
|
tracking: { properties: ["letter-spacing"], valueType: "raw" },
|
|
84
84
|
decoration: { properties: ["text-decoration"], valueType: "raw" },
|
|
85
|
+
list: { properties: ["list-style"], valueType: "raw" },
|
|
85
86
|
ring: { properties: ["outline"], valueType: "ring" },
|
|
86
87
|
cursor: { properties: ["cursor"], valueType: "raw" },
|
|
87
88
|
transition: { properties: ["transition"], valueType: "raw" },
|
|
@@ -115,7 +116,9 @@ var KEYWORD_MAP = {
|
|
|
115
116
|
"select-none": [{ property: "user-select", value: "none" }],
|
|
116
117
|
"pointer-events-none": [{ property: "pointer-events", value: "none" }],
|
|
117
118
|
"whitespace-nowrap": [{ property: "white-space", value: "nowrap" }],
|
|
118
|
-
"shrink-0": [{ property: "flex-shrink", value: "0" }]
|
|
119
|
+
"shrink-0": [{ property: "flex-shrink", value: "0" }],
|
|
120
|
+
italic: [{ property: "font-style", value: "italic" }],
|
|
121
|
+
"not-italic": [{ property: "font-style", value: "normal" }]
|
|
119
122
|
};
|
|
120
123
|
var DISPLAY_MAP = {
|
|
121
124
|
flex: "flex",
|
|
@@ -399,6 +402,9 @@ function resolveToken(parsed) {
|
|
|
399
402
|
if (property === "ring") {
|
|
400
403
|
return { declarations: resolveRingMulti(value), pseudo };
|
|
401
404
|
}
|
|
405
|
+
if (property === "list") {
|
|
406
|
+
return { declarations: resolveList(value), pseudo };
|
|
407
|
+
}
|
|
402
408
|
const resolvedValue = resolveValue(value, mapping.valueType, property);
|
|
403
409
|
const declarations = mapping.properties.map((prop) => ({
|
|
404
410
|
property: prop,
|
|
@@ -551,6 +557,17 @@ function resolveRingMulti(value) {
|
|
|
551
557
|
}
|
|
552
558
|
return [{ property: "outline-color", value: resolveColor(value, "ring") }];
|
|
553
559
|
}
|
|
560
|
+
var LIST_STYLE_KEYWORDS = new Set(["none", "disc", "decimal"]);
|
|
561
|
+
var LIST_POSITION_KEYWORDS = new Set(["inside", "outside"]);
|
|
562
|
+
function resolveList(value) {
|
|
563
|
+
if (LIST_STYLE_KEYWORDS.has(value)) {
|
|
564
|
+
return [{ property: "list-style", value }];
|
|
565
|
+
}
|
|
566
|
+
if (LIST_POSITION_KEYWORDS.has(value)) {
|
|
567
|
+
return [{ property: "list-style-position", value }];
|
|
568
|
+
}
|
|
569
|
+
throw new TokenResolveError(`Invalid list value '${value}'. Use: none, disc, decimal, inside, outside.`, `list:${value}`);
|
|
570
|
+
}
|
|
554
571
|
function resolveRaw(value, property) {
|
|
555
572
|
if (property === "border-r" || property === "border-l" || property === "border-t" || property === "border-b") {
|
|
556
573
|
const num = Number(value);
|
|
@@ -206,6 +206,13 @@ function form(sdkMethod, options) {
|
|
|
206
206
|
submitting,
|
|
207
207
|
dirty,
|
|
208
208
|
valid,
|
|
209
|
+
fields: new Proxy(Object.create(null), {
|
|
210
|
+
get(_target, prop) {
|
|
211
|
+
if (typeof prop === "string")
|
|
212
|
+
return prop;
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}),
|
|
209
216
|
__bindElement: (el) => {
|
|
210
217
|
boundElement = el;
|
|
211
218
|
el.addEventListener("input", handleInputOrChange);
|
|
@@ -12,6 +12,53 @@ import {
|
|
|
12
12
|
|
|
13
13
|
// src/router/navigate.ts
|
|
14
14
|
var DEFAULT_NAV_THRESHOLD_MS = 500;
|
|
15
|
+
function interpolatePath(path, params) {
|
|
16
|
+
const segments = path.split("/");
|
|
17
|
+
return segments.map((segment) => {
|
|
18
|
+
if (segment.startsWith(":")) {
|
|
19
|
+
const paramName = segment.slice(1);
|
|
20
|
+
const value = params?.[paramName];
|
|
21
|
+
if (value === undefined) {
|
|
22
|
+
throw new TypeError(`Missing route param "${paramName}" for path "${path}"`);
|
|
23
|
+
}
|
|
24
|
+
return encodeURIComponent(value);
|
|
25
|
+
}
|
|
26
|
+
if (segment === "*") {
|
|
27
|
+
const value = params?.["*"];
|
|
28
|
+
if (value === undefined) {
|
|
29
|
+
throw new TypeError(`Missing wildcard param "*" for path "${path}"`);
|
|
30
|
+
}
|
|
31
|
+
return value.replace(/^\/+|\/+$/g, "").split("/").map((part) => encodeURIComponent(part)).join("/");
|
|
32
|
+
}
|
|
33
|
+
return segment;
|
|
34
|
+
}).join("/");
|
|
35
|
+
}
|
|
36
|
+
function buildSearch(search) {
|
|
37
|
+
if (!search)
|
|
38
|
+
return "";
|
|
39
|
+
if (typeof search === "string") {
|
|
40
|
+
if (search === "")
|
|
41
|
+
return "";
|
|
42
|
+
return search.startsWith("?") ? search : `?${search}`;
|
|
43
|
+
}
|
|
44
|
+
const params = search instanceof URLSearchParams ? new URLSearchParams(search) : new URLSearchParams;
|
|
45
|
+
if (!(search instanceof URLSearchParams)) {
|
|
46
|
+
const entries = Object.entries(search).sort(([left], [right]) => left.localeCompare(right));
|
|
47
|
+
for (const [key, rawValue] of entries) {
|
|
48
|
+
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
49
|
+
for (const value of values) {
|
|
50
|
+
if (value === undefined || value === null)
|
|
51
|
+
continue;
|
|
52
|
+
params.append(key, String(value));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const query = params.toString();
|
|
57
|
+
return query ? `?${query}` : "";
|
|
58
|
+
}
|
|
59
|
+
function buildNavigationUrl(to, options) {
|
|
60
|
+
return `${interpolatePath(to, options?.params)}${buildSearch(options?.search)}`;
|
|
61
|
+
}
|
|
15
62
|
function createRouter(routes, initialUrl, options) {
|
|
16
63
|
const ssrCtx = getSSRContext();
|
|
17
64
|
const isSSR = ssrCtx !== undefined;
|
|
@@ -195,10 +242,11 @@ function createRouter(routes, initialUrl, options) {
|
|
|
195
242
|
}
|
|
196
243
|
}
|
|
197
244
|
}
|
|
198
|
-
async function navigate(
|
|
245
|
+
async function navigate(input) {
|
|
246
|
+
const navUrl = buildNavigationUrl(input.to, input);
|
|
199
247
|
const gen = ++navigateGen;
|
|
200
248
|
const handle = startPrefetch(navUrl);
|
|
201
|
-
if (
|
|
249
|
+
if (input.replace) {
|
|
202
250
|
window.history.replaceState(null, "", navUrl);
|
|
203
251
|
} else {
|
|
204
252
|
window.history.pushState(null, "", navUrl);
|
|
@@ -150,6 +150,19 @@ type ClientAccessEvent = {
|
|
|
150
150
|
type: "access:role_changed";
|
|
151
151
|
} | {
|
|
152
152
|
type: "access:plan_changed";
|
|
153
|
+
} | {
|
|
154
|
+
type: "access:plan_assigned";
|
|
155
|
+
planId: string;
|
|
156
|
+
} | {
|
|
157
|
+
type: "access:addon_attached";
|
|
158
|
+
addonId: string;
|
|
159
|
+
} | {
|
|
160
|
+
type: "access:addon_detached";
|
|
161
|
+
addonId: string;
|
|
162
|
+
} | {
|
|
163
|
+
type: "access:limit_reset";
|
|
164
|
+
entitlement: string;
|
|
165
|
+
max: number;
|
|
153
166
|
};
|
|
154
167
|
interface AccessEventClientOptions {
|
|
155
168
|
/** WebSocket URL. Defaults to deriving from window.location. */
|
package/dist/src/auth/public.js
CHANGED
|
@@ -171,8 +171,16 @@ function handleAccessEvent(accessSet, event, flagEntitlementMap) {
|
|
|
171
171
|
case "access:limit_updated":
|
|
172
172
|
handleLimitUpdate(accessSet, current, event.entitlement, event.consumed, event.remaining, event.max);
|
|
173
173
|
break;
|
|
174
|
+
case "access:plan_assigned":
|
|
175
|
+
handlePlanAssigned(accessSet, current, event.planId);
|
|
176
|
+
break;
|
|
177
|
+
case "access:limit_reset":
|
|
178
|
+
handleLimitReset(accessSet, current, event.entitlement, event.max);
|
|
179
|
+
break;
|
|
174
180
|
case "access:role_changed":
|
|
175
181
|
case "access:plan_changed":
|
|
182
|
+
case "access:addon_attached":
|
|
183
|
+
case "access:addon_detached":
|
|
176
184
|
break;
|
|
177
185
|
}
|
|
178
186
|
}
|
|
@@ -200,6 +208,26 @@ function handleFlagToggle(accessSet, current, flag, enabled, flagEntitlementMap)
|
|
|
200
208
|
}
|
|
201
209
|
accessSet.value = { ...current, flags: newFlags, entitlements: newEntitlements };
|
|
202
210
|
}
|
|
211
|
+
function handlePlanAssigned(accessSet, current, planId) {
|
|
212
|
+
accessSet.value = { ...current, plan: planId };
|
|
213
|
+
}
|
|
214
|
+
function handleLimitReset(accessSet, current, entitlement, max) {
|
|
215
|
+
const existingEntry = current.entitlements[entitlement];
|
|
216
|
+
if (!existingEntry)
|
|
217
|
+
return;
|
|
218
|
+
const newLimit = { max, consumed: 0, remaining: max };
|
|
219
|
+
const newEntitlements = { ...current.entitlements };
|
|
220
|
+
const reasons = existingEntry.reasons.filter((r) => r !== "limit_reached");
|
|
221
|
+
const wasOnlyLimitBlocked = existingEntry.reasons.length > 0 && existingEntry.reasons.every((r) => r === "limit_reached");
|
|
222
|
+
newEntitlements[entitlement] = {
|
|
223
|
+
...existingEntry,
|
|
224
|
+
allowed: wasOnlyLimitBlocked ? true : existingEntry.allowed || reasons.length === 0,
|
|
225
|
+
reasons,
|
|
226
|
+
reason: reasons[0],
|
|
227
|
+
meta: { ...existingEntry.meta, limit: newLimit }
|
|
228
|
+
};
|
|
229
|
+
accessSet.value = { ...current, entitlements: newEntitlements };
|
|
230
|
+
}
|
|
203
231
|
function handleLimitUpdate(accessSet, current, entitlement, consumed, remaining, max) {
|
|
204
232
|
const existingEntry = current.entitlements[entitlement];
|
|
205
233
|
if (!existingEntry)
|
package/dist/src/css/public.js
CHANGED
|
@@ -89,9 +89,11 @@ interface SdkMethodWithMeta<
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
/** Reserved property names that cannot be used as field names on FormInstance. */
|
|
92
|
-
type ReservedFormNames = "submitting" | "dirty" | "valid" | "action" | "method" | "onSubmit" | "reset" | "setFieldError" | "submit" | "__bindElement";
|
|
92
|
+
type ReservedFormNames = "submitting" | "dirty" | "valid" | "action" | "method" | "onSubmit" | "reset" | "setFieldError" | "submit" | "fields" | "__bindElement";
|
|
93
93
|
/** Mapped type providing FieldState for each field in TBody. */
|
|
94
94
|
type FieldAccessors<TBody> = { [K in keyof TBody] : FieldState<TBody[K]> };
|
|
95
|
+
/** Mapped type providing typed field name strings for compile-time input validation. */
|
|
96
|
+
type FieldNames<TBody> = { readonly [K in keyof TBody & string] : K };
|
|
95
97
|
/** Base properties available on every form instance. */
|
|
96
98
|
interface FormBaseProperties<TBody> {
|
|
97
99
|
action: string;
|
|
@@ -103,6 +105,7 @@ interface FormBaseProperties<TBody> {
|
|
|
103
105
|
submitting: Signal<boolean>;
|
|
104
106
|
dirty: ReadonlySignal<boolean>;
|
|
105
107
|
valid: ReadonlySignal<boolean>;
|
|
108
|
+
fields: FieldNames<TBody>;
|
|
106
109
|
__bindElement: (el: HTMLFormElement) => void;
|
|
107
110
|
}
|
|
108
111
|
/**
|
|
@@ -164,4 +167,4 @@ interface FormDataOptions {
|
|
|
164
167
|
* "true"/"false" become booleans.
|
|
165
168
|
*/
|
|
166
169
|
declare function formDataToObject(formData: FormData, options?: FormDataOptions): Record<string, unknown>;
|
|
167
|
-
export { validate, formDataToObject, form, createFieldState, ValidationResult, SdkMethodWithMeta, SdkMethod, FormSchema, FormOptions, FormInstance, FormDataOptions, FieldState };
|
|
170
|
+
export { validate, formDataToObject, form, createFieldState, ValidationResult, SdkMethodWithMeta, SdkMethod, FormSchema, FormOptions, FormInstance, FormDataOptions, FieldState, FieldNames };
|
package/dist/src/form/public.js
CHANGED
package/dist/src/index.d.ts
CHANGED
|
@@ -620,9 +620,11 @@ interface SdkMethodWithMeta<
|
|
|
620
620
|
};
|
|
621
621
|
}
|
|
622
622
|
/** Reserved property names that cannot be used as field names on FormInstance. */
|
|
623
|
-
type ReservedFormNames = "submitting" | "dirty" | "valid" | "action" | "method" | "onSubmit" | "reset" | "setFieldError" | "submit" | "__bindElement";
|
|
623
|
+
type ReservedFormNames = "submitting" | "dirty" | "valid" | "action" | "method" | "onSubmit" | "reset" | "setFieldError" | "submit" | "fields" | "__bindElement";
|
|
624
624
|
/** Mapped type providing FieldState for each field in TBody. */
|
|
625
625
|
type FieldAccessors<TBody> = { [K in keyof TBody] : FieldState<TBody[K]> };
|
|
626
|
+
/** Mapped type providing typed field name strings for compile-time input validation. */
|
|
627
|
+
type FieldNames<TBody> = { readonly [K in keyof TBody & string] : K };
|
|
626
628
|
/** Base properties available on every form instance. */
|
|
627
629
|
interface FormBaseProperties<TBody> {
|
|
628
630
|
action: string;
|
|
@@ -634,6 +636,7 @@ interface FormBaseProperties<TBody> {
|
|
|
634
636
|
submitting: Signal<boolean>;
|
|
635
637
|
dirty: ReadonlySignal<boolean>;
|
|
636
638
|
valid: ReadonlySignal<boolean>;
|
|
639
|
+
fields: FieldNames<TBody>;
|
|
637
640
|
__bindElement: (el: HTMLFormElement) => void;
|
|
638
641
|
}
|
|
639
642
|
/**
|
|
@@ -915,6 +918,8 @@ type ExtractParams<T extends string> = [ExtractParamsFromSegments<WithoutWildcar
|
|
|
915
918
|
* - Fallback: `string` → `string` (backward compat)
|
|
916
919
|
*/
|
|
917
920
|
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;
|
|
921
|
+
/** Union of route pattern keys from a route map. */
|
|
922
|
+
type RoutePattern<TRouteMap extends Record<string, unknown>> = keyof TRouteMap & string;
|
|
918
923
|
/**
|
|
919
924
|
* Union of all valid URL shapes for a route map.
|
|
920
925
|
* Maps each route pattern key through `PathWithParams` to produce the accepted URL shapes.
|
|
@@ -924,7 +929,7 @@ type PathWithParams<T extends string> = T extends `${infer Before}*` ? `${PathWi
|
|
|
924
929
|
* RoutePaths<{ '/': ..., '/tasks/:id': ... }> = '/' | `/tasks/${string}`
|
|
925
930
|
* ```
|
|
926
931
|
*/
|
|
927
|
-
type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in
|
|
932
|
+
type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in RoutePattern<TRouteMap>] : PathWithParams<K> }[RoutePattern<TRouteMap>];
|
|
928
933
|
/** Schema interface for parsing and validating values (search params, path params). */
|
|
929
934
|
interface SearchParamSchema<T> {
|
|
930
935
|
parse(data: unknown): {
|
|
@@ -1089,11 +1094,25 @@ interface LinkFactoryOptions {
|
|
|
1089
1094
|
* @returns A Link component function
|
|
1090
1095
|
*/
|
|
1091
1096
|
declare function createLink(currentPath: ReadonlySignal<string>, navigate: (url: string) => void, factoryOptions?: LinkFactoryOptions): (props: LinkProps) => HTMLAnchorElement;
|
|
1097
|
+
type NavigateSearchValue = string | number | boolean | null | undefined;
|
|
1098
|
+
type NavigateSearch = string | URLSearchParams | Record<string, NavigateSearchValue | readonly NavigateSearchValue[]>;
|
|
1092
1099
|
/** Options for router.navigate(). */
|
|
1093
1100
|
interface NavigateOptions {
|
|
1094
1101
|
/** Use history.replaceState instead of pushState. */
|
|
1095
1102
|
replace?: boolean;
|
|
1096
|
-
|
|
1103
|
+
/** Route params used to interpolate dynamic segments in the route pattern. */
|
|
1104
|
+
params?: Record<string, string>;
|
|
1105
|
+
/** Search params appended to the final URL. */
|
|
1106
|
+
search?: NavigateSearch;
|
|
1107
|
+
}
|
|
1108
|
+
type NavigateOptionsFor<TPath extends string> = string extends TPath ? NavigateOptions : TPath extends `${string}:${string}` | `${string}*` ? Omit<NavigateOptions, "params"> & {
|
|
1109
|
+
params: ExtractParams<TPath>;
|
|
1110
|
+
} : Omit<NavigateOptions, "params"> & {
|
|
1111
|
+
params?: never;
|
|
1112
|
+
};
|
|
1113
|
+
type NavigateInput<TPath extends string = string> = {
|
|
1114
|
+
to: TPath;
|
|
1115
|
+
} & NavigateOptionsFor<TPath>;
|
|
1097
1116
|
/** Handle returned by prefetchNavData for cancellation. */
|
|
1098
1117
|
interface PrefetchHandle {
|
|
1099
1118
|
abort: () => void;
|
|
@@ -1118,13 +1137,14 @@ interface RouterOptions {
|
|
|
1118
1137
|
*
|
|
1119
1138
|
* Generic over the route map `T`. Defaults to `RouteDefinitionMap` (string
|
|
1120
1139
|
* index signature) for backward compatibility — unparameterized `Router`
|
|
1121
|
-
* accepts any string in `navigate()`.
|
|
1140
|
+
* accepts any string in `navigate().to`.
|
|
1122
1141
|
*
|
|
1123
1142
|
* Method syntax on `navigate`, `revalidate`, and `dispose` enables bivariant
|
|
1124
1143
|
* parameter checking under `strictFunctionTypes`. This means `Router<T>` is
|
|
1125
1144
|
* assignable to `Router` (the unparameterized default), which is required for
|
|
1126
1145
|
* storing typed routers in the `RouterContext` without contravariance errors.
|
|
1127
|
-
* At call sites, TypeScript still enforces the `
|
|
1146
|
+
* At call sites, TypeScript still enforces the `RoutePattern<T>` constraint and
|
|
1147
|
+
* the params required for each route pattern.
|
|
1128
1148
|
*/
|
|
1129
1149
|
interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
|
|
1130
1150
|
/** Current matched route (reactive signal). */
|
|
@@ -1135,8 +1155,8 @@ interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>
|
|
|
1135
1155
|
loaderError: Signal<Error | null>;
|
|
1136
1156
|
/** Parsed search params from the current route (reactive signal). */
|
|
1137
1157
|
searchParams: Signal<Record<string, unknown>>;
|
|
1138
|
-
/** Navigate to a
|
|
1139
|
-
navigate(
|
|
1158
|
+
/** Navigate to a route pattern, interpolating params and search into the final URL. */
|
|
1159
|
+
navigate<TPath extends RoutePattern<T>>(input: NavigateInput<TPath>): Promise<void>;
|
|
1140
1160
|
/** Re-run all loaders for the current route. */
|
|
1141
1161
|
revalidate(): Promise<void>;
|
|
1142
1162
|
/** Remove popstate listener and clean up the router. */
|
|
@@ -1503,4 +1523,4 @@ declare function resetRelationSchemas_TEST_ONLY(): void;
|
|
|
1503
1523
|
* ```
|
|
1504
1524
|
*/
|
|
1505
1525
|
declare function createTestStore(data: Record<string, Record<string, unknown>>): EntityStore;
|
|
1506
|
-
export { zoomOut, zoomIn, variants, validate, useSearchParams, useRouter, useParams, useDialogStack, useContext, untrack, slideOutToTop, slideOutToRight, slideOutToLeft, slideOutToBottom, slideInFromTop, slideInFromRight, slideInFromLeft, slideInFromBottom, signal, setAdapter, s, resolveChildren, resetRelationSchemas_TEST_ONLY, resetInjectedStyles, registerRelationSchema, ref, queryMatch, query, parseSearchParams, palettes, onMount2 as onMount, mount, keyframes, isRenderNode, isQueryDescriptor, invalidate, injectCSS, hydrate, globalCss, getRelationSchema, getQueryEnvelopeStore, getInjectedCSS, getEntityStore, getAdapter, formDataToObject, form, fadeOut, fadeIn, defineTheme, defineRoutes, css, createTestStore, createRouter, createOptimisticHandler, 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, RelationSchema, RelationFieldDef, Ref, ReadonlySignal, RawDeclaration, RENDER_NODE_BRAND, QueryResult, QueryOptions, QueryMatchHandlers, QueryEnvelopeStore, QueryEnvelope, QueryDescriptor3 as QueryDescriptor, PresenceProps, Presence, PathWithParams, ParamSchema, OutletContextValue, OutletContext, Outlet, NavigateOptions, MountOptions, MountHandle, MatchedRoute, LoaderData, ListTransitionProps, ListTransition, 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 };
|
|
1526
|
+
export { zoomOut, zoomIn, variants, validate, useSearchParams, useRouter, useParams, useDialogStack, useContext, untrack, slideOutToTop, slideOutToRight, slideOutToLeft, slideOutToBottom, slideInFromTop, slideInFromRight, slideInFromLeft, slideInFromBottom, signal, setAdapter, s, resolveChildren, resetRelationSchemas_TEST_ONLY, resetInjectedStyles, registerRelationSchema, ref, queryMatch, query, parseSearchParams, palettes, onMount2 as onMount, mount, keyframes, isRenderNode, isQueryDescriptor, invalidate, injectCSS, hydrate, globalCss, getRelationSchema, getQueryEnvelopeStore, getInjectedCSS, getEntityStore, getAdapter, formDataToObject, form, fadeOut, fadeIn, defineTheme, defineRoutes, css, createTestStore, createRouter, createOptimisticHandler, 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, RoutePattern, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, RenderText, RenderNode, RenderElement, RenderAdapter, RelationSchema, RelationFieldDef, Ref, ReadonlySignal, RawDeclaration, RENDER_NODE_BRAND, QueryResult, QueryOptions, QueryMatchHandlers, QueryEnvelopeStore, QueryEnvelope, QueryDescriptor3 as QueryDescriptor, PresenceProps, Presence, PathWithParams, ParamSchema, OutletContextValue, OutletContext, Outlet, NavigateOptions, NavigateInput, MountOptions, MountHandle, MatchedRoute, LoaderData, ListTransitionProps, ListTransition, 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 };
|
package/dist/src/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
slideOutToTop,
|
|
21
21
|
zoomIn,
|
|
22
22
|
zoomOut
|
|
23
|
-
} from "../shared/chunk-
|
|
23
|
+
} from "../shared/chunk-4txc67nd.js";
|
|
24
24
|
import {
|
|
25
25
|
Outlet,
|
|
26
26
|
OutletContext,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
import"../shared/chunk-dksg08fq.js";
|
|
36
36
|
import {
|
|
37
37
|
createRouter
|
|
38
|
-
} from "../shared/chunk-
|
|
38
|
+
} from "../shared/chunk-wymw818z.js";
|
|
39
39
|
import {
|
|
40
40
|
defineRoutes
|
|
41
41
|
} from "../shared/chunk-83g4h38e.js";
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
form,
|
|
45
45
|
formDataToObject,
|
|
46
46
|
validate
|
|
47
|
-
} from "../shared/chunk-
|
|
47
|
+
} from "../shared/chunk-5dbq8jp9.js";
|
|
48
48
|
import {
|
|
49
49
|
EntityStore,
|
|
50
50
|
QueryEnvelopeStore,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
resolveChildren,
|
|
73
73
|
s,
|
|
74
74
|
variants
|
|
75
|
-
} from "../shared/chunk-
|
|
75
|
+
} from "../shared/chunk-1wby7nex.js";
|
|
76
76
|
import {
|
|
77
77
|
__append,
|
|
78
78
|
__element,
|
package/dist/src/internals.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
deserializeProps,
|
|
3
3
|
onAnimationsComplete,
|
|
4
4
|
resolveComponent
|
|
5
|
-
} from "../shared/chunk-
|
|
5
|
+
} from "../shared/chunk-4txc67nd.js";
|
|
6
6
|
import {
|
|
7
7
|
__attr,
|
|
8
8
|
__classList,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
SIZE_KEYWORDS,
|
|
41
41
|
SPACING_SCALE,
|
|
42
42
|
compileTheme
|
|
43
|
-
} from "../shared/chunk-
|
|
43
|
+
} from "../shared/chunk-1wby7nex.js";
|
|
44
44
|
import {
|
|
45
45
|
__append,
|
|
46
46
|
__child,
|
|
@@ -34,6 +34,8 @@ type ExtractParams<T extends string> = [ExtractParamsFromSegments<WithoutWildcar
|
|
|
34
34
|
* - Fallback: `string` → `string` (backward compat)
|
|
35
35
|
*/
|
|
36
36
|
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;
|
|
37
|
+
/** Union of route pattern keys from a route map. */
|
|
38
|
+
type RoutePattern<TRouteMap extends Record<string, unknown>> = keyof TRouteMap & string;
|
|
37
39
|
/**
|
|
38
40
|
* Union of all valid URL shapes for a route map.
|
|
39
41
|
* Maps each route pattern key through `PathWithParams` to produce the accepted URL shapes.
|
|
@@ -43,7 +45,7 @@ type PathWithParams<T extends string> = T extends `${infer Before}*` ? `${PathWi
|
|
|
43
45
|
* RoutePaths<{ '/': ..., '/tasks/:id': ... }> = '/' | `/tasks/${string}`
|
|
44
46
|
* ```
|
|
45
47
|
*/
|
|
46
|
-
type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in
|
|
48
|
+
type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in RoutePattern<TRouteMap>] : PathWithParams<K> }[RoutePattern<TRouteMap>];
|
|
47
49
|
/** Schema interface for parsing and validating values (search params, path params). */
|
|
48
50
|
interface SearchParamSchema<T> {
|
|
49
51
|
parse(data: unknown): {
|
|
@@ -251,11 +253,25 @@ interface LinkFactoryOptions {
|
|
|
251
253
|
* @returns A Link component function
|
|
252
254
|
*/
|
|
253
255
|
declare function createLink(currentPath: ReadonlySignal<string>, navigate: (url: string) => void, factoryOptions?: LinkFactoryOptions): (props: LinkProps) => HTMLAnchorElement;
|
|
256
|
+
type NavigateSearchValue = string | number | boolean | null | undefined;
|
|
257
|
+
type NavigateSearch = string | URLSearchParams | Record<string, NavigateSearchValue | readonly NavigateSearchValue[]>;
|
|
254
258
|
/** Options for router.navigate(). */
|
|
255
259
|
interface NavigateOptions {
|
|
256
260
|
/** Use history.replaceState instead of pushState. */
|
|
257
261
|
replace?: boolean;
|
|
262
|
+
/** Route params used to interpolate dynamic segments in the route pattern. */
|
|
263
|
+
params?: Record<string, string>;
|
|
264
|
+
/** Search params appended to the final URL. */
|
|
265
|
+
search?: NavigateSearch;
|
|
258
266
|
}
|
|
267
|
+
type NavigateOptionsFor<TPath extends string> = string extends TPath ? NavigateOptions : TPath extends `${string}:${string}` | `${string}*` ? Omit<NavigateOptions, "params"> & {
|
|
268
|
+
params: ExtractParams<TPath>;
|
|
269
|
+
} : Omit<NavigateOptions, "params"> & {
|
|
270
|
+
params?: never;
|
|
271
|
+
};
|
|
272
|
+
type NavigateInput<TPath extends string = string> = {
|
|
273
|
+
to: TPath;
|
|
274
|
+
} & NavigateOptionsFor<TPath>;
|
|
259
275
|
/** Handle returned by prefetchNavData for cancellation. */
|
|
260
276
|
interface PrefetchHandle {
|
|
261
277
|
abort: () => void;
|
|
@@ -280,13 +296,14 @@ interface RouterOptions {
|
|
|
280
296
|
*
|
|
281
297
|
* Generic over the route map `T`. Defaults to `RouteDefinitionMap` (string
|
|
282
298
|
* index signature) for backward compatibility — unparameterized `Router`
|
|
283
|
-
* accepts any string in `navigate()`.
|
|
299
|
+
* accepts any string in `navigate().to`.
|
|
284
300
|
*
|
|
285
301
|
* Method syntax on `navigate`, `revalidate`, and `dispose` enables bivariant
|
|
286
302
|
* parameter checking under `strictFunctionTypes`. This means `Router<T>` is
|
|
287
303
|
* assignable to `Router` (the unparameterized default), which is required for
|
|
288
304
|
* storing typed routers in the `RouterContext` without contravariance errors.
|
|
289
|
-
* At call sites, TypeScript still enforces the `
|
|
305
|
+
* At call sites, TypeScript still enforces the `RoutePattern<T>` constraint and
|
|
306
|
+
* the params required for each route pattern.
|
|
290
307
|
*/
|
|
291
308
|
interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
|
|
292
309
|
/** Current matched route (reactive signal). */
|
|
@@ -297,8 +314,8 @@ interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>
|
|
|
297
314
|
loaderError: Signal<Error | null>;
|
|
298
315
|
/** Parsed search params from the current route (reactive signal). */
|
|
299
316
|
searchParams: Signal<Record<string, unknown>>;
|
|
300
|
-
/** Navigate to a
|
|
301
|
-
navigate(
|
|
317
|
+
/** Navigate to a route pattern, interpolating params and search into the final URL. */
|
|
318
|
+
navigate<TPath extends RoutePattern<T>>(input: NavigateInput<TPath>): Promise<void>;
|
|
302
319
|
/** Re-run all loaders for the current route. */
|
|
303
320
|
revalidate(): Promise<void>;
|
|
304
321
|
/** Remove popstate listener and clean up the router. */
|
|
@@ -405,4 +422,4 @@ declare function parseSearchParams<T = Record<string, string>>(urlParams: URLSea
|
|
|
405
422
|
* @returns The current search params value
|
|
406
423
|
*/
|
|
407
424
|
declare function useSearchParams<T>(searchSignal: ReadonlySignal<T>): T;
|
|
408
|
-
export { useSearchParams, useRouter, useParams, parseSearchParams, defineRoutes, createRouter, createLink, TypedRoutes, TypedRouter, SearchParamSchema, RouterViewProps, RouterView, RouterContext, Router, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, PathWithParams, ParamSchema, OutletContextValue, OutletContext, Outlet, NavigateOptions, MatchedRoute, LoaderData, LinkProps, InferRouteMap, ExtractParams, CompiledRoute };
|
|
425
|
+
export { useSearchParams, useRouter, useParams, parseSearchParams, defineRoutes, createRouter, createLink, TypedRoutes, TypedRouter, SearchParamSchema, RouterViewProps, RouterView, RouterContext, Router, RoutePattern, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, PathWithParams, ParamSchema, OutletContextValue, OutletContext, Outlet, NavigateOptions, NavigateInput, MatchedRoute, LoaderData, LinkProps, InferRouteMap, ExtractParams, CompiledRoute };
|
package/dist/src/test/index.d.ts
CHANGED
|
@@ -138,25 +138,8 @@ type ExtractParams<T extends string> = [ExtractParamsFromSegments<WithoutWildcar
|
|
|
138
138
|
} : Record<string, never> : HasWildcard<T> extends true ? { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string } & {
|
|
139
139
|
"*": string;
|
|
140
140
|
} : { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string };
|
|
141
|
-
/**
|
|
142
|
-
|
|
143
|
-
* - Static: `'/'` → `'/'`
|
|
144
|
-
* - Param: `'/tasks/:id'` → `` `/tasks/${string}` ``
|
|
145
|
-
* - Wildcard: `'/files/*'` → `` `/files/${string}` ``
|
|
146
|
-
* - Multi: `'/users/:id/posts/:postId'` → `` `/users/${string}/posts/${string}` ``
|
|
147
|
-
* - Fallback: `string` → `string` (backward compat)
|
|
148
|
-
*/
|
|
149
|
-
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;
|
|
150
|
-
/**
|
|
151
|
-
* Union of all valid URL shapes for a route map.
|
|
152
|
-
* Maps each route pattern key through `PathWithParams` to produce the accepted URL shapes.
|
|
153
|
-
*
|
|
154
|
-
* Example:
|
|
155
|
-
* ```
|
|
156
|
-
* RoutePaths<{ '/': ..., '/tasks/:id': ... }> = '/' | `/tasks/${string}`
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
|
-
type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in keyof TRouteMap & string] : PathWithParams<K> }[keyof TRouteMap & string];
|
|
141
|
+
/** Union of route pattern keys from a route map. */
|
|
142
|
+
type RoutePattern<TRouteMap extends Record<string, unknown>> = keyof TRouteMap & string;
|
|
160
143
|
/** Schema interface for parsing and validating values (search params, path params). */
|
|
161
144
|
interface SearchParamSchema<T> {
|
|
162
145
|
parse(data: unknown): {
|
|
@@ -273,23 +256,38 @@ interface Signal<T> {
|
|
|
273
256
|
/** Manually notify all subscribers (useful after mutating the value in place). */
|
|
274
257
|
notify(): void;
|
|
275
258
|
}
|
|
259
|
+
type NavigateSearchValue = string | number | boolean | null | undefined;
|
|
260
|
+
type NavigateSearch = string | URLSearchParams | Record<string, NavigateSearchValue | readonly NavigateSearchValue[]>;
|
|
276
261
|
/** Options for router.navigate(). */
|
|
277
262
|
interface NavigateOptions {
|
|
278
263
|
/** Use history.replaceState instead of pushState. */
|
|
279
264
|
replace?: boolean;
|
|
265
|
+
/** Route params used to interpolate dynamic segments in the route pattern. */
|
|
266
|
+
params?: Record<string, string>;
|
|
267
|
+
/** Search params appended to the final URL. */
|
|
268
|
+
search?: NavigateSearch;
|
|
280
269
|
}
|
|
270
|
+
type NavigateOptionsFor<TPath extends string> = string extends TPath ? NavigateOptions : TPath extends `${string}:${string}` | `${string}*` ? Omit<NavigateOptions, "params"> & {
|
|
271
|
+
params: ExtractParams<TPath>;
|
|
272
|
+
} : Omit<NavigateOptions, "params"> & {
|
|
273
|
+
params?: never;
|
|
274
|
+
};
|
|
275
|
+
type NavigateInput<TPath extends string = string> = {
|
|
276
|
+
to: TPath;
|
|
277
|
+
} & NavigateOptionsFor<TPath>;
|
|
281
278
|
/**
|
|
282
279
|
* The router instance returned by createRouter.
|
|
283
280
|
*
|
|
284
281
|
* Generic over the route map `T`. Defaults to `RouteDefinitionMap` (string
|
|
285
282
|
* index signature) for backward compatibility — unparameterized `Router`
|
|
286
|
-
* accepts any string in `navigate()`.
|
|
283
|
+
* accepts any string in `navigate().to`.
|
|
287
284
|
*
|
|
288
285
|
* Method syntax on `navigate`, `revalidate`, and `dispose` enables bivariant
|
|
289
286
|
* parameter checking under `strictFunctionTypes`. This means `Router<T>` is
|
|
290
287
|
* assignable to `Router` (the unparameterized default), which is required for
|
|
291
288
|
* storing typed routers in the `RouterContext` without contravariance errors.
|
|
292
|
-
* At call sites, TypeScript still enforces the `
|
|
289
|
+
* At call sites, TypeScript still enforces the `RoutePattern<T>` constraint and
|
|
290
|
+
* the params required for each route pattern.
|
|
293
291
|
*/
|
|
294
292
|
interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
|
|
295
293
|
/** Current matched route (reactive signal). */
|
|
@@ -300,8 +298,8 @@ interface Router<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>
|
|
|
300
298
|
loaderError: Signal<Error | null>;
|
|
301
299
|
/** Parsed search params from the current route (reactive signal). */
|
|
302
300
|
searchParams: Signal<Record<string, unknown>>;
|
|
303
|
-
/** Navigate to a
|
|
304
|
-
navigate(
|
|
301
|
+
/** Navigate to a route pattern, interpolating params and search into the final URL. */
|
|
302
|
+
navigate<TPath extends RoutePattern<T>>(input: NavigateInput<TPath>): Promise<void>;
|
|
305
303
|
/** Re-run all loaders for the current route. */
|
|
306
304
|
revalidate(): Promise<void>;
|
|
307
305
|
/** Remove popstate listener and clean up the router. */
|
package/dist/src/test/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRouter
|
|
3
|
-
} from "../../shared/chunk-
|
|
3
|
+
} from "../../shared/chunk-wymw818z.js";
|
|
4
4
|
import {
|
|
5
5
|
defineRoutes
|
|
6
6
|
} from "../../shared/chunk-83g4h38e.js";
|
|
@@ -199,7 +199,7 @@ async function createTestRouter(routes, opts) {
|
|
|
199
199
|
container.setAttribute("data-testid", "test-router-container");
|
|
200
200
|
await renderCurrentRoute(router, container);
|
|
201
201
|
async function navigate(path) {
|
|
202
|
-
await router.navigate(path);
|
|
202
|
+
await router.navigate({ to: path });
|
|
203
203
|
await renderCurrentRoute(router, container);
|
|
204
204
|
}
|
|
205
205
|
return { component: container, navigate, router };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertz/ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Vertz UI framework — signals, components, JSX runtime",
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
"typecheck": "tsc --noEmit"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@vertz/fetch": "^0.2.
|
|
72
|
+
"@vertz/fetch": "^0.2.14"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@happy-dom/global-registrator": "^20.7.0",
|
|
76
|
-
"@vertz/schema": "^0.2.
|
|
76
|
+
"@vertz/schema": "^0.2.14",
|
|
77
77
|
"bunup": "^0.16.31",
|
|
78
78
|
"happy-dom": "^20.7.0",
|
|
79
79
|
"typescript": "^5.7.0"
|