@tailor-platform/app-shell 1.15.0 → 1.16.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 (98) hide show
  1. package/dist/app-shell-core.css +1 -1
  2. package/dist/app-shell.d.ts +208 -114
  3. package/dist/app-shell.js +3449 -3446
  4. package/dist/{appshell-DLVBFo5J.js → appshell-B0wh5Lq0.js} +625 -512
  5. package/dist/style-entry.d.ts +116 -96
  6. package/dist/testing.d.ts +116 -96
  7. package/dist/testing.js +1 -1
  8. package/dist/vite-plugin.d.ts +116 -96
  9. package/package.json +8 -8
  10. package/skills/app-shell-patterns/SKILL.md +101 -14
  11. package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +115 -0
  12. package/skills/app-shell-patterns/references/api/create-typed-paths.md +117 -0
  13. package/skills/app-shell-patterns/references/api/define-i18n-labels.md +143 -0
  14. package/skills/app-shell-patterns/references/api/define-module.md +247 -0
  15. package/skills/app-shell-patterns/references/api/define-resource.md +307 -0
  16. package/skills/app-shell-patterns/references/api/guards/hidden.md +202 -0
  17. package/skills/app-shell-patterns/references/api/guards/overview.md +354 -0
  18. package/skills/app-shell-patterns/references/api/guards/pass.md +129 -0
  19. package/skills/app-shell-patterns/references/api/guards/redirect-to.md +307 -0
  20. package/skills/app-shell-patterns/references/api/router/use-location.md +240 -0
  21. package/skills/app-shell-patterns/references/api/router/use-navigate.md +138 -0
  22. package/skills/app-shell-patterns/references/api/router/use-params.md +218 -0
  23. package/skills/app-shell-patterns/references/api/use-ai-chat.md +110 -0
  24. package/skills/app-shell-patterns/references/api/use-app-shell-config.md +126 -0
  25. package/skills/app-shell-patterns/references/api/use-app-shell-data.md +146 -0
  26. package/skills/app-shell-patterns/references/api/use-app-shell.md +143 -0
  27. package/skills/app-shell-patterns/references/api/use-auth.md +145 -0
  28. package/skills/app-shell-patterns/references/api/use-override-breadcrumb.md +74 -0
  29. package/skills/app-shell-patterns/references/api/use-page-meta.md +96 -0
  30. package/skills/app-shell-patterns/references/api/use-register-command-palette-actions.md +90 -0
  31. package/skills/app-shell-patterns/references/api/use-resolved-locale.md +67 -0
  32. package/skills/app-shell-patterns/references/api/use-route-error.md +214 -0
  33. package/skills/app-shell-patterns/references/api/use-theme.md +108 -0
  34. package/skills/app-shell-patterns/references/api/use-time-zone.md +80 -0
  35. package/skills/app-shell-patterns/references/api/use-toast.md +107 -0
  36. package/skills/app-shell-patterns/references/components/action-panel.md +168 -0
  37. package/skills/app-shell-patterns/references/components/activity-card.md +142 -0
  38. package/skills/app-shell-patterns/references/components/ai-chat.md +315 -0
  39. package/skills/app-shell-patterns/references/components/alert.md +202 -0
  40. package/skills/app-shell-patterns/references/components/app-shell.md +530 -0
  41. package/skills/app-shell-patterns/references/components/appearance-switcher.md +87 -0
  42. package/skills/app-shell-patterns/references/components/attachment.md +138 -0
  43. package/skills/app-shell-patterns/references/components/autocomplete.md +278 -0
  44. package/skills/app-shell-patterns/references/components/avatar.md +80 -0
  45. package/skills/app-shell-patterns/references/components/badge.md +309 -0
  46. package/skills/app-shell-patterns/references/components/button.md +164 -0
  47. package/skills/app-shell-patterns/references/components/card.md +109 -0
  48. package/skills/app-shell-patterns/references/components/checkbox.md +169 -0
  49. package/skills/app-shell-patterns/references/components/combobox.md +318 -0
  50. package/skills/app-shell-patterns/references/components/command-palette.md +413 -0
  51. package/skills/app-shell-patterns/references/components/csv-importer.md +214 -0
  52. package/skills/app-shell-patterns/references/components/data-table.md +953 -0
  53. package/skills/app-shell-patterns/references/components/date-picker.md +248 -0
  54. package/skills/app-shell-patterns/references/components/default-header.md +75 -0
  55. package/skills/app-shell-patterns/references/components/default-sidebar.md +136 -0
  56. package/skills/app-shell-patterns/references/components/description-card.md +569 -0
  57. package/skills/app-shell-patterns/references/components/dialog.md +164 -0
  58. package/skills/app-shell-patterns/references/components/document-progress-card.md +154 -0
  59. package/skills/app-shell-patterns/references/components/form.md +378 -0
  60. package/skills/app-shell-patterns/references/components/global-header-layout.md +132 -0
  61. package/skills/app-shell-patterns/references/components/grid.md +184 -0
  62. package/skills/app-shell-patterns/references/components/input.md +83 -0
  63. package/skills/app-shell-patterns/references/components/layout.md +539 -0
  64. package/skills/app-shell-patterns/references/components/menu.md +218 -0
  65. package/skills/app-shell-patterns/references/components/metric-card.md +94 -0
  66. package/skills/app-shell-patterns/references/components/select.md +283 -0
  67. package/skills/app-shell-patterns/references/components/sheet.md +237 -0
  68. package/skills/app-shell-patterns/references/components/sidebar-group.md +466 -0
  69. package/skills/app-shell-patterns/references/components/sidebar-item.md +458 -0
  70. package/skills/app-shell-patterns/references/components/sidebar-layout.md +258 -0
  71. package/skills/app-shell-patterns/references/components/spinner.md +81 -0
  72. package/skills/app-shell-patterns/references/components/table.md +188 -0
  73. package/skills/app-shell-patterns/references/components/tabs.md +158 -0
  74. package/skills/app-shell-patterns/references/components/textarea.md +122 -0
  75. package/skills/app-shell-patterns/references/components/timeline.md +317 -0
  76. package/skills/app-shell-patterns/references/components/toolbar.md +138 -0
  77. package/skills/app-shell-patterns/references/components/tooltip.md +144 -0
  78. package/skills/app-shell-patterns/references/components/with-guard.md +445 -0
  79. package/skills/app-shell-patterns/references/concepts/authentication.md +301 -0
  80. package/skills/app-shell-patterns/references/concepts/custom-components.md +59 -0
  81. package/skills/app-shell-patterns/references/concepts/file-based-routing.md +350 -0
  82. package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +11 -4
  83. package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
  84. package/skills/app-shell-patterns/references/concepts/routing-navigation.md +387 -0
  85. package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +388 -0
  86. package/skills/app-shell-patterns/references/{fundamental/design-system.md → concepts/styling-theming.md} +258 -110
  87. package/skills/app-shell-patterns/references/migrations.md +34 -0
  88. package/skills/app-shell-patterns/references/pages/{detail.md → document-detail.md} +4 -27
  89. package/skills/app-shell-patterns/references/patterns/form-composer.md +43 -45
  90. package/skills/app-shell-patterns/references/patterns/form-modal.md +39 -100
  91. package/skills/app-shell-patterns/references/patterns/form-sectioned.md +12 -38
  92. package/skills/app-shell-patterns/references/patterns/form-single-page.md +11 -32
  93. package/skills/app-shell-patterns/references/patterns/form-wizard.md +12 -53
  94. package/skills/app-shell-patterns/references/patterns/interaction-confirm.md +11 -27
  95. package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +13 -27
  96. package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
  97. package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +11 -86
  98. package/skills/app-shell-patterns/references/fundamental/components.md +0 -1009
@@ -0,0 +1,388 @@
1
+ ---
2
+ title: Sidebar Navigation
3
+ description: Learn how to customize sidebar navigation with auto-generation or composition mode
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/concepts/sidebar-navigation.docs.outline.md — do not edit by hand. -->
7
+
8
+ # Sidebar Navigation
9
+
10
+ AppShell provides flexible sidebar navigation with two modes:
11
+
12
+ - **Auto-generation mode**: Automatically generates navigation from module/resource definitions
13
+ - **Composition mode**: Full control over sidebar structure using declarative components
14
+
15
+ ## Quick Start
16
+
17
+ ### Auto-generation Mode (Default)
18
+
19
+ The simplest way to use the sidebar - navigation items are automatically generated from your module definitions:
20
+
21
+ ```tsx
22
+ import { AppShell, SidebarLayout } from "@tailor-platform/app-shell";
23
+
24
+ const App = () => (
25
+ <AppShell modules={modules}>
26
+ <SidebarLayout />
27
+ </AppShell>
28
+ );
29
+ ```
30
+
31
+ ### Composition Mode
32
+
33
+ For full control over sidebar structure, pass children to `DefaultSidebar` via the `sidebar` prop:
34
+
35
+ ```tsx
36
+ import {
37
+ AppShell,
38
+ SidebarLayout,
39
+ DefaultSidebar,
40
+ SidebarItem,
41
+ SidebarGroup,
42
+ SidebarSeparator,
43
+ } from "@tailor-platform/app-shell";
44
+ import { Package, Settings } from "lucide-react";
45
+
46
+ const App = () => (
47
+ <AppShell modules={modules}>
48
+ <SidebarLayout
49
+ sidebar={
50
+ <DefaultSidebar>
51
+ <SidebarItem to="/dashboard" />
52
+ <SidebarSeparator />
53
+ <SidebarGroup title="Products" icon={<Package />}>
54
+ <SidebarItem to="/products/all" />
55
+ <SidebarItem to="/products/categories" />
56
+ </SidebarGroup>
57
+ <SidebarItem to="/settings" icon={<Settings />} />
58
+ </DefaultSidebar>
59
+ }
60
+ />
61
+ </AppShell>
62
+ );
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Components
68
+
69
+ ### SidebarItem
70
+
71
+ A navigation item that automatically resolves title and icon from resource definitions.
72
+
73
+ #### Props
74
+
75
+ | Prop | Type | Required | Description |
76
+ | ---------- | ----------------- | -------- | ------------------------------------------------------------------------------- |
77
+ | `to` | `string` | Yes | Target URL. External URLs (http://...) are rendered as external links |
78
+ | `title` | `LocalizedString` | No | Override title (i18n supported). When omitted, auto-resolved from resource meta |
79
+ | `icon` | `ReactNode` | No | Override icon. When omitted, auto-resolved from resource meta |
80
+ | `external` | `boolean` | No | Opens link in new tab with external link icon |
81
+ | `render` | `function` | No | Custom render function for full UI control |
82
+
83
+ #### Examples
84
+
85
+ ```tsx
86
+ // Auto-resolved from resource meta
87
+ <SidebarItem to="/dashboard" />
88
+
89
+ // Override title and icon
90
+ <SidebarItem to="/" title="Home" icon={<Home />} />
91
+
92
+ // External link
93
+ <SidebarItem to="https://docs.example.com" external />
94
+
95
+ // Custom rendering with render prop
96
+ <SidebarItem
97
+ to="/tasks"
98
+ render={({ title, icon, isActive }) => (
99
+ <div className={isActive ? "font-bold" : ""}>
100
+ {icon}
101
+ <span>{title}</span>
102
+ <Badge>5</Badge>
103
+ </div>
104
+ )}
105
+ />
106
+ ```
107
+
108
+ #### Render Prop
109
+
110
+ When using the `render` prop, you receive `SidebarItemRenderProps`:
111
+
112
+ | Property | Type | Description |
113
+ | ---------- | ------------------------ | ----------------------------------------------- |
114
+ | `title` | `string` | Resolved title (from override or resource meta) |
115
+ | `url` | `string` | Target URL |
116
+ | `icon` | `ReactNode \| undefined` | Resolved icon |
117
+ | `isActive` | `boolean` | Whether this item is currently active |
118
+
119
+ ---
120
+
121
+ ### SidebarGroup
122
+
123
+ A collapsible group for organizing navigation items.
124
+
125
+ #### Props
126
+
127
+ | Prop | Type | Required | Description |
128
+ | ------------- | ----------------- | -------- | ---------------------------------------------- |
129
+ | `title` | `LocalizedString` | Yes | Group title (supports i18n) |
130
+ | `icon` | `ReactNode` | No | Group icon |
131
+ | `to` | `string` | No | When specified, title becomes a clickable link |
132
+ | `defaultOpen` | `boolean` | No | Initial expanded state. Default: `true` |
133
+ | `children` | `ReactNode` | Yes | Child items (SidebarItem, SidebarGroup, etc.) |
134
+
135
+ #### Examples
136
+
137
+ ```tsx
138
+ // Basic group
139
+ <SidebarGroup title="Products" icon={<Package />}>
140
+ <SidebarItem to="/products/all" />
141
+ <SidebarItem to="/products/categories" />
142
+ </SidebarGroup>
143
+
144
+ // Clickable group header
145
+ <SidebarGroup title="Settings" icon={<Settings />} to="/settings">
146
+ <SidebarItem to="/settings/profile" />
147
+ <SidebarItem to="/settings/security" />
148
+ </SidebarGroup>
149
+
150
+ // Initially collapsed
151
+ <SidebarGroup title="Archives" defaultOpen={false}>
152
+ <SidebarItem to="/archives/2024" />
153
+ <SidebarItem to="/archives/2023" />
154
+ </SidebarGroup>
155
+
156
+ // Nested groups
157
+ <SidebarGroup title="Products" icon={<Package />}>
158
+ <SidebarItem to="/products/all" />
159
+ <SidebarGroup title="Archives" defaultOpen={false}>
160
+ <SidebarItem to="/products/archives/2024" />
161
+ <SidebarItem to="/products/archives/2023" />
162
+ </SidebarGroup>
163
+ </SidebarGroup>
164
+ ```
165
+
166
+ #### i18n Support
167
+
168
+ Group titles support localized strings:
169
+
170
+ ```tsx
171
+ import { defineI18nLabels } from "@tailor-platform/app-shell";
172
+
173
+ const labels = defineI18nLabels({
174
+ en: { products: "Products" },
175
+ ja: { products: "製品" },
176
+ });
177
+
178
+ <SidebarGroup title={labels.t("products")} icon={<Package />}>
179
+ <SidebarItem to="/products/all" />
180
+ </SidebarGroup>;
181
+ ```
182
+
183
+ ---
184
+
185
+ ### SidebarSeparator
186
+
187
+ A visual divider between sidebar sections.
188
+
189
+ #### Props
190
+
191
+ This component takes no props.
192
+
193
+ #### Example
194
+
195
+ ```tsx
196
+ <DefaultSidebar>
197
+ <SidebarItem to="/dashboard" />
198
+ <SidebarSeparator />
199
+ <SidebarItem to="/settings" />
200
+ </DefaultSidebar>
201
+ ```
202
+
203
+ ---
204
+
205
+ ### DefaultSidebar
206
+
207
+ The main sidebar container that supports both auto-generation and composition modes.
208
+
209
+ #### Props
210
+
211
+ | Prop | Type | Required | Description |
212
+ | ---------- | ----------- | -------- | --------------------------------------- |
213
+ | `header` | `ReactNode` | No | Custom header content |
214
+ | `footer` | `ReactNode` | No | Custom footer content |
215
+ | `children` | `ReactNode` | No | When provided, enables composition mode |
216
+
217
+ #### Examples
218
+
219
+ ```tsx
220
+ // Auto-generation mode
221
+ <DefaultSidebar />
222
+
223
+ // With custom header and footer
224
+ <DefaultSidebar
225
+ header={<Logo />}
226
+ footer={<UserMenu />}
227
+ />
228
+
229
+ // Composition mode with custom navigation
230
+ <DefaultSidebar header={<Logo />}>
231
+ <SidebarItem to="/dashboard" />
232
+ <SidebarGroup title="Products">
233
+ <SidebarItem to="/products/all" />
234
+ </SidebarGroup>
235
+ </DefaultSidebar>
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Hooks
241
+
242
+ ### usePageMeta
243
+
244
+ A hook to retrieve page metadata (title, icon) for a given URL path.
245
+
246
+ #### Signature
247
+
248
+ ```typescript
249
+ const usePageMeta: (path: string) => PageMeta | null;
250
+
251
+ type PageMeta = {
252
+ title: string;
253
+ icon?: ReactNode;
254
+ };
255
+ ```
256
+
257
+ #### Parameters
258
+
259
+ | Parameter | Type | Description |
260
+ | --------- | -------- | ------------------------------------------------- |
261
+ | `path` | `string` | URL path to find meta for (e.g., "/products/all") |
262
+
263
+ #### Returns
264
+
265
+ - `PageMeta` - Object containing `title` and optional `icon` if found
266
+ - `null` - For external links or when path is not found
267
+
268
+ #### Example
269
+
270
+ ```tsx
271
+ import { usePageMeta } from "@tailor-platform/app-shell";
272
+
273
+ const MyComponent = () => {
274
+ const pageMeta = usePageMeta("/products/all");
275
+
276
+ if (!pageMeta) {
277
+ return <span>Unknown Page</span>;
278
+ }
279
+
280
+ return (
281
+ <div>
282
+ {pageMeta.icon}
283
+ <span>{pageMeta.title}</span>
284
+ </div>
285
+ );
286
+ };
287
+ ```
288
+
289
+ ---
290
+
291
+ ## Access Control
292
+
293
+ ### Auto-generation Mode
294
+
295
+ In auto-generation mode, `guards` defined in `defineModule`/`defineResource` are automatically evaluated. Modules/resources that return `hidden()` will not appear in the sidebar.
296
+
297
+ ```tsx
298
+ import { defineModule, defineResource, pass, hidden } from "@tailor-platform/app-shell";
299
+
300
+ const adminModule = defineModule({
301
+ path: "admin",
302
+ meta: { title: "Admin" },
303
+ // If this guard returns hidden(), the module won't appear in sidebar
304
+ guards: [({ context }) => (context.currentUser.role === "admin" ? pass() : hidden())],
305
+ resources: [
306
+ defineResource({
307
+ path: "users",
308
+ meta: { title: "Users" },
309
+ component: () => <div>Users</div>,
310
+ }),
311
+ ],
312
+ });
313
+
314
+ // Used with auto-generation mode
315
+ <DefaultSidebar />;
316
+ ```
317
+
318
+ ### Composition Mode
319
+
320
+ In composition mode, use the `WithGuard` component to control visibility of sidebar items. This allows you to reuse the same guard logic used in route definitions.
321
+
322
+ ```tsx
323
+ import { WithGuard, pass, hidden } from "@tailor-platform/app-shell";
324
+
325
+ // Define a guard function
326
+ const isAdminGuard = ({ context }) => (context.currentUser.role === "admin" ? pass() : hidden());
327
+
328
+ <DefaultSidebar>
329
+ <SidebarItem to="/dashboard" />
330
+
331
+ {/* Wrap items with WithGuard for conditional visibility */}
332
+ <WithGuard guards={[isAdminGuard]}>
333
+ <SidebarGroup title="Admin" icon={<Shield />}>
334
+ <SidebarItem to="/admin/users" />
335
+ <SidebarItem to="/admin/settings" />
336
+ </SidebarGroup>
337
+ </WithGuard>
338
+ </DefaultSidebar>;
339
+ ```
340
+
341
+ #### Curried Guards
342
+
343
+ For parameterized guards, use the curried pattern:
344
+
345
+ ```tsx
346
+ // Define a curried guard factory
347
+ const hasRole =
348
+ (role: string) =>
349
+ ({ context }) =>
350
+ context.currentUser.role === role ? pass() : hidden();
351
+
352
+ <DefaultSidebar>
353
+ <WithGuard guards={[hasRole("admin")]}>
354
+ <SidebarItem to="/admin" />
355
+ </WithGuard>
356
+
357
+ <WithGuard guards={[hasRole("manager")]}>
358
+ <SidebarItem to="/reports" />
359
+ </WithGuard>
360
+ </DefaultSidebar>;
361
+ ```
362
+
363
+ > **Note**: Route-level access control (e.g., redirects) still works via `guards` in `defineResource`, even in composition mode. `WithGuard` only controls visibility—it does not prevent navigation to protected routes.
364
+
365
+ ---
366
+
367
+ ## Migration from Auto-generation
368
+
369
+ If you're currently using auto-generated navigation and want to customize it:
370
+
371
+ 1. **Keep auto-generation for most items**, add custom items where needed:
372
+
373
+ ```tsx
374
+ // Before: Pure auto-generation
375
+ <DefaultSidebar />
376
+
377
+ // After: Composition with similar structure
378
+ <DefaultSidebar>
379
+ <SidebarItem to="/dashboard" />
380
+ <SidebarItem to="/products" />
381
+ <SidebarSeparator />
382
+ <SidebarItem to="https://docs.example.com" title="Documentation" external />
383
+ </DefaultSidebar>
384
+ ```
385
+
386
+ 2. **Title and icon are auto-resolved** from your resource definitions, so you don't need to specify them unless you want to override.
387
+
388
+ 3. **External links** can now be added directly in the sidebar.