@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
|
@@ -9,15 +9,20 @@ description: "Best-practice UI patterns and correct component usage for building
|
|
|
9
9
|
|
|
10
10
|
Select and implement the correct UI pattern using @tailor-platform/app-shell components.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Concepts
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Cross-cutting guides that underpin every screen — styling & theming and the token system, GraphQL data access, building custom components, plus auth and routing. Patterns and components build on these.
|
|
15
15
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| [
|
|
19
|
-
| [
|
|
20
|
-
| [
|
|
16
|
+
| Name | Description |
|
|
17
|
+
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| [Authentication](references/concepts/authentication.md) | Set up OAuth2/OIDC authentication with Tailor Platform's Auth service using the AuthProvider component |
|
|
19
|
+
| [Custom Components](references/concepts/custom-components.md) | When AppShell lacks a component — compose first, and if you must build one, conform to the token system |
|
|
20
|
+
| [File-Based Routing](references/concepts/file-based-routing.md) | Define pages via directory structure using the Vite plugin instead of explicit module configuration |
|
|
21
|
+
| [GraphQL Conventions](references/concepts/graphql.md) | Conventions for data access in AppShell apps — urql setup, fragment collocation, the connection pattern, and mutation cache invalidation |
|
|
22
|
+
| [Modules and Resources](references/concepts/modules-and-resources.md) | Learn how to structure your AppShell application using modules and resources for automatic routing, navigation, and breadcrumbs |
|
|
23
|
+
| [Routing and Navigation](references/concepts/routing-navigation.md) | Learn how to navigate between pages using React Router hooks and components re-exported from AppShell |
|
|
24
|
+
| [Sidebar Navigation](references/concepts/sidebar-navigation.md) | Learn how to customize sidebar navigation with auto-generation or composition mode |
|
|
25
|
+
| [Styling and Theming](references/concepts/styling-theming.md) | The AppShell design system — Tailwind CSS v4 setup, theming and palettes, the token catalog, typography, and the styling boundary |
|
|
21
26
|
|
|
22
27
|
## Migrations
|
|
23
28
|
|
|
@@ -25,20 +30,98 @@ These are the foundational rules that underpin all patterns. All patterns build
|
|
|
25
30
|
|
|
26
31
|
Read it when upgrading `@tailor-platform/app-shell`, and whenever styling, theming, or dark mode looks wrong after a version bump. These breakages are silent: the build succeeds and nothing warns, so the cause is not discoverable from the error output. The package ships no CHANGELOG, so this file is the only migration record available locally.
|
|
27
32
|
|
|
28
|
-
## Available
|
|
33
|
+
## Available Components
|
|
34
|
+
|
|
35
|
+
Every AppShell component, its API surface, and usage guidance. Read the entry for the exact props, variants, and examples.
|
|
36
|
+
|
|
37
|
+
| Name | Description |
|
|
38
|
+
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| [ActionPanel](references/components/action-panel.md) | Display a title and a vertical list of actions with per-row loading and disabled states |
|
|
40
|
+
| [ActivityCard](references/components/activity-card.md) | Timeline of recent document activities with avatars and overflow dialog |
|
|
41
|
+
| [AIChat](references/components/ai-chat.md) | Building blocks for an LLM assistant UI — a streaming conversation view over a composer, plus reasoning, tool-call, and citation parts |
|
|
42
|
+
| [Alert](references/components/alert.md) | Contextual status messages with automatic variant icons |
|
|
43
|
+
| [AppShell](references/components/app-shell.md) | The root component that provides routing, navigation, and theming for your application |
|
|
44
|
+
| [AppearanceSwitcher](references/components/appearance-switcher.md) | Pre-built dropdown for toggling the application color theme |
|
|
45
|
+
| [Attachment](references/components/attachment.md) | Attachment list with upload, previews, and per-item actions; compose with Card for titles and surface styling |
|
|
46
|
+
| [Autocomplete](references/components/autocomplete.md) | Text input with a suggestion list — value is the raw input string, not a discrete item selection |
|
|
47
|
+
| [Avatar](references/components/avatar.md) | User avatar with image and fallback (Base UI) |
|
|
48
|
+
| [Badge](references/components/badge.md) | Display status, labels, and tags with customizable variants |
|
|
49
|
+
| [Button](references/components/button.md) | Styled button with multiple variants and sizes |
|
|
50
|
+
| [Card](references/components/card.md) | General-purpose container with consistent styling using a compound component API |
|
|
51
|
+
| [Checkbox](references/components/checkbox.md) | Styled checkbox for boolean form fields, with indeterminate state and automatic Field / React Hook Form integration |
|
|
52
|
+
| [Combobox](references/components/combobox.md) | Searchable combobox with single/multi selection, built-in filtering, async data fetching, and user-creatable items |
|
|
53
|
+
| [CommandPalette](references/components/command-palette.md) | Keyboard-driven quick navigation with fuzzy search for all routes in your application |
|
|
54
|
+
| [CsvImporter](references/components/csv-importer.md) | Guided multi-step CSV import flow with drag-and-drop upload, column mapping, validation, and inline error correction |
|
|
55
|
+
| [DataTable](references/components/data-table.md) | Compound data table component with sortable columns, filter chips, cursor-based pagination, row actions, and multi-row selection |
|
|
56
|
+
| [DatePicker](references/components/date-picker.md) | Accessible date input components (@internationalized/date + Base UI) |
|
|
57
|
+
| [DefaultHeader](references/components/default-header.md) | The built-in SidebarLayout top bar, extensible via an actions slot |
|
|
58
|
+
| [DefaultSidebar](references/components/default-sidebar.md) | Built-in sidebar component for auto-generated or composed navigation, with optional search suppression and icon-rail mode |
|
|
59
|
+
| [DescriptionCard](references/components/description-card.md) | Display structured key-value information in a responsive grid layout with automatic field rendering |
|
|
60
|
+
| [Dialog](references/components/dialog.md) | Modal dialog with a compound component API |
|
|
61
|
+
| [DocumentProgressCard](references/components/document-progress-card.md) | Generic card visualising a document's lifecycle state — optional percentage, stacked progress bar, and status legend |
|
|
62
|
+
| [Form, Field, and Fieldset](references/components/form.md) | Components for building validated forms with automatic accessibility wiring, validation state management, and optional React Hook Form integration |
|
|
63
|
+
| [GlobalHeaderLayout](references/components/global-header-layout.md) | Opinionated layout with an app-wide header above the whole shell and a sidebar that collapses to a persistent icon rail |
|
|
64
|
+
| [Grid](references/components/grid.md) | Generic CSS-Grid layout primitive for equal or custom-width columns with responsive reflow, auto-fit, and spanning |
|
|
65
|
+
| [Input](references/components/input.md) | Styled text input with consistent theming |
|
|
66
|
+
| [Layout](references/components/layout.md) | Responsive column layout component for organizing page content in 1, 2, or 3 columns |
|
|
67
|
+
| [Menu](references/components/menu.md) | Dropdown menu with a compound component API, supporting checkbox/radio items, groups, separators, and nested sub-menus |
|
|
68
|
+
| [MetricCard](references/components/metric-card.md) | Compact card for dashboard KPI summaries with title, value, optional trend and description |
|
|
69
|
+
| [Select](references/components/select.md) | Single or multi-select dropdown with optional async data fetching |
|
|
70
|
+
| [Sheet](references/components/sheet.md) | Slide-in panel backed by a Drawer with native swipe-to-dismiss support |
|
|
71
|
+
| [SidebarGroup](references/components/sidebar-group.md) | Collapsible group component for organizing sidebar navigation items with icons and nested structure |
|
|
72
|
+
| [SidebarItem](references/components/sidebar-item.md) | Individual navigation item for customizing sidebar with icons, active states, and external links |
|
|
73
|
+
| [SidebarLayout](references/components/sidebar-layout.md) | Default AppShell layout with a built-in sidebar, content header, optional app-wide top bar, and an escape-hatch body slot |
|
|
74
|
+
| [Spinner](references/components/spinner.md) | Lightweight loading indicator component with accessible defaults and preset sizes |
|
|
75
|
+
| [Table](references/components/table.md) | Semantic HTML table with pre-styled sub-components |
|
|
76
|
+
| [Tabs](references/components/tabs.md) | Tab navigation with a compound component API |
|
|
77
|
+
| [Textarea](references/components/textarea.md) | Styled multi-line text input sized by rows, with automatic Field / React Hook Form integration |
|
|
78
|
+
| [Timeline](references/components/timeline.md) | Composable primitives for building time-based layouts with axis guides, row backgrounds, intervals, and dependency links |
|
|
79
|
+
| [Toolbar](references/components/toolbar.md) | Full-width action bars with composable rows, grouped controls, and keyboard navigation |
|
|
80
|
+
| [Tooltip](references/components/tooltip.md) | Hover/focus tooltip with configurable placement and shared delay via Tooltip.Provider |
|
|
81
|
+
| [WithGuard](references/components/with-guard.md) | Conditionally render UI elements based on guard evaluation with support for async permissions checks |
|
|
82
|
+
|
|
83
|
+
## Available Hooks & Functions
|
|
84
|
+
|
|
85
|
+
Hooks, factory functions, guards, and router utilities exported by AppShell.
|
|
86
|
+
|
|
87
|
+
| Name | Description |
|
|
88
|
+
| ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- |
|
|
89
|
+
| [createAIGatewayClient](references/api/create-ai-gateway-client.md) | Create a low-level AI Gateway client that reuses AppShell authentication |
|
|
90
|
+
| [createTypedPaths](references/api/create-typed-paths.md) | Generate type-safe route paths from file-based routing |
|
|
91
|
+
| [defineI18nLabels](references/api/define-i18n-labels.md) | Define internationalized labels for multi-language support |
|
|
92
|
+
| [defineModule](references/api/define-module.md) | Define a top-level module that appears in the main navigation |
|
|
93
|
+
| [defineResource](references/api/define-resource.md) | Define a nested resource (page) within a module |
|
|
94
|
+
| [hidden](references/api/guards/hidden.md) | Guard function that denies access and returns 404 Not Found |
|
|
95
|
+
| [Guards Overview](references/api/guards/overview.md) | Access control system for routes and components using guard functions |
|
|
96
|
+
| [pass](references/api/guards/pass.md) | Guard function that allows access and continues to the next guard |
|
|
97
|
+
| [redirectTo](references/api/guards/redirect-to.md) | Guard function that redirects to another page |
|
|
98
|
+
| [useLocation](references/api/router/use-location.md) | Hook to access current location object with pathname, search, and state |
|
|
99
|
+
| [useNavigate](references/api/router/use-navigate.md) | Hook for programmatic navigation between routes |
|
|
100
|
+
| [useParams](references/api/router/use-params.md) | Hook to access dynamic route parameters |
|
|
101
|
+
| [useAIChat](references/api/use-ai-chat.md) | Simple text-only chat hook for AI Gateway |
|
|
102
|
+
| [useAppShell](references/api/use-app-shell.md) | Hook to access AppShell context data and configuration |
|
|
103
|
+
| [useAppShellConfig](references/api/use-app-shell-config.md) | Hook to access AppShell configuration data |
|
|
104
|
+
| [useAppShellData](references/api/use-app-shell-data.md) | Hook to access custom context data passed to AppShell |
|
|
105
|
+
| [useAuth](references/api/use-auth.md) | Hook for accessing authentication state and methods |
|
|
106
|
+
| [useOverrideBreadcrumb](references/api/use-override-breadcrumb.md) | Hook for dynamically overriding breadcrumb titles from within page components |
|
|
107
|
+
| [usePageMeta](references/api/use-page-meta.md) | Hook to resolve page metadata from route path |
|
|
108
|
+
| [useRegisterCommandPaletteActions](references/api/use-register-command-palette-actions.md) | Hook for registering contextual page actions into the CommandPalette |
|
|
109
|
+
| [useResolvedLocale](references/api/use-resolved-locale.md) | Hook to access the full BCP-47 locale and language code from AppShell context |
|
|
110
|
+
| [useRouteError](references/api/use-route-error.md) | Hook to access error details in custom error boundaries |
|
|
111
|
+
| [useTheme](references/api/use-theme.md) | Hook for accessing and controlling theme (light/dark mode) |
|
|
112
|
+
| [useTimeZone](references/api/use-time-zone.md) | Hook to access the configured IANA timezone from AppShell context |
|
|
113
|
+
| [useToast](references/api/use-toast.md) | Hook for displaying toast notifications |
|
|
29
114
|
|
|
30
|
-
|
|
115
|
+
## Available Pages
|
|
31
116
|
|
|
117
|
+
A page is the shape of a whole screen — the outer choice, made before picking patterns for the parts inside it. Where a pattern is one recipe, a page fixes the layout of a whole screen and says what belongs in each part of it. Match the screen first, then use the patterns the entry cites for the pieces within it.
|
|
32
118
|
|
|
119
|
+
| Slug | Name | Description |
|
|
120
|
+
| -------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
121
|
+
| [`document-detail`](references/pages/document-detail.md) | Document Detail Page | The screen for a single record — its summary, its contents, the records around it, and the actions available on it |
|
|
33
122
|
|
|
34
123
|
## Available Patterns
|
|
35
124
|
|
|
36
|
-
### detail
|
|
37
|
-
|
|
38
|
-
| Slug | Name | Description |
|
|
39
|
-
| ----------------------------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------- |
|
|
40
|
-
| [`detail/hero-with-actions`](references/patterns/detail-hero-with-actions.md) | Hero With Actions Detail | Single-record detail view with workflow actions and activity timeline |
|
|
41
|
-
|
|
42
125
|
### form
|
|
43
126
|
|
|
44
127
|
| Slug | Name | Description |
|
|
@@ -66,22 +149,23 @@ A page is the shape of a whole screen — the outer choice, made before picking
|
|
|
66
149
|
## How to Use
|
|
67
150
|
|
|
68
151
|
1. Identify the user's intent (list, detail, form, interaction, screen composition, recipe)
|
|
69
|
-
2. Match
|
|
70
|
-
3.
|
|
71
|
-
4. Read
|
|
72
|
-
5.
|
|
152
|
+
2. Building a whole screen? Match it to a **page** entry first and read that. A page fixes the screen's shape — its layout, what goes where, and in what order — before any of the parts inside it are chosen.
|
|
153
|
+
3. Match each part you are building to a **pattern** entry slug from the tables above. A one-off recipe rather than a screen skips straight to this step.
|
|
154
|
+
4. Read the entry's detailed spec: `references/<category>/<slug>.md` (relative to this file)
|
|
155
|
+
5. Read the concept references for styling, design tokens, GraphQL, and custom components: `references/concepts/`; component and hook APIs live in `references/components/` and `references/api/`
|
|
156
|
+
6. Implement using ONLY the imports listed in the entry's `requiredImports` — for a page, the `requiredImports` of the pattern it sent you to
|
|
73
157
|
|
|
74
158
|
## Rules
|
|
75
159
|
|
|
76
160
|
- ALWAYS cite the entry slug in a comment at the top of the file:
|
|
77
|
-
`/* pattern: list/dense-scan
|
|
78
|
-
- NEVER mix patterns in a
|
|
161
|
+
`/* pattern: list/dense-scan */`. Cite the pattern you implemented, even when a page entry sent you to it.
|
|
162
|
+
- NEVER mix two patterns that solve the same problem in one component — one part, one recipe. Composing patterns for _different_ parts of a screen is expected, and the screen's page entry says which.
|
|
79
163
|
- ALWAYS use AppShell components — do NOT use raw HTML or third-party UI libraries
|
|
80
|
-
- If no entry matches, compose directly from
|
|
164
|
+
- If no entry matches, compose directly from the concept references and component docs
|
|
81
165
|
|
|
82
166
|
### Cross-cutting UX rules (apply to every screen)
|
|
83
167
|
|
|
84
|
-
Full rationale in [`
|
|
168
|
+
Full rationale in [`styling-theming`](references/concepts/styling-theming.md) → Composition & emphasis rules.
|
|
85
169
|
|
|
86
170
|
- **One primary action per view:** at most one primary/filled `Button`; everything else is `outline`/`secondary`/`ghost`.
|
|
87
171
|
- **Status badges by semantic color:** a **filled** semantic variant for the record's primary/lifecycle status, **`outline-*`** for secondary statuses, **`subtle-*`** for tags; reserve brand `default` for non-status emphasis.
|
|
@@ -89,5 +173,5 @@ Full rationale in [`design-system.md`](references/fundamental/design-system.md)
|
|
|
89
173
|
- **Action placement:** primary CTA + status in `Layout.Header`; workflow actions in `ActionPanel`; back/navigation in the breadcrumb — never in `ActionPanel`.
|
|
90
174
|
- **Metric tiles always go in a `Grid`** (`columns={{ initial: 1, md: 2, xl: 4 }}`) — never one-per-row.
|
|
91
175
|
- **Forms default to `form/modal`** — only build a routed full-page form when the design explicitly calls for one.
|
|
92
|
-
- **Forms use AppShell `Form` + `Field`**, submitting via `onFormSubmit` — never a bare `<form onSubmit>` with `FormData`. `onFormSubmit` reads registered `Field.Root`s, so every control (dropdowns included) just needs a wrapping `Field.Root name="…"` — no `name` on the control, no `useState`. React Hook Form is optional, consumer-installed, and only warranted for cross-field validation, field arrays, or a Zod resolver. Details in [`
|
|
176
|
+
- **Forms use AppShell `Form` + `Field`**, submitting via `onFormSubmit` — never a bare `<form onSubmit>` with `FormData`. `onFormSubmit` reads registered `Field.Root`s, so every control (dropdowns included) just needs a wrapping `Field.Root name="…"` — no `name` on the control, no `useState`. React Hook Form is optional, consumer-installed, and only warranted for cross-field validation, field arrays, or a Zod resolver. Details in [`Form`](references/components/form.md) and the `form/*` patterns.
|
|
93
177
|
- **Handle every state:** loading (skeleton), empty (labelled empty state), and error (inline + retry) — never ship only the happy path.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: createAIGatewayClient
|
|
3
|
+
description: Create a low-level AI Gateway client that reuses AppShell authentication
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/create-ai-gateway-client.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# createAIGatewayClient
|
|
9
|
+
|
|
10
|
+
Creates a small AI Gateway transport client for text-only chat completions.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
function createAIGatewayClient(config: {
|
|
16
|
+
gatewayUri: string;
|
|
17
|
+
authClient: AuthClient;
|
|
18
|
+
}): AIGatewayClient;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Parameters
|
|
22
|
+
|
|
23
|
+
### `gatewayUri`
|
|
24
|
+
|
|
25
|
+
- **Type:** `string`
|
|
26
|
+
- **Required:** Yes
|
|
27
|
+
- **Description:** Base URL of the AI Gateway
|
|
28
|
+
|
|
29
|
+
### `authClient`
|
|
30
|
+
|
|
31
|
+
- **Type:** `AuthClient`
|
|
32
|
+
- **Required:** Yes
|
|
33
|
+
- **Description:** Auth client used for authenticated requests via `authClient.fetch(...)`
|
|
34
|
+
|
|
35
|
+
## Return Value
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
interface AIGatewayClient {
|
|
39
|
+
streamChatCompletion(request: AIGatewayChatRequest): AsyncIterable<AIChatCompletionEvent>;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The iterable yields completion events:
|
|
44
|
+
|
|
45
|
+
- `text-delta` — append `event.text` to build the assistant response
|
|
46
|
+
- `done` — terminal event with an optional `finishReason`
|
|
47
|
+
|
|
48
|
+
## Related Types
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
type AIGatewayChatMessage =
|
|
52
|
+
| {
|
|
53
|
+
role: "system" | "user";
|
|
54
|
+
content: string;
|
|
55
|
+
}
|
|
56
|
+
| {
|
|
57
|
+
role: "assistant";
|
|
58
|
+
content?: string;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
interface AIGatewayChatRequest {
|
|
62
|
+
model: string;
|
|
63
|
+
messages: AIGatewayChatMessage[];
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
type AIChatCompletionEvent =
|
|
68
|
+
| {
|
|
69
|
+
type: "text-delta";
|
|
70
|
+
text: string;
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
type: "done";
|
|
74
|
+
finishReason?: string;
|
|
75
|
+
};
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { createAuthClient, createAIGatewayClient } from "@tailor-platform/app-shell";
|
|
82
|
+
|
|
83
|
+
const authClient = createAuthClient({
|
|
84
|
+
clientId: "your-client-id",
|
|
85
|
+
appUri: "https://xyz.erp.dev",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const aiClient = createAIGatewayClient({
|
|
89
|
+
gatewayUri: "https://your-ai-gateway.example.com",
|
|
90
|
+
authClient,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
let text = "";
|
|
94
|
+
for await (const event of aiClient.streamChatCompletion({
|
|
95
|
+
model: "gpt-5-mini",
|
|
96
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
97
|
+
})) {
|
|
98
|
+
if (event.type === "text-delta") {
|
|
99
|
+
text += event.text;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log(text);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Notes
|
|
107
|
+
|
|
108
|
+
- AppShell chooses the appropriate AI Gateway transport automatically
|
|
109
|
+
- The low-level API is intentionally narrow: text deltas plus completion metadata
|
|
110
|
+
- `request.signal` is passed through so callers can abort in-flight work
|
|
111
|
+
|
|
112
|
+
## Related
|
|
113
|
+
|
|
114
|
+
- [Authentication Concept](../concepts/authentication.md)
|
|
115
|
+
- [useAIChat](./use-ai-chat.md)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: createTypedPaths
|
|
3
|
+
description: Generate type-safe route paths from file-based routing
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/create-typed-paths.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# createTypedPaths
|
|
9
|
+
|
|
10
|
+
Generates type-safe route path helpers from file-based routing structure. Only available when using the Vite plugin.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
function createTypedPaths<T extends Record<string, PageEntry>>(pages: T): TypedPaths<T>;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Parameters
|
|
19
|
+
|
|
20
|
+
### `pages`
|
|
21
|
+
|
|
22
|
+
- **Type:** `Record<string, PageEntry>`
|
|
23
|
+
- **Required:** Yes
|
|
24
|
+
- **Description:** Pages object from virtual module (auto-generated by Vite plugin)
|
|
25
|
+
|
|
26
|
+
## Return Value
|
|
27
|
+
|
|
28
|
+
Type-safe path builder functions for each route.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Basic Usage
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { createTypedPaths } from "@tailor-platform/app-shell";
|
|
36
|
+
import pages from "virtual:app-shell-pages";
|
|
37
|
+
|
|
38
|
+
const paths = createTypedPaths(pages);
|
|
39
|
+
|
|
40
|
+
// Type-safe navigation
|
|
41
|
+
navigate(paths.products.detail({ id: "123" }));
|
|
42
|
+
// Result: "/products/123"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### With useNavigate
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { useNavigate } from "@tailor-platform/app-shell";
|
|
49
|
+
|
|
50
|
+
function ProductCard({ product }: { product: Product }) {
|
|
51
|
+
const navigate = useNavigate();
|
|
52
|
+
const paths = createTypedPaths(pages);
|
|
53
|
+
|
|
54
|
+
const handleClick = () => {
|
|
55
|
+
navigate(paths.products.detail({ id: product.id }));
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return <button onClick={handleClick}>View Details</button>;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### With Link Component
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { Link } from "@tailor-platform/app-shell";
|
|
66
|
+
|
|
67
|
+
function ProductLink({ id }: { id: string }) {
|
|
68
|
+
const paths = createTypedPaths(pages);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<Link to={paths.products.detail({ id })}>
|
|
72
|
+
View Product
|
|
73
|
+
</Link>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Nested Routes
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// File structure:
|
|
82
|
+
// pages/
|
|
83
|
+
// orders/
|
|
84
|
+
// page.tsx
|
|
85
|
+
// [id]/
|
|
86
|
+
// page.tsx
|
|
87
|
+
// edit/
|
|
88
|
+
// page.tsx
|
|
89
|
+
|
|
90
|
+
paths.orders.index(); // "/orders"
|
|
91
|
+
paths.orders.detail({ id: "1" }); // "/orders/1"
|
|
92
|
+
paths.orders.edit({ id: "1" }); // "/orders/1/edit"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## TypeScript Benefits
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// ✅ Type-safe parameters
|
|
99
|
+
paths.products.detail({ id: "123" }); // Valid
|
|
100
|
+
|
|
101
|
+
// ❌ Type error - missing required param
|
|
102
|
+
paths.products.detail(); // Error: Argument required
|
|
103
|
+
|
|
104
|
+
// ❌ Type error - wrong param name
|
|
105
|
+
paths.products.detail({ productId: "123" }); // Error: Unknown key
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## File-Based Routing Only
|
|
109
|
+
|
|
110
|
+
This function is only available when using the Vite plugin with file-based routing.
|
|
111
|
+
|
|
112
|
+
See [File-Based Routing](../concepts/file-based-routing.md) for setup.
|
|
113
|
+
|
|
114
|
+
## Related
|
|
115
|
+
|
|
116
|
+
- [File-Based Routing](../concepts/file-based-routing.md) - Setup guide
|
|
117
|
+
- [useNavigate](./router/use-navigate.md) - Programmatic navigation
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: defineI18nLabels
|
|
3
|
+
description: Define internationalized labels for multi-language support
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/hooks/define-i18n-labels.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# defineI18nLabels
|
|
9
|
+
|
|
10
|
+
Creates internationalized labels that automatically resolve based on the current locale.
|
|
11
|
+
|
|
12
|
+
## Signature
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
function defineI18nLabels<T extends Record<string, Record<string, string>>>(
|
|
16
|
+
labels: T,
|
|
17
|
+
): I18nLabels<T>;
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Parameters
|
|
21
|
+
|
|
22
|
+
### `labels`
|
|
23
|
+
|
|
24
|
+
- **Type:** `Record<string, Record<string, string>>`
|
|
25
|
+
- **Required:** Yes
|
|
26
|
+
- **Description:** Object mapping label keys to locale-specific strings
|
|
27
|
+
|
|
28
|
+
## Return Value
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
{
|
|
32
|
+
t: (key: keyof T) => LocalizedString;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Basic Labels
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { defineI18nLabels } from "@tailor-platform/app-shell";
|
|
42
|
+
|
|
43
|
+
const labels = defineI18nLabels({
|
|
44
|
+
dashboard: {
|
|
45
|
+
en: "Dashboard",
|
|
46
|
+
ja: "ダッシュボード",
|
|
47
|
+
},
|
|
48
|
+
products: {
|
|
49
|
+
en: "Products",
|
|
50
|
+
ja: "商品",
|
|
51
|
+
},
|
|
52
|
+
settings: {
|
|
53
|
+
en: "Settings",
|
|
54
|
+
ja: "設定",
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Use in modules
|
|
59
|
+
const dashboardModule = defineModule({
|
|
60
|
+
path: "dashboard",
|
|
61
|
+
meta: {
|
|
62
|
+
title: labels.t("dashboard"),
|
|
63
|
+
},
|
|
64
|
+
component: DashboardPage,
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Multiple Locales
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
const labels = defineI18nLabels({
|
|
72
|
+
welcome: {
|
|
73
|
+
en: "Welcome",
|
|
74
|
+
ja: "ようこそ",
|
|
75
|
+
es: "Bienvenido",
|
|
76
|
+
fr: "Bienvenue",
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### In Components
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
function WelcomeMessage() {
|
|
85
|
+
const labels = defineI18nLabels({
|
|
86
|
+
greeting: {
|
|
87
|
+
en: "Hello",
|
|
88
|
+
ja: "こんにちは",
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return <h1>{labels.t("greeting")}</h1>;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### With SidebarGroup
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { SidebarGroup } from "@tailor-platform/app-shell";
|
|
100
|
+
|
|
101
|
+
const labels = defineI18nLabels({
|
|
102
|
+
admin: {
|
|
103
|
+
en: "Administration",
|
|
104
|
+
ja: "管理",
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
<SidebarGroup title={labels.t("admin")}>
|
|
109
|
+
<SidebarItem to="/admin/users" />
|
|
110
|
+
</SidebarGroup>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Setting Locale
|
|
114
|
+
|
|
115
|
+
The active locale is controlled by the `locale` prop on `AppShell`:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
<AppShell locale="ja" modules={modules}>
|
|
119
|
+
<SidebarLayout />
|
|
120
|
+
</AppShell>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Supported locales: `en`, `ja`
|
|
124
|
+
|
|
125
|
+
If not specified, auto-detects from browser settings.
|
|
126
|
+
|
|
127
|
+
## TypeScript
|
|
128
|
+
|
|
129
|
+
Full type safety:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const labels = defineI18nLabels({
|
|
133
|
+
dashboard: { en: "Dashboard", ja: "ダッシュボード" },
|
|
134
|
+
products: { en: "Products", ja: "商品" },
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
labels.t("dashboard"); // ✅ Valid
|
|
138
|
+
labels.t("invalid"); // ❌ Type error
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Related
|
|
142
|
+
|
|
143
|
+
- [defineModule](./define-module.md) - Use labels in modules
|