@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,202 @@
1
+ ---
2
+ title: hidden
3
+ description: Guard function that denies access and returns 404 Not Found
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/hooks/guards/hidden.docs.outline.md — do not edit by hand. -->
7
+
8
+ # hidden
9
+
10
+ Returns a guard result that denies access and makes the route return 404 Not Found. The route is also hidden from navigation and search.
11
+
12
+ ## Signature
13
+
14
+ ```typescript
15
+ function hidden(): GuardResult;
16
+ ```
17
+
18
+ ## Return Type
19
+
20
+ ```typescript
21
+ {
22
+ type: "hidden";
23
+ }
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```typescript
29
+ import { hidden, type Guard } from "@tailor-platform/app-shell";
30
+
31
+ const denyAccess: Guard = () => {
32
+ return hidden();
33
+ };
34
+ ```
35
+
36
+ ## When to Use
37
+
38
+ Use `hidden()` when:
39
+
40
+ - ✅ Access should be denied
41
+ - ✅ User doesn't have required permissions
42
+ - ✅ You want to hide the page completely (404)
43
+ - ✅ Feature is not available for current user
44
+
45
+ ## Effects
46
+
47
+ When `hidden()` is returned:
48
+
49
+ - 🚫 Route returns **404 Not Found**
50
+ - 🚫 Hidden from **sidebar navigation**
51
+ - 🚫 Hidden from **CommandPalette** search
52
+ - 🚫 Not shown in **breadcrumbs**
53
+ - 🚫 Direct URL access returns 404
54
+
55
+ ## Examples
56
+
57
+ ### Deny All Access
58
+
59
+ ```typescript
60
+ const denyAll: Guard = () => hidden();
61
+ ```
62
+
63
+ ### Role-Based Hiding
64
+
65
+ ```typescript
66
+ const adminOnly: Guard = ({ context }) => {
67
+ if (context.currentUser?.role !== "admin") {
68
+ return hidden(); // Non-admins see 404
69
+ }
70
+ return pass();
71
+ };
72
+ ```
73
+
74
+ ### Permission-Based Hiding
75
+
76
+ ```typescript
77
+ const requirePermission =
78
+ (perm: string): Guard =>
79
+ ({ context }) => {
80
+ if (!context.permissions.includes(perm)) {
81
+ return hidden(); // No permission → 404
82
+ }
83
+ return pass();
84
+ };
85
+ ```
86
+
87
+ ### Feature Flag
88
+
89
+ ```typescript
90
+ const requireBetaFeature: Guard = ({ context }) => {
91
+ if (!context.featureFlags?.beta) {
92
+ return hidden(); // Feature disabled → 404
93
+ }
94
+ return pass();
95
+ };
96
+ ```
97
+
98
+ ### Subscription Tier
99
+
100
+ ```typescript
101
+ const premiumOnly: Guard = ({ context }) => {
102
+ if (context.currentUser?.plan !== "premium") {
103
+ return hidden(); // Free users see 404
104
+ }
105
+ return pass();
106
+ };
107
+ ```
108
+
109
+ ### Conditional Hiding
110
+
111
+ ```typescript
112
+ const conditionalHide: Guard = ({ context }) => {
113
+ // Multiple conditions
114
+ if (!context.currentUser || context.currentUser.suspended || !context.currentUser.emailVerified) {
115
+ return hidden();
116
+ }
117
+ return pass();
118
+ };
119
+ ```
120
+
121
+ ### Async Permission Check
122
+
123
+ ```typescript
124
+ const asyncHide: Guard = async ({ context }) => {
125
+ const allowed = await fetch("/api/check-access");
126
+ if (!allowed) {
127
+ return hidden();
128
+ }
129
+ return pass();
130
+ };
131
+ ```
132
+
133
+ ## vs redirectTo()
134
+
135
+ | Aspect | hidden() | redirectTo() |
136
+ | -------------- | -------------------- | ------------------------ |
137
+ | **Result** | 404 Not Found | Redirect to page |
138
+ | **URL** | Stays same | Changes to new URL |
139
+ | **Navigation** | Hidden | Not affected |
140
+ | **Use Case** | Deny access silently | Send to login/error page |
141
+
142
+ ### Example: When to Use Each
143
+
144
+ ```typescript
145
+ // Use hidden() - Silently deny access
146
+ const adminFeature: Guard = ({ context }) => {
147
+ if (!isAdmin(context)) {
148
+ return hidden(); // Non-admins don't even see this exists
149
+ }
150
+ return pass();
151
+ };
152
+
153
+ // Use redirectTo() - Explicitly redirect
154
+ const requireAuth: Guard = ({ context }) => {
155
+ if (!context.currentUser) {
156
+ return redirectTo("/login"); // Unauthenticated users go to login
157
+ }
158
+ return pass();
159
+ };
160
+ ```
161
+
162
+ ## Navigation Impact
163
+
164
+ ```typescript
165
+ // Before guard (user is not admin):
166
+ Sidebar:
167
+ › Dashboard
168
+ › Products
169
+ › Admin Panel ← Visible
170
+
171
+ // After guard returns hidden():
172
+ Sidebar:
173
+ › Dashboard
174
+ › Products
175
+ ← Admin Panel disappeared
176
+
177
+ // Direct URL access: /admin
178
+ // Result: 404 Not Found
179
+ ```
180
+
181
+ ## WithGuard Component
182
+
183
+ `hidden()` works with `WithGuard` to hide UI elements:
184
+
185
+ ```typescript
186
+ import { WithGuard, hidden, pass } from "@tailor-platform/app-shell";
187
+
188
+ const isAdmin = ({ context }) =>
189
+ context.currentUser?.role === "admin" ? pass() : hidden();
190
+
191
+ <WithGuard guards={[isAdmin]}>
192
+ <Button>Delete All Users</Button>
193
+ </WithGuard>
194
+ // Non-admins: button doesn't render
195
+ ```
196
+
197
+ ## Related
198
+
199
+ - [pass()](./pass.md) - Allow access and continue
200
+ - [redirectTo()](./redirect-to.md) - Redirect to another page
201
+ - [Guards Overview](./overview.md) - Complete guard system guide
202
+ - [WithGuard Component](../../components/with-guard.md) - Component-level guards
@@ -0,0 +1,354 @@
1
+ ---
2
+ title: Guards Overview
3
+ description: Access control system for routes and components using guard functions
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/hooks/guards/overview.docs.outline.md — do not edit by hand. -->
7
+
8
+ # Guards Overview
9
+
10
+ Guards are functions that control access to routes and UI elements in AppShell. They provide a flexible, composable way to implement permission-based and role-based access control.
11
+
12
+ ## How Guards Work
13
+
14
+ Guards are executed sequentially and can return one of three results:
15
+
16
+ - **`pass()`** - Allow access, continue to next guard
17
+ - **`hidden()`** - Deny access, return 404
18
+ - **`redirectTo(path)`** - Redirect to another page
19
+
20
+ If any guard returns `hidden()` or `redirectTo()`, execution stops immediately.
21
+
22
+ ## Guard Function Signature
23
+
24
+ ```typescript
25
+ type Guard = (ctx: GuardContext) => GuardResult | Promise<GuardResult>;
26
+
27
+ type GuardContext = {
28
+ context: ContextData; // Your custom context from AppShell
29
+ };
30
+
31
+ type GuardResult = { type: "pass" } | { type: "hidden" } | { type: "redirect"; to: string };
32
+ ```
33
+
34
+ ## Guard Functions
35
+
36
+ ### pass()
37
+
38
+ Allows access and continues to the next guard.
39
+
40
+ ```typescript
41
+ import { pass } from "@tailor-platform/app-shell";
42
+
43
+ const allowAll: Guard = () => pass();
44
+ ```
45
+
46
+ [Full Reference →](./pass.md)
47
+
48
+ ### hidden()
49
+
50
+ Denies access and shows 404 Not Found.
51
+
52
+ ```typescript
53
+ import { hidden } from "@tailor-platform/app-shell";
54
+
55
+ const denyAll: Guard = () => hidden();
56
+ ```
57
+
58
+ [Full Reference →](./hidden.md)
59
+
60
+ ### redirectTo(path)
61
+
62
+ Redirects to another page.
63
+
64
+ ```typescript
65
+ import { redirectTo } from "@tailor-platform/app-shell";
66
+
67
+ const redirectToLogin: Guard = () => redirectTo("/login");
68
+ ```
69
+
70
+ [Full Reference →](./redirect-to.md)
71
+
72
+ ## Usage Locations
73
+
74
+ ### Route-Level Guards
75
+
76
+ Applied to modules and resources:
77
+
78
+ ```typescript
79
+ import { defineModule, pass, hidden } from "@tailor-platform/app-shell";
80
+
81
+ const adminModule = defineModule({
82
+ path: "admin",
83
+ component: AdminPage,
84
+ guards: [
85
+ ({ context }) => {
86
+ return context.currentUser?.role === "admin" ? pass() : hidden();
87
+ },
88
+ ],
89
+ });
90
+ ```
91
+
92
+ ### Component-Level Guards
93
+
94
+ Applied to UI elements with `WithGuard`:
95
+
96
+ ```typescript
97
+ import { WithGuard, pass, hidden } from "@tailor-platform/app-shell";
98
+
99
+ const isAdmin = ({ context }) =>
100
+ context.currentUser?.role === "admin" ? pass() : hidden();
101
+
102
+ <WithGuard guards={[isAdmin]}>
103
+ <Button>Delete All</Button>
104
+ </WithGuard>
105
+ ```
106
+
107
+ ## Context Data
108
+
109
+ Guards receive context data from AppShell:
110
+
111
+ ```typescript
112
+ // Define your context type
113
+ declare module "@tailor-platform/app-shell" {
114
+ interface AppShellRegister {
115
+ contextData: {
116
+ currentUser: User | null;
117
+ permissions: string[];
118
+ featureFlags: FeatureFlags;
119
+ };
120
+ }
121
+ }
122
+
123
+ // Pass context to AppShell
124
+ <AppShell
125
+ modules={modules}
126
+ contextData={{
127
+ currentUser,
128
+ permissions,
129
+ featureFlags,
130
+ }}
131
+ >
132
+ {/* ... */}
133
+ </AppShell>
134
+
135
+ // Access in guards
136
+ const guard: Guard = ({ context }) => {
137
+ // context is fully typed!
138
+ if (context.currentUser) {
139
+ return pass();
140
+ }
141
+ return hidden();
142
+ };
143
+ ```
144
+
145
+ ## Common Patterns
146
+
147
+ ### Authentication Check
148
+
149
+ ```typescript
150
+ const requireAuth: Guard = ({ context }) => {
151
+ if (!context.currentUser) {
152
+ return redirectTo("/login");
153
+ }
154
+ return pass();
155
+ };
156
+ ```
157
+
158
+ ### Role-Based Access
159
+
160
+ ```typescript
161
+ const requireAdmin: Guard = ({ context }) => {
162
+ if (context.currentUser?.role !== "admin") {
163
+ return hidden();
164
+ }
165
+ return pass();
166
+ };
167
+ ```
168
+
169
+ ### Permission-Based Access
170
+
171
+ ```typescript
172
+ const requirePermission =
173
+ (permission: string): Guard =>
174
+ ({ context }) => {
175
+ if (!context.permissions.includes(permission)) {
176
+ return hidden();
177
+ }
178
+ return pass();
179
+ };
180
+
181
+ // Usage
182
+ guards: [requirePermission("users:delete")];
183
+ ```
184
+
185
+ ### Feature Flags
186
+
187
+ ```typescript
188
+ const requireFeature =
189
+ (flag: string): Guard =>
190
+ ({ context }) => {
191
+ if (!context.featureFlags[flag]) {
192
+ return hidden();
193
+ }
194
+ return pass();
195
+ };
196
+ ```
197
+
198
+ ### Async Permission Check
199
+
200
+ ```typescript
201
+ const checkApiPermission: Guard = async ({ context }) => {
202
+ const response = await fetch("/api/permissions/admin");
203
+ const { allowed } = await response.json();
204
+ return allowed ? pass() : hidden();
205
+ };
206
+ ```
207
+
208
+ ### Multiple Guards (AND logic)
209
+
210
+ ```typescript
211
+ const guards = [requireAuth, requireAdmin, requireFeature("beta")];
212
+
213
+ // All must pass() for access to be granted
214
+ defineModule({
215
+ path: "admin",
216
+ guards: guards,
217
+ });
218
+ ```
219
+
220
+ ### Reusable Guard Library
221
+
222
+ ```typescript
223
+ // guards.ts
224
+ export const requireAuth: Guard = ({ context }) => {
225
+ return context.currentUser ? pass() : redirectTo("/login");
226
+ };
227
+
228
+ export const requireRole =
229
+ (role: string): Guard =>
230
+ ({ context }) => {
231
+ return context.currentUser?.role === role ? pass() : hidden();
232
+ };
233
+
234
+ export const requirePermission =
235
+ (perm: string): Guard =>
236
+ ({ context }) => {
237
+ return context.permissions.includes(perm) ? pass() : hidden();
238
+ };
239
+
240
+ // Usage across application
241
+ import { requireAuth, requireRole } from "./guards";
242
+
243
+ defineModule({
244
+ path: "admin",
245
+ guards: [requireAuth, requireRole("admin")],
246
+ });
247
+ ```
248
+
249
+ ## Guard Execution Order
250
+
251
+ Guards are executed sequentially in the order they're defined:
252
+
253
+ ```typescript
254
+ guards: [guardA, guardB, guardC];
255
+
256
+ // Execution:
257
+ // 1. guardA runs → if not pass(), stop
258
+ // 2. guardB runs → if not pass(), stop
259
+ // 3. guardC runs → if not pass(), stop
260
+ // 4. All passed → grant access
261
+ ```
262
+
263
+ ## Navigation Behavior
264
+
265
+ When guards return `hidden()`:
266
+
267
+ - Route returns 404 Not Found
268
+ - Item hidden from sidebar navigation
269
+ - Item hidden from CommandPalette
270
+ - Breadcrumbs don't show the page
271
+
272
+ When guards return `redirectTo()`:
273
+
274
+ - User is redirected immediately
275
+ - Original URL is not accessible
276
+ - Useful for login flows
277
+
278
+ ## Best Practices
279
+
280
+ ### Do:
281
+
282
+ - ✅ Keep guards simple and focused
283
+ - ✅ Reuse guards across routes and components
284
+ - ✅ Use descriptive names (requireAuth, not guard1)
285
+ - ✅ Return quickly for better performance
286
+ - ✅ Cache expensive checks when possible
287
+
288
+ ### Don't:
289
+
290
+ - ❌ Make guards too complex (extract logic)
291
+ - ❌ Have side effects in guards (logging OK)
292
+ - ❌ Duplicate guard logic (DRY principle)
293
+ - ❌ Forget to handle async errors
294
+ - ❌ Use redirectTo() in WithGuard (not supported)
295
+
296
+ ## TypeScript
297
+
298
+ Full type safety:
299
+
300
+ ```typescript
301
+ import { type Guard, type GuardContext, type GuardResult } from "@tailor-platform/app-shell";
302
+
303
+ const myGuard: Guard = (ctx: GuardContext): GuardResult => {
304
+ // Fully typed context
305
+ return pass();
306
+ };
307
+
308
+ // Async guard
309
+ const asyncGuard: Guard = async (ctx): Promise<GuardResult> => {
310
+ await someAsyncCheck();
311
+ return pass();
312
+ };
313
+ ```
314
+
315
+ ## Performance
316
+
317
+ ### Sync Guards (Fast)
318
+
319
+ ```typescript
320
+ const isAdmin: Guard = ({ context }) => {
321
+ return context.currentUser?.role === "admin" ? pass() : hidden();
322
+ };
323
+ // ~0ms - Instant
324
+ ```
325
+
326
+ ### Async Guards (Slower)
327
+
328
+ ```typescript
329
+ const checkPermission: Guard = async ({ context }) => {
330
+ const allowed = await fetch("/api/check");
331
+ return allowed ? pass() : hidden();
332
+ };
333
+ // ~50-200ms - Network request
334
+ ```
335
+
336
+ **Tip:** Prefer sync guards when possible. Cache API results in context data.
337
+
338
+ ## Comparison: Route vs Component Guards
339
+
340
+ | Aspect | Route Guards | Component Guards (WithGuard) |
341
+ | ------------------------- | --------------------------- | ---------------------------- |
342
+ | **Location** | defineModule/defineResource | WithGuard component |
343
+ | **Supports pass()** | ✅ Yes | ✅ Yes |
344
+ | **Supports hidden()** | ✅ Yes | ✅ Yes |
345
+ | **Supports redirectTo()** | ✅ Yes | ❌ No |
346
+ | **Execution** | Before route loads | During render |
347
+ | **Use Case** | Page access control | UI element visibility |
348
+
349
+ ## Related
350
+
351
+ - [pass()](./pass.md) - Allow access guard function
352
+ - [hidden()](./hidden.md) - Hide/deny access guard function
353
+ - [redirectTo()](./redirect-to.md) - Redirect guard function
354
+ - [WithGuard Component](../../components/with-guard.md) - Component-level guards
@@ -0,0 +1,129 @@
1
+ ---
2
+ title: pass
3
+ description: Guard function that allows access and continues to the next guard
4
+ ---
5
+
6
+ <!-- GENERATED by docs-kit from docs-src/hooks/guards/pass.docs.outline.md — do not edit by hand. -->
7
+
8
+ # pass
9
+
10
+ Returns a guard result that allows access and continues to the next guard in the chain.
11
+
12
+ ## Signature
13
+
14
+ ```typescript
15
+ function pass(): GuardResult;
16
+ ```
17
+
18
+ ## Return Type
19
+
20
+ ```typescript
21
+ {
22
+ type: "pass";
23
+ }
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```typescript
29
+ import { pass, type Guard } from "@tailor-platform/app-shell";
30
+
31
+ const allowAccess: Guard = () => {
32
+ return pass();
33
+ };
34
+ ```
35
+
36
+ ## When to Use
37
+
38
+ Use `pass()` when:
39
+
40
+ - ✅ Access should be granted
41
+ - ✅ User meets the required conditions
42
+ - ✅ You want to continue to the next guard
43
+
44
+ ## Examples
45
+
46
+ ### Always Allow
47
+
48
+ ```typescript
49
+ const allowAll: Guard = () => pass();
50
+ ```
51
+
52
+ ### Conditional Access
53
+
54
+ ```typescript
55
+ const requireAuth: Guard = ({ context }) => {
56
+ if (context.currentUser) {
57
+ return pass(); // User is authenticated
58
+ }
59
+ return redirectTo("/login");
60
+ };
61
+ ```
62
+
63
+ ### Role Check
64
+
65
+ ```typescript
66
+ const requireAdmin: Guard = ({ context }) => {
67
+ if (context.currentUser?.role === "admin") {
68
+ return pass(); // User is admin
69
+ }
70
+ return hidden();
71
+ };
72
+ ```
73
+
74
+ ### Permission Check
75
+
76
+ ```typescript
77
+ const requirePermission =
78
+ (perm: string): Guard =>
79
+ ({ context }) => {
80
+ if (context.permissions.includes(perm)) {
81
+ return pass(); // User has permission
82
+ }
83
+ return hidden();
84
+ };
85
+ ```
86
+
87
+ ### Multiple Conditions
88
+
89
+ ```typescript
90
+ const complexGuard: Guard = ({ context }) => {
91
+ // Check multiple conditions
92
+ if (context.currentUser && context.currentUser.active && !context.currentUser.suspended) {
93
+ return pass(); // All conditions met
94
+ }
95
+ return hidden();
96
+ };
97
+ ```
98
+
99
+ ### Async Guard
100
+
101
+ ```typescript
102
+ const asyncGuard: Guard = async ({ context }) => {
103
+ const isValid = await validateToken(context.token);
104
+ if (isValid) {
105
+ return pass();
106
+ }
107
+ return redirectTo("/login");
108
+ };
109
+ ```
110
+
111
+ ## Guard Chaining
112
+
113
+ When `pass()` is returned, the next guard in the array executes:
114
+
115
+ ```typescript
116
+ guards: [
117
+ guardA, // Returns pass() → Continue to guardB
118
+ guardB, // Returns pass() → Continue to guardC
119
+ guardC, // Returns pass() → Grant access
120
+ ];
121
+ ```
122
+
123
+ If all guards return `pass()`, access is granted.
124
+
125
+ ## Related
126
+
127
+ - [hidden()](./hidden.md) - Deny access and return 404
128
+ - [redirectTo()](./redirect-to.md) - Redirect to another page
129
+ - [Guards Overview](./overview.md) - Complete guard system guide