@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,539 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Layout
|
|
3
|
+
description: Responsive column layout component for organizing page content in 1, 2, or 3 columns
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- GENERATED by docs-kit from docs-src/components/layout.docs.outline.md — do not edit by hand. -->
|
|
7
|
+
|
|
8
|
+
# Layout
|
|
9
|
+
|
|
10
|
+
`Layout` is a responsive column layout component that helps you organize page content into 1, 2, or 3 columns with automatic responsive behavior. Perfect for detail pages, dashboards, and forms.
|
|
11
|
+
|
|
12
|
+
## Import
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { Layout } from "@tailor-platform/app-shell";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Basic Usage
|
|
19
|
+
|
|
20
|
+
The column count is auto-detected from the number of `Layout.Column` children:
|
|
21
|
+
|
|
22
|
+
<example-preview name="basic-usage"></example-preview>
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
function BasicUsage() {
|
|
26
|
+
return (
|
|
27
|
+
<Layout>
|
|
28
|
+
<Layout.Column>
|
|
29
|
+
<h2>Main Content</h2>
|
|
30
|
+
<p>Your main content goes here...</p>
|
|
31
|
+
</Layout.Column>
|
|
32
|
+
<Layout.Column>
|
|
33
|
+
<h2>Sidebar</h2>
|
|
34
|
+
<p>Additional info or actions...</p>
|
|
35
|
+
</Layout.Column>
|
|
36
|
+
</Layout>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Props
|
|
42
|
+
|
|
43
|
+
### Layout Props
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
| ----------- | ------------------- | ------------ | --------------------------------------------------------------------------------------- |
|
|
47
|
+
| `className` | `string` | - | Additional CSS classes for container |
|
|
48
|
+
| `style` | `CSSProperties` | - | Inline styles for the layout container |
|
|
49
|
+
| `children` | `Layout.Column[]` | **Required** | `Layout.Header` and/or `Layout.Column` components |
|
|
50
|
+
| `fill` | `boolean` | `false` | Fill the available height instead of growing with content (see [Fill Mode](#fill-mode)) |
|
|
51
|
+
| `columns` | `1 \| 2 \| 3` | - | **(Deprecated)** Auto-detected from `Layout.Column` children count when omitted |
|
|
52
|
+
| `title` | `string` | - | **(Deprecated)** Use `<Layout.Header title="...">` instead |
|
|
53
|
+
| `actions` | `React.ReactNode[]` | - | **(Deprecated)** Use `<Layout.Header actions={[...]}>` instead |
|
|
54
|
+
| `gap` | `number` | `4` | **(Deprecated)** Use `className` (e.g. `className="gap-6"`) instead |
|
|
55
|
+
|
|
56
|
+
### Layout.Header Props
|
|
57
|
+
|
|
58
|
+
`Layout.Header` is a compound sub-component for page-level headers. Place it as a direct child of `<Layout>`, above any `<Layout.Column>` children.
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
| ---------- | ------------------- | ------- | ---------------------------------------------------------- |
|
|
62
|
+
| `title` | `string` | - | Page title (left side, rendered as `<h1>`) |
|
|
63
|
+
| `actions` | `React.ReactNode[]` | - | Action buttons or nodes (right side) |
|
|
64
|
+
| `children` | `React.ReactNode` | - | Full-width content below the title/actions row (e.g. tabs) |
|
|
65
|
+
|
|
66
|
+
### Layout.Column Props
|
|
67
|
+
|
|
68
|
+
| Prop | Type | Default | Description |
|
|
69
|
+
| ----------- | ----------------------------- | ------- | ------------------------------------------------------------------------- |
|
|
70
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
71
|
+
| `style` | `CSSProperties` | - | Inline styles for the column |
|
|
72
|
+
| `area` | `"left" \| "main" \| "right"` | - | Column area role for explicit width control (see [Area Mode](#area-mode)) |
|
|
73
|
+
| `children` | `React.ReactNode` | - | Column content |
|
|
74
|
+
|
|
75
|
+
## Column Configurations
|
|
76
|
+
|
|
77
|
+
### 1 Column
|
|
78
|
+
|
|
79
|
+
Full-width layout, always stacks vertically:
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
<Layout>
|
|
83
|
+
<Layout.Column>
|
|
84
|
+
<DescriptionCard data={data} fields={fields} />
|
|
85
|
+
</Layout.Column>
|
|
86
|
+
</Layout>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Responsive behavior:**
|
|
90
|
+
|
|
91
|
+
- All screens: 1 column (full width)
|
|
92
|
+
|
|
93
|
+
### 2 Columns
|
|
94
|
+
|
|
95
|
+
Main content with sidebar:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<Layout>
|
|
99
|
+
<Layout.Column>
|
|
100
|
+
{/* Main content - flexible width */}
|
|
101
|
+
<DescriptionCard data={orderData} fields={orderFields} />
|
|
102
|
+
</Layout.Column>
|
|
103
|
+
<Layout.Column>
|
|
104
|
+
{/* Sidebar - fixed 280px on desktop */}
|
|
105
|
+
<Card>Quick Actions</Card>
|
|
106
|
+
<Card>History</Card>
|
|
107
|
+
</Layout.Column>
|
|
108
|
+
</Layout>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Responsive behavior:**
|
|
112
|
+
|
|
113
|
+
- Mobile (< 1024px): Stacks vertically
|
|
114
|
+
- Desktop (≥ 1024px): First column flexible, second column 280px
|
|
115
|
+
|
|
116
|
+
**Use cases:**
|
|
117
|
+
|
|
118
|
+
- Detail pages with sidebar
|
|
119
|
+
- Forms with preview
|
|
120
|
+
- Main content + related items
|
|
121
|
+
|
|
122
|
+
### 3 Columns
|
|
123
|
+
|
|
124
|
+
Left sidebar, main content, right sidebar:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<Layout>
|
|
128
|
+
<Layout.Column>
|
|
129
|
+
{/* Left sidebar - fixed 320px */}
|
|
130
|
+
<Navigation />
|
|
131
|
+
</Layout.Column>
|
|
132
|
+
<Layout.Column>
|
|
133
|
+
{/* Main content - flexible */}
|
|
134
|
+
<DescriptionCard data={data} fields={fields} />
|
|
135
|
+
</Layout.Column>
|
|
136
|
+
<Layout.Column>
|
|
137
|
+
{/* Right sidebar - fixed 280px */}
|
|
138
|
+
<ActivityFeed />
|
|
139
|
+
</Layout.Column>
|
|
140
|
+
</Layout>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Responsive behavior:**
|
|
144
|
+
|
|
145
|
+
- Mobile (< 1280px): Stacks vertically
|
|
146
|
+
- Desktop (≥ 1280px): Left 320px, middle flexible, right 280px
|
|
147
|
+
|
|
148
|
+
**Use cases:**
|
|
149
|
+
|
|
150
|
+
- Dashboards with multiple panels
|
|
151
|
+
- Complex detail pages
|
|
152
|
+
- Editor with navigation and preview
|
|
153
|
+
|
|
154
|
+
### 4+ Columns
|
|
155
|
+
|
|
156
|
+
When more than 3 `Layout.Column` children are provided, all columns share equal width:
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
<Layout>
|
|
160
|
+
<Layout.Column>{/* 25% */}</Layout.Column>
|
|
161
|
+
<Layout.Column>{/* 25% */}</Layout.Column>
|
|
162
|
+
<Layout.Column>{/* 25% */}</Layout.Column>
|
|
163
|
+
<Layout.Column>{/* 25% */}</Layout.Column>
|
|
164
|
+
</Layout>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Responsive behavior:**
|
|
168
|
+
|
|
169
|
+
- Mobile (< 1280px): Stacks vertically
|
|
170
|
+
- Desktop (≥ 1280px): Equal-width columns (`repeat(N, 1fr)`)
|
|
171
|
+
|
|
172
|
+
## Header
|
|
173
|
+
|
|
174
|
+
Use `Layout.Header` to add a page-level header with title, actions, and optional full-width content:
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
<Layout>
|
|
178
|
+
<Layout.Header
|
|
179
|
+
title="Order #12345"
|
|
180
|
+
actions={[
|
|
181
|
+
<Button key="edit">Edit</Button>,
|
|
182
|
+
<Button key="delete" variant="destructive">
|
|
183
|
+
Delete
|
|
184
|
+
</Button>,
|
|
185
|
+
]}
|
|
186
|
+
/>
|
|
187
|
+
<Layout.Column>{/* ... */}</Layout.Column>
|
|
188
|
+
<Layout.Column>{/* ... */}</Layout.Column>
|
|
189
|
+
</Layout>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The header displays:
|
|
193
|
+
|
|
194
|
+
- **Title** on the left (rendered as `<h1>`, large and bold)
|
|
195
|
+
- **Actions** on the right (buttons, dropdowns, etc.)
|
|
196
|
+
- **Children** (optional) full-width below the title/actions row
|
|
197
|
+
|
|
198
|
+
### Header with Tabs
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<Layout>
|
|
202
|
+
<Layout.Header title="Purchase Orders" actions={[<Button key="create">Create</Button>]}>
|
|
203
|
+
<Tabs value={tab} onValueChange={setTab}>
|
|
204
|
+
<TabsList>
|
|
205
|
+
<TabsTrigger value="all">All</TabsTrigger>
|
|
206
|
+
<TabsTrigger value="open">Open</TabsTrigger>
|
|
207
|
+
</TabsList>
|
|
208
|
+
</Tabs>
|
|
209
|
+
</Layout.Header>
|
|
210
|
+
<Layout.Column>…</Layout.Column>
|
|
211
|
+
</Layout>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Area Mode
|
|
215
|
+
|
|
216
|
+
By default, column widths are determined by position (first, second, third). You can use the `area` prop on `Layout.Column` to explicitly assign roles:
|
|
217
|
+
|
|
218
|
+
| Area | Width |
|
|
219
|
+
| --------- | -------------- |
|
|
220
|
+
| `"left"` | Fixed 320px |
|
|
221
|
+
| `"main"` | Flexible (1fr) |
|
|
222
|
+
| `"right"` | Fixed 280px |
|
|
223
|
+
| _(unset)_ | Flexible (1fr) |
|
|
224
|
+
|
|
225
|
+
If any `Layout.Column` has an `area` prop, all columns switch to area-based widths. Columns without an `area` default to flexible (`1fr`).
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
<Layout>
|
|
229
|
+
<Layout.Column area="left">
|
|
230
|
+
<nav>Sidebar</nav>
|
|
231
|
+
</Layout.Column>
|
|
232
|
+
<Layout.Column area="main">
|
|
233
|
+
<h2>Content</h2>
|
|
234
|
+
</Layout.Column>
|
|
235
|
+
</Layout>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Columns are rendered in source order — place them in the visual order you want.
|
|
239
|
+
|
|
240
|
+
## Fill Mode
|
|
241
|
+
|
|
242
|
+
By default, `<Layout>` grows with its content and the AppShell content area scrolls. Set `fill` to instead stretch the layout to the available height and bound its column row, so a child component can scroll **internally** while the page chrome stays pinned:
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
<Layout fill>
|
|
246
|
+
<Layout.Header title="Products" />
|
|
247
|
+
<Layout.Column>
|
|
248
|
+
<DataTable.Root value={table}>
|
|
249
|
+
<DataTable.Toolbar>
|
|
250
|
+
<DataTable.Filters />
|
|
251
|
+
</DataTable.Toolbar>
|
|
252
|
+
<DataTable.Table />
|
|
253
|
+
<DataTable.Footer>
|
|
254
|
+
<DataTable.Pagination />
|
|
255
|
+
</DataTable.Footer>
|
|
256
|
+
</DataTable.Root>
|
|
257
|
+
</Layout.Column>
|
|
258
|
+
</Layout>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
With `fill`, the `Layout.Header` (title/actions), the `DataTable` toolbar, its column header row, and its footer all remain visible regardless of row count — only the table's rows region scrolls vertically. When the content is short enough to fit, nothing stretches and no scrollbar appears.
|
|
262
|
+
|
|
263
|
+
Use `fill` for pages whose main content manages its own scrolling (typically a `DataTable`). Leave it off for pages that should flow and scroll naturally (forms, articles, dashboards). It is intended for single-row layouts; when multiple columns stack vertically on mobile, the content area scrolls as usual.
|
|
264
|
+
|
|
265
|
+
> Because the shell is viewport-bounded, page content scrolls inside the content area rather than on the document. If you have code that read `window`/document scroll, reach for the content scroll container instead — see [Accessing the content scroll container](./sidebar-layout.md#accessing-the-content-scroll-container).
|
|
266
|
+
|
|
267
|
+
## Gap Spacing
|
|
268
|
+
|
|
269
|
+
Use the `gap` prop to control the space between columns. Supported steps are `4`, `6` and `8`:
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
<Layout gap={6}>
|
|
273
|
+
<Layout.Column>{/* ... */}</Layout.Column>
|
|
274
|
+
<Layout.Column>{/* ... */}</Layout.Column>
|
|
275
|
+
</Layout>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Examples
|
|
279
|
+
|
|
280
|
+
### Order Detail Page
|
|
281
|
+
|
|
282
|
+
```tsx
|
|
283
|
+
function OrderDetailPage() {
|
|
284
|
+
const { id } = useParams();
|
|
285
|
+
const order = useOrder(id);
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
<Layout>
|
|
289
|
+
<Layout.Header
|
|
290
|
+
title={`Order #${order.orderNumber}`}
|
|
291
|
+
actions={[
|
|
292
|
+
<Button key="print" variant="outline">
|
|
293
|
+
Print
|
|
294
|
+
</Button>,
|
|
295
|
+
<Button key="edit">Edit Order</Button>,
|
|
296
|
+
]}
|
|
297
|
+
/>
|
|
298
|
+
<Layout.Column>
|
|
299
|
+
<DescriptionCard
|
|
300
|
+
data={order}
|
|
301
|
+
fields={[
|
|
302
|
+
{ key: "customer.name", label: "Customer" },
|
|
303
|
+
{ key: "orderDate", label: "Order Date", type: "date" },
|
|
304
|
+
{ key: "status", label: "Status", type: "badge" },
|
|
305
|
+
{ type: "divider" },
|
|
306
|
+
{ key: "total", label: "Total", type: "money" },
|
|
307
|
+
{ key: "shippingAddress", label: "Shipping", type: "address" },
|
|
308
|
+
]}
|
|
309
|
+
/>
|
|
310
|
+
</Layout.Column>
|
|
311
|
+
<Layout.Column>
|
|
312
|
+
<Card>
|
|
313
|
+
<h3>Quick Actions</h3>
|
|
314
|
+
<Button fullWidth>Mark as Shipped</Button>
|
|
315
|
+
<Button fullWidth>Send Invoice</Button>
|
|
316
|
+
</Card>
|
|
317
|
+
<Card>
|
|
318
|
+
<h3>Order History</h3>
|
|
319
|
+
<Timeline events={order.history} />
|
|
320
|
+
</Card>
|
|
321
|
+
</Layout.Column>
|
|
322
|
+
</Layout>
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Dashboard with 3 Columns
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
function Dashboard() {
|
|
331
|
+
return (
|
|
332
|
+
<Layout>
|
|
333
|
+
<Layout.Header title="Dashboard" />
|
|
334
|
+
<Layout.Column>
|
|
335
|
+
<Card>
|
|
336
|
+
<h3>Navigation</h3>
|
|
337
|
+
<nav>
|
|
338
|
+
<a href="#overview">Overview</a>
|
|
339
|
+
<a href="#sales">Sales</a>
|
|
340
|
+
<a href="#products">Products</a>
|
|
341
|
+
</nav>
|
|
342
|
+
</Card>
|
|
343
|
+
</Layout.Column>
|
|
344
|
+
<Layout.Column>
|
|
345
|
+
<Card>
|
|
346
|
+
<h2>Sales Overview</h2>
|
|
347
|
+
<Chart data={salesData} />
|
|
348
|
+
</Card>
|
|
349
|
+
<Card>
|
|
350
|
+
<h2>Recent Orders</h2>
|
|
351
|
+
<OrdersTable orders={recentOrders} />
|
|
352
|
+
</Card>
|
|
353
|
+
</Layout.Column>
|
|
354
|
+
<Layout.Column>
|
|
355
|
+
<Card>
|
|
356
|
+
<h3>Activity Feed</h3>
|
|
357
|
+
<ActivityList activities={activities} />
|
|
358
|
+
</Card>
|
|
359
|
+
</Layout.Column>
|
|
360
|
+
</Layout>
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Form with Live Preview
|
|
366
|
+
|
|
367
|
+
```tsx
|
|
368
|
+
function ProductEditor() {
|
|
369
|
+
const [product, setProduct] = useState(initialProduct);
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<Layout>
|
|
373
|
+
<Layout.Header
|
|
374
|
+
title="Edit Product"
|
|
375
|
+
actions={[
|
|
376
|
+
<Button key="cancel" variant="outline">
|
|
377
|
+
Cancel
|
|
378
|
+
</Button>,
|
|
379
|
+
<Button key="save">Save Changes</Button>,
|
|
380
|
+
]}
|
|
381
|
+
/>
|
|
382
|
+
<Layout.Column>
|
|
383
|
+
<Card>
|
|
384
|
+
<h3>Product Details</h3>
|
|
385
|
+
<Input
|
|
386
|
+
label="Name"
|
|
387
|
+
value={product.name}
|
|
388
|
+
onChange={(e) => setProduct({ ...product, name: e.target.value })}
|
|
389
|
+
/>
|
|
390
|
+
<Input
|
|
391
|
+
label="Price"
|
|
392
|
+
type="number"
|
|
393
|
+
value={product.price}
|
|
394
|
+
onChange={(e) => setProduct({ ...product, price: e.target.value })}
|
|
395
|
+
/>
|
|
396
|
+
<Textarea
|
|
397
|
+
label="Description"
|
|
398
|
+
value={product.description}
|
|
399
|
+
onChange={(e) => setProduct({ ...product, description: e.target.value })}
|
|
400
|
+
/>
|
|
401
|
+
</Card>
|
|
402
|
+
</Layout.Column>
|
|
403
|
+
<Layout.Column>
|
|
404
|
+
<Card>
|
|
405
|
+
<h3>Preview</h3>
|
|
406
|
+
<ProductCard product={product} />
|
|
407
|
+
</Card>
|
|
408
|
+
</Layout.Column>
|
|
409
|
+
</Layout>
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Area-Based Layout
|
|
415
|
+
|
|
416
|
+
```tsx
|
|
417
|
+
function EditorPage() {
|
|
418
|
+
return (
|
|
419
|
+
<Layout>
|
|
420
|
+
<Layout.Header title="Editor" />
|
|
421
|
+
<Layout.Column area="left">
|
|
422
|
+
<FileTree />
|
|
423
|
+
</Layout.Column>
|
|
424
|
+
<Layout.Column area="main">
|
|
425
|
+
<CodeEditor />
|
|
426
|
+
</Layout.Column>
|
|
427
|
+
<Layout.Column area="right">
|
|
428
|
+
<PropertiesPanel />
|
|
429
|
+
</Layout.Column>
|
|
430
|
+
</Layout>
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### Single Column with Header
|
|
436
|
+
|
|
437
|
+
```tsx
|
|
438
|
+
<Layout>
|
|
439
|
+
<Layout.Header title="Settings" actions={[<Button key="save">Save Changes</Button>]} />
|
|
440
|
+
<Layout.Column>
|
|
441
|
+
<Card>
|
|
442
|
+
<h3>Account Settings</h3>
|
|
443
|
+
<SettingsForm />
|
|
444
|
+
</Card>
|
|
445
|
+
</Layout.Column>
|
|
446
|
+
</Layout>
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Responsive Behavior
|
|
450
|
+
|
|
451
|
+
The Layout component automatically handles responsive breakpoints:
|
|
452
|
+
|
|
453
|
+
### Breakpoints
|
|
454
|
+
|
|
455
|
+
| Screen Size | 1 Column | 2 Columns | 3+ Columns |
|
|
456
|
+
| ------------------------- | ---------- | ------------ | ------------ |
|
|
457
|
+
| Mobile (< 1024px) | Full width | Stacked | Stacked |
|
|
458
|
+
| Desktop (1024px - 1280px) | Full width | Side-by-side | Stacked |
|
|
459
|
+
| Large (≥ 1280px) | Full width | Side-by-side | Side-by-side |
|
|
460
|
+
|
|
461
|
+
### Column Widths
|
|
462
|
+
|
|
463
|
+
**2 Columns (Desktop):**
|
|
464
|
+
|
|
465
|
+
- Column 1: Flexible (takes remaining space)
|
|
466
|
+
- Column 2: Fixed 280px
|
|
467
|
+
|
|
468
|
+
**3 Columns (Desktop):**
|
|
469
|
+
|
|
470
|
+
- Column 1: Fixed 320px
|
|
471
|
+
- Column 2: Flexible (takes remaining space)
|
|
472
|
+
- Column 3: Fixed 280px
|
|
473
|
+
|
|
474
|
+
**4+ Columns (Desktop):**
|
|
475
|
+
|
|
476
|
+
- All columns: Equal width (`repeat(N, 1fr)`)
|
|
477
|
+
|
|
478
|
+
## Validation
|
|
479
|
+
|
|
480
|
+
The Layout component validates its children:
|
|
481
|
+
|
|
482
|
+
- Only `Layout.Header` and `Layout.Column` are recognized as direct children; other elements are silently filtered out
|
|
483
|
+
- If multiple `Layout.Header` children are provided, only the first one is rendered
|
|
484
|
+
- When the deprecated `columns` prop is set and doesn't match the actual `Layout.Column` child count, a console warning is emitted
|
|
485
|
+
|
|
486
|
+
## Styling
|
|
487
|
+
|
|
488
|
+
### Custom Styling
|
|
489
|
+
|
|
490
|
+
Add custom classes to the layout container. Keep to properties the layout doesn't set itself — it manages its own vertical padding and column gap (`gap`):
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
<Layout className="bg-muted rounded-lg">{/* ... */}</Layout>
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Add custom classes to individual columns:
|
|
497
|
+
|
|
498
|
+
```tsx
|
|
499
|
+
<Layout>
|
|
500
|
+
<Layout.Column className="bg-card shadow-sm">{/* Main content with background */}</Layout.Column>
|
|
501
|
+
<Layout.Column className="space-y-4">{/* Sidebar with extra spacing */}</Layout.Column>
|
|
502
|
+
</Layout>
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
## Best Practices
|
|
506
|
+
|
|
507
|
+
### Do:
|
|
508
|
+
|
|
509
|
+
- ✅ Use 2 columns for detail pages with sidebar
|
|
510
|
+
- ✅ Use 3 columns for dashboards and complex layouts
|
|
511
|
+
- ✅ Add meaningful titles to pages
|
|
512
|
+
- ✅ Group related actions in the header
|
|
513
|
+
- ✅ Keep sidebars focused (5-7 items max)
|
|
514
|
+
|
|
515
|
+
### Don't:
|
|
516
|
+
|
|
517
|
+
- ❌ Use 3 columns for mobile-first designs (too complex)
|
|
518
|
+
- ❌ Mix Layout with other layout systems (conflicts)
|
|
519
|
+
- ❌ Put too many actions in header (use dropdown menus)
|
|
520
|
+
- ❌ Forget to handle responsive behavior
|
|
521
|
+
|
|
522
|
+
## Accessibility
|
|
523
|
+
|
|
524
|
+
- Semantic HTML structure
|
|
525
|
+
- Proper heading hierarchy
|
|
526
|
+
- Keyboard navigation support
|
|
527
|
+
- Screen reader friendly
|
|
528
|
+
|
|
529
|
+
## Related Components
|
|
530
|
+
|
|
531
|
+
- [Grid](./grid.md) - Content-level grid for arranging items into columns
|
|
532
|
+
- [DescriptionCard](./description-card.md) - Display data in columns
|
|
533
|
+
- [Badge](./badge.md) - Status indicators
|
|
534
|
+
- [SidebarLayout](./sidebar-layout.md) - App-level layout
|
|
535
|
+
|
|
536
|
+
## Related Concepts
|
|
537
|
+
|
|
538
|
+
- [Styling and Theming](../concepts/styling-theming.md) - Customize appearance
|
|
539
|
+
- [Modules and Resources](../concepts/modules-and-resources.md) - Page structure
|