@tailor-platform/app-shell 1.15.0 → 1.17.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/dist/app-shell-core.css +1 -1
- package/dist/app-shell.d.ts +811 -131
- package/dist/app-shell.js +7155 -5797
- package/dist/{appshell-DLVBFo5J.js → appshell-CahhZy7v.js} +656 -524
- package/dist/semantic-contrast.test.ts +154 -0
- package/dist/style-entry.d.ts +147 -92
- package/dist/testing.d.ts +152 -95
- package/dist/testing.js +1 -1
- package/dist/theme-bridge.test.ts +101 -1
- package/dist/theme.bridge.css +91 -0
- package/dist/theme.css +6 -1
- package/dist/themes/_template.css +7 -1
- package/dist/themes/bloom.css +0 -6
- package/dist/themes/cream.css +0 -6
- package/dist/themes/default.css +389 -69
- package/dist/vite-plugin.d.ts +147 -92
- package/package.json +8 -8
- package/skills/app-shell-patterns/SKILL.md +108 -19
- 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 +132 -0
- package/skills/app-shell-patterns/references/api/use-app-shell-data.md +150 -0
- package/skills/app-shell-patterns/references/api/use-app-shell.md +150 -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 +104 -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 +181 -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 +1168 -0
- package/skills/app-shell-patterns/references/components/date-picker.md +259 -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/filter-rail.md +165 -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 +472 -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/sidebar-section.md +114 -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 +356 -0
- package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +31 -18
- package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
- package/skills/app-shell-patterns/references/concepts/routing-navigation.md +425 -0
- package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +420 -0
- package/skills/app-shell-patterns/references/concepts/styling-theming.md +785 -0
- package/skills/app-shell-patterns/references/migrations.md +55 -0
- package/skills/app-shell-patterns/references/pages/{detail.md → document-detail.md} +10 -33
- package/skills/app-shell-patterns/references/patterns/form-composer.md +43 -45
- package/skills/app-shell-patterns/references/patterns/form-modal.md +37 -92
- 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 +136 -139
- package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
- package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +13 -88
- package/skills/app-shell-patterns/references/fundamental/components.md +0 -1009
- package/skills/app-shell-patterns/references/fundamental/design-system.md +0 -440
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useParams
|
|
3
|
+
description: Hook to access dynamic route parameters
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/router/use-params.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# useParams
|
|
9
|
+
|
|
10
|
+
React Router hook to access dynamic route parameters from the URL. Re-exported from `react-router` for convenience.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const useParams: <T extends Record<string, string>>() => T;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Access Single Parameter
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { useParams } from "@tailor-platform/app-shell";
|
|
24
|
+
|
|
25
|
+
// Route: /products/:id
|
|
26
|
+
function ProductDetail() {
|
|
27
|
+
const { id } = useParams();
|
|
28
|
+
|
|
29
|
+
return <div>Product ID: {id}</div>;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Multiple Parameters
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// Route: /categories/:category/products/:id
|
|
37
|
+
function ProductInCategory() {
|
|
38
|
+
const { category, id } = useParams();
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div>
|
|
42
|
+
Category: {category}
|
|
43
|
+
<br />
|
|
44
|
+
Product ID: {id}
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### With Data Fetching
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
function OrderDetail() {
|
|
54
|
+
const { id } = useParams();
|
|
55
|
+
const [order, setOrder] = useState(null);
|
|
56
|
+
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
fetch(`/api/orders/${id}`)
|
|
59
|
+
.then(r => r.json())
|
|
60
|
+
.then(setOrder);
|
|
61
|
+
}, [id]);
|
|
62
|
+
|
|
63
|
+
return <div>Order #{id}</div>;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### TypeScript with Type Safety
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { useParams } from "@tailor-platform/app-shell";
|
|
71
|
+
|
|
72
|
+
interface ProductParams {
|
|
73
|
+
id: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function ProductDetail() {
|
|
77
|
+
const { id } = useParams<ProductParams>();
|
|
78
|
+
// ^ type: string
|
|
79
|
+
|
|
80
|
+
return <div>Product {id}</div>;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Route Definition
|
|
85
|
+
|
|
86
|
+
Parameters are defined in `defineResource` using `:param` syntax:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { defineModule, defineResource } from "@tailor-platform/app-shell";
|
|
90
|
+
|
|
91
|
+
const productsModule = defineModule({
|
|
92
|
+
path: "products",
|
|
93
|
+
component: ProductsList,
|
|
94
|
+
resources: [
|
|
95
|
+
defineResource({
|
|
96
|
+
path: ":id", // ← Dynamic parameter
|
|
97
|
+
component: () => {
|
|
98
|
+
const { id } = useParams(); // Access here
|
|
99
|
+
return <div>Product {id}</div>;
|
|
100
|
+
},
|
|
101
|
+
}),
|
|
102
|
+
],
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Nested Parameters
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const ordersModule = defineModule({
|
|
110
|
+
path: "orders",
|
|
111
|
+
component: OrdersList,
|
|
112
|
+
resources: [
|
|
113
|
+
defineResource({
|
|
114
|
+
path: ":orderId",
|
|
115
|
+
component: OrderDetail,
|
|
116
|
+
subResources: [
|
|
117
|
+
defineResource({
|
|
118
|
+
path: "items/:itemId",
|
|
119
|
+
component: () => {
|
|
120
|
+
const { orderId, itemId } = useParams();
|
|
121
|
+
return <div>Order {orderId}, Item {itemId}</div>;
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
],
|
|
125
|
+
}),
|
|
126
|
+
],
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// URL: /orders/123/items/456
|
|
130
|
+
// useParams() returns: { orderId: "123", itemId: "456" }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Important Notes
|
|
134
|
+
|
|
135
|
+
### Always Import from AppShell
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// ✅ Correct
|
|
139
|
+
import { useParams } from "@tailor-platform/app-shell";
|
|
140
|
+
|
|
141
|
+
// ❌ Wrong - won't work with AppShell's router
|
|
142
|
+
import { useParams } from "react-router";
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Parameters are Always Strings
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const { id } = useParams();
|
|
149
|
+
// id is always a string, even for numeric IDs
|
|
150
|
+
|
|
151
|
+
// Convert if needed:
|
|
152
|
+
const numericId = parseInt(id, 10);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Optional Parameters
|
|
156
|
+
|
|
157
|
+
For optional parameters, check for undefined:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
const { filter } = useParams();
|
|
161
|
+
|
|
162
|
+
if (filter) {
|
|
163
|
+
// Filter is provided
|
|
164
|
+
} else {
|
|
165
|
+
// Filter is optional and not provided
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Examples
|
|
170
|
+
|
|
171
|
+
### Edit Page
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// Route: /products/:id/edit
|
|
175
|
+
function ProductEdit() {
|
|
176
|
+
const { id } = useParams();
|
|
177
|
+
const [product, setProduct] = useState(null);
|
|
178
|
+
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
loadProduct(id).then(setProduct);
|
|
181
|
+
}, [id]);
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<form>
|
|
185
|
+
<h1>Edit Product {id}</h1>
|
|
186
|
+
{/* form fields */}
|
|
187
|
+
</form>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Delete Confirmation
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
function DeleteConfirmation() {
|
|
196
|
+
const { id } = useParams();
|
|
197
|
+
const navigate = useNavigate();
|
|
198
|
+
|
|
199
|
+
const handleDelete = async () => {
|
|
200
|
+
await deleteProduct(id);
|
|
201
|
+
navigate("/products");
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div>
|
|
206
|
+
<p>Delete product {id}?</p>
|
|
207
|
+
<button onClick={handleDelete}>Confirm</button>
|
|
208
|
+
</div>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Related
|
|
214
|
+
|
|
215
|
+
- [useNavigate](./use-navigate.md) - Programmatic navigation
|
|
216
|
+
- [useLocation](./use-location.md) - Access current location
|
|
217
|
+
- [defineResource](../define-resource.md) - Define routes with parameters
|
|
218
|
+
- [Routing & Navigation](../../concepts/routing-navigation.md) - Navigation guide
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useAIChat
|
|
3
|
+
description: Simple text-only chat hook for AI Gateway
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/use-ai-chat.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# useAIChat
|
|
9
|
+
|
|
10
|
+
React hook for simple text-only chat on top of `createAIGatewayClient`.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const useAIChat: (config: { client: AIGatewayClient; model: string }) => {
|
|
16
|
+
messages: AIChatMessage[];
|
|
17
|
+
status: "ready" | "submitted" | "streaming" | "error";
|
|
18
|
+
error?: Error;
|
|
19
|
+
sendMessage: (message: string) => Promise<boolean>;
|
|
20
|
+
stop: () => void;
|
|
21
|
+
};
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Return Value
|
|
25
|
+
|
|
26
|
+
### `messages`
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
interface AIChatMessage {
|
|
30
|
+
id: string;
|
|
31
|
+
role: "user" | "assistant";
|
|
32
|
+
content: string;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### `status`
|
|
37
|
+
|
|
38
|
+
- **Type:** `"ready" | "submitted" | "streaming" | "error"`
|
|
39
|
+
- **Description:** Current request state
|
|
40
|
+
|
|
41
|
+
### `error`
|
|
42
|
+
|
|
43
|
+
- **Type:** `Error | undefined`
|
|
44
|
+
- **Description:** Last request error, if any
|
|
45
|
+
|
|
46
|
+
### `sendMessage()`
|
|
47
|
+
|
|
48
|
+
- **Type:** `(message: string) => Promise<boolean>`
|
|
49
|
+
- **Description:** Appends a user message and streams the assistant response
|
|
50
|
+
- **Returns:** `true` when the request completes successfully, `false` when the call is ignored, stopped, or fails
|
|
51
|
+
|
|
52
|
+
### `stop()`
|
|
53
|
+
|
|
54
|
+
- **Type:** `() => void`
|
|
55
|
+
- **Description:** Aborts the current request if one is in progress
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { createAuthClient, createAIGatewayClient, useAIChat } from "@tailor-platform/app-shell";
|
|
61
|
+
|
|
62
|
+
const authClient = createAuthClient({
|
|
63
|
+
clientId: "your-client-id",
|
|
64
|
+
appUri: "https://xyz.erp.dev",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const aiClient = createAIGatewayClient({
|
|
68
|
+
gatewayUri: "https://your-ai-gateway.example.com",
|
|
69
|
+
authClient,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export function ChatScreen() {
|
|
73
|
+
const { messages, sendMessage, status, stop, error } = useAIChat({
|
|
74
|
+
client: aiClient,
|
|
75
|
+
model: "gpt-5-mini",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div>
|
|
80
|
+
{messages.map((message) => (
|
|
81
|
+
<div key={message.id}>
|
|
82
|
+
{message.role}: {message.content}
|
|
83
|
+
</div>
|
|
84
|
+
))}
|
|
85
|
+
|
|
86
|
+
<button
|
|
87
|
+
onClick={() => void sendMessage("Hello")}
|
|
88
|
+
disabled={status === "submitted" || status === "streaming"}
|
|
89
|
+
>
|
|
90
|
+
Send
|
|
91
|
+
</button>
|
|
92
|
+
<button onClick={stop} disabled={status !== "submitted" && status !== "streaming"}>
|
|
93
|
+
Stop
|
|
94
|
+
</button>
|
|
95
|
+
{error ? <div>{error.message}</div> : null}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Notes
|
|
102
|
+
|
|
103
|
+
- AppShell chooses the appropriate AI Gateway transport automatically
|
|
104
|
+
- The hook is intentionally text-only
|
|
105
|
+
- System prompts and custom history shaping should use the low-level client directly
|
|
106
|
+
- `stop()` keeps any already-streamed assistant text and ignores late chunks from the stopped request
|
|
107
|
+
|
|
108
|
+
## Related
|
|
109
|
+
|
|
110
|
+
- [createAIGatewayClient](./create-ai-gateway-client.md)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useAppShellConfig
|
|
3
|
+
description: Hook to access AppShell configuration data
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/use-app-shell-config.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# useAppShellConfig
|
|
9
|
+
|
|
10
|
+
React hook to access only the AppShell configuration (title, icon, favicon, appInfo, and the resolved `configurations` object with modules, settingsResources, basePath, locale, and timeZone). This is a lighter alternative to `useAppShell` when you only need configuration data.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const useAppShellConfig: () => {
|
|
16
|
+
title?: string;
|
|
17
|
+
icon?: React.ReactNode;
|
|
18
|
+
favicon?: string;
|
|
19
|
+
appInfo?: AppInfo;
|
|
20
|
+
configurations: {
|
|
21
|
+
modules: ReturnType<typeof defineModule>[];
|
|
22
|
+
settingsResources: ReturnType<typeof defineResource>[];
|
|
23
|
+
basePath?: string;
|
|
24
|
+
locale: string;
|
|
25
|
+
resolvedLocale?: string;
|
|
26
|
+
timeZone?: string;
|
|
27
|
+
errorBoundary: ErrorBoundaryComponent;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Return Value
|
|
33
|
+
|
|
34
|
+
| Property | Type | Description |
|
|
35
|
+
| ---------------- | ------------------------------ | ------------------------------------------------ |
|
|
36
|
+
| `title` | `string \| undefined` | App title |
|
|
37
|
+
| `icon` | `React.ReactNode \| undefined` | App icon |
|
|
38
|
+
| `favicon` | `string \| undefined` | Favicon URL |
|
|
39
|
+
| `appInfo` | `AppInfo \| undefined` | Configuration for the built-in `/__appinfo` page |
|
|
40
|
+
| `configurations` | object | Resolved configuration, see below |
|
|
41
|
+
|
|
42
|
+
### `configurations`
|
|
43
|
+
|
|
44
|
+
| Property | Type | Description |
|
|
45
|
+
| ------------------- | ------------------------------------- | ----------------------------------------------------- |
|
|
46
|
+
| `modules` | `ReturnType<typeof defineModule>[]` | Registered modules (`Module` itself is not exported) |
|
|
47
|
+
| `settingsResources` | `ReturnType<typeof defineResource>[]` | Resources that appear only in Settings menu |
|
|
48
|
+
| `basePath` | `string \| undefined` | Base path for all routes |
|
|
49
|
+
| `locale` | `string` | Language subtag used for built-in UI strings (`"en"`) |
|
|
50
|
+
| `resolvedLocale` | `string \| undefined` | Full BCP-47 tag used for Intl / date formatting |
|
|
51
|
+
| `timeZone` | `string \| undefined` | IANA timezone used by date/time components |
|
|
52
|
+
| `errorBoundary` | `ErrorBoundaryComponent` | Global error boundary element |
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
### Display App Info
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { useAppShellConfig } from "@tailor-platform/app-shell";
|
|
60
|
+
|
|
61
|
+
function AppInfo() {
|
|
62
|
+
const { title, configurations } = useAppShellConfig();
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div>
|
|
66
|
+
<h2>{title}</h2>
|
|
67
|
+
<p>Base: {configurations.basePath}</p>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Access Modules
|
|
74
|
+
|
|
75
|
+
Module titles are `LocalizedString` values (a string or a `(locale) => string` function), so the example lists `path` instead of rendering `meta.title` directly.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
function ModuleList() {
|
|
79
|
+
const { configurations } = useAppShellConfig();
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<ul>
|
|
83
|
+
{configurations.modules.map((module) => (
|
|
84
|
+
<li key={module.path}>{module.path}</li>
|
|
85
|
+
))}
|
|
86
|
+
</ul>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Settings Resources
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
function SettingsMenu() {
|
|
95
|
+
const { configurations } = useAppShellConfig();
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div>
|
|
99
|
+
<h3>Settings</h3>
|
|
100
|
+
{configurations.settingsResources.map((resource) => (
|
|
101
|
+
<button key={resource.path}>{resource.path}</button>
|
|
102
|
+
))}
|
|
103
|
+
</div>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## When to Use
|
|
109
|
+
|
|
110
|
+
Use `useAppShellConfig` when you only need configuration data:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// ✅ Good - subscribes to configuration only
|
|
114
|
+
const { configurations } = useAppShellConfig();
|
|
115
|
+
|
|
116
|
+
// ❌ Overkill - useAppShell also subscribes to contextData changes
|
|
117
|
+
const { configurations } = useAppShell();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Comparison with Other Hooks
|
|
121
|
+
|
|
122
|
+
| Hook | Returns | Use When |
|
|
123
|
+
| ------------------- | --------------------------------------------------- | ------------------- |
|
|
124
|
+
| `useAppShellConfig` | `{ title, icon, favicon, appInfo, configurations }` | Need config data |
|
|
125
|
+
| `useAppShellData` | `{ contextData }` | Need custom context |
|
|
126
|
+
| `useAppShell` | Both, merged into one object | Need both |
|
|
127
|
+
|
|
128
|
+
## Related
|
|
129
|
+
|
|
130
|
+
- [useAppShell](./use-app-shell.md) - Full context access
|
|
131
|
+
- [useAppShellData](./use-app-shell-data.md) - Context data only
|
|
132
|
+
- [AppShell Component](../components/app-shell.md) - Root component
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useAppShellData
|
|
3
|
+
description: Hook to access custom context data passed to AppShell
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/use-app-shell-data.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# useAppShellData
|
|
9
|
+
|
|
10
|
+
React hook to access only the custom context data. This is a lighter alternative to `useAppShell` when you only need the contextData.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const useAppShellData: () => {
|
|
16
|
+
contextData: ContextData;
|
|
17
|
+
};
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Return Value
|
|
21
|
+
|
|
22
|
+
| Property | Type | Description |
|
|
23
|
+
| ------------- | ------------- | ------------------------------------------------------------------------- |
|
|
24
|
+
| `contextData` | `ContextData` | Custom context data passed to AppShell (type-safe via `AppShellRegister`) |
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Basic Access
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { useAppShellData } from "@tailor-platform/app-shell";
|
|
32
|
+
|
|
33
|
+
function UserProfile() {
|
|
34
|
+
const { contextData } = useAppShellData();
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div>
|
|
38
|
+
<p>Welcome, {contextData.currentUser?.name}</p>
|
|
39
|
+
<p>Role: {contextData.currentUser?.role}</p>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Display User Info
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
function UserInfo() {
|
|
49
|
+
const { contextData } = useAppShellData();
|
|
50
|
+
|
|
51
|
+
if (!contextData.currentUser) {
|
|
52
|
+
return <div>Not logged in</div>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div>
|
|
57
|
+
<h2>{contextData.currentUser.name}</h2>
|
|
58
|
+
<p>{contextData.currentUser.email}</p>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Check Permissions
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
function AdminPanel() {
|
|
68
|
+
const { contextData } = useAppShellData();
|
|
69
|
+
const canManageUsers = contextData.permissions.includes("users:manage");
|
|
70
|
+
|
|
71
|
+
if (!canManageUsers) {
|
|
72
|
+
return <AccessDenied />;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return <UserManagement />;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Feature Flags
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
function BetaFeature() {
|
|
83
|
+
const { contextData } = useAppShellData();
|
|
84
|
+
|
|
85
|
+
if (!contextData.featureFlags?.newEditor) {
|
|
86
|
+
return <LegacyEditor />;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return <NewEditor />;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Type Safety
|
|
94
|
+
|
|
95
|
+
Define your context type with module augmentation:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// types.d.ts
|
|
99
|
+
type User = { name: string; email: string; role: string };
|
|
100
|
+
|
|
101
|
+
declare module "@tailor-platform/app-shell" {
|
|
102
|
+
interface AppShellRegister {
|
|
103
|
+
contextData: {
|
|
104
|
+
currentUser: User | null;
|
|
105
|
+
permissions: string[];
|
|
106
|
+
tenantId: string;
|
|
107
|
+
featureFlags: {
|
|
108
|
+
newEditor: boolean;
|
|
109
|
+
betaDashboard: boolean;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Now `useAppShellData()` returns fully typed data:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const { contextData } = useAppShellData();
|
|
120
|
+
contextData.currentUser; // Type: User | null
|
|
121
|
+
contextData.permissions; // Type: string[]
|
|
122
|
+
contextData.featureFlags; // Type: { newEditor: boolean, betaDashboard: boolean }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## When to Use
|
|
126
|
+
|
|
127
|
+
Use `useAppShellData` when you only need context data:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// ✅ Good - subscribes to context data only
|
|
131
|
+
const { contextData } = useAppShellData();
|
|
132
|
+
|
|
133
|
+
// ❌ Overkill - useAppShell also subscribes to configuration changes
|
|
134
|
+
const { contextData } = useAppShell();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Comparison with Other Hooks
|
|
138
|
+
|
|
139
|
+
| Hook | Returns | Use When |
|
|
140
|
+
| ------------------- | --------------------------------------------------- | ------------------- |
|
|
141
|
+
| `useAppShellData` | `{ contextData }` | Need custom context |
|
|
142
|
+
| `useAppShellConfig` | `{ title, icon, favicon, appInfo, configurations }` | Need config data |
|
|
143
|
+
| `useAppShell` | Both, merged into one object | Need both |
|
|
144
|
+
|
|
145
|
+
## Related
|
|
146
|
+
|
|
147
|
+
- [useAppShell](./use-app-shell.md) - Full context access
|
|
148
|
+
- [useAppShellConfig](./use-app-shell-config.md) - Configuration only
|
|
149
|
+
- [AppShell Component](../components/app-shell.md) - Root component
|
|
150
|
+
- [Guards Overview](./guards/overview.md) - Using context in guards
|