@purestack/ts-components 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -0
  3. package/dist/ts-components.d.mts +1662 -0
  4. package/dist/ts-components.d.mts.map +1 -0
  5. package/dist/ts-components.mjs +9200 -0
  6. package/dist/ts-components.mjs.map +1 -0
  7. package/package.json +130 -0
  8. package/src/defineComponents.ts +87 -0
  9. package/src/index.ts +270 -0
  10. package/src/registerStyles.ts +63 -0
  11. package/src/standard/alertBox/alertBox.ts +64 -0
  12. package/src/standard/autoId.ts +25 -0
  13. package/src/standard/badge/badge.ts +41 -0
  14. package/src/standard/badge/badgeStyle.ts +21 -0
  15. package/src/standard/barChart/barChart.ts +338 -0
  16. package/src/standard/barChart/barChartStyle.ts +81 -0
  17. package/src/standard/btn/btn.ts +191 -0
  18. package/src/standard/btn/btnStyle.ts +59 -0
  19. package/src/standard/btnGroup/btnGroup.ts +208 -0
  20. package/src/standard/btnGroup/btnGroupStyle.ts +85 -0
  21. package/src/standard/chart/cartesianChart.ts +99 -0
  22. package/src/standard/chart/chartDefaults.ts +25 -0
  23. package/src/standard/chart/chartUtils.ts +84 -0
  24. package/src/standard/classicLogo/classicLogo.ts +429 -0
  25. package/src/standard/classicLogo/classicLogoStyle.ts +292 -0
  26. package/src/standard/componentVariant.ts +153 -0
  27. package/src/standard/composer/composer.ts +1035 -0
  28. package/src/standard/composer/composerCanvasInitialStyle.ts +225 -0
  29. package/src/standard/composer/composerCanvasRevertStyle.ts +14 -0
  30. package/src/standard/composer/composerCanvasSharedStyle.ts +60 -0
  31. package/src/standard/composer/composerCanvasStyleTypes.ts +8 -0
  32. package/src/standard/composer/composerCanvasThemeStyle.ts +53 -0
  33. package/src/standard/composer/composerStyle.ts +156 -0
  34. package/src/standard/composer/emailHtmlPolicy.ts +474 -0
  35. package/src/standard/consent/consent.ts +173 -0
  36. package/src/standard/consent/consentStyle.ts +44 -0
  37. package/src/standard/contactForm/contactForm.ts +135 -0
  38. package/src/standard/contactForm/contactFormStyle.ts +116 -0
  39. package/src/standard/doughnutChart/doughnutChart.ts +527 -0
  40. package/src/standard/doughnutChart/doughnutChartStyle.ts +64 -0
  41. package/src/standard/dropFiles/dropFiles.ts +480 -0
  42. package/src/standard/dropFiles/dropFilesStyle.ts +171 -0
  43. package/src/standard/expandablePanel/expandablePanel.ts +106 -0
  44. package/src/standard/expandablePanel/expandablePanelStyle.ts +56 -0
  45. package/src/standard/flex/flex.ts +269 -0
  46. package/src/standard/flex/flexStyle.ts +556 -0
  47. package/src/standard/footer/footer.ts +93 -0
  48. package/src/standard/footer/footerStyle.ts +39 -0
  49. package/src/standard/form/autoCompleteInput.ts +567 -0
  50. package/src/standard/form/form.ts +205 -0
  51. package/src/standard/form/formCheck.ts +96 -0
  52. package/src/standard/form/formInputField.ts +184 -0
  53. package/src/standard/form/formSelectField.ts +152 -0
  54. package/src/standard/form/formStyle.ts +585 -0
  55. package/src/standard/form/multiAutoCompleteInput.ts +880 -0
  56. package/src/standard/grid/grid.ts +177 -0
  57. package/src/standard/grid/gridStyle.ts +56 -0
  58. package/src/standard/icon/icon.ts +96 -0
  59. package/src/standard/icon/iconStyle.ts +50 -0
  60. package/src/standard/landing/codeShowcase.ts +54 -0
  61. package/src/standard/landing/comparisonColumn.ts +30 -0
  62. package/src/standard/landing/comparisonFeature.ts +22 -0
  63. package/src/standard/landing/comparisonTable.ts +38 -0
  64. package/src/standard/landing/ctaSection.ts +59 -0
  65. package/src/standard/landing/featureCard.ts +41 -0
  66. package/src/standard/landing/landing.ts +52 -0
  67. package/src/standard/landing/landingBand.ts +217 -0
  68. package/src/standard/landing/landingSection.ts +43 -0
  69. package/src/standard/landing/landingTypes.ts +141 -0
  70. package/src/standard/landing/metricItem.ts +25 -0
  71. package/src/standard/landing/metricStrip.ts +20 -0
  72. package/src/standard/lineChart/lineChart.ts +462 -0
  73. package/src/standard/lineChart/lineChartStyle.ts +91 -0
  74. package/src/standard/logo/logo.ts +192 -0
  75. package/src/standard/logo/logoStyle.ts +164 -0
  76. package/src/standard/modal/modal.ts +171 -0
  77. package/src/standard/modal/modalStore.ts +154 -0
  78. package/src/standard/modal/modalStyle.ts +190 -0
  79. package/src/standard/navMenu/navMenu.ts +278 -0
  80. package/src/standard/navMenu/navMenuStyle.ts +323 -0
  81. package/src/standard/pageLinks/pageLinks.ts +90 -0
  82. package/src/standard/pageScript/pageScript.ts +155 -0
  83. package/src/standard/pageToc/pageToc.ts +154 -0
  84. package/src/standard/pageToc/pageTocStyle.ts +372 -0
  85. package/src/standard/panel/panel.ts +55 -0
  86. package/src/standard/panel/panelStyle.ts +15 -0
  87. package/src/standard/pricing/pricing.ts +146 -0
  88. package/src/standard/searchBox/searchBox.ts +54 -0
  89. package/src/standard/searchBox/searchBoxStyle.ts +180 -0
  90. package/src/standard/sectionHeader/sectionHeader.ts +99 -0
  91. package/src/standard/signIn/signIn.ts +167 -0
  92. package/src/standard/signIn/signInStyle.ts +70 -0
  93. package/src/standard/tabs/tabs.ts +193 -0
  94. package/src/standard/tabs/tabsStyle.ts +231 -0
  95. package/src/standard/themeToggle/themeToggle.ts +33 -0
  96. package/src/standard/themeToggle/themeToggleStyle.ts +88 -0
  97. package/src/standard/toast/toastHost.ts +42 -0
  98. package/src/standard/toast/toastStore.ts +50 -0
  99. package/src/standard/topBar/topBar.ts +101 -0
  100. package/src/standard/topBar/topBarStyle.ts +169 -0
  101. package/src/standard/virtualList/variableVirtualTable.ts +371 -0
  102. package/src/standard/virtualList/virtualList.ts +423 -0
  103. package/src/standard/virtualList/virtualListStyle.ts +34 -0
  104. package/src/standard/virtualList/virtualTable.ts +179 -0
  105. package/src/standard/virtualList/virtualTableStyle.ts +24 -0
  106. package/tsconfig.json +23 -0
@@ -0,0 +1,190 @@
1
+ import type { ThemePalette } from '@purestack/ts-style'
2
+ import { styleBuilder, type ThemeMode, themes } from '@purestack/ts-style'
3
+
4
+ export function registerModalStyles() {
5
+ themes.forEach((theme, palette) => {
6
+ registerModalShellStyles(theme, palette)
7
+ registerModalMotionStyles(theme)
8
+ registerModalSizeStyles(theme)
9
+ })
10
+ }
11
+
12
+ function registerModalShellStyles(theme: ThemeMode, palette: ThemePalette) {
13
+ styleBuilder
14
+ .select('.modal', theme)
15
+ .position('fixed')
16
+ .inset('0')
17
+ .margin('0')
18
+ .padding('0')
19
+ .border('none')
20
+ .background('transparent')
21
+ .maxWidth('100vw')
22
+ .maxHeight('100vh')
23
+ .width('100%')
24
+ .height('100%')
25
+ .overflow('hidden')
26
+
27
+ styleBuilder
28
+ .select('.modal[open]', theme)
29
+ .display('grid')
30
+ .placeItems('center')
31
+
32
+ styleBuilder.select('.modal:not([open])', theme).display('none')
33
+
34
+ styleBuilder
35
+ .select('.modal::backdrop', theme)
36
+ .background(palette.current.overlay)
37
+ .opacity('1')
38
+
39
+ styleBuilder
40
+ .select('.modal--fade::backdrop', theme)
41
+ .opacity('0')
42
+ .transition('opacity 420ms ease')
43
+
44
+ styleBuilder.select('.modal--fade[open]::backdrop', theme).opacity('0.8')
45
+
46
+ styleBuilder
47
+ .select('.modal__panel', theme)
48
+ .position('relative')
49
+ .display('grid')
50
+ .width('min(92vw, 40rem)')
51
+ .maxHeight('min(86vh, 56.25rem)')
52
+ .overflow('auto')
53
+ .background(palette.current.canvas)
54
+ .boxShadow(palette.effect.softShadow)
55
+ .color(palette.current.text.default)
56
+ .transform('translate3d(0, 0, 0)')
57
+ .opacity('1')
58
+
59
+ styleBuilder
60
+ .select('.modal__surface', theme)
61
+ .display('grid')
62
+ .gap('1em')
63
+ .minHeight('100%')
64
+ .padding('1em')
65
+ .borderRadius(palette.radii.lg)
66
+
67
+ styleBuilder
68
+ .select('.modal__header', theme)
69
+ .display('grid')
70
+ .gridTemplateColumns('minmax(0, 1fr) auto minmax(0, 1fr)')
71
+ .alignItems('center')
72
+ .gap('0.6em')
73
+
74
+ styleBuilder
75
+ .select('.modal__title', theme)
76
+ .gridColumn('2')
77
+ .justifySelf('center')
78
+ .margin('0')
79
+ .apply(palette.applyFont(palette.font.size.h3, palette.font.weight.w700))
80
+ .textAlign('center')
81
+ .color(palette.current.text.default)
82
+
83
+ styleBuilder
84
+ .select('.modal__header [data-modal-close]', theme)
85
+ .gridColumn('3')
86
+ .justifySelf('end')
87
+
88
+ styleBuilder
89
+ .select('.modal__body', theme)
90
+ .display('grid')
91
+ .minWidth('0')
92
+ .justifyItems('center')
93
+ .textAlign('center')
94
+
95
+ styleBuilder
96
+ .select('.modal__footer', theme)
97
+ .display('flex')
98
+ .flexWrap('wrap')
99
+ .alignItems('center')
100
+ .justifyContent('center')
101
+ .gap('0.6em')
102
+
103
+ styleBuilder.select('.modal__footer:empty', theme).display('none')
104
+
105
+ styleBuilder
106
+ .select('.modal--animated .modal__panel', theme)
107
+ .transition('transform 700ms cubic-bezier(0.16, 1, 0.3, 1)')
108
+
109
+ styleBuilder
110
+ .select('.modal--fade.modal--animated .modal__panel', theme)
111
+ .transition(
112
+ 'transform 700ms cubic-bezier(0.16, 1, 0.3, 1), opacity 420ms ease',
113
+ )
114
+
115
+ styleBuilder
116
+ .select(
117
+ '.modal--fade[data-modal-state="opening"] .modal__panel, .modal--fade[data-modal-state="closing"] .modal__panel',
118
+ theme,
119
+ )
120
+ .opacity('0')
121
+
122
+ styleBuilder
123
+ .select(
124
+ '.modal--fade.modal--slide-top[data-modal-state="opening"] .modal__panel, .modal--fade.modal--slide-top[data-modal-state="closing"] .modal__panel, .modal--fade.modal--slide-right[data-modal-state="opening"] .modal__panel, .modal--fade.modal--slide-right[data-modal-state="closing"] .modal__panel, .modal--fade.modal--slide-bottom[data-modal-state="opening"] .modal__panel, .modal--fade.modal--slide-bottom[data-modal-state="closing"] .modal__panel, .modal--fade.modal--slide-left[data-modal-state="opening"] .modal__panel, .modal--fade.modal--slide-left[data-modal-state="closing"] .modal__panel',
125
+ theme,
126
+ )
127
+ .opacity('0.45')
128
+
129
+ styleBuilder
130
+ .select(
131
+ '.modal--fade[data-modal-state="opening"]::backdrop, .modal--fade[data-modal-state="closing"]::backdrop',
132
+ theme,
133
+ )
134
+ .opacity('0')
135
+ }
136
+
137
+ function registerModalMotionStyles(theme: ThemeMode) {
138
+ styleBuilder
139
+ .select(
140
+ '.modal--slide-top[data-modal-state="opening"] .modal__panel, .modal--slide-top[data-modal-state="closing"] .modal__panel',
141
+ theme,
142
+ )
143
+ .transform('translate3d(0, calc(-50vh - 50%), 0)')
144
+
145
+ styleBuilder
146
+ .select(
147
+ '.modal--slide-right[data-modal-state="opening"] .modal__panel, .modal--slide-right[data-modal-state="closing"] .modal__panel',
148
+ theme,
149
+ )
150
+ .transform('translate3d(calc(50vw + 50%), 0, 0)')
151
+
152
+ styleBuilder
153
+ .select(
154
+ '.modal--slide-bottom[data-modal-state="opening"] .modal__panel, .modal--slide-bottom[data-modal-state="closing"] .modal__panel',
155
+ theme,
156
+ )
157
+ .transform('translate3d(0, calc(50vh + 50%), 0)')
158
+
159
+ styleBuilder
160
+ .select(
161
+ '.modal--slide-left[data-modal-state="opening"] .modal__panel, .modal--slide-left[data-modal-state="closing"] .modal__panel',
162
+ theme,
163
+ )
164
+ .transform('translate3d(calc(-50vw - 50%), 0, 0)')
165
+
166
+ styleBuilder
167
+ .select('.modal--animated .modal__panel', theme)
168
+ .media('prefers-reduced-motion: reduce')
169
+ .transition('none')
170
+
171
+ styleBuilder
172
+ .select('.modal::backdrop', theme)
173
+ .media('prefers-reduced-motion: reduce')
174
+ .transition('none')
175
+ }
176
+
177
+ function registerModalSizeStyles(theme: ThemeMode) {
178
+ styleBuilder
179
+ .select('.modal--size-sm .modal__panel', theme)
180
+ .width('min(92vw, 26.25rem)')
181
+ styleBuilder
182
+ .select('.modal--size-md .modal__panel', theme)
183
+ .width('min(92vw, 40rem)')
184
+ styleBuilder
185
+ .select('.modal--size-lg .modal__panel', theme)
186
+ .width('min(94vw, 53.75rem)')
187
+ styleBuilder
188
+ .select('.modal--size-xl .modal__panel', theme)
189
+ .width('min(96vw, 67.5rem)')
190
+ }
@@ -0,0 +1,278 @@
1
+ import {
2
+ type NavItem,
3
+ type TsSsgContext,
4
+ tryResolveTsSsgContext,
5
+ } from '@purestack/ts-common'
6
+ import type { SemanticTone } from '@purestack/ts-style'
7
+ import { urlNormalizer } from '@purestack/ts-util'
8
+ import {
9
+ type ComputedRef,
10
+ computed,
11
+ defineComponent,
12
+ html,
13
+ type RefOrValue,
14
+ type SRef,
15
+ unref,
16
+ } from 'regor'
17
+ import {
18
+ type ComponentVariant,
19
+ type ComponentVariantMode,
20
+ resolveComponentClasses,
21
+ } from '../componentVariant'
22
+
23
+ export interface NavMenu {
24
+ items?: NavItem[] | SRef<NavItem[]>
25
+ currentUrl?: RefOrValue<string>
26
+ navItems?: ComputedRef<NavItemState[]>
27
+ tone?: RefOrValue<SemanticTone>
28
+ variant?: RefOrValue<ComponentVariant>
29
+ variantMode?: RefOrValue<ComponentVariantMode>
30
+ signInAvatarSrc?: RefOrValue<string>
31
+ signInAvatarAlt?: RefOrValue<string>
32
+ classes?: ComputedRef<string>
33
+ searchEnabled?: boolean
34
+ navRoot?: string
35
+ }
36
+
37
+ export interface NavList {
38
+ items?: NavItemState[]
39
+ tone?: SemanticTone
40
+ }
41
+
42
+ export interface NavItemState extends NavItem {
43
+ isActive: boolean
44
+ isOpen: boolean
45
+ stateKey: string
46
+ linkClass?: string[]
47
+ ariaCurrent?: string
48
+ }
49
+
50
+ const navItemTemplate = html`<li class="nav__item">
51
+ <details
52
+ r-if="item.children && item.children.length > 0"
53
+ class="nav__group"
54
+ :open="item.isOpen"
55
+ :data-nav-group-key="item.stateKey"
56
+ :data-nav-default-open="item.isOpen ? 'true' : undefined"
57
+ >
58
+ <summary class="nav__summary w-full">
59
+ <BtnLink
60
+ variant="none"
61
+ :icon="item.icon"
62
+ :tone="item.tone"
63
+ :class="item.linkClass"
64
+ :aria-current="item.ariaCurrent"
65
+ >
66
+ {{ item.title }}
67
+ </BtnLink>
68
+ <Icon
69
+ class="nav__chevron fs-xxs"
70
+ name="tabler:chevron-down"
71
+ aria-hidden="true"/>
72
+ </summary>
73
+ <NavList :items="item.children" :tone="item.tone"></NavList>
74
+ </details>
75
+ <BtnLink
76
+ r-else
77
+ variant="none"
78
+ :icon="item.icon"
79
+ :href="item.url"
80
+ :tone="item.tone"
81
+ :class="item.linkClass"
82
+ :aria-current="item.ariaCurrent"
83
+ >
84
+ {{ item.title }}
85
+ </BtnLink>
86
+ </li>`
87
+
88
+ const navListTemplate = html`<ul class="nav__list">
89
+ <NavItem r-for="item in items"/>
90
+ </ul>`
91
+
92
+ const DEFAULT_NAV_MENU_TONE: SemanticTone = 'neutral'
93
+ const DEFAULT_NAV_MENU_VARIANT: ComponentVariant = 'flat'
94
+ const DEFAULT_NAV_MENU_VARIANT_MODE: ComponentVariantMode = 'stateless'
95
+
96
+ const navMenuTemplate = html`<nav
97
+ class="nav__menu"
98
+ :class="classes"
99
+ :data-nav-root="navRoot"
100
+ aria-label="Site navigation"
101
+ >
102
+ <div class="nav__header-row">
103
+ <div class="nav__header">Navigation</div>
104
+ <SignIn
105
+ class="nav__account"
106
+ :avatarSrc="signInAvatarSrc"
107
+ :avatarAlt="signInAvatarAlt"/>
108
+ <button
109
+ class="nav__panel-toggle tone-fill-surface-all tone-text-surface-all tone-border-surface-all"
110
+ type="button"
111
+ title="Navigation"
112
+ aria-label="Toggle navigation panel"
113
+ data-nav-menu-toggle
114
+ >
115
+ <span class="nav__panel-toggle-icon" aria-hidden="true">
116
+ <Icon name="iconoir:pin"/>
117
+ </span>
118
+ <span class="nav__panel-toggle-label">navigation</span>
119
+ </button>
120
+ <button
121
+ class="nav__collapse-toggle tone-text-surface-all tone-fill-surface-hover tone-fill-surface-active tone-border-surface-hover tone-border-surface-active opacity-25 opacity-1-hover"
122
+ type="button"
123
+ title="Collapse navigation"
124
+ aria-label="Collapse navigation"
125
+ data-nav-menu-collapse
126
+ >
127
+ <span
128
+ class="nav__collapse-toggle-icon nav__collapse-toggle-icon--collapse p-1"
129
+ aria-hidden="true"
130
+ >
131
+ <Icon name="iconoir:pin-slash"/>
132
+ </span>
133
+ <span
134
+ class="nav__collapse-toggle-icon nav__collapse-toggle-icon--open p-1"
135
+ aria-hidden="true"
136
+ >
137
+ <Icon name="iconoir:pin"/>
138
+ </span>
139
+ </button>
140
+ </div>
141
+ <NavList :items="navItems"></NavList>
142
+ <SearchBox r-if="searchEnabled" class="nav__search mt-1"/>
143
+ <script>
144
+ window.tsSsgNavMenu?.hydrate(document.currentScript?.parentElement)
145
+ </script>
146
+ </nav>`
147
+
148
+ function resolveNavItems(context?: TsSsgContext): NavItem[] {
149
+ const items = context?.navigation?.items ?? []
150
+ if (items.length > 0) return items
151
+ return context?.navigation?.global ?? []
152
+ }
153
+
154
+ function resolveCurrentPath(
155
+ currentUrl: string | undefined,
156
+ context?: TsSsgContext,
157
+ ): string | undefined {
158
+ const fromProp = urlNormalizer.normalizeInternalPath(currentUrl)
159
+ if (fromProp) return fromProp
160
+ const fromContext = urlNormalizer.normalizeInternalPath(
161
+ context?.pageInfo?.urlPath,
162
+ )
163
+ if (fromContext) return fromContext
164
+ if (typeof window !== 'undefined' && window.location?.pathname) {
165
+ return urlNormalizer.normalizeInternalPath(window.location.pathname)
166
+ }
167
+ return undefined
168
+ }
169
+
170
+ function buildNavState(
171
+ items: NavItem[],
172
+ currentPath: string | undefined,
173
+ parentKey = '',
174
+ ): NavItemState[] {
175
+ return unref(items).map((item) => {
176
+ const stateKey = resolveNavItemStateKey(item, parentKey)
177
+ const childStates = item.children
178
+ ? buildNavState(item.children, currentPath, stateKey)
179
+ : []
180
+ const itemPath = urlNormalizer.normalizeInternalPath(item.url)
181
+ const isActive = Boolean(
182
+ itemPath && currentPath && itemPath === currentPath,
183
+ )
184
+ const hasActiveChild = childStates.some(
185
+ (child) => child.isActive || child.isOpen,
186
+ )
187
+ return {
188
+ ...item,
189
+ tone: isActive ? 'accent' : 'neutral',
190
+ ...(childStates.length > 0 ? { children: childStates } : {}),
191
+ isActive,
192
+ isOpen: isActive || hasActiveChild,
193
+ stateKey,
194
+ linkClass: [
195
+ 'fs-body ws-normal justify-start w-full tone-fill-surface-hover tone-fill-surface-active rounded-sm',
196
+ isActive ? 'active tone-text-surface-active' : 'tone-text',
197
+ ],
198
+ ariaCurrent: isActive ? 'page' : undefined,
199
+ }
200
+ })
201
+ }
202
+
203
+ function resolveNavItemStateKey(item: NavItem, parentKey: string) {
204
+ const segment = normalizeNavStateKeyPart(item.id ?? item.url ?? item.title)
205
+ return parentKey ? `${parentKey}/${segment}` : segment
206
+ }
207
+
208
+ function normalizeNavStateKeyPart(value: string) {
209
+ const normalized = value
210
+ .trim()
211
+ .replaceAll('\\', '/')
212
+ .replace(/^\/+|\/+$/g, '')
213
+ return normalized || 'item'
214
+ }
215
+
216
+ function defineNavItemComponent() {
217
+ return defineComponent<{ item: NavItemState }>(navItemTemplate, {})
218
+ }
219
+
220
+ function defineNavListComponent() {
221
+ return defineComponent<NavList>(navListTemplate, {
222
+ props: ['items', 'tone'],
223
+ context: (head) => ({
224
+ ...head.props,
225
+ items: head.props.items,
226
+ tone: head.props.tone,
227
+ }),
228
+ })
229
+ }
230
+
231
+ function defineNavMenuComponent() {
232
+ return defineComponent<NavMenu>(navMenuTemplate, {
233
+ props: [
234
+ 'items',
235
+ 'currentUrl',
236
+ 'tone',
237
+ 'variant',
238
+ 'variantMode',
239
+ 'signInAvatarSrc',
240
+ 'signInAvatarAlt',
241
+ ],
242
+ context: (head) => {
243
+ const context = tryResolveTsSsgContext(head)
244
+ const props = head.props
245
+ return {
246
+ ...props,
247
+ classes: computed(() =>
248
+ resolveComponentClasses(
249
+ { ...props, tone: unref(props.tone) || DEFAULT_NAV_MENU_TONE },
250
+ {
251
+ defaultVariant: DEFAULT_NAV_MENU_VARIANT,
252
+ defaultVariantMode: DEFAULT_NAV_MENU_VARIANT_MODE,
253
+ },
254
+ ),
255
+ ),
256
+ searchEnabled: context?.site.pagefind?.enabled === true,
257
+ navRoot: normalizeNavStateKeyPart(context?.navigation?.root ?? ''),
258
+ navItems: computed(() =>
259
+ buildNavState(
260
+ unref(props.items) ?? resolveNavItems(context),
261
+ resolveCurrentPath(unref(props.currentUrl), context),
262
+ ),
263
+ ),
264
+ }
265
+ },
266
+ })
267
+ }
268
+
269
+ export function defineNavigationComponents() {
270
+ const navItem = defineNavItemComponent()
271
+ const navList = defineNavListComponent()
272
+ const navMenu = defineNavMenuComponent()
273
+ return {
274
+ navItem,
275
+ navList,
276
+ navMenu,
277
+ }
278
+ }