0
# Layout Components
1
2
NextUI's layout components provide the structural foundation for organizing content, creating visual hierarchy, and managing spacing in your applications.
3
4
## Capabilities
5
6
### Card
7
8
A flexible container component for grouping related content with customizable shadows, borders, and interactive states.
9
10
```typescript { .api }
11
interface CardProps {
12
/** Card content */
13
children?: React.ReactNode;
14
/** Card shadow intensity */
15
shadow?: "none" | "sm" | "md" | "lg";
16
/** Border radius size */
17
radius?: "none" | "sm" | "md" | "lg";
18
/** Whether card takes full available width */
19
fullWidth?: boolean;
20
/** Enable hover elevation effect */
21
isHoverable?: boolean;
22
/** Enable press/click interaction */
23
isPressable?: boolean;
24
/** Apply blur backdrop effect */
25
isBlurred?: boolean;
26
/** Disable all interactions */
27
isDisabled?: boolean;
28
/** Disable animations */
29
disableAnimation?: boolean;
30
/** Disable ripple effect on press */
31
disableRipple?: boolean;
32
/** Allow text selection when pressable */
33
allowTextSelectionOnPress?: boolean;
34
/** Custom CSS class */
35
className?: string;
36
/** Slot-based styling */
37
classNames?: SlotsToClasses<CardSlots>;
38
/** Press event handler */
39
onPress?: () => void;
40
}
41
42
type CardSlots = "base" | "header" | "body" | "footer";
43
44
function Card(props: CardProps): JSX.Element;
45
46
/**
47
* Hook for Card state management
48
*/
49
function useCard(props: CardProps): {
50
Component: React.ElementType;
51
slots: Record<CardSlots, string>;
52
classNames: SlotsToClasses<CardSlots>;
53
getCardProps: () => any;
54
};
55
```
56
57
### Card Sections
58
59
Specialized components for structuring content within cards.
60
61
```typescript { .api }
62
interface CardHeaderProps {
63
/** Header content */
64
children?: React.ReactNode;
65
/** Custom CSS class */
66
className?: string;
67
}
68
69
interface CardBodyProps {
70
/** Body content */
71
children?: React.ReactNode;
72
/** Custom CSS class */
73
className?: string;
74
}
75
76
interface CardFooterProps {
77
/** Footer content */
78
children?: React.ReactNode;
79
/** Custom CSS class */
80
className?: string;
81
}
82
83
function CardHeader(props: CardHeaderProps): JSX.Element;
84
function CardBody(props: CardBodyProps): JSX.Element;
85
function CardFooter(props: CardFooterProps): JSX.Element;
86
```
87
88
**Card Usage Example:**
89
90
```typescript
91
import { Card, CardHeader, CardBody, CardFooter, Button, Image } from "@nextui-org/react";
92
93
function ProductCard() {
94
return (
95
<Card isHoverable isPressable className="max-w-[300px]">
96
<CardHeader className="pb-0 pt-2 px-4 flex-col items-start">
97
<p className="text-tiny uppercase font-bold">Daily Mix</p>
98
<small className="text-default-500">12 Tracks</small>
99
<h4 className="font-bold text-large">Frontend Radio</h4>
100
</CardHeader>
101
<CardBody className="overflow-visible py-2">
102
<Image
103
alt="Card background"
104
className="object-cover rounded-xl"
105
src="/images/hero-card-complete.jpeg"
106
width={270}
107
/>
108
</CardBody>
109
<CardFooter className="pt-2">
110
<Button
111
className="w-full"
112
color="primary"
113
radius="lg"
114
size="sm"
115
>
116
Play Now
117
</Button>
118
</CardFooter>
119
</Card>
120
);
121
}
122
```
123
124
### Card Context
125
126
Context system for sharing card state across card sections.
127
128
```typescript { .api }
129
interface CardProviderProps {
130
children: React.ReactNode;
131
value: CardContextValue;
132
}
133
134
interface CardContextValue {
135
slots: Record<CardSlots, string>;
136
classNames?: SlotsToClasses<CardSlots>;
137
isPressed?: boolean;
138
isHovered?: boolean;
139
isDisabled?: boolean;
140
}
141
142
const CardProvider: React.FC<CardProviderProps>;
143
144
/**
145
* Hook to access card context
146
* @throws Error if used outside CardProvider
147
*/
148
function useCardContext(): CardContextValue;
149
```
150
151
### Spacer
152
153
A flexible spacing component for creating consistent gaps between elements.
154
155
```typescript { .api }
156
interface SpacerProps {
157
/** Horizontal spacing (as CSS units or responsive scale) */
158
x?: number | string;
159
/** Vertical spacing (as CSS units or responsive scale) */
160
y?: number | string;
161
/** Custom CSS class */
162
className?: string;
163
}
164
165
function Spacer(props: SpacerProps): JSX.Element;
166
167
/**
168
* Hook for Spacer state management
169
*/
170
function useSpacer(props: SpacerProps): {
171
Component: React.ElementType;
172
getSpacerProps: () => any;
173
};
174
```
175
176
**Spacer Usage Examples:**
177
178
```typescript
179
import { Spacer, Button } from "@nextui-org/react";
180
181
function SpacingExample() {
182
return (
183
<div className="flex flex-col">
184
<Button>First Button</Button>
185
{/* Vertical spacing */}
186
<Spacer y={4} />
187
<Button>Second Button</Button>
188
189
{/* Horizontal spacing in flex row */}
190
<div className="flex">
191
<Button>Left</Button>
192
<Spacer x={2} />
193
<Button>Right</Button>
194
</div>
195
</div>
196
);
197
}
198
```
199
200
### Divider
201
202
A visual separator for organizing content sections with customizable orientation and styling.
203
204
```typescript { .api }
205
interface DividerProps {
206
/** Divider orientation */
207
orientation?: "horizontal" | "vertical";
208
/** Custom CSS class */
209
className?: string;
210
}
211
212
function Divider(props: DividerProps): JSX.Element;
213
214
/**
215
* Hook for Divider state management
216
*/
217
function useDivider(props: DividerProps): {
218
Component: React.ElementType;
219
getDividerProps: () => any;
220
};
221
```
222
223
**Divider Usage Examples:**
224
225
```typescript
226
import { Divider, Card, CardBody } from "@nextui-org/react";
227
228
function ContentSection() {
229
return (
230
<Card>
231
<CardBody>
232
<div>Section 1 Content</div>
233
234
{/* Horizontal divider */}
235
<Divider className="my-4" />
236
237
<div>Section 2 Content</div>
238
239
{/* Vertical divider in flex layout */}
240
<div className="flex items-center gap-4">
241
<span>Left content</span>
242
<Divider orientation="vertical" className="h-8" />
243
<span>Right content</span>
244
</div>
245
</CardBody>
246
</Card>
247
);
248
}
249
```
250
251
### Scroll Shadow
252
253
A container component that adds visual shadows to indicate scrollable content overflow.
254
255
```typescript { .api }
256
interface ScrollShadowProps {
257
/** Content to be wrapped with scroll shadows */
258
children?: React.ReactNode;
259
/** Shadow visibility configuration */
260
visibility?: ScrollShadowVisibility;
261
/** Scroll direction for shadow calculation */
262
orientation?: ScrollShadowOrientation;
263
/** Container height (required for vertical scrolling) */
264
height?: number | string;
265
/** Container width (required for horizontal scrolling) */
266
width?: number | string;
267
/** Maximum height before scrolling */
268
maxHeight?: number | string;
269
/** Whether shadows are enabled */
270
isEnabled?: boolean;
271
/** Shadow size */
272
size?: number;
273
/** Hide scrollbar */
274
hideScrollBar?: boolean;
275
/** Offset before showing shadows */
276
offset?: number;
277
/** Custom CSS class */
278
className?: string;
279
}
280
281
type ScrollShadowVisibility = "auto" | "top" | "bottom" | "left" | "right" | "both" | "none";
282
type ScrollShadowOrientation = "vertical" | "horizontal";
283
284
function ScrollShadow(props: ScrollShadowProps): JSX.Element;
285
286
/**
287
* Hook for ScrollShadow state management
288
*/
289
function useScrollShadow(props: ScrollShadowProps): {
290
Component: React.ElementType;
291
getScrollShadowProps: () => any;
292
getWrapperProps: () => any;
293
isTopShadowVisible: boolean;
294
isBottomShadowVisible: boolean;
295
isLeftShadowVisible: boolean;
296
isRightShadowVisible: boolean;
297
};
298
```
299
300
**ScrollShadow Usage Examples:**
301
302
```typescript
303
import { ScrollShadow, Card, CardBody } from "@nextui-org/react";
304
305
function ScrollableContent() {
306
const longContent = Array.from({ length: 50 }, (_, i) => (
307
<div key={i} className="py-2 px-4 border-b">
308
Item {i + 1}
309
</div>
310
));
311
312
return (
313
<Card>
314
<CardBody>
315
{/* Vertical scrolling with shadows */}
316
<ScrollShadow
317
height="300px"
318
className="w-full"
319
hideScrollBar
320
>
321
<div className="space-y-2">
322
{longContent}
323
</div>
324
</ScrollShadow>
325
326
{/* Horizontal scrolling */}
327
<ScrollShadow
328
orientation="horizontal"
329
width="300px"
330
className="mt-4"
331
>
332
<div className="flex gap-4 w-max">
333
{Array.from({ length: 20 }, (_, i) => (
334
<div
335
key={i}
336
className="min-w-[120px] p-4 bg-gray-100 rounded"
337
>
338
Card {i + 1}
339
</div>
340
))}
341
</div>
342
</ScrollShadow>
343
</CardBody>
344
</Card>
345
);
346
}
347
```
348
349
## Layout Component Types
350
351
```typescript { .api }
352
// Shared types for layout components
353
interface LayoutBaseProps {
354
/** Component content */
355
children?: React.ReactNode;
356
/** Custom CSS class */
357
className?: string;
358
}
359
360
// Card-specific types
361
interface CardContextValue {
362
slots: Record<CardSlots, string>;
363
classNames?: SlotsToClasses<CardSlots>;
364
isPressed?: boolean;
365
isHovered?: boolean;
366
isDisabled?: boolean;
367
}
368
369
// Spacing utilities
370
type SpacingValue = number | string | {
371
xs?: number | string;
372
sm?: number | string;
373
md?: number | string;
374
lg?: number | string;
375
xl?: number | string;
376
};
377
378
// Scroll shadow utilities
379
interface ScrollShadowState {
380
isScrollable: boolean;
381
canScrollUp: boolean;
382
canScrollDown: boolean;
383
canScrollLeft: boolean;
384
canScrollRight: boolean;
385
scrollTop: number;
386
scrollLeft: number;
387
scrollHeight: number;
388
scrollWidth: number;
389
clientHeight: number;
390
clientWidth: number;
391
}
392
```
393
394
## Integration Examples
395
396
### Responsive Card Layout
397
398
```typescript
399
import { Card, CardHeader, CardBody, Spacer, Divider } from "@nextui-org/react";
400
401
function ResponsiveLayout() {
402
return (
403
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
404
{[1, 2, 3, 4, 5, 6].map((item) => (
405
<Card key={item} className="h-full">
406
<CardHeader>
407
<h3 className="text-lg font-semibold">Card {item}</h3>
408
</CardHeader>
409
<Divider />
410
<CardBody className="flex-grow">
411
<p>Card content goes here...</p>
412
<Spacer y={2} />
413
<p>More content with consistent spacing.</p>
414
</CardBody>
415
</Card>
416
))}
417
</div>
418
);
419
}
420
```
421
422
### Complex Layout with ScrollShadow
423
424
```typescript
425
import {
426
Card, CardHeader, CardBody,
427
ScrollShadow, Spacer, Divider
428
} from "@nextui-org/react";
429
430
function DashboardLayout() {
431
return (
432
<div className="flex h-screen">
433
{/* Sidebar */}
434
<Card className="w-64 rounded-none">
435
<CardHeader>
436
<h2>Navigation</h2>
437
</CardHeader>
438
<Divider />
439
<CardBody className="p-0">
440
<ScrollShadow height="100%">
441
<div className="p-4 space-y-2">
442
{/* Navigation items */}
443
</div>
444
</ScrollShadow>
445
</CardBody>
446
</Card>
447
448
<Spacer x={1} />
449
450
{/* Main content */}
451
<Card className="flex-1 rounded-none">
452
<CardHeader>
453
<h1>Dashboard</h1>
454
</CardHeader>
455
<Divider />
456
<CardBody>
457
<ScrollShadow height="calc(100vh - 120px)">
458
<div className="space-y-6">
459
{/* Main content */}
460
</div>
461
</ScrollShadow>
462
</CardBody>
463
</Card>
464
</div>
465
);
466
}
467
```