@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.
Files changed (109) hide show
  1. package/dist/app-shell-core.css +1 -1
  2. package/dist/app-shell.d.ts +811 -131
  3. package/dist/app-shell.js +7155 -5797
  4. package/dist/{appshell-DLVBFo5J.js → appshell-CahhZy7v.js} +656 -524
  5. package/dist/semantic-contrast.test.ts +154 -0
  6. package/dist/style-entry.d.ts +147 -92
  7. package/dist/testing.d.ts +152 -95
  8. package/dist/testing.js +1 -1
  9. package/dist/theme-bridge.test.ts +101 -1
  10. package/dist/theme.bridge.css +91 -0
  11. package/dist/theme.css +6 -1
  12. package/dist/themes/_template.css +7 -1
  13. package/dist/themes/bloom.css +0 -6
  14. package/dist/themes/cream.css +0 -6
  15. package/dist/themes/default.css +389 -69
  16. package/dist/vite-plugin.d.ts +147 -92
  17. package/package.json +8 -8
  18. package/skills/app-shell-patterns/SKILL.md +108 -19
  19. package/skills/app-shell-patterns/references/api/create-ai-gateway-client.md +115 -0
  20. package/skills/app-shell-patterns/references/api/create-typed-paths.md +117 -0
  21. package/skills/app-shell-patterns/references/api/define-i18n-labels.md +143 -0
  22. package/skills/app-shell-patterns/references/api/define-module.md +247 -0
  23. package/skills/app-shell-patterns/references/api/define-resource.md +307 -0
  24. package/skills/app-shell-patterns/references/api/guards/hidden.md +202 -0
  25. package/skills/app-shell-patterns/references/api/guards/overview.md +354 -0
  26. package/skills/app-shell-patterns/references/api/guards/pass.md +129 -0
  27. package/skills/app-shell-patterns/references/api/guards/redirect-to.md +307 -0
  28. package/skills/app-shell-patterns/references/api/router/use-location.md +240 -0
  29. package/skills/app-shell-patterns/references/api/router/use-navigate.md +138 -0
  30. package/skills/app-shell-patterns/references/api/router/use-params.md +218 -0
  31. package/skills/app-shell-patterns/references/api/use-ai-chat.md +110 -0
  32. package/skills/app-shell-patterns/references/api/use-app-shell-config.md +132 -0
  33. package/skills/app-shell-patterns/references/api/use-app-shell-data.md +150 -0
  34. package/skills/app-shell-patterns/references/api/use-app-shell.md +150 -0
  35. package/skills/app-shell-patterns/references/api/use-auth.md +145 -0
  36. package/skills/app-shell-patterns/references/api/use-override-breadcrumb.md +74 -0
  37. package/skills/app-shell-patterns/references/api/use-page-meta.md +96 -0
  38. package/skills/app-shell-patterns/references/api/use-register-command-palette-actions.md +90 -0
  39. package/skills/app-shell-patterns/references/api/use-resolved-locale.md +67 -0
  40. package/skills/app-shell-patterns/references/api/use-route-error.md +214 -0
  41. package/skills/app-shell-patterns/references/api/use-theme.md +108 -0
  42. package/skills/app-shell-patterns/references/api/use-time-zone.md +80 -0
  43. package/skills/app-shell-patterns/references/api/use-toast.md +104 -0
  44. package/skills/app-shell-patterns/references/components/action-panel.md +168 -0
  45. package/skills/app-shell-patterns/references/components/activity-card.md +142 -0
  46. package/skills/app-shell-patterns/references/components/ai-chat.md +315 -0
  47. package/skills/app-shell-patterns/references/components/alert.md +202 -0
  48. package/skills/app-shell-patterns/references/components/app-shell.md +530 -0
  49. package/skills/app-shell-patterns/references/components/appearance-switcher.md +87 -0
  50. package/skills/app-shell-patterns/references/components/attachment.md +138 -0
  51. package/skills/app-shell-patterns/references/components/autocomplete.md +278 -0
  52. package/skills/app-shell-patterns/references/components/avatar.md +80 -0
  53. package/skills/app-shell-patterns/references/components/badge.md +309 -0
  54. package/skills/app-shell-patterns/references/components/button.md +164 -0
  55. package/skills/app-shell-patterns/references/components/card.md +181 -0
  56. package/skills/app-shell-patterns/references/components/checkbox.md +169 -0
  57. package/skills/app-shell-patterns/references/components/combobox.md +318 -0
  58. package/skills/app-shell-patterns/references/components/command-palette.md +413 -0
  59. package/skills/app-shell-patterns/references/components/csv-importer.md +214 -0
  60. package/skills/app-shell-patterns/references/components/data-table.md +1168 -0
  61. package/skills/app-shell-patterns/references/components/date-picker.md +259 -0
  62. package/skills/app-shell-patterns/references/components/default-header.md +75 -0
  63. package/skills/app-shell-patterns/references/components/default-sidebar.md +136 -0
  64. package/skills/app-shell-patterns/references/components/description-card.md +569 -0
  65. package/skills/app-shell-patterns/references/components/dialog.md +164 -0
  66. package/skills/app-shell-patterns/references/components/document-progress-card.md +154 -0
  67. package/skills/app-shell-patterns/references/components/filter-rail.md +165 -0
  68. package/skills/app-shell-patterns/references/components/form.md +378 -0
  69. package/skills/app-shell-patterns/references/components/global-header-layout.md +132 -0
  70. package/skills/app-shell-patterns/references/components/grid.md +184 -0
  71. package/skills/app-shell-patterns/references/components/input.md +83 -0
  72. package/skills/app-shell-patterns/references/components/layout.md +539 -0
  73. package/skills/app-shell-patterns/references/components/menu.md +218 -0
  74. package/skills/app-shell-patterns/references/components/metric-card.md +94 -0
  75. package/skills/app-shell-patterns/references/components/select.md +283 -0
  76. package/skills/app-shell-patterns/references/components/sheet.md +237 -0
  77. package/skills/app-shell-patterns/references/components/sidebar-group.md +472 -0
  78. package/skills/app-shell-patterns/references/components/sidebar-item.md +458 -0
  79. package/skills/app-shell-patterns/references/components/sidebar-layout.md +258 -0
  80. package/skills/app-shell-patterns/references/components/sidebar-section.md +114 -0
  81. package/skills/app-shell-patterns/references/components/spinner.md +81 -0
  82. package/skills/app-shell-patterns/references/components/table.md +188 -0
  83. package/skills/app-shell-patterns/references/components/tabs.md +158 -0
  84. package/skills/app-shell-patterns/references/components/textarea.md +122 -0
  85. package/skills/app-shell-patterns/references/components/timeline.md +317 -0
  86. package/skills/app-shell-patterns/references/components/toolbar.md +138 -0
  87. package/skills/app-shell-patterns/references/components/tooltip.md +144 -0
  88. package/skills/app-shell-patterns/references/components/with-guard.md +445 -0
  89. package/skills/app-shell-patterns/references/concepts/authentication.md +301 -0
  90. package/skills/app-shell-patterns/references/concepts/custom-components.md +59 -0
  91. package/skills/app-shell-patterns/references/concepts/file-based-routing.md +356 -0
  92. package/skills/app-shell-patterns/references/{fundamental → concepts}/graphql.md +31 -18
  93. package/skills/app-shell-patterns/references/concepts/modules-and-resources.md +229 -0
  94. package/skills/app-shell-patterns/references/concepts/routing-navigation.md +425 -0
  95. package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +420 -0
  96. package/skills/app-shell-patterns/references/concepts/styling-theming.md +785 -0
  97. package/skills/app-shell-patterns/references/migrations.md +55 -0
  98. package/skills/app-shell-patterns/references/pages/{detail.md → document-detail.md} +10 -33
  99. package/skills/app-shell-patterns/references/patterns/form-composer.md +43 -45
  100. package/skills/app-shell-patterns/references/patterns/form-modal.md +37 -92
  101. package/skills/app-shell-patterns/references/patterns/form-sectioned.md +12 -38
  102. package/skills/app-shell-patterns/references/patterns/form-single-page.md +11 -32
  103. package/skills/app-shell-patterns/references/patterns/form-wizard.md +12 -53
  104. package/skills/app-shell-patterns/references/patterns/interaction-confirm.md +11 -27
  105. package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +136 -139
  106. package/skills/app-shell-patterns/references/patterns/interaction-toast.md +10 -34
  107. package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +13 -88
  108. package/skills/app-shell-patterns/references/fundamental/components.md +0 -1009
  109. 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