@tailor-platform/app-shell 1.14.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.
- package/LICENSE.md +21 -0
- package/dist/app-shell-core.css +1 -1
- package/dist/app-shell.d.ts +1203 -316
- package/dist/app-shell.js +4562 -3307
- package/dist/{appshell-CtS8Y3LW.js → appshell-B0wh5Lq0.js} +850 -549
- package/dist/style-entry.d.ts +118 -98
- package/dist/testing.d.ts +118 -98
- package/dist/testing.js +1 -1
- package/dist/themes/_template.css +1 -1
- package/dist/vite-plugin.d.ts +118 -98
- package/package.json +13 -13
- package/skills/app-shell-patterns/SKILL.md +108 -24
- package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +115 -0
- package/skills/app-shell-patterns/references/api/create-typed-paths.md +117 -0
- package/skills/app-shell-patterns/references/api/define-i18n-labels.md +143 -0
- package/skills/app-shell-patterns/references/api/define-module.md +247 -0
- package/skills/app-shell-patterns/references/api/define-resource.md +307 -0
- package/skills/app-shell-patterns/references/api/guards/hidden.md +202 -0
- package/skills/app-shell-patterns/references/api/guards/overview.md +354 -0
- package/skills/app-shell-patterns/references/api/guards/pass.md +129 -0
- package/skills/app-shell-patterns/references/api/guards/redirect-to.md +307 -0
- package/skills/app-shell-patterns/references/api/router/use-location.md +240 -0
- package/skills/app-shell-patterns/references/api/router/use-navigate.md +138 -0
- package/skills/app-shell-patterns/references/api/router/use-params.md +218 -0
- package/skills/app-shell-patterns/references/api/use-ai-chat.md +110 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-config.md +126 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-data.md +146 -0
- package/skills/app-shell-patterns/references/api/use-app-shell.md +143 -0
- package/skills/app-shell-patterns/references/api/use-auth.md +145 -0
- package/skills/app-shell-patterns/references/api/use-override-breadcrumb.md +74 -0
- package/skills/app-shell-patterns/references/api/use-page-meta.md +96 -0
- package/skills/app-shell-patterns/references/api/use-register-command-palette-actions.md +90 -0
- package/skills/app-shell-patterns/references/api/use-resolved-locale.md +67 -0
- package/skills/app-shell-patterns/references/api/use-route-error.md +214 -0
- package/skills/app-shell-patterns/references/api/use-theme.md +108 -0
- package/skills/app-shell-patterns/references/api/use-time-zone.md +80 -0
- package/skills/app-shell-patterns/references/api/use-toast.md +107 -0
- package/skills/app-shell-patterns/references/components/action-panel.md +168 -0
- package/skills/app-shell-patterns/references/components/activity-card.md +142 -0
- package/skills/app-shell-patterns/references/components/ai-chat.md +315 -0
- package/skills/app-shell-patterns/references/components/alert.md +202 -0
- package/skills/app-shell-patterns/references/components/app-shell.md +530 -0
- package/skills/app-shell-patterns/references/components/appearance-switcher.md +87 -0
- package/skills/app-shell-patterns/references/components/attachment.md +138 -0
- package/skills/app-shell-patterns/references/components/autocomplete.md +278 -0
- package/skills/app-shell-patterns/references/components/avatar.md +80 -0
- package/skills/app-shell-patterns/references/components/badge.md +309 -0
- package/skills/app-shell-patterns/references/components/button.md +164 -0
- package/skills/app-shell-patterns/references/components/card.md +109 -0
- package/skills/app-shell-patterns/references/components/checkbox.md +169 -0
- package/skills/app-shell-patterns/references/components/combobox.md +318 -0
- package/skills/app-shell-patterns/references/components/command-palette.md +413 -0
- package/skills/app-shell-patterns/references/components/csv-importer.md +214 -0
- package/skills/app-shell-patterns/references/components/data-table.md +953 -0
- package/skills/app-shell-patterns/references/components/date-picker.md +248 -0
- package/skills/app-shell-patterns/references/components/default-header.md +75 -0
- package/skills/app-shell-patterns/references/components/default-sidebar.md +136 -0
- package/skills/app-shell-patterns/references/components/description-card.md +569 -0
- package/skills/app-shell-patterns/references/components/dialog.md +164 -0
- package/skills/app-shell-patterns/references/components/document-progress-card.md +154 -0
- package/skills/app-shell-patterns/references/components/form.md +378 -0
- package/skills/app-shell-patterns/references/components/global-header-layout.md +132 -0
- package/skills/app-shell-patterns/references/components/grid.md +184 -0
- package/skills/app-shell-patterns/references/components/input.md +83 -0
- package/skills/app-shell-patterns/references/components/layout.md +539 -0
- package/skills/app-shell-patterns/references/components/menu.md +218 -0
- package/skills/app-shell-patterns/references/components/metric-card.md +94 -0
- package/skills/app-shell-patterns/references/components/select.md +283 -0
- package/skills/app-shell-patterns/references/components/sheet.md +237 -0
- package/skills/app-shell-patterns/references/components/sidebar-group.md +466 -0
- package/skills/app-shell-patterns/references/components/sidebar-item.md +458 -0
- package/skills/app-shell-patterns/references/components/sidebar-layout.md +258 -0
- package/skills/app-shell-patterns/references/components/spinner.md +81 -0
- package/skills/app-shell-patterns/references/components/table.md +188 -0
- package/skills/app-shell-patterns/references/components/tabs.md +158 -0
- package/skills/app-shell-patterns/references/components/textarea.md +122 -0
- package/skills/app-shell-patterns/references/components/timeline.md +317 -0
- package/skills/app-shell-patterns/references/components/toolbar.md +138 -0
- package/skills/app-shell-patterns/references/components/tooltip.md +144 -0
- package/skills/app-shell-patterns/references/components/with-guard.md +445 -0
- package/skills/app-shell-patterns/references/concepts/authentication.md +301 -0
- package/skills/app-shell-patterns/references/concepts/custom-components.md +59 -0
- package/skills/app-shell-patterns/references/concepts/file-based-routing.md +350 -0
- package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +11 -4
- package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
- package/skills/app-shell-patterns/references/concepts/routing-navigation.md +387 -0
- package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +388 -0
- package/skills/app-shell-patterns/references/{fundamental/design-system.md → concepts/styling-theming.md} +260 -105
- package/skills/app-shell-patterns/references/migrations.md +34 -0
- package/skills/app-shell-patterns/references/pages/document-detail.md +1125 -0
- package/skills/app-shell-patterns/references/patterns/form-composer.md +44 -46
- package/skills/app-shell-patterns/references/patterns/form-modal.md +39 -100
- package/skills/app-shell-patterns/references/patterns/form-sectioned.md +12 -38
- package/skills/app-shell-patterns/references/patterns/form-single-page.md +11 -32
- package/skills/app-shell-patterns/references/patterns/form-wizard.md +12 -53
- package/skills/app-shell-patterns/references/patterns/interaction-confirm.md +11 -27
- package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +14 -28
- package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
- package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +11 -86
- package/skills/app-shell-patterns/references/fundamental/components.md +0 -981
- package/skills/app-shell-patterns/references/patterns/detail-hero-with-actions.md +0 -201
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: defineModule
|
|
3
|
+
description: Define a top-level module that appears in the main navigation
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/define-module.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# defineModule
|
|
9
|
+
|
|
10
|
+
Creates a top-level module that appears in the main navigation. Modules can contain resources and optionally have their own landing page component.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
function defineModule(props: DefineModuleProps): Module;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Parameters
|
|
19
|
+
|
|
20
|
+
### `path`
|
|
21
|
+
|
|
22
|
+
- **Type:** `string`
|
|
23
|
+
- **Required:** Yes
|
|
24
|
+
- **Description:** URL path segment for the module
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
defineModule({
|
|
28
|
+
path: "products", // URL: /products
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### `component`
|
|
33
|
+
|
|
34
|
+
- **Type:** `(props: ResourceComponentProps) => React.ReactNode`
|
|
35
|
+
- **Required:** No
|
|
36
|
+
- **Description:** Landing page component for the module. If omitted, the module redirects to its first resource, and its breadcrumb segment is rendered as plain text (not a link).
|
|
37
|
+
|
|
38
|
+
**ResourceComponentProps:**
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
{
|
|
42
|
+
title: string; // Resolved title
|
|
43
|
+
icon?: React.ReactNode; // Module icon
|
|
44
|
+
resources?: Resource[]; // Child resources
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### `resources`
|
|
49
|
+
|
|
50
|
+
- **Type:** `Resource[]`
|
|
51
|
+
- **Required:** Yes
|
|
52
|
+
- **Description:** Array of resources within this module. Define using `defineResource()`.
|
|
53
|
+
|
|
54
|
+
### `meta`
|
|
55
|
+
|
|
56
|
+
- **Type:** `object`
|
|
57
|
+
- **Required:** No
|
|
58
|
+
- **Description:** Metadata configuration for the module
|
|
59
|
+
|
|
60
|
+
**meta.title**
|
|
61
|
+
|
|
62
|
+
- **Type:** `string | LocalizedString`
|
|
63
|
+
- **Default:** Capitalized `path`
|
|
64
|
+
- **Description:** Display title in navigation and breadcrumbs
|
|
65
|
+
|
|
66
|
+
**meta.icon**
|
|
67
|
+
|
|
68
|
+
- **Type:** `React.ReactNode`
|
|
69
|
+
- **Description:** Icon displayed in sidebar navigation
|
|
70
|
+
|
|
71
|
+
**meta.breadcrumbTitle**
|
|
72
|
+
|
|
73
|
+
- **Type:** `string | ((segment: string) => string)`
|
|
74
|
+
- **Description:** Custom breadcrumb segment title override
|
|
75
|
+
|
|
76
|
+
### `guards`
|
|
77
|
+
|
|
78
|
+
- **Type:** `Guard[]`
|
|
79
|
+
- **Required:** No
|
|
80
|
+
- **Description:** Access control guards executed in order. If any guard returns non-pass, access is denied.
|
|
81
|
+
|
|
82
|
+
See [Guards Overview](./guards/overview.md) for details.
|
|
83
|
+
|
|
84
|
+
### `errorBoundary`
|
|
85
|
+
|
|
86
|
+
- **Type:** `React.ReactNode`
|
|
87
|
+
- **Required:** No
|
|
88
|
+
- **Description:** Error boundary component for this module and its child resources. Use `useRouteError` hook to access error details.
|
|
89
|
+
|
|
90
|
+
## Return Type
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
Module;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
A module object that can be passed to the `modules` prop of `AppShell`.
|
|
97
|
+
|
|
98
|
+
## Examples
|
|
99
|
+
|
|
100
|
+
### Basic Module
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { defineModule } from "@tailor-platform/app-shell";
|
|
104
|
+
|
|
105
|
+
const dashboardModule = defineModule({
|
|
106
|
+
path: "dashboard",
|
|
107
|
+
component: () => <h1>Dashboard</h1>,
|
|
108
|
+
resources: [],
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Module with Icon and Title
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { Home } from "lucide-react";
|
|
116
|
+
|
|
117
|
+
const dashboardModule = defineModule({
|
|
118
|
+
path: "dashboard",
|
|
119
|
+
meta: {
|
|
120
|
+
title: "Dashboard",
|
|
121
|
+
icon: <Home />,
|
|
122
|
+
},
|
|
123
|
+
component: DashboardPage,
|
|
124
|
+
resources: [],
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Module with Resources
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const productsModule = defineModule({
|
|
132
|
+
path: "products",
|
|
133
|
+
component: ProductsListPage,
|
|
134
|
+
resources: [
|
|
135
|
+
defineResource({
|
|
136
|
+
path: ":id",
|
|
137
|
+
component: ProductDetailPage,
|
|
138
|
+
}),
|
|
139
|
+
defineResource({
|
|
140
|
+
path: "categories",
|
|
141
|
+
component: CategoriesPage,
|
|
142
|
+
}),
|
|
143
|
+
],
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Module without Component (Auto-redirect)
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
const dashboardModule = defineModule({
|
|
151
|
+
path: "dashboard",
|
|
152
|
+
// No component - automatically redirects to first resource
|
|
153
|
+
resources: [
|
|
154
|
+
defineResource({
|
|
155
|
+
path: "overview",
|
|
156
|
+
component: OverviewPage,
|
|
157
|
+
}),
|
|
158
|
+
defineResource({
|
|
159
|
+
path: "analytics",
|
|
160
|
+
component: AnalyticsPage,
|
|
161
|
+
}),
|
|
162
|
+
],
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Module with Guards
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { pass, hidden } from "@tailor-platform/app-shell";
|
|
170
|
+
|
|
171
|
+
const adminModule = defineModule({
|
|
172
|
+
path: "admin",
|
|
173
|
+
component: AdminPage,
|
|
174
|
+
resources: [adminResources],
|
|
175
|
+
guards: [
|
|
176
|
+
({ context }) => {
|
|
177
|
+
return context.currentUser?.role === "admin" ? pass() : hidden();
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Module with Error Boundary
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { useRouteError } from "@tailor-platform/app-shell";
|
|
187
|
+
|
|
188
|
+
const ErrorBoundary = () => {
|
|
189
|
+
const error = useRouteError() as Error;
|
|
190
|
+
return (
|
|
191
|
+
<div>
|
|
192
|
+
<h1>Module Error</h1>
|
|
193
|
+
<p>{error.message}</p>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const productsModule = defineModule({
|
|
199
|
+
path: "products",
|
|
200
|
+
component: ProductsPage,
|
|
201
|
+
resources: [],
|
|
202
|
+
errorBoundary: <ErrorBoundary />,
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Module with Internationalization
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { defineI18nLabels } from "@tailor-platform/app-shell";
|
|
210
|
+
|
|
211
|
+
const labels = defineI18nLabels({
|
|
212
|
+
dashboard: {
|
|
213
|
+
en: "Dashboard",
|
|
214
|
+
ja: "ダッシュボード",
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const dashboardModule = defineModule({
|
|
219
|
+
path: "dashboard",
|
|
220
|
+
meta: {
|
|
221
|
+
title: labels.t("dashboard"),
|
|
222
|
+
},
|
|
223
|
+
component: DashboardPage,
|
|
224
|
+
resources: [],
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## TypeScript
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { type DefineModuleProps, type Module } from "@tailor-platform/app-shell";
|
|
232
|
+
|
|
233
|
+
const props: DefineModuleProps = {
|
|
234
|
+
path: "products",
|
|
235
|
+
component: ProductsPage,
|
|
236
|
+
resources: [],
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const module: Module = defineModule(props);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Related
|
|
243
|
+
|
|
244
|
+
- [defineResource](./define-resource.md) - Define nested resources
|
|
245
|
+
- [Guards Overview](./guards/overview.md) - Access control
|
|
246
|
+
- [defineI18nLabels](./define-i18n-labels.md) - Internationalization
|
|
247
|
+
- [Modules & Resources Concept](../concepts/modules-and-resources.md) - Detailed guide
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: defineResource
|
|
3
|
+
description: Define a nested resource (page) within a module
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/define-resource.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# defineResource
|
|
9
|
+
|
|
10
|
+
Creates a nested resource (page) within a module. Resources represent individual pages in your application hierarchy.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
function defineResource(props: DefineResourceProps): Resource;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Parameters
|
|
19
|
+
|
|
20
|
+
### `path`
|
|
21
|
+
|
|
22
|
+
- **Type:** `string`
|
|
23
|
+
- **Required:** Yes
|
|
24
|
+
- **Description:** URL path segment for the resource. Supports dynamic parameters with `:param` syntax.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
defineResource({
|
|
28
|
+
path: ":id", // Dynamic: /products/:id
|
|
29
|
+
path: "categories", // Static: /products/categories
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### `component`
|
|
34
|
+
|
|
35
|
+
- **Type:** `(props: ResourceComponentProps) => React.ReactNode`
|
|
36
|
+
- **Required:** Yes
|
|
37
|
+
- **Description:** Page component to render
|
|
38
|
+
|
|
39
|
+
**ResourceComponentProps:**
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
{
|
|
43
|
+
title: string; // Resolved title
|
|
44
|
+
icon?: React.ReactNode; // Inherited from module
|
|
45
|
+
resources?: Resource[]; // Child resources
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `meta`
|
|
50
|
+
|
|
51
|
+
- **Type:** `object`
|
|
52
|
+
- **Required:** No
|
|
53
|
+
- **Description:** Metadata configuration
|
|
54
|
+
|
|
55
|
+
**meta.title**
|
|
56
|
+
|
|
57
|
+
- **Type:** `string | LocalizedString`
|
|
58
|
+
- **Default:** Capitalized `path`
|
|
59
|
+
- **Description:** Display title in navigation and breadcrumbs
|
|
60
|
+
|
|
61
|
+
**meta.icon**
|
|
62
|
+
|
|
63
|
+
- **Type:** `React.ReactNode`
|
|
64
|
+
- **Description:** Icon override (inherits from module by default)
|
|
65
|
+
|
|
66
|
+
**meta.breadcrumbTitle**
|
|
67
|
+
|
|
68
|
+
- **Type:** `string | ((segment: string) => string)`
|
|
69
|
+
- **Description:** Custom breadcrumb segment title
|
|
70
|
+
|
|
71
|
+
### `subResources`
|
|
72
|
+
|
|
73
|
+
- **Type:** `Resource[]`
|
|
74
|
+
- **Required:** No
|
|
75
|
+
- **Description:** Nested resources within this resource
|
|
76
|
+
|
|
77
|
+
### `guards`
|
|
78
|
+
|
|
79
|
+
- **Type:** `Guard[]`
|
|
80
|
+
- **Required:** No
|
|
81
|
+
- **Description:** Access control guards
|
|
82
|
+
|
|
83
|
+
See [Guards Overview](./guards/overview.md) for details.
|
|
84
|
+
|
|
85
|
+
### `errorBoundary`
|
|
86
|
+
|
|
87
|
+
- **Type:** `React.ReactNode`
|
|
88
|
+
- **Required:** No
|
|
89
|
+
- **Description:** Error boundary component for this resource
|
|
90
|
+
|
|
91
|
+
## Return Type
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
Resource;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
A resource object used in the `resources` array of `defineModule`.
|
|
98
|
+
|
|
99
|
+
## Examples
|
|
100
|
+
|
|
101
|
+
### Basic Resource
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { defineResource } from "@tailor-platform/app-shell";
|
|
105
|
+
|
|
106
|
+
const detailResource = defineResource({
|
|
107
|
+
path: ":id",
|
|
108
|
+
component: () => <div>Detail Page</div>,
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Resource with Title
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const categoriesResource = defineResource({
|
|
116
|
+
path: "categories",
|
|
117
|
+
meta: {
|
|
118
|
+
title: "Product Categories",
|
|
119
|
+
},
|
|
120
|
+
component: CategoriesPage,
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Dynamic Route with useParams
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { useParams } from "@tailor-platform/app-shell";
|
|
128
|
+
|
|
129
|
+
const productDetailResource = defineResource({
|
|
130
|
+
path: ":id",
|
|
131
|
+
meta: {
|
|
132
|
+
title: "Product Details",
|
|
133
|
+
},
|
|
134
|
+
component: () => {
|
|
135
|
+
const { id } = useParams();
|
|
136
|
+
return <div>Product {id}</div>;
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Nested Resources
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const ordersResource = defineResource({
|
|
145
|
+
path: "orders",
|
|
146
|
+
component: OrdersListPage,
|
|
147
|
+
subResources: [
|
|
148
|
+
defineResource({
|
|
149
|
+
path: ":id",
|
|
150
|
+
component: OrderDetailPage,
|
|
151
|
+
subResources: [
|
|
152
|
+
defineResource({
|
|
153
|
+
path: "edit",
|
|
154
|
+
component: OrderEditPage,
|
|
155
|
+
}),
|
|
156
|
+
],
|
|
157
|
+
}),
|
|
158
|
+
],
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// URLs:
|
|
162
|
+
// /orders
|
|
163
|
+
// /orders/:id
|
|
164
|
+
// /orders/:id/edit
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Resource with Guards
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { pass, hidden } from "@tailor-platform/app-shell";
|
|
171
|
+
|
|
172
|
+
const adminSettingsResource = defineResource({
|
|
173
|
+
path: "admin-settings",
|
|
174
|
+
component: AdminSettingsPage,
|
|
175
|
+
guards: [
|
|
176
|
+
({ context }) => {
|
|
177
|
+
return context.currentUser?.role === "admin" ? pass() : hidden();
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Resource with Error Boundary
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { useRouteError } from "@tailor-platform/app-shell";
|
|
187
|
+
|
|
188
|
+
const ErrorBoundary = () => {
|
|
189
|
+
const error = useRouteError() as Error;
|
|
190
|
+
return <div>Error: {error.message}</div>;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const detailResource = defineResource({
|
|
194
|
+
path: ":id",
|
|
195
|
+
component: DetailPage,
|
|
196
|
+
errorBoundary: <ErrorBoundary />,
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Resource with Custom Breadcrumb
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const orderResource = defineResource({
|
|
204
|
+
path: ":id",
|
|
205
|
+
meta: {
|
|
206
|
+
breadcrumbTitle: (segment) => `Order #${segment}`,
|
|
207
|
+
},
|
|
208
|
+
component: OrderDetailPage,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Breadcrumb shows: "Orders > Order #12345"
|
|
212
|
+
// Instead of: "Orders > 12345"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Multiple Resources
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
const productsModule = defineModule({
|
|
219
|
+
path: "products",
|
|
220
|
+
component: ProductsPage,
|
|
221
|
+
resources: [
|
|
222
|
+
defineResource({
|
|
223
|
+
path: ":id",
|
|
224
|
+
meta: { title: "Product Details" },
|
|
225
|
+
component: ProductDetailPage,
|
|
226
|
+
}),
|
|
227
|
+
defineResource({
|
|
228
|
+
path: "categories",
|
|
229
|
+
meta: { title: "Categories" },
|
|
230
|
+
component: CategoriesPage,
|
|
231
|
+
}),
|
|
232
|
+
defineResource({
|
|
233
|
+
path: "brands",
|
|
234
|
+
meta: { title: "Brands" },
|
|
235
|
+
component: BrandsPage,
|
|
236
|
+
}),
|
|
237
|
+
],
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Navigation Behavior
|
|
242
|
+
|
|
243
|
+
Resources appear in:
|
|
244
|
+
|
|
245
|
+
- ✅ Sidebar navigation (top-level resources only)
|
|
246
|
+
- ✅ Breadcrumbs (all levels)
|
|
247
|
+
- ✅ CommandPalette search (all levels)
|
|
248
|
+
- ❌ Main navigation menu (use modules instead)
|
|
249
|
+
|
|
250
|
+
### Example Navigation
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
defineModule({
|
|
254
|
+
path: "products",
|
|
255
|
+
component: ProductsPage,
|
|
256
|
+
resources: [
|
|
257
|
+
defineResource({
|
|
258
|
+
path: "all",
|
|
259
|
+
component: AllProductsPage, // Appears in sidebar
|
|
260
|
+
}),
|
|
261
|
+
defineResource({
|
|
262
|
+
path: ":id",
|
|
263
|
+
component: ProductDetailPage,
|
|
264
|
+
subResources: [
|
|
265
|
+
defineResource({
|
|
266
|
+
path: "edit",
|
|
267
|
+
component: EditPage, // Only in breadcrumbs, not sidebar
|
|
268
|
+
}),
|
|
269
|
+
],
|
|
270
|
+
}),
|
|
271
|
+
],
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Sidebar:**
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
› Products
|
|
279
|
+
- All Products
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Breadcrumbs (on edit page):**
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
Products > Product Details > Edit
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## TypeScript
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
import { type DefineResourceProps, type Resource } from "@tailor-platform/app-shell";
|
|
292
|
+
|
|
293
|
+
const props: DefineResourceProps = {
|
|
294
|
+
path: ":id",
|
|
295
|
+
component: DetailPage,
|
|
296
|
+
guards: [],
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const resource: Resource = defineResource(props);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Related
|
|
303
|
+
|
|
304
|
+
- [defineModule](./define-module.md) - Define top-level modules
|
|
305
|
+
- [Guards Overview](./guards/overview.md) - Access control
|
|
306
|
+
- [useParams](./router/use-params.md) - Access route parameters
|
|
307
|
+
- [Modules & Resources Concept](../concepts/modules-and-resources.md) - Detailed guide
|