@riverbankcms/sdk 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +239 -0
  2. package/dist/cli/index.js +22 -5
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/client/client.js +1 -1
  5. package/dist/client/client.js.map +1 -1
  6. package/dist/client/client.mjs +1 -1
  7. package/dist/client/client.mjs.map +1 -1
  8. package/dist/server/{Layout-BClXUTsd.d.mts → Layout-B7cvis7r.d.mts} +3 -3
  9. package/dist/server/{Layout-UXGjXv8M.d.ts → Layout-wBtJLTVX.d.ts} +3 -3
  10. package/dist/server/{chunk-VSFQRHYZ.js → chunk-3B364WO2.js} +4 -4
  11. package/dist/server/chunk-3B364WO2.js.map +1 -0
  12. package/dist/server/{chunk-5STV4MWD.js → chunk-EIVISR62.js} +112 -27
  13. package/dist/server/chunk-EIVISR62.js.map +1 -0
  14. package/dist/server/{chunk-X4STRF2V.mjs → chunk-I7ZR2WO3.mjs} +2 -2
  15. package/dist/server/{chunk-X4STRF2V.mjs.map → chunk-I7ZR2WO3.mjs.map} +1 -1
  16. package/dist/server/{chunk-ZSKOHNE7.js → chunk-IVHIQFJH.js} +2 -2
  17. package/dist/server/{chunk-ZSKOHNE7.js.map → chunk-IVHIQFJH.js.map} +1 -1
  18. package/dist/server/{chunk-L5EA4FXU.mjs → chunk-XXFF4RVR.mjs} +6 -6
  19. package/dist/server/chunk-XXFF4RVR.mjs.map +1 -0
  20. package/dist/server/{chunk-KFLZGNPO.mjs → chunk-YXA4GAAQ.mjs} +113 -28
  21. package/dist/server/chunk-YXA4GAAQ.mjs.map +1 -0
  22. package/dist/server/{components-DppHY5oD.d.ts → components-CICSJyp_.d.ts} +1 -1
  23. package/dist/server/{components-BmaJxgCV.d.mts → components-CMMwDXTW.d.mts} +1 -1
  24. package/dist/server/components.d.mts +2 -2
  25. package/dist/server/components.d.ts +2 -2
  26. package/dist/server/components.js +3 -3
  27. package/dist/server/components.mjs +2 -2
  28. package/dist/server/index.js +2 -2
  29. package/dist/server/index.mjs +1 -1
  30. package/dist/server/navigation.d.mts +138 -57
  31. package/dist/server/navigation.d.ts +138 -57
  32. package/dist/server/navigation.js +6 -2
  33. package/dist/server/navigation.js.map +1 -1
  34. package/dist/server/navigation.mjs +9 -5
  35. package/dist/server/rendering/server.d.mts +1 -1
  36. package/dist/server/rendering/server.d.ts +1 -1
  37. package/dist/server/rendering/server.js +3 -3
  38. package/dist/server/rendering/server.mjs +2 -2
  39. package/dist/server/rendering.d.mts +3 -3
  40. package/dist/server/rendering.d.ts +3 -3
  41. package/dist/server/rendering.js +3 -3
  42. package/dist/server/rendering.mjs +2 -2
  43. package/dist/server/server.js +2 -2
  44. package/dist/server/server.mjs +1 -1
  45. package/package.json +1 -1
  46. package/dist/server/chunk-5STV4MWD.js.map +0 -1
  47. package/dist/server/chunk-KFLZGNPO.mjs.map +0 -1
  48. package/dist/server/chunk-L5EA4FXU.mjs.map +0 -1
  49. package/dist/server/chunk-VSFQRHYZ.js.map +0 -1
@@ -12,26 +12,28 @@ import '@riverbankcms/db';
12
12
  * Navigation helper utilities for SDK sites.
13
13
  *
14
14
  * Provides helpers to transform CMS navigation data into render-ready structures.
15
- * Supports both simple NavItem arrays and full MenuViewModels for block rendering.
15
+ * All navigation functions return nested structures supporting dropdowns.
16
16
  *
17
- * @example Simple usage
17
+ * @example Getting nav items
18
18
  * ```ts
19
- * import { getPrimaryNavItems } from '@riverbankcms/sdk/navigation';
19
+ * import { getPrimaryNavItems, isNavLink, isNavDropdown } from '@riverbankcms/sdk/navigation';
20
20
  *
21
21
  * const headerNav = getPrimaryNavItems(siteData.navigation);
22
- * // [{ href: '/', label: 'Home', isExternal: false }, ...]
22
+ * headerNav.forEach(item => {
23
+ * if (isNavLink(item)) {
24
+ * console.log(item.href);
25
+ * } else {
26
+ * console.log(`${item.label} has ${item.children.length} children`);
27
+ * }
28
+ * });
23
29
  * ```
24
30
  *
25
- * @example Block rendering usage
31
+ * @example Building menu and logo
26
32
  * ```ts
27
- * import { buildMenuViewModel, buildLogoViewModel } from '@riverbankcms/sdk/navigation';
28
- *
29
- * const menu = buildMenuViewModel(siteData.navigation);
30
- * const logo = buildLogoViewModel(siteData.layout.logo, siteData.site.title);
33
+ * import { buildMenu, buildLogo } from '@riverbankcms/sdk/navigation';
31
34
  *
32
- * renderBlock(siteHeaderManifest, layout.header, {
33
- * viewModelOverrides: { menu, content: { logo } },
34
- * });
35
+ * const menu = buildMenu(siteData.navigation, siteData.routes);
36
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
35
37
  * ```
36
38
  *
37
39
  * @packageDocumentation
@@ -111,43 +113,116 @@ type LogoViewModel = {
111
113
  storageBucket?: string;
112
114
  } | null;
113
115
  /**
114
- * A simplified navigation item structure for component rendering.
116
+ * A navigation link item with a direct URL.
117
+ * Use `kind` discriminator for type-safe narrowing.
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * if (item.kind === 'link') {
122
+ * console.log(item.href); // TypeScript knows href exists
123
+ * }
124
+ * ```
115
125
  */
116
- type NavItem = {
117
- /** The URL to navigate to */
118
- href: string;
126
+ type NavLink = {
127
+ /** Discriminator for type narrowing */
128
+ kind: 'link';
129
+ /** Unique identifier from CMS */
130
+ id: string;
119
131
  /** Display text for the navigation link */
120
132
  label: string;
133
+ /** The URL to navigate to */
134
+ href: string;
121
135
  /** Whether link should open in new tab (external links) */
122
136
  isExternal: boolean;
123
137
  };
124
138
  /**
125
- * Simple nav link with pre-resolved href for block rendering.
139
+ * A dropdown container holding child navigation items.
140
+ * Clicking reveals children instead of navigating.
141
+ * Max 1 level of nesting (children are always NavLink, not NavDropdown).
126
142
  */
127
- type SimpleNavLink = {
143
+ type NavDropdown = {
144
+ /** Discriminator for type narrowing */
145
+ kind: 'dropdown';
146
+ /** Unique identifier from CMS */
128
147
  id: string;
148
+ /** Display text for the dropdown trigger */
129
149
  label: string;
130
- href: string;
131
- isExternal: boolean;
150
+ /** Child navigation links */
151
+ children: NavLink[];
132
152
  };
133
153
  /**
134
- * Simple menu view model with pre-resolved hrefs.
135
- * Use this instead of MenuViewModel for cleaner data flow.
154
+ * Navigation item - either a link or a dropdown container.
155
+ * Use `kind` property for type-safe discrimination.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * const items = getPrimaryNavItems(navigation);
160
+ * items.forEach(item => {
161
+ * if (item.kind === 'link') {
162
+ * console.log(item.href);
163
+ * } else {
164
+ * console.log(item.children.length);
165
+ * }
166
+ * });
167
+ * ```
168
+ */
169
+ type NavItem = NavLink | NavDropdown;
170
+ /**
171
+ * Type guard to check if a navigation item is a link.
172
+ */
173
+ declare function isNavLink(item: NavItem): item is NavLink;
174
+ /**
175
+ * Type guard to check if a navigation item is a dropdown.
136
176
  */
137
- type SimpleMenuViewModel = {
138
- items: SimpleNavLink[];
139
- ctaItem: SimpleNavLink | null;
177
+ declare function isNavDropdown(item: NavItem): item is NavDropdown;
178
+ /**
179
+ * Navigation menu with items and optional CTA.
180
+ * Built from CMS navigation data with pre-resolved hrefs.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const menu = buildMenu(siteData.navigation, siteData.routes);
185
+ * menu.items.forEach(item => {
186
+ * if (item.kind === 'link') {
187
+ * console.log(item.href);
188
+ * } else {
189
+ * console.log(item.children);
190
+ * }
191
+ * });
192
+ * ```
193
+ */
194
+ type Menu = {
195
+ items: NavItem[];
196
+ ctaItem: NavLink | null;
140
197
  };
141
198
  /**
142
- * Simple logo data for block rendering.
199
+ * Logo data for site rendering.
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
204
+ * if (logo) {
205
+ * <img src={logo.src} alt={logo.alt} />
206
+ * }
207
+ * ```
143
208
  */
144
- type SimpleLogo = {
209
+ type Logo = {
145
210
  type: 'image';
146
211
  src: string;
147
212
  alt: string;
148
213
  width?: number;
149
214
  height?: number;
150
215
  } | null;
216
+ /** @deprecated Use `NavLink` instead */
217
+ type SimpleNavLink = NavLink;
218
+ /** @deprecated Use `NavDropdown` instead */
219
+ type SimpleNavDropdown = NavDropdown;
220
+ /** @deprecated Use `NavItem` instead */
221
+ type SimpleNavItem = NavItem;
222
+ /** @deprecated Use `Menu` instead */
223
+ type SimpleMenuViewModel = Menu;
224
+ /** @deprecated Use `Logo` instead */
225
+ type SimpleLogo = Logo;
151
226
  /**
152
227
  * Get the primary navigation menu object.
153
228
  * Returns menu marked as isPrimary, or first menu if none marked.
@@ -155,7 +230,7 @@ type SimpleLogo = {
155
230
  * @example
156
231
  * ```ts
157
232
  * const menu = getPrimaryNavigation(siteData.navigation);
158
- * console.log(menu?.title); // "Main Navigation"
233
+ * console.log(menu?.name); // "main"
159
234
  * ```
160
235
  */
161
236
  declare function getPrimaryNavigation(navigation: NavigationMenuWithItems[]): NavigationMenuWithItems | null;
@@ -170,19 +245,22 @@ declare function getPrimaryNavigation(navigation: NavigationMenuWithItems[]): Na
170
245
  declare function getNavigationBySlug(navigation: NavigationMenuWithItems[], slug: string): NavigationMenuWithItems | null;
171
246
  /**
172
247
  * Get nav items from the primary menu (marked isPrimary, or first menu).
173
- * Returns empty array if no navigation configured.
248
+ * Returns nested structure supporting both links and dropdowns.
174
249
  *
175
250
  * @example
176
251
  * ```ts
177
252
  * const headerNav = getPrimaryNavItems(siteData.navigation);
178
- * // [{ href: '/', label: 'Home', isExternal: false }, ...]
253
+ * headerNav.forEach(item => {
254
+ * if (item.kind === 'dropdown') {
255
+ * console.log(`${item.label} has ${item.children.length} children`);
256
+ * }
257
+ * });
179
258
  * ```
180
259
  */
181
260
  declare function getPrimaryNavItems(navigation: NavigationMenuWithItems[]): NavItem[];
182
261
  /**
183
262
  * Get nav items from a specific menu by slug.
184
- * Useful for footer nav, secondary nav, etc.
185
- * Returns empty array if menu not found.
263
+ * Returns nested structure supporting both links and dropdowns.
186
264
  *
187
265
  * @example
188
266
  * ```ts
@@ -191,7 +269,17 @@ declare function getPrimaryNavItems(navigation: NavigationMenuWithItems[]): NavI
191
269
  */
192
270
  declare function getNavItemsBySlug(navigation: NavigationMenuWithItems[], slug: string): NavItem[];
193
271
  /**
194
- * Transform a menu into simple NavItem array.
272
+ * Transform a menu into NavItem array.
273
+ * Builds nested structure from flat items, supporting dropdowns with children.
274
+ *
275
+ * @example
276
+ * ```ts
277
+ * const nav = transformToNavItems(menu);
278
+ * // [
279
+ * // { kind: 'link', href: '/', label: 'Home', ... },
280
+ * // { kind: 'dropdown', label: 'Services', children: [...] },
281
+ * // ]
282
+ * ```
195
283
  */
196
284
  declare function transformToNavItems(menu: NavigationMenuWithItems | null): NavItem[];
197
285
  /**
@@ -225,46 +313,39 @@ declare function buildMenuViewModel(navigation: NavigationMenuWithItems[]): Menu
225
313
  */
226
314
  declare function buildLogoViewModel(logo: LogoSource, fallbackTitle: string | null | undefined): LogoViewModel;
227
315
  /**
228
- * Build a SimpleMenuViewModel from navigation data with pre-resolved hrefs.
229
- * Use this instead of buildMenuViewModel for cleaner data flow.
316
+ * Build a Menu from navigation data with pre-resolved hrefs.
317
+ * Supports dropdown containers with nested children.
230
318
  *
231
319
  * @param navigation - Navigation menus from site data
232
320
  * @param routes - Route map for resolving internal links
233
321
  *
234
322
  * @example
235
323
  * ```ts
236
- * const menu = buildSimpleMenu(siteData.navigation, siteData.routes);
237
- * // { items: [{ id, label, href: '/', isExternal: false }], cta: null }
324
+ * const menu = buildMenu(siteData.navigation, siteData.routes);
325
+ * menu.items.forEach(item => {
326
+ * if (item.kind === 'dropdown') {
327
+ * console.log(item.children);
328
+ * }
329
+ * });
238
330
  * ```
239
331
  */
240
- declare function buildSimpleMenu(navigation: NavigationMenuWithItems[], routes: RouteMap): SimpleMenuViewModel;
332
+ declare function buildMenu(navigation: NavigationMenuWithItems[], routes: RouteMap): Menu;
333
+ /** @deprecated Use `buildMenu` instead */
334
+ declare const buildSimpleMenu: typeof buildMenu;
241
335
  /**
242
- * Build a SimpleLogo from site layout data.
336
+ * Build a Logo from site layout data.
243
337
  *
244
338
  * @param logo - Logo data from site layout
245
339
  * @param fallbackAlt - Fallback alt text (usually site title)
246
340
  *
247
341
  * @example
248
342
  * ```ts
249
- * const logo = buildSimpleLogo(siteData.layout.logo, siteData.site.title);
343
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
250
344
  * // { src: 'https://...', alt: 'Site Name', width: 200, height: 50 }
251
345
  * ```
252
346
  */
253
- declare function buildSimpleLogo(logo: {
254
- url?: string | null;
255
- alt?: string | null;
256
- width?: number | null;
257
- height?: number | null;
258
- } | null, fallbackAlt: string | null | undefined): SimpleLogo;
259
- /**
260
- * @deprecated Use `transformToNavItems` instead.
261
- * This alias is maintained for backwards compatibility only.
262
- */
263
- declare const transformNavItems: typeof transformToNavItems;
264
- /**
265
- * @deprecated Use `getPrimaryNavigation` instead.
266
- * This alias is maintained for backwards compatibility only.
267
- */
268
- declare const selectPrimaryMenu: typeof getPrimaryNavigation;
347
+ declare function buildLogo(logo: Partial<LogoSource> | null, fallbackAlt: string | null | undefined): Logo;
348
+ /** @deprecated Use `buildLogo` instead */
349
+ declare const buildSimpleLogo: typeof buildLogo;
269
350
 
270
- export { type CustomLinkValue, type ExternalLinkValue, type InternalLinkValue, type LinkValue, type LogoSource, type LogoViewModel, type MenuCtaViewModel, type MenuLinkViewModel, type MenuViewModel, type NavItem, NavigationMenuWithItems, type SimpleLogo, type SimpleMenuViewModel, type SimpleNavLink, buildLogoViewModel, buildMenuViewModel, buildSimpleLogo, buildSimpleMenu, getNavItemsBySlug, getNavigationBySlug, getPrimaryNavItems, getPrimaryNavigation, selectPrimaryMenu, transformNavItems, transformToNavItems };
351
+ export { type CustomLinkValue, type ExternalLinkValue, type InternalLinkValue, type LinkValue, type Logo, type LogoSource, type LogoViewModel, type Menu, type MenuCtaViewModel, type MenuLinkViewModel, type MenuViewModel, type NavDropdown, type NavItem, type NavLink, NavigationMenuWithItems, type SimpleLogo, type SimpleMenuViewModel, type SimpleNavDropdown, type SimpleNavItem, type SimpleNavLink, buildLogo, buildLogoViewModel, buildMenu, buildMenuViewModel, buildSimpleLogo, buildSimpleMenu, getNavItemsBySlug, getNavigationBySlug, getPrimaryNavItems, getPrimaryNavigation, isNavDropdown, isNavLink, transformToNavItems };
@@ -12,26 +12,28 @@ import '@riverbankcms/db';
12
12
  * Navigation helper utilities for SDK sites.
13
13
  *
14
14
  * Provides helpers to transform CMS navigation data into render-ready structures.
15
- * Supports both simple NavItem arrays and full MenuViewModels for block rendering.
15
+ * All navigation functions return nested structures supporting dropdowns.
16
16
  *
17
- * @example Simple usage
17
+ * @example Getting nav items
18
18
  * ```ts
19
- * import { getPrimaryNavItems } from '@riverbankcms/sdk/navigation';
19
+ * import { getPrimaryNavItems, isNavLink, isNavDropdown } from '@riverbankcms/sdk/navigation';
20
20
  *
21
21
  * const headerNav = getPrimaryNavItems(siteData.navigation);
22
- * // [{ href: '/', label: 'Home', isExternal: false }, ...]
22
+ * headerNav.forEach(item => {
23
+ * if (isNavLink(item)) {
24
+ * console.log(item.href);
25
+ * } else {
26
+ * console.log(`${item.label} has ${item.children.length} children`);
27
+ * }
28
+ * });
23
29
  * ```
24
30
  *
25
- * @example Block rendering usage
31
+ * @example Building menu and logo
26
32
  * ```ts
27
- * import { buildMenuViewModel, buildLogoViewModel } from '@riverbankcms/sdk/navigation';
28
- *
29
- * const menu = buildMenuViewModel(siteData.navigation);
30
- * const logo = buildLogoViewModel(siteData.layout.logo, siteData.site.title);
33
+ * import { buildMenu, buildLogo } from '@riverbankcms/sdk/navigation';
31
34
  *
32
- * renderBlock(siteHeaderManifest, layout.header, {
33
- * viewModelOverrides: { menu, content: { logo } },
34
- * });
35
+ * const menu = buildMenu(siteData.navigation, siteData.routes);
36
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
35
37
  * ```
36
38
  *
37
39
  * @packageDocumentation
@@ -111,43 +113,116 @@ type LogoViewModel = {
111
113
  storageBucket?: string;
112
114
  } | null;
113
115
  /**
114
- * A simplified navigation item structure for component rendering.
116
+ * A navigation link item with a direct URL.
117
+ * Use `kind` discriminator for type-safe narrowing.
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * if (item.kind === 'link') {
122
+ * console.log(item.href); // TypeScript knows href exists
123
+ * }
124
+ * ```
115
125
  */
116
- type NavItem = {
117
- /** The URL to navigate to */
118
- href: string;
126
+ type NavLink = {
127
+ /** Discriminator for type narrowing */
128
+ kind: 'link';
129
+ /** Unique identifier from CMS */
130
+ id: string;
119
131
  /** Display text for the navigation link */
120
132
  label: string;
133
+ /** The URL to navigate to */
134
+ href: string;
121
135
  /** Whether link should open in new tab (external links) */
122
136
  isExternal: boolean;
123
137
  };
124
138
  /**
125
- * Simple nav link with pre-resolved href for block rendering.
139
+ * A dropdown container holding child navigation items.
140
+ * Clicking reveals children instead of navigating.
141
+ * Max 1 level of nesting (children are always NavLink, not NavDropdown).
126
142
  */
127
- type SimpleNavLink = {
143
+ type NavDropdown = {
144
+ /** Discriminator for type narrowing */
145
+ kind: 'dropdown';
146
+ /** Unique identifier from CMS */
128
147
  id: string;
148
+ /** Display text for the dropdown trigger */
129
149
  label: string;
130
- href: string;
131
- isExternal: boolean;
150
+ /** Child navigation links */
151
+ children: NavLink[];
132
152
  };
133
153
  /**
134
- * Simple menu view model with pre-resolved hrefs.
135
- * Use this instead of MenuViewModel for cleaner data flow.
154
+ * Navigation item - either a link or a dropdown container.
155
+ * Use `kind` property for type-safe discrimination.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * const items = getPrimaryNavItems(navigation);
160
+ * items.forEach(item => {
161
+ * if (item.kind === 'link') {
162
+ * console.log(item.href);
163
+ * } else {
164
+ * console.log(item.children.length);
165
+ * }
166
+ * });
167
+ * ```
168
+ */
169
+ type NavItem = NavLink | NavDropdown;
170
+ /**
171
+ * Type guard to check if a navigation item is a link.
172
+ */
173
+ declare function isNavLink(item: NavItem): item is NavLink;
174
+ /**
175
+ * Type guard to check if a navigation item is a dropdown.
136
176
  */
137
- type SimpleMenuViewModel = {
138
- items: SimpleNavLink[];
139
- ctaItem: SimpleNavLink | null;
177
+ declare function isNavDropdown(item: NavItem): item is NavDropdown;
178
+ /**
179
+ * Navigation menu with items and optional CTA.
180
+ * Built from CMS navigation data with pre-resolved hrefs.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const menu = buildMenu(siteData.navigation, siteData.routes);
185
+ * menu.items.forEach(item => {
186
+ * if (item.kind === 'link') {
187
+ * console.log(item.href);
188
+ * } else {
189
+ * console.log(item.children);
190
+ * }
191
+ * });
192
+ * ```
193
+ */
194
+ type Menu = {
195
+ items: NavItem[];
196
+ ctaItem: NavLink | null;
140
197
  };
141
198
  /**
142
- * Simple logo data for block rendering.
199
+ * Logo data for site rendering.
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
204
+ * if (logo) {
205
+ * <img src={logo.src} alt={logo.alt} />
206
+ * }
207
+ * ```
143
208
  */
144
- type SimpleLogo = {
209
+ type Logo = {
145
210
  type: 'image';
146
211
  src: string;
147
212
  alt: string;
148
213
  width?: number;
149
214
  height?: number;
150
215
  } | null;
216
+ /** @deprecated Use `NavLink` instead */
217
+ type SimpleNavLink = NavLink;
218
+ /** @deprecated Use `NavDropdown` instead */
219
+ type SimpleNavDropdown = NavDropdown;
220
+ /** @deprecated Use `NavItem` instead */
221
+ type SimpleNavItem = NavItem;
222
+ /** @deprecated Use `Menu` instead */
223
+ type SimpleMenuViewModel = Menu;
224
+ /** @deprecated Use `Logo` instead */
225
+ type SimpleLogo = Logo;
151
226
  /**
152
227
  * Get the primary navigation menu object.
153
228
  * Returns menu marked as isPrimary, or first menu if none marked.
@@ -155,7 +230,7 @@ type SimpleLogo = {
155
230
  * @example
156
231
  * ```ts
157
232
  * const menu = getPrimaryNavigation(siteData.navigation);
158
- * console.log(menu?.title); // "Main Navigation"
233
+ * console.log(menu?.name); // "main"
159
234
  * ```
160
235
  */
161
236
  declare function getPrimaryNavigation(navigation: NavigationMenuWithItems[]): NavigationMenuWithItems | null;
@@ -170,19 +245,22 @@ declare function getPrimaryNavigation(navigation: NavigationMenuWithItems[]): Na
170
245
  declare function getNavigationBySlug(navigation: NavigationMenuWithItems[], slug: string): NavigationMenuWithItems | null;
171
246
  /**
172
247
  * Get nav items from the primary menu (marked isPrimary, or first menu).
173
- * Returns empty array if no navigation configured.
248
+ * Returns nested structure supporting both links and dropdowns.
174
249
  *
175
250
  * @example
176
251
  * ```ts
177
252
  * const headerNav = getPrimaryNavItems(siteData.navigation);
178
- * // [{ href: '/', label: 'Home', isExternal: false }, ...]
253
+ * headerNav.forEach(item => {
254
+ * if (item.kind === 'dropdown') {
255
+ * console.log(`${item.label} has ${item.children.length} children`);
256
+ * }
257
+ * });
179
258
  * ```
180
259
  */
181
260
  declare function getPrimaryNavItems(navigation: NavigationMenuWithItems[]): NavItem[];
182
261
  /**
183
262
  * Get nav items from a specific menu by slug.
184
- * Useful for footer nav, secondary nav, etc.
185
- * Returns empty array if menu not found.
263
+ * Returns nested structure supporting both links and dropdowns.
186
264
  *
187
265
  * @example
188
266
  * ```ts
@@ -191,7 +269,17 @@ declare function getPrimaryNavItems(navigation: NavigationMenuWithItems[]): NavI
191
269
  */
192
270
  declare function getNavItemsBySlug(navigation: NavigationMenuWithItems[], slug: string): NavItem[];
193
271
  /**
194
- * Transform a menu into simple NavItem array.
272
+ * Transform a menu into NavItem array.
273
+ * Builds nested structure from flat items, supporting dropdowns with children.
274
+ *
275
+ * @example
276
+ * ```ts
277
+ * const nav = transformToNavItems(menu);
278
+ * // [
279
+ * // { kind: 'link', href: '/', label: 'Home', ... },
280
+ * // { kind: 'dropdown', label: 'Services', children: [...] },
281
+ * // ]
282
+ * ```
195
283
  */
196
284
  declare function transformToNavItems(menu: NavigationMenuWithItems | null): NavItem[];
197
285
  /**
@@ -225,46 +313,39 @@ declare function buildMenuViewModel(navigation: NavigationMenuWithItems[]): Menu
225
313
  */
226
314
  declare function buildLogoViewModel(logo: LogoSource, fallbackTitle: string | null | undefined): LogoViewModel;
227
315
  /**
228
- * Build a SimpleMenuViewModel from navigation data with pre-resolved hrefs.
229
- * Use this instead of buildMenuViewModel for cleaner data flow.
316
+ * Build a Menu from navigation data with pre-resolved hrefs.
317
+ * Supports dropdown containers with nested children.
230
318
  *
231
319
  * @param navigation - Navigation menus from site data
232
320
  * @param routes - Route map for resolving internal links
233
321
  *
234
322
  * @example
235
323
  * ```ts
236
- * const menu = buildSimpleMenu(siteData.navigation, siteData.routes);
237
- * // { items: [{ id, label, href: '/', isExternal: false }], cta: null }
324
+ * const menu = buildMenu(siteData.navigation, siteData.routes);
325
+ * menu.items.forEach(item => {
326
+ * if (item.kind === 'dropdown') {
327
+ * console.log(item.children);
328
+ * }
329
+ * });
238
330
  * ```
239
331
  */
240
- declare function buildSimpleMenu(navigation: NavigationMenuWithItems[], routes: RouteMap): SimpleMenuViewModel;
332
+ declare function buildMenu(navigation: NavigationMenuWithItems[], routes: RouteMap): Menu;
333
+ /** @deprecated Use `buildMenu` instead */
334
+ declare const buildSimpleMenu: typeof buildMenu;
241
335
  /**
242
- * Build a SimpleLogo from site layout data.
336
+ * Build a Logo from site layout data.
243
337
  *
244
338
  * @param logo - Logo data from site layout
245
339
  * @param fallbackAlt - Fallback alt text (usually site title)
246
340
  *
247
341
  * @example
248
342
  * ```ts
249
- * const logo = buildSimpleLogo(siteData.layout.logo, siteData.site.title);
343
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
250
344
  * // { src: 'https://...', alt: 'Site Name', width: 200, height: 50 }
251
345
  * ```
252
346
  */
253
- declare function buildSimpleLogo(logo: {
254
- url?: string | null;
255
- alt?: string | null;
256
- width?: number | null;
257
- height?: number | null;
258
- } | null, fallbackAlt: string | null | undefined): SimpleLogo;
259
- /**
260
- * @deprecated Use `transformToNavItems` instead.
261
- * This alias is maintained for backwards compatibility only.
262
- */
263
- declare const transformNavItems: typeof transformToNavItems;
264
- /**
265
- * @deprecated Use `getPrimaryNavigation` instead.
266
- * This alias is maintained for backwards compatibility only.
267
- */
268
- declare const selectPrimaryMenu: typeof getPrimaryNavigation;
347
+ declare function buildLogo(logo: Partial<LogoSource> | null, fallbackAlt: string | null | undefined): Logo;
348
+ /** @deprecated Use `buildLogo` instead */
349
+ declare const buildSimpleLogo: typeof buildLogo;
269
350
 
270
- export { type CustomLinkValue, type ExternalLinkValue, type InternalLinkValue, type LinkValue, type LogoSource, type LogoViewModel, type MenuCtaViewModel, type MenuLinkViewModel, type MenuViewModel, type NavItem, NavigationMenuWithItems, type SimpleLogo, type SimpleMenuViewModel, type SimpleNavLink, buildLogoViewModel, buildMenuViewModel, buildSimpleLogo, buildSimpleMenu, getNavItemsBySlug, getNavigationBySlug, getPrimaryNavItems, getPrimaryNavigation, selectPrimaryMenu, transformNavItems, transformToNavItems };
351
+ export { type CustomLinkValue, type ExternalLinkValue, type InternalLinkValue, type LinkValue, type Logo, type LogoSource, type LogoViewModel, type Menu, type MenuCtaViewModel, type MenuLinkViewModel, type MenuViewModel, type NavDropdown, type NavItem, type NavLink, NavigationMenuWithItems, type SimpleLogo, type SimpleMenuViewModel, type SimpleNavDropdown, type SimpleNavItem, type SimpleNavLink, buildLogo, buildLogoViewModel, buildMenu, buildMenuViewModel, buildSimpleLogo, buildSimpleMenu, getNavItemsBySlug, getNavigationBySlug, getPrimaryNavItems, getPrimaryNavigation, isNavDropdown, isNavLink, transformToNavItems };
@@ -10,7 +10,9 @@
10
10
 
11
11
 
12
12
 
13
- var _chunk5STV4MWDjs = require('./chunk-5STV4MWD.js');
13
+
14
+
15
+ var _chunkEIVISR62js = require('./chunk-EIVISR62.js');
14
16
  require('./chunk-DGUM43GV.js');
15
17
 
16
18
 
@@ -24,5 +26,7 @@ require('./chunk-DGUM43GV.js');
24
26
 
25
27
 
26
28
 
27
- exports.buildLogoViewModel = _chunk5STV4MWDjs.buildLogoViewModel; exports.buildMenuViewModel = _chunk5STV4MWDjs.buildMenuViewModel; exports.buildSimpleLogo = _chunk5STV4MWDjs.buildSimpleLogo; exports.buildSimpleMenu = _chunk5STV4MWDjs.buildSimpleMenu; exports.getNavItemsBySlug = _chunk5STV4MWDjs.getNavItemsBySlug; exports.getNavigationBySlug = _chunk5STV4MWDjs.getNavigationBySlug; exports.getPrimaryNavItems = _chunk5STV4MWDjs.getPrimaryNavItems; exports.getPrimaryNavigation = _chunk5STV4MWDjs.getPrimaryNavigation; exports.selectPrimaryMenu = _chunk5STV4MWDjs.selectPrimaryMenu; exports.transformNavItems = _chunk5STV4MWDjs.transformNavItems; exports.transformToNavItems = _chunk5STV4MWDjs.transformToNavItems;
29
+
30
+
31
+ exports.buildLogo = _chunkEIVISR62js.buildLogo; exports.buildLogoViewModel = _chunkEIVISR62js.buildLogoViewModel; exports.buildMenu = _chunkEIVISR62js.buildMenu; exports.buildMenuViewModel = _chunkEIVISR62js.buildMenuViewModel; exports.buildSimpleLogo = _chunkEIVISR62js.buildSimpleLogo; exports.buildSimpleMenu = _chunkEIVISR62js.buildSimpleMenu; exports.getNavItemsBySlug = _chunkEIVISR62js.getNavItemsBySlug; exports.getNavigationBySlug = _chunkEIVISR62js.getNavigationBySlug; exports.getPrimaryNavItems = _chunkEIVISR62js.getPrimaryNavItems; exports.getPrimaryNavigation = _chunkEIVISR62js.getPrimaryNavigation; exports.isNavDropdown = _chunkEIVISR62js.isNavDropdown; exports.isNavLink = _chunkEIVISR62js.isNavLink; exports.transformToNavItems = _chunkEIVISR62js.transformToNavItems;
28
32
  //# sourceMappingURL=navigation.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/navigation.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,2sBAAC","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/navigation.js"}
1
+ {"version":3,"sources":["/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/navigation.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,mxBAAC","file":"/Users/will/Projects/Business/cms/builder/packages/sdk/dist/server/navigation.js"}
@@ -1,5 +1,7 @@
1
1
  import {
2
+ buildLogo,
2
3
  buildLogoViewModel,
4
+ buildMenu,
3
5
  buildMenuViewModel,
4
6
  buildSimpleLogo,
5
7
  buildSimpleMenu,
@@ -7,13 +9,15 @@ import {
7
9
  getNavigationBySlug,
8
10
  getPrimaryNavItems,
9
11
  getPrimaryNavigation,
10
- selectPrimaryMenu,
11
- transformNavItems,
12
+ isNavDropdown,
13
+ isNavLink,
12
14
  transformToNavItems
13
- } from "./chunk-KFLZGNPO.mjs";
15
+ } from "./chunk-YXA4GAAQ.mjs";
14
16
  import "./chunk-BJTO5JO5.mjs";
15
17
  export {
18
+ buildLogo,
16
19
  buildLogoViewModel,
20
+ buildMenu,
17
21
  buildMenuViewModel,
18
22
  buildSimpleLogo,
19
23
  buildSimpleMenu,
@@ -21,8 +25,8 @@ export {
21
25
  getNavigationBySlug,
22
26
  getPrimaryNavItems,
23
27
  getPrimaryNavigation,
24
- selectPrimaryMenu,
25
- transformNavItems,
28
+ isNavDropdown,
29
+ isNavLink,
26
30
  transformToNavItems
27
31
  };
28
32
  //# sourceMappingURL=navigation.mjs.map
@@ -1,5 +1,5 @@
1
1
  export { b as Page, P as PageProps } from '../loadPage-B8mQUUSo.mjs';
2
- export { H as HeaderData, L as Layout, a as LayoutProps } from '../Layout-BClXUTsd.mjs';
2
+ export { H as HeaderData, L as Layout, a as LayoutProps } from '../Layout-B7cvis7r.mjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React from 'react';
5
5
  import { T as Theme } from '../types-Dsu9wsUh.mjs';
@@ -1,5 +1,5 @@
1
1
  export { b as Page, P as PageProps } from '../loadPage-DP3nrHBi.js';
2
- export { H as HeaderData, L as Layout, a as LayoutProps } from '../Layout-UXGjXv8M.js';
2
+ export { H as HeaderData, L as Layout, a as LayoutProps } from '../Layout-wBtJLTVX.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React from 'react';
5
5
  import { T as Theme } from '../types-CVykEqXN.js';