@vertz/ui 0.2.37 → 0.2.41

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.
@@ -20,7 +20,7 @@ import {
20
20
  pushScope,
21
21
  resumeHydration,
22
22
  runCleanups
23
- } from "./chunk-1yd6jfw5.js";
23
+ } from "./chunk-2k26a794.js";
24
24
 
25
25
  // src/dom/dom-adapter.ts
26
26
  function createDOMAdapter() {
@@ -54,6 +54,37 @@ function wrapSignalProps(value) {
54
54
  }
55
55
  return wrapped;
56
56
  }
57
+ function wrapSignalPropsLazy(propsObj, initial) {
58
+ if (initial == null || typeof initial !== "object" || Array.isArray(initial)) {
59
+ return wrapSignalProps(initial);
60
+ }
61
+ const source = initial;
62
+ const keys = Object.keys(source);
63
+ const wrapped = {};
64
+ for (const key of keys) {
65
+ const propValue = source[key];
66
+ if (isSignalLike(propValue)) {
67
+ Object.defineProperty(wrapped, key, {
68
+ get() {
69
+ return propValue.value;
70
+ },
71
+ enumerable: true,
72
+ configurable: true
73
+ });
74
+ } else if (typeof propValue === "function") {
75
+ wrapped[key] = propValue;
76
+ } else {
77
+ Object.defineProperty(wrapped, key, {
78
+ get() {
79
+ return propsObj.value[key];
80
+ },
81
+ enumerable: true,
82
+ configurable: true
83
+ });
84
+ }
85
+ }
86
+ return wrapped;
87
+ }
57
88
  function asKey(ctx) {
58
89
  return ctx;
59
90
  }
@@ -87,8 +118,10 @@ function createContext(defaultValue, __stableId) {
87
118
  return;
88
119
  }
89
120
  const props = valueOrProps;
90
- const { value: rawValue, children } = props;
91
- const value = wrapSignalProps(rawValue);
121
+ const rawValue = props.value;
122
+ const { children } = props;
123
+ const valueDesc = Object.getOwnPropertyDescriptor(props, "value");
124
+ const value = valueDesc?.get ? wrapSignalPropsLazy(props, rawValue) : wrapSignalProps(rawValue);
92
125
  const parentScope = getContextScope();
93
126
  const scope = parentScope ? new Map(parentScope) : new Map;
94
127
  scope.set(asKey(ctx), value);
@@ -729,4 +762,4 @@ function lifecycleEffect(fn) {
729
762
  return dispose;
730
763
  }
731
764
 
732
- export { registerSSRResolver, getSSRContext, hasSSRResolver, createContext, useContext, getContextScope, setContextScope, startHydration, endHydration, discardDeferredEffects, getIsHydrating, pauseHydration, resumeHydration, advanceCursor, claimElement, claimText, claimComment, enterChildren, exitChildren, DisposalScopeError, onCleanup, _tryOnCleanup, pushScope, popScope, runCleanups, batch, setReadValueCallback, untrack, startSignalCollection, stopSignalCollection, signal, computed, domEffect, deferredDomEffect, lifecycleEffect };
765
+ export { registerSSRResolver, getSSRContext, hasSSRResolver, createContext, useContext, getContextScope, setContextScope, startHydration, endHydration, discardDeferredEffects, getIsHydrating, pauseHydration, resumeHydration, advanceCursor, claimElement, claimText, claimComment, enterChildren, exitChildren, DisposalScopeError, onCleanup, _tryOnCleanup, pushScope, popScope, runCleanups, batch, getSubscriber, getReadValueCallback, setReadValueCallback, untrack, startSignalCollection, stopSignalCollection, signal, computed, domEffect, deferredDomEffect, lifecycleEffect };
@@ -4,10 +4,10 @@ import {
4
4
  __element,
5
5
  __enterChildren,
6
6
  __exitChildren
7
- } from "./chunk-dh32wkrv.js";
7
+ } from "./chunk-29x7mbne.js";
8
8
  import {
9
9
  getSSRContext
10
- } from "./chunk-1yd6jfw5.js";
10
+ } from "./chunk-2k26a794.js";
11
11
 
12
12
  // src/component/children.ts
13
13
  var MAX_RESOLVE_DEPTH = 100;
@@ -958,6 +958,33 @@ ${cssVars.join(`
958
958
  return { fontFaceCss, cssVarsCss, cssVarLines, preloadTags, preloadItems };
959
959
  }
960
960
 
961
+ // src/css/google-font.ts
962
+ function googleFont(family, options) {
963
+ const style = options.style ?? "normal";
964
+ const styles = Array.isArray(style) ? style : [style];
965
+ const display = options.display ?? "swap";
966
+ const subsets = options.subsets ?? ["latin"];
967
+ const weight = typeof options.weight === "number" ? String(options.weight) : options.weight;
968
+ return {
969
+ __brand: "FontDescriptor",
970
+ family,
971
+ weight: Array.isArray(weight) ? weight.join(";") : String(weight),
972
+ style: styles[0] ?? "normal",
973
+ display,
974
+ src: undefined,
975
+ fallback: options.fallback ?? [],
976
+ subsets,
977
+ adjustFontFallback: options.adjustFontFallback ?? true,
978
+ __google: {
979
+ family,
980
+ weight: options.weight,
981
+ style: styles,
982
+ subsets,
983
+ display
984
+ }
985
+ };
986
+ }
987
+
961
988
  // src/css/global-css.ts
962
989
  function globalCss(input) {
963
990
  const rules = [];
@@ -1247,4 +1274,4 @@ function variants(config) {
1247
1274
  return fn;
1248
1275
  }
1249
1276
 
1250
- export { resolveChildren, children, PROPERTY_MAP, KEYWORD_MAP, DISPLAY_MAP, SPACING_SCALE, RADIUS_SCALE, SHADOW_SCALE, FONT_SIZE_SCALE, FONT_WEIGHT_SCALE, LINE_HEIGHT_SCALE, ALIGNMENT_MAP, SIZE_KEYWORDS, HEIGHT_AXIS_PROPERTIES, COLOR_NAMESPACES, CSS_COLOR_KEYWORDS, CONTENT_MAP, PSEUDO_PREFIXES, PSEUDO_MAP, injectCSS, resetInjectedStyles, getInjectedCSS, css, font, compileFonts, globalCss, s, defineTheme, compileTheme, ThemeProvider, variants };
1277
+ export { resolveChildren, children, PROPERTY_MAP, KEYWORD_MAP, DISPLAY_MAP, SPACING_SCALE, RADIUS_SCALE, SHADOW_SCALE, FONT_SIZE_SCALE, FONT_WEIGHT_SCALE, LINE_HEIGHT_SCALE, ALIGNMENT_MAP, SIZE_KEYWORDS, HEIGHT_AXIS_PROPERTIES, COLOR_NAMESPACES, CSS_COLOR_KEYWORDS, CONTENT_MAP, PSEUDO_PREFIXES, PSEUDO_MAP, injectCSS, resetInjectedStyles, getInjectedCSS, css, font, compileFonts, googleFont, globalCss, s, defineTheme, compileTheme, ThemeProvider, variants };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  computed,
3
3
  signal
4
- } from "./chunk-1yd6jfw5.js";
4
+ } from "./chunk-2k26a794.js";
5
5
 
6
6
  // src/form/field-state.ts
7
7
  function createFieldState(_name, initialValue) {
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-jrtrk5z4.js";
4
4
  import {
5
5
  registerActiveQuery
6
- } from "./chunk-pv0apt9z.js";
6
+ } from "./chunk-kt7127xc.js";
7
7
  import {
8
8
  isBrowser
9
- } from "./chunk-sjypbv24.js";
9
+ } from "./chunk-xs4hak0m.js";
10
10
  import {
11
11
  _tryOnCleanup,
12
12
  batch,
@@ -16,7 +16,7 @@ import {
16
16
  setReadValueCallback,
17
17
  signal,
18
18
  untrack
19
- } from "./chunk-1yd6jfw5.js";
19
+ } from "./chunk-2k26a794.js";
20
20
 
21
21
  // src/query/cache.ts
22
22
  class MemoryCache {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  injectCSS
3
- } from "./chunk-g60cswzm.js";
3
+ } from "./chunk-3n9teyam.js";
4
4
  import {
5
5
  createContext
6
- } from "./chunk-1yd6jfw5.js";
6
+ } from "./chunk-2k26a794.js";
7
7
 
8
8
  // src/dom/animation.ts
9
9
  function onAnimationsComplete(el, callback) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createContext,
3
3
  useContext
4
- } from "./chunk-1yd6jfw5.js";
4
+ } from "./chunk-2k26a794.js";
5
5
 
6
6
  // src/router/router-context.ts
7
7
  var RouterContext = createContext(undefined, "@vertz/ui::RouterContext");
@@ -7,12 +7,14 @@ import {
7
7
  } from "./chunk-jrtrk5z4.js";
8
8
  import {
9
9
  isBrowser
10
- } from "./chunk-sjypbv24.js";
10
+ } from "./chunk-xs4hak0m.js";
11
11
  import {
12
12
  batch,
13
+ getReadValueCallback,
13
14
  getSSRContext,
15
+ getSubscriber,
14
16
  signal
15
- } from "./chunk-1yd6jfw5.js";
17
+ } from "./chunk-2k26a794.js";
16
18
 
17
19
  // src/router/reactive-search-params.ts
18
20
  function shallowEqual(a, b) {
@@ -267,11 +269,14 @@ function createRouter(routes, initialUrlOrOptions, maybeOptions) {
267
269
  if (typeof key === "symbol")
268
270
  return;
269
271
  const ctx = getSSRContext();
270
- if (ctx) {
271
- const m = matchRoute(routes, ctx.url);
272
- return m?.search?.[key];
272
+ const search = ctx ? matchRoute(routes, ctx.url)?.search ?? {} : fallbackMatch?.search ?? {};
273
+ const sub = getSubscriber();
274
+ if (sub) {
275
+ const cb = getReadValueCallback();
276
+ if (cb)
277
+ cb(search);
273
278
  }
274
- return fallbackMatch?.search?.[key];
279
+ return search[key];
275
280
  },
276
281
  set() {
277
282
  if (true) {
@@ -337,7 +342,11 @@ function createRouter(routes, initialUrlOrOptions, maybeOptions) {
337
342
  dispose: () => {}
338
343
  };
339
344
  }
345
+ function extractPathname(rawUrl) {
346
+ return rawUrl.split("?")[0]?.split("#")[0] || "/";
347
+ }
340
348
  const url = initialUrl ?? window.location.pathname + window.location.search;
349
+ let lastPathname = extractPathname(url);
341
350
  const initialMatch = matchRoute(routes, url);
342
351
  function normalizeUrl(rawUrl) {
343
352
  const qIdx = rawUrl.indexOf("?");
@@ -495,21 +504,22 @@ function createRouter(routes, initialUrlOrOptions, maybeOptions) {
495
504
  async function navigate(input) {
496
505
  const navUrl = buildNavigationUrl(input.to, input);
497
506
  const navMatch = matchRoute(routes, navUrl);
498
- const navPathname = navUrl.split("?")[0]?.split("#")[0] || "/";
499
- const isSearchParamOnly = window.location.pathname === navPathname;
507
+ const navPathname = extractPathname(navUrl);
508
+ const isSearchParamOnly = lastPathname === navPathname;
500
509
  const gen = ++navigateGen;
501
510
  const handle = isSearchParamOnly ? null : startPrefetch(navUrl);
502
- if (input.replace) {
503
- window.history.replaceState(null, "", navUrl);
504
- } else {
505
- window.history.pushState(null, "", navUrl);
506
- }
507
511
  const isCachedNav = visitedUrls.has(normalizeUrl(navUrl));
508
512
  if (!isCachedNav && (handle?.firstEvent || handle?.done)) {
509
513
  await awaitPrefetch(handle);
510
514
  }
511
515
  if (gen !== navigateGen)
512
516
  return;
517
+ if (input.replace) {
518
+ window.history.replaceState(null, "", navUrl);
519
+ } else {
520
+ window.history.pushState(null, "", navUrl);
521
+ }
522
+ lastPathname = navPathname;
513
523
  const transitionConfig = isSearchParamOnly ? undefined : input.viewTransition ?? navMatch?.route.viewTransition ?? options?.viewTransition;
514
524
  await applyNavigation(navUrl, navMatch, transitionConfig, isSearchParamOnly);
515
525
  }
@@ -527,10 +537,14 @@ function createRouter(routes, initialUrlOrOptions, maybeOptions) {
527
537
  }
528
538
  const onPopState = () => {
529
539
  const popUrl = window.location.pathname + window.location.search;
530
- startPrefetch(popUrl);
540
+ const popPathname = extractPathname(popUrl);
541
+ const isSearchParamOnly = lastPathname === popPathname;
542
+ lastPathname = popPathname;
543
+ if (!isSearchParamOnly)
544
+ startPrefetch(popUrl);
531
545
  const match = matchRoute(routes, popUrl);
532
- const transitionConfig = match?.route.viewTransition ?? options?.viewTransition;
533
- applyNavigation(popUrl, match, transitionConfig).catch(() => {});
546
+ const transitionConfig = isSearchParamOnly ? undefined : match?.route.viewTransition ?? options?.viewTransition;
547
+ applyNavigation(popUrl, match, transitionConfig, isSearchParamOnly).catch(() => {});
534
548
  };
535
549
  window.addEventListener("popstate", onPopState);
536
550
  function dispose() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getSSRContext
3
- } from "./chunk-1yd6jfw5.js";
3
+ } from "./chunk-2k26a794.js";
4
4
 
5
5
  // src/query/invalidate.ts
6
6
  var registry = new Set;
@@ -5,7 +5,7 @@ import {
5
5
  pushScope,
6
6
  runCleanups,
7
7
  untrack
8
- } from "./chunk-1yd6jfw5.js";
8
+ } from "./chunk-2k26a794.js";
9
9
 
10
10
  // src/component/lifecycle.ts
11
11
  var mountFrames = [];
@@ -3,21 +3,21 @@ import {
3
3
  beginDeferringMounts,
4
4
  discardDeferredMounts,
5
5
  flushDeferredMounts
6
- } from "./chunk-mntc8w0g.js";
6
+ } from "./chunk-pbw64893.js";
7
7
  import {
8
8
  __append,
9
9
  __classList,
10
10
  __element,
11
11
  __enterChildren,
12
12
  __exitChildren,
13
- __staticText
14
- } from "./chunk-dh32wkrv.js";
13
+ __insert
14
+ } from "./chunk-29x7mbne.js";
15
15
  import {
16
16
  RouterContext
17
- } from "./chunk-9p84cvet.js";
17
+ } from "./chunk-dxfd1ptg.js";
18
18
  import {
19
19
  isBrowser
20
- } from "./chunk-sjypbv24.js";
20
+ } from "./chunk-xs4hak0m.js";
21
21
  import {
22
22
  _tryOnCleanup,
23
23
  createContext,
@@ -32,7 +32,7 @@ import {
32
32
  startHydration,
33
33
  untrack,
34
34
  useContext
35
- } from "./chunk-1yd6jfw5.js";
35
+ } from "./chunk-2k26a794.js";
36
36
 
37
37
  // src/component/error-boundary-context.ts
38
38
  var handlerStack = [];
@@ -130,18 +130,7 @@ function createLink(currentPath, navigate, factoryOptions) {
130
130
  const el = __element("a", props);
131
131
  __on(el, "click", handleClick);
132
132
  __enterChildren(el);
133
- if (typeof children === "function") {
134
- const result = children();
135
- if (typeof result === "string") {
136
- __append(el, __staticText(result));
137
- } else {
138
- __append(el, result);
139
- }
140
- } else if (typeof children === "string") {
141
- __append(el, __staticText(children));
142
- } else {
143
- __append(el, children);
144
- }
133
+ __insert(el, children);
145
134
  __exitChildren();
146
135
  if (activeClass) {
147
136
  __classList(el, {
@@ -190,18 +179,7 @@ function Link({
190
179
  const el = __element("a", props);
191
180
  __on(el, "click", handleClick);
192
181
  __enterChildren(el);
193
- if (typeof children === "function") {
194
- const result = children();
195
- if (typeof result === "string") {
196
- __append(el, __staticText(result));
197
- } else {
198
- __append(el, result);
199
- }
200
- } else if (typeof children === "string") {
201
- __append(el, __staticText(children));
202
- } else {
203
- __append(el, children);
204
- }
182
+ __insert(el, children);
205
183
  __exitChildren();
206
184
  if (activeClass) {
207
185
  __classList(el, {
@@ -1,8 +1,7 @@
1
1
  // src/theme/registry.ts
2
- var _components = null;
3
- var _primitives = null;
2
+ var _resolved = null;
4
3
  function registerTheme(resolved) {
5
- if (!resolved || typeof resolved !== "object" || !resolved.components || typeof resolved.components !== "object") {
4
+ if (!resolved || typeof resolved !== "object" || !("components" in resolved) || !resolved.components) {
6
5
  throw new Error(`registerTheme() expects an object with a "components" property.
7
6
 
8
7
  ` + `Example:
@@ -11,11 +10,10 @@ function registerTheme(resolved) {
11
10
  ` + ` registerTheme(configureTheme({ palette: 'zinc' }));
12
11
  `);
13
12
  }
14
- _components = resolved.components;
15
- _primitives = resolved.components.primitives ?? {};
13
+ _resolved = resolved;
16
14
  }
17
15
  function _getComponent(name) {
18
- if (!_components) {
16
+ if (!_resolved) {
19
17
  throw new Error(`No theme registered. Call registerTheme() before using components from @vertz/ui/components.
20
18
 
21
19
  ` + `Example:
@@ -24,13 +22,16 @@ function _getComponent(name) {
24
22
  ` + ` registerTheme(configureTheme({ palette: 'zinc' }));
25
23
  `);
26
24
  }
27
- return Reflect.get(_components, name);
25
+ return Reflect.get(_resolved.components, name);
28
26
  }
29
27
  function _getPrimitive(name) {
30
- if (!_primitives) {
28
+ if (!_resolved) {
31
29
  throw new Error(`No theme registered. Call registerTheme() before using components from @vertz/ui/components.`);
32
30
  }
33
- return Reflect.get(_primitives, name);
31
+ const primitives = _resolved.components.primitives;
32
+ if (!primitives)
33
+ return;
34
+ return Reflect.get(primitives, name);
34
35
  }
35
36
 
36
37
  export { registerTheme, _getComponent, _getPrimitive };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hasSSRResolver
3
- } from "./chunk-1yd6jfw5.js";
3
+ } from "./chunk-2k26a794.js";
4
4
 
5
5
  // src/env/is-browser.ts
6
6
  function isBrowser() {
@@ -164,13 +164,22 @@ declare function can(entitlement: Entitlement, entity?: {
164
164
  declare function canSignals(entitlement: Entitlement, entity?: {
165
165
  __access?: Record<string, AccessCheckData>;
166
166
  }): RawAccessCheck;
167
- /** Client-side access events (no orgId/userId — server scopes the broadcast) */
167
+ /**
168
+ * Client-side access events.
169
+ *
170
+ * Includes resourceType/resourceId for client-side resource-level filtering.
171
+ * orgId is stripped (routing is server-side only via WebSocket connection keying).
172
+ */
168
173
  type ClientAccessEvent = {
169
174
  type: "access:flag_toggled";
175
+ resourceType: string;
176
+ resourceId: string;
170
177
  flag: string;
171
178
  enabled: boolean;
172
179
  } | {
173
180
  type: "access:limit_updated";
181
+ resourceType: string;
182
+ resourceId: string;
174
183
  entitlement: string;
175
184
  consumed: number;
176
185
  remaining: number;
@@ -179,17 +188,27 @@ type ClientAccessEvent = {
179
188
  type: "access:role_changed";
180
189
  } | {
181
190
  type: "access:plan_changed";
191
+ resourceType: string;
192
+ resourceId: string;
182
193
  } | {
183
194
  type: "access:plan_assigned";
195
+ resourceType: string;
196
+ resourceId: string;
184
197
  planId: string;
185
198
  } | {
186
199
  type: "access:addon_attached";
200
+ resourceType: string;
201
+ resourceId: string;
187
202
  addonId: string;
188
203
  } | {
189
204
  type: "access:addon_detached";
205
+ resourceType: string;
206
+ resourceId: string;
190
207
  addonId: string;
191
208
  } | {
192
209
  type: "access:limit_reset";
210
+ resourceType: string;
211
+ resourceId: string;
193
212
  entitlement: string;
194
213
  max: number;
195
214
  };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  RouterContext
3
- } from "../../shared/chunk-9p84cvet.js";
3
+ } from "../../shared/chunk-dxfd1ptg.js";
4
4
  import {
5
5
  invalidateTenantQueries
6
- } from "../../shared/chunk-pv0apt9z.js";
6
+ } from "../../shared/chunk-kt7127xc.js";
7
7
  import {
8
8
  isBrowser
9
- } from "../../shared/chunk-sjypbv24.js";
9
+ } from "../../shared/chunk-xs4hak0m.js";
10
10
  import {
11
11
  _tryOnCleanup,
12
12
  computed,
@@ -14,7 +14,7 @@ import {
14
14
  getSSRContext,
15
15
  signal,
16
16
  useContext
17
- } from "../../shared/chunk-1yd6jfw5.js";
17
+ } from "../../shared/chunk-2k26a794.js";
18
18
 
19
19
  // src/auth/access-context.ts
20
20
  var AccessContext = createContext(undefined, "@vertz/ui::AccessContext");
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  _getComponent,
3
3
  _getPrimitive
4
- } from "../../shared/chunk-mwc4v48d.js";
4
+ } from "../../shared/chunk-w6a0t2xs.js";
5
5
 
6
6
  // src/components/index.ts
7
7
  function createComponentProxy(name) {
@@ -103,6 +103,14 @@ interface FontOptions {
103
103
  }
104
104
  type FontStyle = "normal" | "italic";
105
105
  type FontDisplay = "auto" | "block" | "swap" | "fallback" | "optional";
106
+ /** @internal Metadata for Google Fonts descriptors. Present only on googleFont() results. */
107
+ interface GoogleFontMeta {
108
+ readonly family: string;
109
+ readonly weight: string | number | number[];
110
+ readonly style: FontStyle[];
111
+ readonly subsets: string[];
112
+ readonly display: FontDisplay;
113
+ }
106
114
  interface FontDescriptor {
107
115
  readonly __brand: "FontDescriptor";
108
116
  readonly family: string;
@@ -114,6 +122,8 @@ interface FontDescriptor {
114
122
  readonly subsets: string[];
115
123
  readonly unicodeRange?: string;
116
124
  readonly adjustFontFallback: boolean | FallbackFontName;
125
+ /** @internal — Google Fonts metadata. Present only for googleFont() descriptors. */
126
+ readonly __google?: GoogleFontMeta;
117
127
  }
118
128
  /** Structured description of a resource to preload. */
119
129
  interface PreloadItem {
@@ -150,6 +160,29 @@ declare function font(family: string, options: FontOptions): FontDescriptor;
150
160
  * @returns Compiled @font-face CSS, CSS var lines, and preload link tags.
151
161
  */
152
162
  declare function compileFonts(fonts: Record<string, FontDescriptor>, options?: CompileFontsOptions): CompiledFonts;
163
+ type FontStyle2 = "normal" | "italic";
164
+ type FontDisplay2 = "auto" | "block" | "swap" | "fallback" | "optional";
165
+ interface GoogleFontOptions {
166
+ /** Weight range ('100..900') or specific weights ([400, 700]). */
167
+ weight: string | number | number[];
168
+ /** Font style(s). Default: 'normal'. */
169
+ style?: FontStyle2 | FontStyle2[];
170
+ /** font-display strategy. Default: 'swap'. */
171
+ display?: FontDisplay2;
172
+ /** Character subsets. Default: ['latin']. */
173
+ subsets?: string[];
174
+ /** Fallback fonts. Auto-detected from Google's font category if omitted. */
175
+ fallback?: string[];
176
+ /** Enable metric-adjusted fallback @font-face. Default: true. */
177
+ adjustFontFallback?: boolean;
178
+ }
179
+ /**
180
+ * Declare a Google Font for auto-fetch at dev/build time.
181
+ *
182
+ * Returns a FontDescriptor with `src: undefined` and `__google` metadata.
183
+ * The dev server / build pipeline resolves the metadata to local .woff2 files.
184
+ */
185
+ declare function googleFont(family: string, options: GoogleFontOptions): FontDescriptor;
153
186
  /** Input to globalCss(): selector → property-value map. */
154
187
  type GlobalCSSInput = Record<string, Record<string, string>>;
155
188
  /** Output of globalCss(): extracted CSS string. */
@@ -301,4 +334,4 @@ interface VariantFunction<V extends VariantDefinitions> {
301
334
  * @returns A function that accepts variant props and returns a className string.
302
335
  */
303
336
  declare function variants<V extends VariantDefinitions>(config: VariantsConfig<V>): VariantFunction<V>;
304
- export { variants, s, globalCss, font, defineTheme, css, compileTheme, compileFonts, VariantsConfig, VariantProps, VariantFunction, UtilityClass, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, StyleValue, StyleEntry, PreloadItem, GlobalCSSOutput, GlobalCSSInput, FontSrc, FontOptions, FontFallbackMetrics, FontDescriptor, FallbackFontName, CompiledTheme, CompiledFonts, CompileThemeOptions, CompileFontsOptions, CSSOutput, CSSInput };
337
+ export { variants, s, googleFont, globalCss, font, defineTheme, css, compileTheme, compileFonts, VariantsConfig, VariantProps, VariantFunction, UtilityClass, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, StyleValue, StyleEntry, PreloadItem, GoogleFontOptions, GoogleFontMeta, GlobalCSSOutput, GlobalCSSInput, FontSrc, FontOptions, FontFallbackMetrics, FontDescriptor, FallbackFontName, CompiledTheme, CompiledFonts, CompileThemeOptions, CompileFontsOptions, CSSOutput, CSSInput };
@@ -6,15 +6,17 @@ import {
6
6
  defineTheme,
7
7
  font,
8
8
  globalCss,
9
+ googleFont,
9
10
  s,
10
11
  variants
11
- } from "../../shared/chunk-g60cswzm.js";
12
- import"../../shared/chunk-dh32wkrv.js";
12
+ } from "../../shared/chunk-3n9teyam.js";
13
+ import"../../shared/chunk-29x7mbne.js";
13
14
  import"../../shared/chunk-h1fsr8kv.js";
14
- import"../../shared/chunk-1yd6jfw5.js";
15
+ import"../../shared/chunk-2k26a794.js";
15
16
  export {
16
17
  variants,
17
18
  s,
19
+ googleFont,
18
20
  globalCss,
19
21
  font,
20
22
  defineTheme,
@@ -3,8 +3,8 @@ import {
3
3
  form,
4
4
  formDataToObject,
5
5
  validate
6
- } from "../../shared/chunk-hcgnfw27.js";
7
- import"../../shared/chunk-1yd6jfw5.js";
6
+ } from "../../shared/chunk-7479q3cz.js";
7
+ import"../../shared/chunk-2k26a794.js";
8
8
  export {
9
9
  validate,
10
10
  formDataToObject,
@@ -400,6 +400,14 @@ interface FontOptions {
400
400
  }
401
401
  type FontStyle = "normal" | "italic";
402
402
  type FontDisplay = "auto" | "block" | "swap" | "fallback" | "optional";
403
+ /** @internal Metadata for Google Fonts descriptors. Present only on googleFont() results. */
404
+ interface GoogleFontMeta {
405
+ readonly family: string;
406
+ readonly weight: string | number | number[];
407
+ readonly style: FontStyle[];
408
+ readonly subsets: string[];
409
+ readonly display: FontDisplay;
410
+ }
403
411
  interface FontDescriptor {
404
412
  readonly __brand: "FontDescriptor";
405
413
  readonly family: string;
@@ -411,6 +419,8 @@ interface FontDescriptor {
411
419
  readonly subsets: string[];
412
420
  readonly unicodeRange?: string;
413
421
  readonly adjustFontFallback: boolean | FallbackFontName;
422
+ /** @internal — Google Fonts metadata. Present only for googleFont() descriptors. */
423
+ readonly __google?: GoogleFontMeta;
414
424
  }
415
425
  /** Structured description of a resource to preload. */
416
426
  interface PreloadItem {
@@ -1543,8 +1553,8 @@ declare function defineRoutes<const T extends Record<string, RouteConfigLike>>(m
1543
1553
  interface LinkProps<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
1544
1554
  /** The target URL path. */
1545
1555
  href: RoutePaths<T>;
1546
- /** Text or content for the link. Accepts string, Node, or a thunk returning either. */
1547
- children: string | Node | (() => string | Node);
1556
+ /** Content for the link. Accepts string, Node, arrays, or thunks same as JSX children. */
1557
+ children: ChildValue;
1548
1558
  /** Class applied when the link's href matches the current path. */
1549
1559
  activeClass?: string;
1550
1560
  /** Static class name for the anchor element. */
@@ -2140,6 +2150,11 @@ interface RegisterThemeInput {
2140
2150
  * Call once at app startup, before any component from `@vertz/ui/components` is used.
2141
2151
  * Calling again replaces the previously registered theme.
2142
2152
  *
2153
+ * IMPORTANT: This stores the resolved theme WITHOUT accessing `.components`.
2154
+ * Accessing `.components` would trigger eager compilation of all ~40 component
2155
+ * styles (~74KB CSS) at startup time. Instead, styles are compiled lazily
2156
+ * per-component when first accessed via _getComponent()/_getPrimitive(). (#1979)
2157
+ *
2143
2158
  * @example
2144
2159
  * ```ts
2145
2160
  * import { registerTheme } from '@vertz/ui';
package/dist/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  registerTheme
3
- } from "../shared/chunk-mwc4v48d.js";
3
+ } from "../shared/chunk-w6a0t2xs.js";
4
4
  import {
5
5
  ANIMATION_DURATION,
6
6
  ANIMATION_EASING,
@@ -25,7 +25,7 @@ import {
25
25
  slideOutToTop,
26
26
  zoomIn,
27
27
  zoomOut
28
- } from "../shared/chunk-rxx916ae.js";
28
+ } from "../shared/chunk-bmcthk92.js";
29
29
  import {
30
30
  ErrorBoundary,
31
31
  Link,
@@ -36,16 +36,16 @@ import {
36
36
  getCurrentErrorHandler,
37
37
  parseSearchParams,
38
38
  useSearchParams
39
- } from "../shared/chunk-jt34jcfg.js";
39
+ } from "../shared/chunk-sb69h6ns.js";
40
40
  import {
41
41
  beginDeferringMounts,
42
42
  discardDeferredMounts,
43
43
  flushDeferredMounts,
44
44
  onMount
45
- } from "../shared/chunk-mntc8w0g.js";
45
+ } from "../shared/chunk-pbw64893.js";
46
46
  import {
47
47
  createRouter
48
- } from "../shared/chunk-9ybtmy8t.js";
48
+ } from "../shared/chunk-f0f80gxe.js";
49
49
  import {
50
50
  defineRoutes
51
51
  } from "../shared/chunk-ah86rm07.js";
@@ -54,7 +54,7 @@ import {
54
54
  form,
55
55
  formDataToObject,
56
56
  validate
57
- } from "../shared/chunk-hcgnfw27.js";
57
+ } from "../shared/chunk-7479q3cz.js";
58
58
  import {
59
59
  EntityStore,
60
60
  FieldSelectionTracker,
@@ -66,7 +66,7 @@ import {
66
66
  query,
67
67
  registerRelationSchema,
68
68
  resetRelationSchemas_TEST_ONLY
69
- } from "../shared/chunk-4eatzp0p.js";
69
+ } from "../shared/chunk-8ft6568m.js";
70
70
  import"../shared/chunk-jrtrk5z4.js";
71
71
  import {
72
72
  ThemeProvider,
@@ -83,7 +83,7 @@ import {
83
83
  resolveChildren,
84
84
  s,
85
85
  variants
86
- } from "../shared/chunk-g60cswzm.js";
86
+ } from "../shared/chunk-3n9teyam.js";
87
87
  import {
88
88
  RENDER_NODE_BRAND,
89
89
  __append,
@@ -96,20 +96,20 @@ import {
96
96
  getAdapter,
97
97
  isRenderNode,
98
98
  setAdapter
99
- } from "../shared/chunk-dh32wkrv.js";
99
+ } from "../shared/chunk-29x7mbne.js";
100
100
  import"../shared/chunk-h1fsr8kv.js";
101
101
  import {
102
102
  RouterContext,
103
103
  useParams,
104
104
  useRouter
105
- } from "../shared/chunk-9p84cvet.js";
105
+ } from "../shared/chunk-dxfd1ptg.js";
106
106
  import {
107
107
  invalidate,
108
108
  invalidateTenantQueries
109
- } from "../shared/chunk-pv0apt9z.js";
109
+ } from "../shared/chunk-kt7127xc.js";
110
110
  import {
111
111
  isBrowser
112
- } from "../shared/chunk-sjypbv24.js";
112
+ } from "../shared/chunk-xs4hak0m.js";
113
113
  import {
114
114
  DisposalScopeError,
115
115
  _tryOnCleanup,
@@ -134,7 +134,7 @@ import {
134
134
  startHydration,
135
135
  untrack,
136
136
  useContext
137
- } from "../shared/chunk-1yd6jfw5.js";
137
+ } from "../shared/chunk-2k26a794.js";
138
138
  // src/component/default-error-fallback.ts
139
139
  function DefaultErrorFallback({ error, retry }) {
140
140
  const container = document.createElement("div");
@@ -197,6 +197,14 @@ interface CompileFontsOptions {
197
197
  }
198
198
  type FontStyle = "normal" | "italic";
199
199
  type FontDisplay = "auto" | "block" | "swap" | "fallback" | "optional";
200
+ /** @internal Metadata for Google Fonts descriptors. Present only on googleFont() results. */
201
+ interface GoogleFontMeta {
202
+ readonly family: string;
203
+ readonly weight: string | number | number[];
204
+ readonly style: FontStyle[];
205
+ readonly subsets: string[];
206
+ readonly display: FontDisplay;
207
+ }
200
208
  interface FontDescriptor {
201
209
  readonly __brand: "FontDescriptor";
202
210
  readonly family: string;
@@ -208,6 +216,8 @@ interface FontDescriptor {
208
216
  readonly subsets: string[];
209
217
  readonly unicodeRange?: string;
210
218
  readonly adjustFontFallback: boolean | FallbackFontName;
219
+ /** @internal — Google Fonts metadata. Present only for googleFont() descriptors. */
220
+ readonly __google?: GoogleFontMeta;
211
221
  }
212
222
  /** Structured description of a resource to preload. */
213
223
  interface PreloadItem {
@@ -492,10 +502,13 @@ declare function clearChildren(container: Node): void;
492
502
  * also accepts a raw Signal for direct use in tests.
493
503
  * @param keyFn - Extracts a unique key from each item (receives item and index).
494
504
  * Pass `null` for unkeyed lists — triggers full-replacement mode (safe but slower).
495
- * @param renderFn - Creates a DOM node for an item (called once per key)
505
+ * @param renderFn - Creates a DOM node for an item (called once per key).
506
+ * Receives the item and its index in the array. Note: for keyed lists,
507
+ * the index is the position at creation time and is NOT updated when
508
+ * items reorder — use a key-based approach for stable ordering display.
496
509
  * @returns A dispose function to stop the reactive list reconciliation
497
510
  */
498
- declare function __list<T>(container: HTMLElement, items: Signal<T[]> | (() => T[]), keyFn: ((item: T, index: number) => string | number) | null, renderFn: (item: T) => Node): DisposeFn;
511
+ declare function __list<T>(container: HTMLElement, items: Signal<T[]> | (() => T[]), keyFn: ((item: T, index: number) => string | number) | null, renderFn: (item: T, index: number) => Node): DisposeFn;
499
512
  /**
500
513
  * Lifecycle hooks for list animation (enter/exit/reorder).
501
514
  *
@@ -533,10 +546,13 @@ declare const ListAnimationContext: Context<ListAnimationHooks | undefined>;
533
546
  *
534
547
  * @param items - A signal or getter function containing the array of items
535
548
  * @param keyFn - Extracts a unique key from each item. Pass null for unkeyed mode.
536
- * @param renderFn - Creates a DOM node for an item (called once per key)
549
+ * @param renderFn - Creates a DOM node for an item (called once per key).
550
+ * Receives the item and its index in the array. Note: for keyed lists,
551
+ * the index is the position at creation time and is NOT updated when
552
+ * items reorder — use a key-based approach for stable ordering display.
537
553
  * @returns A DisposableNode (DocumentFragment with dispose method)
538
554
  */
539
- declare function __listValue<T>(items: Signal<T[]> | (() => T[]), keyFn: ((item: T, index: number) => string | number) | null, renderFn: (item: T) => Node): DisposableNode;
555
+ declare function __listValue<T>(items: Signal<T[]> | (() => T[]), keyFn: ((item: T, index: number) => string | number) | null, renderFn: (item: T, index: number) => Node): DisposableNode;
540
556
  /**
541
557
  * Apply a spread props object to a DOM element.
542
558
  *
@@ -3,13 +3,13 @@ import {
3
3
  deserializeProps,
4
4
  onAnimationsComplete,
5
5
  resolveComponent
6
- } from "../shared/chunk-rxx916ae.js";
6
+ } from "../shared/chunk-bmcthk92.js";
7
7
  import {
8
8
  __discardMountFrame,
9
9
  __flushMountFrame,
10
10
  __on,
11
11
  __pushMountFrame
12
- } from "../shared/chunk-mntc8w0g.js";
12
+ } from "../shared/chunk-pbw64893.js";
13
13
  import {
14
14
  executeLoaders,
15
15
  matchPath,
@@ -20,7 +20,7 @@ import {
20
20
  MemoryCache,
21
21
  QueryEnvelopeStore,
22
22
  deriveKey
23
- } from "../shared/chunk-4eatzp0p.js";
23
+ } from "../shared/chunk-8ft6568m.js";
24
24
  import"../shared/chunk-jrtrk5z4.js";
25
25
  import {
26
26
  ALIGNMENT_MAP,
@@ -41,7 +41,7 @@ import {
41
41
  SIZE_KEYWORDS,
42
42
  SPACING_SCALE,
43
43
  compileTheme
44
- } from "../shared/chunk-g60cswzm.js";
44
+ } from "../shared/chunk-3n9teyam.js";
45
45
  import {
46
46
  RENDER_NODE_BRAND,
47
47
  __append,
@@ -60,16 +60,16 @@ import {
60
60
  getAdapter,
61
61
  isRenderNode,
62
62
  setAdapter
63
- } from "../shared/chunk-dh32wkrv.js";
63
+ } from "../shared/chunk-29x7mbne.js";
64
64
  import {
65
65
  SVG_NS,
66
66
  normalizeSVGAttr,
67
67
  styleObjectToString
68
68
  } from "../shared/chunk-h1fsr8kv.js";
69
- import"../shared/chunk-pv0apt9z.js";
69
+ import"../shared/chunk-kt7127xc.js";
70
70
  import {
71
71
  isBrowser
72
- } from "../shared/chunk-sjypbv24.js";
72
+ } from "../shared/chunk-xs4hak0m.js";
73
73
  import {
74
74
  _tryOnCleanup,
75
75
  claimComment,
@@ -90,7 +90,7 @@ import {
90
90
  startSignalCollection,
91
91
  stopSignalCollection,
92
92
  useContext
93
- } from "../shared/chunk-1yd6jfw5.js";
93
+ } from "../shared/chunk-2k26a794.js";
94
94
  // src/dom/conditional.ts
95
95
  function clearBetween(start, end) {
96
96
  let current = start.nextSibling;
@@ -300,11 +300,11 @@ function __list(container, items, keyFn, renderFn) {
300
300
  if (keyFn) {
301
301
  const itemSig = signal(item);
302
302
  const proxy = createItemProxy(itemSig);
303
- const node = renderFn(proxy);
303
+ const node = renderFn(proxy, i);
304
304
  itemSignalMap.set(key, itemSig);
305
305
  nodeMap.set(key, node);
306
306
  } else {
307
- const node = renderFn(item);
307
+ const node = renderFn(item, i);
308
308
  nodeMap.set(key, node);
309
309
  }
310
310
  popScope();
@@ -324,9 +324,9 @@ function __list(container, items, keyFn, renderFn) {
324
324
  }
325
325
  nodeMap.clear();
326
326
  itemSignalMap.clear();
327
- for (const item of newItems) {
327
+ for (const [i, item] of newItems.entries()) {
328
328
  const scope = pushScope();
329
- const node = renderFn(item);
329
+ const node = renderFn(item, i);
330
330
  popScope();
331
331
  container.appendChild(node);
332
332
  const internalKey = nodeMap.size;
@@ -357,7 +357,7 @@ function __list(container, items, keyFn, renderFn) {
357
357
  const itemSig = signal(item);
358
358
  const proxy = createItemProxy(itemSig);
359
359
  const scope = pushScope();
360
- node = renderFn(proxy);
360
+ node = renderFn(proxy, i);
361
361
  popScope();
362
362
  nodeMap.set(key, node);
363
363
  scopeMap.set(key, scope);
@@ -479,7 +479,7 @@ function __listValue(items, keyFn, renderFn) {
479
479
  itemSignalMap.clear();
480
480
  for (const [i, item] of newItems.entries()) {
481
481
  const scope = pushScope();
482
- const node = renderFn(item);
482
+ const node = renderFn(item, i);
483
483
  popScope();
484
484
  endMarker.parentNode?.insertBefore(node, endMarker);
485
485
  nodeMap.set(i, node);
@@ -494,7 +494,7 @@ function __listValue(items, keyFn, renderFn) {
494
494
  const itemSig = signal(item);
495
495
  const proxy = createItemProxy2(itemSig);
496
496
  const scope = pushScope();
497
- const node = renderFn(proxy);
497
+ const node = renderFn(proxy, i);
498
498
  popScope();
499
499
  nodeMap.set(key, node);
500
500
  scopeMap.set(key, scope);
@@ -548,7 +548,7 @@ function __listValue(items, keyFn, renderFn) {
548
548
  const itemSig = signal(item);
549
549
  const proxy = createItemProxy2(itemSig);
550
550
  const scope = pushScope();
551
- node = renderFn(proxy);
551
+ node = renderFn(proxy, i);
552
552
  popScope();
553
553
  nodeMap.set(key, node);
554
554
  scopeMap.set(key, scope);
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  query
3
- } from "../../shared/chunk-4eatzp0p.js";
3
+ } from "../../shared/chunk-8ft6568m.js";
4
4
  import"../../shared/chunk-jrtrk5z4.js";
5
- import"../../shared/chunk-pv0apt9z.js";
6
- import"../../shared/chunk-sjypbv24.js";
7
- import"../../shared/chunk-1yd6jfw5.js";
5
+ import"../../shared/chunk-kt7127xc.js";
6
+ import"../../shared/chunk-xs4hak0m.js";
7
+ import"../../shared/chunk-2k26a794.js";
8
8
 
9
9
  // src/query/public.ts
10
10
  import { isQueryDescriptor } from "@vertz/fetch";
@@ -267,6 +267,8 @@ type LoaderData<T> = T extends {
267
267
  * Returns an array of compiled routes preserving definition order.
268
268
  */
269
269
  declare function defineRoutes<const T extends Record<string, RouteConfigLike>>(map: T): TypedRoutes<T>;
270
+ /** A single child value: DOM node, string, number, null, undefined, thunk, or nested array. */
271
+ type ChildValue = Node | string | number | null | undefined | ChildValue[] | (() => ChildValue);
270
272
  /**
271
273
  * A reactive signal that holds a value and notifies subscribers on change.
272
274
  */
@@ -320,8 +322,8 @@ type UnwrapSignals<T> = T extends object ? { [K in keyof T] : Unwrapped<T[K]> }
320
322
  interface LinkProps<T extends Record<string, RouteConfigLike> = RouteDefinitionMap> {
321
323
  /** The target URL path. */
322
324
  href: RoutePaths<T>;
323
- /** Text or content for the link. Accepts string, Node, or a thunk returning either. */
324
- children: string | Node | (() => string | Node);
325
+ /** Content for the link. Accepts string, Node, arrays, or thunks same as JSX children. */
326
+ children: ChildValue;
325
327
  /** Class applied when the link's href matches the current path. */
326
328
  activeClass?: string;
327
329
  /** Static class name for the anchor element. */
@@ -6,24 +6,24 @@ import {
6
6
  createLink,
7
7
  parseSearchParams,
8
8
  useSearchParams
9
- } from "../../shared/chunk-jt34jcfg.js";
10
- import"../../shared/chunk-mntc8w0g.js";
9
+ } from "../../shared/chunk-sb69h6ns.js";
10
+ import"../../shared/chunk-pbw64893.js";
11
11
  import {
12
12
  createRouter
13
- } from "../../shared/chunk-9ybtmy8t.js";
13
+ } from "../../shared/chunk-f0f80gxe.js";
14
14
  import {
15
15
  defineRoutes
16
16
  } from "../../shared/chunk-ah86rm07.js";
17
17
  import"../../shared/chunk-jrtrk5z4.js";
18
- import"../../shared/chunk-dh32wkrv.js";
18
+ import"../../shared/chunk-29x7mbne.js";
19
19
  import"../../shared/chunk-h1fsr8kv.js";
20
20
  import {
21
21
  RouterContext,
22
22
  useParams,
23
23
  useRouter
24
- } from "../../shared/chunk-9p84cvet.js";
25
- import"../../shared/chunk-sjypbv24.js";
26
- import"../../shared/chunk-1yd6jfw5.js";
24
+ } from "../../shared/chunk-dxfd1ptg.js";
25
+ import"../../shared/chunk-xs4hak0m.js";
26
+ import"../../shared/chunk-2k26a794.js";
27
27
  export {
28
28
  useSearchParams,
29
29
  useRouter,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createRouter
3
- } from "../../shared/chunk-9ybtmy8t.js";
3
+ } from "../../shared/chunk-f0f80gxe.js";
4
4
  import {
5
5
  defineRoutes
6
6
  } from "../../shared/chunk-ah86rm07.js";
7
7
  import"../../shared/chunk-jrtrk5z4.js";
8
- import"../../shared/chunk-sjypbv24.js";
9
- import"../../shared/chunk-1yd6jfw5.js";
8
+ import"../../shared/chunk-xs4hak0m.js";
9
+ import"../../shared/chunk-2k26a794.js";
10
10
 
11
11
  // src/test/interactions.ts
12
12
  async function click(el) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertz/ui",
3
- "version": "0.2.37",
3
+ "version": "0.2.41",
4
4
  "description": "Vertz UI framework — signals, components, JSX runtime",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -77,11 +77,11 @@
77
77
  "typecheck": "tsc --noEmit"
78
78
  },
79
79
  "dependencies": {
80
- "@vertz/fetch": "^0.2.35"
80
+ "@vertz/fetch": "^0.2.39"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@happy-dom/global-registrator": "^20.7.0",
84
- "@vertz/schema": "^0.2.35",
84
+ "@vertz/schema": "^0.2.39",
85
85
  "bunup": "^0.16.31",
86
86
  "happy-dom": "^20.7.0",
87
87
  "typescript": "^5.7.0"