0
# Layout Components
1
2
Container and structural components for organizing dashboards.
3
4
## Layout Selection
5
6
| Component | Purpose | Key Props |
7
|-----------|---------|-----------|
8
| Card | Content container | `decoration`, `decorationColor` |
9
| Flex | Flexbox layout | `flexDirection`, `justifyContent`, `alignItems` |
10
| Grid | Responsive grid | `numItems`, `numItemsSm/Md/Lg` |
11
| Col | Grid column span | `numColSpan`, `numColSpanSm/Md/Lg` |
12
| Divider | Visual separator | `children` (optional label) |
13
| Dialog | Modal overlay | `open`, `onClose`, `static`, `unmount` |
14
| Accordion | Collapsible sections | `defaultOpen` (use with AccordionList/Header/Body) |
15
16
## Card
17
18
```typescript { .api }
19
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
20
decoration?: "left" | "right" | "top" | "bottom" | "";
21
decorationColor?: Color;
22
}
23
```
24
25
**Examples:**
26
27
```typescript
28
import { Card, Title, Text } from '@tremor/react';
29
30
<Card><Title>Sales Overview</Title></Card>
31
<Card decoration="left" decorationColor="blue"><Title>New Users</Title></Card>
32
```
33
34
## Flex
35
36
```typescript { .api }
37
interface FlexProps extends React.HTMLAttributes<HTMLDivElement> {
38
flexDirection?: "row" | "col" | "row-reverse" | "col-reverse";
39
justifyContent?: "start" | "end" | "center" | "between" | "around" | "evenly";
40
alignItems?: "start" | "end" | "center" | "baseline" | "stretch";
41
children: React.ReactNode;
42
}
43
```
44
45
**Examples:**
46
47
```typescript
48
import { Flex, Title, Button } from '@tremor/react';
49
50
// Header layout
51
<Flex justifyContent="between" alignItems="center">
52
<Title>Dashboard</Title>
53
<Button>Export</Button>
54
</Flex>
55
56
// Vertical stack
57
<Flex flexDirection="col" alignItems="center" className="gap-4">
58
<Title>Welcome</Title>
59
<Button>Continue</Button>
60
</Flex>
61
```
62
63
## Grid
64
65
```typescript { .api }
66
interface GridProps extends React.HTMLAttributes<HTMLDivElement> {
67
numItems?: number; // Base columns
68
numItemsSm?: number; // 640px+
69
numItemsMd?: number; // 768px+
70
numItemsLg?: number; // 1024px+
71
children: React.ReactNode;
72
}
73
```
74
75
**Examples:**
76
77
```typescript
78
import { Grid, Card, Metric, Text } from '@tremor/react';
79
80
// Responsive: 1 col mobile, 2 tablet, 4 desktop
81
<Grid numItems={1} numItemsSm={2} numItemsLg={4} className="gap-6">
82
<Card><Text>Users</Text><Metric>1,234</Metric></Card>
83
<Card><Text>Revenue</Text><Metric>$45,231</Metric></Card>
84
<Card><Text>Conversion</Text><Metric>3.2%</Metric></Card>
85
<Card><Text>Growth</Text><Metric>+12%</Metric></Card>
86
</Grid>
87
```
88
89
## Col
90
91
Use within Grid to control column spans at different breakpoints.
92
93
```typescript { .api }
94
interface ColProps extends React.HTMLAttributes<HTMLDivElement> {
95
numColSpan?: number;
96
numColSpanSm?: number;
97
numColSpanMd?: number;
98
numColSpanLg?: number;
99
children?: React.ReactNode;
100
}
101
```
102
103
**Examples:**
104
105
```typescript
106
import { Grid, Col, Card } from '@tremor/react';
107
108
<Grid numItems={12}>
109
<Col numColSpan={12} numColSpanLg={3}>
110
<Card>Sidebar (3 cols on lg)</Card>
111
</Col>
112
<Col numColSpan={12} numColSpanLg={9}>
113
<Card>Main content (9 cols on lg)</Card>
114
</Col>
115
</Grid>
116
```
117
118
## Divider
119
120
```typescript { .api }
121
interface DividerProps extends React.HTMLAttributes<HTMLDivElement> {
122
children?: React.ReactNode; // Optional centered text label
123
}
124
```
125
126
**Examples:**
127
128
```typescript
129
import { Divider, Card } from '@tremor/react';
130
131
<Card>
132
<div>Section 1</div>
133
<Divider />
134
<div>Section 2</div>
135
</Card>
136
137
// With label
138
<Divider>Settings</Divider>
139
```
140
141
## Dialog
142
143
Modal dialog system. Requires `DialogPanel` child.
144
145
```typescript { .api }
146
interface DialogProps {
147
open: boolean; // Required, controlled
148
onClose: (value: boolean) => void; // Required
149
role?: "dialog" | "alertdialog";
150
static?: boolean; // Disable backdrop/Escape closing
151
unmount?: boolean; // Unmount when closed
152
children: React.ReactNode; // Usually DialogPanel
153
}
154
155
interface DialogPanelProps extends React.HTMLAttributes<HTMLDivElement> {
156
children: React.ReactNode;
157
}
158
```
159
160
**Examples:**
161
162
```typescript
163
import { Dialog, DialogPanel, Button, Title, Text } from '@tremor/react';
164
import { useState } from 'react';
165
166
function BasicDialog() {
167
const [isOpen, setIsOpen] = useState(false);
168
169
return (
170
<>
171
<Button onClick={() => setIsOpen(true)}>Open Dialog</Button>
172
<Dialog open={isOpen} onClose={setIsOpen}>
173
<DialogPanel>
174
<Title>Dialog Title</Title>
175
<Text className="mt-2">Dialog content</Text>
176
<Button className="mt-4" onClick={() => setIsOpen(false)}>Close</Button>
177
</DialogPanel>
178
</Dialog>
179
</>
180
);
181
}
182
183
// Confirmation dialog
184
function ConfirmDialog() {
185
const [isOpen, setIsOpen] = useState(false);
186
187
return (
188
<Dialog open={isOpen} onClose={setIsOpen}>
189
<DialogPanel className="max-w-sm">
190
<Title>Confirm Deletion</Title>
191
<Text>Are you sure? This cannot be undone.</Text>
192
<div className="mt-6 flex gap-3 justify-end">
193
<Button variant="secondary" onClick={() => setIsOpen(false)}>Cancel</Button>
194
<Button color="red" onClick={() => {/* delete */ setIsOpen(false)}}>Delete</Button>
195
</div>
196
</DialogPanel>
197
</Dialog>
198
);
199
}
200
```
201
202
## Accordion
203
204
Collapsible sections. Use `AccordionList` to group multiple accordions.
205
206
```typescript { .api }
207
interface AccordionProps {
208
defaultOpen?: boolean;
209
children: React.ReactNode; // AccordionHeader and AccordionBody
210
}
211
212
interface AccordionListProps {
213
children: React.ReactElement[] | React.ReactElement; // Accordion components
214
}
215
216
interface AccordionHeaderProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
217
children?: React.ReactNode;
218
}
219
220
interface AccordionBodyProps {
221
children?: React.ReactNode;
222
}
223
```
224
225
**Examples:**
226
227
```typescript
228
import {
229
Accordion,
230
AccordionList,
231
AccordionHeader,
232
AccordionBody,
233
Text,
234
} from '@tremor/react';
235
236
// Single accordion
237
<Accordion>
238
<AccordionHeader>Product Information</AccordionHeader>
239
<AccordionBody>
240
<Text>Detailed specifications...</Text>
241
</AccordionBody>
242
</Accordion>
243
244
// Starts open
245
<Accordion defaultOpen={true}>
246
<AccordionHeader>Important Notice</AccordionHeader>
247
<AccordionBody><Text>Visible by default</Text></AccordionBody>
248
</Accordion>
249
250
// Grouped accordions
251
<AccordionList>
252
<Accordion>
253
<AccordionHeader>Shipping</AccordionHeader>
254
<AccordionBody><Text>Free shipping on orders over $50...</Text></AccordionBody>
255
</Accordion>
256
<Accordion>
257
<AccordionHeader>Returns</AccordionHeader>
258
<AccordionBody><Text>Returns accepted within 30 days...</Text></AccordionBody>
259
</Accordion>
260
</AccordionList>
261
```
262
263
**Notes:**
264
- AccordionList provides seamless borders between accordions
265
- Each Accordion manages its own open/close state independently
266
- AccordionHeader renders as `<button>` for accessibility
267
- Use `defaultOpen` to set initial state (uncontrolled)
268
269
## Dashboard Layout Pattern
270
271
```typescript
272
import { Grid, Card, Flex, Title, Text, Metric, Button } from '@tremor/react';
273
274
function Dashboard() {
275
return (
276
<div className="p-6 space-y-6">
277
{/* Header */}
278
<Flex justifyContent="between" alignItems="center">
279
<div>
280
<Title>Analytics Dashboard</Title>
281
<Text>Key performance metrics</Text>
282
</div>
283
<Button>Export Report</Button>
284
</Flex>
285
286
{/* Metrics Grid */}
287
<Grid numItems={1} numItemsSm={2} numItemsLg={4} className="gap-6">
288
<Card decoration="left" decorationColor="blue">
289
<Text>Revenue</Text>
290
<Metric>$45,231</Metric>
291
</Card>
292
{/* More cards... */}
293
</Grid>
294
</div>
295
);
296
}
297
```
298
299
## Common Mistakes
300
301
- ❌ Not providing responsive props for Grid (use numItemsSm/Md/Lg)
302
- ❌ Forgetting DialogPanel inside Dialog
303
- ❌ Using AccordionHeader/Body outside Accordion
304
- ❌ Not wrapping multiple Accordions in AccordionList (missing seamless borders)
305
- ❌ Trying to control Accordion state (use defaultOpen, it's uncontrolled)
306
307
## See Also
308
309
- [Types Reference](./types.md) for Color, Size, FlexDirection, JustifyContent, AlignItems
310