@ceed/cds 1.31.1-next.2 → 1.31.2-next.1
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/components/surfaces/Card.md +656 -462
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +3 -3
- package/dist/index.cjs +38 -23
- package/dist/index.js +38 -23
- package/framer/index.js +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
The Card component is a UI element that groups related content and actions within a single container. It helps users scan and understand information more easily by structuring and visually grouping it. It is commonly used for news feeds, product lists, user profiles, dashboard widgets, and more.
|
|
6
6
|
|
|
7
|
+
Card is composed of five subcomponents: `Card`, `CardContent`, `CardCover`, `CardActions`, and `CardOverflow`.
|
|
8
|
+
|
|
7
9
|
```tsx
|
|
8
10
|
<Card {...args} sx={{
|
|
9
11
|
maxWidth: 320
|
|
@@ -30,26 +32,19 @@ function MyComponent() {
|
|
|
30
32
|
return (
|
|
31
33
|
<Card sx={{ maxWidth: 320 }}>
|
|
32
34
|
<CardContent>
|
|
33
|
-
<Typography level="title-lg"
|
|
34
|
-
<Typography level="body-md"
|
|
35
|
+
<Typography level="title-lg">Card Title</Typography>
|
|
36
|
+
<Typography level="body-md">Card body content goes here.</Typography>
|
|
35
37
|
</CardContent>
|
|
36
38
|
</Card>
|
|
37
39
|
);
|
|
38
40
|
}
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
### Basic Usage
|
|
43
|
+
## Basic Usage
|
|
44
44
|
|
|
45
|
-
The most basic
|
|
45
|
+
The most basic card with a title and body text.
|
|
46
46
|
|
|
47
47
|
```tsx
|
|
48
|
-
<div style={{
|
|
49
|
-
display: 'flex',
|
|
50
|
-
gap: '1rem',
|
|
51
|
-
flexWrap: 'wrap'
|
|
52
|
-
}}>
|
|
53
48
|
<Card sx={{
|
|
54
49
|
maxWidth: 300
|
|
55
50
|
}}>
|
|
@@ -60,172 +55,277 @@ The most basic way to use a card.
|
|
|
60
55
|
</Typography>
|
|
61
56
|
</CardContent>
|
|
62
57
|
</Card>
|
|
63
|
-
</div>
|
|
64
58
|
```
|
|
65
59
|
|
|
66
|
-
|
|
60
|
+
## Variants
|
|
67
61
|
|
|
68
|
-
|
|
62
|
+
Four visual styles are available: `solid`, `soft`, `outlined` (default), and `plain`.
|
|
69
63
|
|
|
70
64
|
```tsx
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
}}>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<Typography level="body-sm">
|
|
65
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
66
|
+
{(['solid', 'soft', 'outlined', 'plain'] as const).map(variant => <Card key={variant} variant={variant} sx={{
|
|
67
|
+
width: 200
|
|
68
|
+
}}>
|
|
69
|
+
<CardContent>
|
|
70
|
+
<Typography level="title-md" sx={{
|
|
71
|
+
textTransform: 'capitalize'
|
|
72
|
+
}}>
|
|
73
|
+
{variant}
|
|
74
|
+
</Typography>
|
|
75
|
+
<Typography level="body-sm">{variant} 스타일 카드</Typography>
|
|
82
76
|
</CardContent>
|
|
83
|
-
</Card>
|
|
77
|
+
</Card>)}
|
|
78
|
+
</Stack>
|
|
79
|
+
```
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
maxWidth: 300
|
|
87
|
-
}}>
|
|
88
|
-
<CardContent>
|
|
89
|
-
<Typography level="title-md">Soft</Typography>
|
|
90
|
-
<Typography level="body-sm">Soft 스타일 카드</Typography>
|
|
91
|
-
</CardContent>
|
|
92
|
-
</Card>
|
|
81
|
+
## Colors
|
|
93
82
|
|
|
94
|
-
|
|
95
|
-
maxWidth: 300
|
|
96
|
-
}}>
|
|
97
|
-
<CardContent>
|
|
98
|
-
<Typography level="title-md">Outlined</Typography>
|
|
99
|
-
<Typography level="body-sm">Outlined 스타일 카드</Typography>
|
|
100
|
-
</CardContent>
|
|
101
|
-
</Card>
|
|
83
|
+
Apply a color scheme to match your UI context.
|
|
102
84
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<
|
|
85
|
+
```tsx
|
|
86
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
87
|
+
{(['primary', 'neutral', 'danger', 'success', 'warning'] as const).map(color => <Card key={color} color={color} variant="soft" sx={{
|
|
88
|
+
width: 180
|
|
89
|
+
}}>
|
|
90
|
+
<CardContent>
|
|
91
|
+
<Typography level="title-md" sx={{
|
|
92
|
+
textTransform: 'capitalize'
|
|
93
|
+
}}>
|
|
94
|
+
{color}
|
|
95
|
+
</Typography>
|
|
96
|
+
<Typography level="body-sm">{color} 색상 카드</Typography>
|
|
109
97
|
</CardContent>
|
|
110
|
-
</Card>
|
|
111
|
-
</
|
|
98
|
+
</Card>)}
|
|
99
|
+
</Stack>
|
|
112
100
|
```
|
|
113
101
|
|
|
114
|
-
|
|
102
|
+
## Sizes
|
|
115
103
|
|
|
116
|
-
|
|
104
|
+
Three sizes control the card's internal padding: `sm`, `md` (default), and `lg`.
|
|
117
105
|
|
|
118
106
|
```tsx
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<CardContent>
|
|
128
|
-
<Typography level="title-md">Primary</Typography>
|
|
129
|
-
<Typography level="body-sm">Primary 색상 카드</Typography>
|
|
130
|
-
</CardContent>
|
|
107
|
+
<Stack direction="row" spacing={2} alignItems="flex-start" flexWrap="wrap">
|
|
108
|
+
<Card size="sm" sx={{
|
|
109
|
+
width: 220
|
|
110
|
+
}}>
|
|
111
|
+
<CardContent>
|
|
112
|
+
<Typography level="title-sm">Small</Typography>
|
|
113
|
+
<Typography level="body-xs">작은 크기의 카드입니다.</Typography>
|
|
114
|
+
</CardContent>
|
|
131
115
|
</Card>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
maxWidth: 300
|
|
116
|
+
<Card size="md" sx={{
|
|
117
|
+
width: 260
|
|
135
118
|
}}>
|
|
136
119
|
<CardContent>
|
|
137
|
-
<Typography level="title-md">
|
|
138
|
-
<Typography level="body-sm"
|
|
120
|
+
<Typography level="title-md">Medium</Typography>
|
|
121
|
+
<Typography level="body-sm">중간 크기의 카드입니다.</Typography>
|
|
139
122
|
</CardContent>
|
|
140
123
|
</Card>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
maxWidth: 300
|
|
124
|
+
<Card size="lg" sx={{
|
|
125
|
+
width: 300
|
|
144
126
|
}}>
|
|
145
127
|
<CardContent>
|
|
146
|
-
<Typography level="title-
|
|
147
|
-
<Typography level="body-
|
|
128
|
+
<Typography level="title-lg">Large</Typography>
|
|
129
|
+
<Typography level="body-md">큰 크기의 카드입니다.</Typography>
|
|
148
130
|
</CardContent>
|
|
149
131
|
</Card>
|
|
132
|
+
</Stack>
|
|
133
|
+
```
|
|
150
134
|
|
|
151
|
-
|
|
152
|
-
|
|
135
|
+
## Horizontal Layout
|
|
136
|
+
|
|
137
|
+
Set `orientation="horizontal"` to arrange the card's children in a row. Combine with `CardOverflow` for a side-by-side image and text layout.
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
<Stack spacing={2} sx={{
|
|
141
|
+
maxWidth: 500
|
|
153
142
|
}}>
|
|
143
|
+
<Card orientation="horizontal" variant="outlined">
|
|
144
|
+
<CardOverflow>
|
|
145
|
+
<AspectRatio ratio="1" sx={{
|
|
146
|
+
width: 140
|
|
147
|
+
}}>
|
|
148
|
+
<img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=280" loading="lazy" alt="Shoes" />
|
|
149
|
+
</AspectRatio>
|
|
150
|
+
</CardOverflow>
|
|
154
151
|
<CardContent>
|
|
155
|
-
<Typography level="title-md"
|
|
156
|
-
<Typography level="body-sm"
|
|
152
|
+
<Typography level="title-md">운동화</Typography>
|
|
153
|
+
<Typography level="body-sm">편안하고 스타일리시한 운동화입니다.</Typography>
|
|
154
|
+
<Stack direction="row" spacing={1} alignItems="center" sx={{
|
|
155
|
+
mt: 'auto'
|
|
156
|
+
}}>
|
|
157
|
+
<Chip variant="outlined" color="primary" size="sm">무료배송</Chip>
|
|
158
|
+
<Typography level="title-sm" color="primary">₩129,000</Typography>
|
|
159
|
+
</Stack>
|
|
157
160
|
</CardContent>
|
|
161
|
+
<CardActions sx={{
|
|
162
|
+
flexDirection: 'column',
|
|
163
|
+
gap: 0.5
|
|
164
|
+
}}>
|
|
165
|
+
<Button size="sm" variant="solid" color="primary">구매</Button>
|
|
166
|
+
<IconButton size="sm" variant="outlined" color="neutral">
|
|
167
|
+
<BookmarkAddIcon />
|
|
168
|
+
</IconButton>
|
|
169
|
+
</CardActions>
|
|
158
170
|
</Card>
|
|
159
171
|
|
|
160
|
-
<Card
|
|
161
|
-
|
|
162
|
-
|
|
172
|
+
<Card orientation="horizontal" variant="outlined">
|
|
173
|
+
<CardOverflow>
|
|
174
|
+
<AspectRatio ratio="1" sx={{
|
|
175
|
+
width: 120
|
|
176
|
+
}}>
|
|
177
|
+
<img src="https://images.unsplash.com/photo-1551963831-b3b1ca40c98e?auto=format&fit=crop&w=240" loading="lazy" alt="Breakfast" />
|
|
178
|
+
</AspectRatio>
|
|
179
|
+
</CardOverflow>
|
|
163
180
|
<CardContent>
|
|
164
|
-
<Typography level="title-
|
|
165
|
-
<Typography level="body-
|
|
181
|
+
<Typography level="title-sm">맛있는 아침식사</Typography>
|
|
182
|
+
<Typography level="body-xs" startDecorator={<LocationOnIcon />}>서울, 한국</Typography>
|
|
183
|
+
<Typography level="body-xs" sx={{
|
|
184
|
+
mt: 0.5
|
|
185
|
+
}}>
|
|
186
|
+
건강하고 맛있는 아침 식사로 하루를 시작해보세요.
|
|
187
|
+
</Typography>
|
|
166
188
|
</CardContent>
|
|
167
189
|
</Card>
|
|
168
|
-
</
|
|
190
|
+
</Stack>
|
|
169
191
|
```
|
|
170
192
|
|
|
171
|
-
|
|
193
|
+
## Inverted Colors
|
|
172
194
|
|
|
173
|
-
|
|
195
|
+
The `invertedColors` prop automatically applies an inverted color scheme to child components (Typography, Button, etc.) — useful for dark-background solid cards.
|
|
174
196
|
|
|
175
197
|
```tsx
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
199
|
+
{(['primary', 'neutral', 'danger'] as const).map(color => <Card key={color} variant="solid" color={color} invertedColors sx={{
|
|
200
|
+
width: 260
|
|
201
|
+
}}>
|
|
202
|
+
<CardContent>
|
|
203
|
+
<Typography level="title-md" sx={{
|
|
204
|
+
textTransform: 'capitalize'
|
|
205
|
+
}}>{color}</Typography>
|
|
206
|
+
<Typography level="body-sm">
|
|
207
|
+
invertedColors를 사용하면 자식 컴포넌트가 자동으로 반전된 색상을 적용받습니다.
|
|
208
|
+
</Typography>
|
|
209
|
+
</CardContent>
|
|
210
|
+
<CardActions>
|
|
211
|
+
<Button variant="soft" size="sm">Action</Button>
|
|
212
|
+
<IconButton variant="soft" size="sm">
|
|
213
|
+
<OpenInNewIcon />
|
|
214
|
+
</IconButton>
|
|
215
|
+
</CardActions>
|
|
216
|
+
</Card>)}
|
|
217
|
+
</Stack>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Full Image Card
|
|
221
|
+
|
|
222
|
+
Use `CardOverflow` to fill the entire card with an image, then overlay `CardContent` using absolute positioning. Pass `component="a"` or `component="button"` to make the whole card clickable like a button.
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
226
|
+
<Card component="a" href="#" sx={{
|
|
227
|
+
width: 280,
|
|
228
|
+
height: 360,
|
|
229
|
+
boxShadow: 'lg',
|
|
230
|
+
textDecoration: 'none',
|
|
231
|
+
'&:hover img': {
|
|
232
|
+
transform: 'scale(1.05)'
|
|
233
|
+
},
|
|
234
|
+
transition: 'box-shadow 0.3s',
|
|
235
|
+
'&:hover': {
|
|
236
|
+
boxShadow: 'xl'
|
|
237
|
+
}
|
|
238
|
+
}} onClick={e => e.preventDefault()}>
|
|
239
|
+
<CardCover>
|
|
240
|
+
<img src="https://images.unsplash.com/photo-1527549993586-dff825b37782?auto=format&fit=crop&w=560&h=720" loading="lazy" alt="Mountain Peak" style={{
|
|
241
|
+
transition: 'transform 0.4s'
|
|
242
|
+
}} />
|
|
243
|
+
</CardCover>
|
|
244
|
+
<CardCover sx={{
|
|
245
|
+
background: 'linear-gradient(to top, rgba(0,0,0,0.7) 30%, rgba(0,0,0,0) 60%)'
|
|
246
|
+
}} />
|
|
247
|
+
<CardContent sx={{
|
|
248
|
+
justifyContent: 'flex-end'
|
|
249
|
+
}}>
|
|
250
|
+
<Typography level="title-lg" textColor="#fff">
|
|
251
|
+
Mountain Peak
|
|
252
|
+
</Typography>
|
|
253
|
+
<Typography level="body-sm" textColor="neutral.300">
|
|
254
|
+
Majestic mountain landscape
|
|
255
|
+
</Typography>
|
|
188
256
|
</CardContent>
|
|
189
257
|
</Card>
|
|
190
258
|
|
|
191
|
-
<Card
|
|
192
|
-
|
|
259
|
+
<Card component="button" sx={{
|
|
260
|
+
width: 280,
|
|
261
|
+
height: 360,
|
|
262
|
+
border: 'none',
|
|
263
|
+
boxShadow: 'lg',
|
|
264
|
+
'&:hover img': {
|
|
265
|
+
transform: 'scale(1.05)'
|
|
266
|
+
},
|
|
267
|
+
'&:focus-visible': {
|
|
268
|
+
outline: '3px solid',
|
|
269
|
+
outlineColor: 'primary.500',
|
|
270
|
+
outlineOffset: 2
|
|
271
|
+
},
|
|
272
|
+
cursor: 'pointer'
|
|
193
273
|
}}>
|
|
194
|
-
<
|
|
195
|
-
<
|
|
196
|
-
|
|
274
|
+
<CardCover>
|
|
275
|
+
<img src="https://images.unsplash.com/photo-1502657877623-f66bf489d236?auto=format&fit=crop&w=560&h=720" loading="lazy" alt="Night view" style={{
|
|
276
|
+
transition: 'transform 0.4s'
|
|
277
|
+
}} />
|
|
278
|
+
</CardCover>
|
|
279
|
+
<CardCover sx={{
|
|
280
|
+
background: 'linear-gradient(to top, rgba(0,0,0,0.8) 20%, rgba(0,0,0,0) 50%)'
|
|
281
|
+
}} />
|
|
282
|
+
<CardContent sx={{
|
|
283
|
+
justifyContent: 'flex-end'
|
|
284
|
+
}}>
|
|
285
|
+
<Typography level="title-lg" textColor="#fff">
|
|
286
|
+
Night View
|
|
287
|
+
</Typography>
|
|
288
|
+
<Typography level="body-sm" textColor="neutral.300">
|
|
289
|
+
A stunning cityscape
|
|
290
|
+
</Typography>
|
|
197
291
|
</CardContent>
|
|
198
292
|
</Card>
|
|
293
|
+
</Stack>
|
|
294
|
+
```
|
|
199
295
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
296
|
+
## CardContent
|
|
297
|
+
|
|
298
|
+
`CardContent` holds the card's primary content area. It adds consistent internal padding and respects the card's `size` prop.
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
<Card>
|
|
302
|
+
<CardContent>
|
|
303
|
+
<Typography level="title-lg">Title</Typography>
|
|
304
|
+
<Typography level="body-md">Body text</Typography>
|
|
305
|
+
</CardContent>
|
|
207
306
|
</Card>
|
|
208
|
-
</div>
|
|
209
307
|
```
|
|
210
308
|
|
|
211
|
-
|
|
309
|
+
## CardCover
|
|
212
310
|
|
|
213
|
-
|
|
311
|
+
`CardCover` displays background media (image, video, or gradient) that covers the full card area. Place it before `CardContent` so content renders on top.
|
|
214
312
|
|
|
215
313
|
```tsx
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}}>
|
|
221
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
<CardCover
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
<CardContent
|
|
228
|
-
|
|
314
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
315
|
+
<Card sx={{
|
|
316
|
+
width: 320,
|
|
317
|
+
boxShadow: 'lg'
|
|
318
|
+
}}>
|
|
319
|
+
<CardCover>
|
|
320
|
+
<img src="https://images.unsplash.com/photo-1502657877623-f66bf489d236?auto=format&fit=crop&w=640" loading="lazy" alt="Night view" />
|
|
321
|
+
</CardCover>
|
|
322
|
+
<CardCover sx={{
|
|
323
|
+
background: 'linear-gradient(to top, rgba(0,0,0,0.6), rgba(0,0,0,0) 200px)'
|
|
324
|
+
}} />
|
|
325
|
+
<CardContent sx={{
|
|
326
|
+
justifyContent: 'flex-end'
|
|
327
|
+
}}>
|
|
328
|
+
<Typography level="title-lg" textColor="#fff">
|
|
229
329
|
Beautiful Night View
|
|
230
330
|
</Typography>
|
|
231
331
|
<Typography level="body-sm" textColor="neutral.300">
|
|
@@ -235,11 +335,15 @@ A card that uses the `CardCover` component to display an image as the background
|
|
|
235
335
|
</Card>
|
|
236
336
|
|
|
237
337
|
<Card sx={{
|
|
238
|
-
|
|
338
|
+
width: 320,
|
|
339
|
+
boxShadow: 'lg'
|
|
239
340
|
}}>
|
|
240
341
|
<CardCover>
|
|
241
|
-
<img src="https://images.unsplash.com/photo-1527549993586-dff825b37782?auto=format&fit=crop&w=
|
|
342
|
+
<img src="https://images.unsplash.com/photo-1527549993586-dff825b37782?auto=format&fit=crop&w=640" loading="lazy" alt="Mountain" />
|
|
242
343
|
</CardCover>
|
|
344
|
+
<CardCover sx={{
|
|
345
|
+
background: 'linear-gradient(to top, rgba(0,0,0,0.6), rgba(0,0,0,0) 200px)'
|
|
346
|
+
}} />
|
|
243
347
|
<CardContent sx={{
|
|
244
348
|
justifyContent: 'flex-end'
|
|
245
349
|
}}>
|
|
@@ -251,43 +355,50 @@ A card that uses the `CardCover` component to display an image as the background
|
|
|
251
355
|
</Typography>
|
|
252
356
|
</CardContent>
|
|
253
357
|
</Card>
|
|
254
|
-
</
|
|
358
|
+
</Stack>
|
|
255
359
|
```
|
|
256
360
|
|
|
257
|
-
|
|
361
|
+
```tsx
|
|
362
|
+
<Card>
|
|
363
|
+
<CardCover>
|
|
364
|
+
<img src="image.jpg" alt="Cover" />
|
|
365
|
+
</CardCover>
|
|
366
|
+
<CardContent>
|
|
367
|
+
<Typography textColor="#fff">Overlay text</Typography>
|
|
368
|
+
</CardContent>
|
|
369
|
+
</Card>
|
|
370
|
+
```
|
|
258
371
|
|
|
259
|
-
|
|
372
|
+
## CardActions
|
|
373
|
+
|
|
374
|
+
`CardActions` places action buttons at the bottom of the card. Use `buttonFlex={1}` to make buttons expand equally.
|
|
260
375
|
|
|
261
376
|
```tsx
|
|
262
|
-
<
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
<
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
</
|
|
276
|
-
<
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
</
|
|
283
|
-
<Button variant="soft" size="sm">
|
|
284
|
-
더보기
|
|
285
|
-
</Button>
|
|
286
|
-
</CardActions>
|
|
377
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
378
|
+
<Card sx={{
|
|
379
|
+
width: 320
|
|
380
|
+
}}>
|
|
381
|
+
<CardContent>
|
|
382
|
+
<Typography level="title-lg">게시물</Typography>
|
|
383
|
+
<Typography level="body-md">
|
|
384
|
+
이것은 액션 버튼이 있는 카드입니다. 하단에 다양한 액션을 수행할 수 있는 버튼들이 있습니다.
|
|
385
|
+
</Typography>
|
|
386
|
+
</CardContent>
|
|
387
|
+
<CardActions>
|
|
388
|
+
<Button variant="soft" size="sm">
|
|
389
|
+
좋아요
|
|
390
|
+
</Button>
|
|
391
|
+
<Button variant="soft" size="sm">
|
|
392
|
+
공유하기
|
|
393
|
+
</Button>
|
|
394
|
+
<Button variant="soft" size="sm">
|
|
395
|
+
더보기
|
|
396
|
+
</Button>
|
|
397
|
+
</CardActions>
|
|
287
398
|
</Card>
|
|
288
399
|
|
|
289
400
|
<Card sx={{
|
|
290
|
-
|
|
401
|
+
width: 320
|
|
291
402
|
}}>
|
|
292
403
|
<CardContent>
|
|
293
404
|
<Typography level="title-lg">설정</Typography>
|
|
@@ -302,58 +413,56 @@ You can place action buttons at the bottom.
|
|
|
302
413
|
</Button>
|
|
303
414
|
</CardActions>
|
|
304
415
|
</Card>
|
|
305
|
-
</
|
|
416
|
+
</Stack>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
<Card>
|
|
421
|
+
<CardContent>...</CardContent>
|
|
422
|
+
<CardActions buttonFlex={1}>
|
|
423
|
+
<Button variant="outlined" color="neutral">Cancel</Button>
|
|
424
|
+
<Button variant="solid" color="primary">Confirm</Button>
|
|
425
|
+
</CardActions>
|
|
426
|
+
</Card>
|
|
306
427
|
```
|
|
307
428
|
|
|
308
|
-
|
|
429
|
+
## CardOverflow
|
|
309
430
|
|
|
310
|
-
|
|
431
|
+
`CardOverflow` lets content break out of the card's padding boundary to span the full width. Use it for edge-to-edge images, dividers, or action areas.
|
|
311
432
|
|
|
312
433
|
```tsx
|
|
313
|
-
<
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}}>
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
<
|
|
322
|
-
|
|
323
|
-
textAlign: 'center'
|
|
434
|
+
<Stack direction="row" spacing={3} alignItems="flex-start" flexWrap="wrap">
|
|
435
|
+
<Box>
|
|
436
|
+
<Typography level="body-sm" sx={{
|
|
437
|
+
mb: 2,
|
|
438
|
+
textAlign: 'center'
|
|
439
|
+
}}>
|
|
440
|
+
일반 Card (패딩 있음)
|
|
441
|
+
</Typography>
|
|
442
|
+
<Card variant="outlined" sx={{
|
|
443
|
+
width: 260
|
|
324
444
|
}}>
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=280" loading="lazy" alt="Profile" style={{
|
|
334
|
-
width: '100%',
|
|
335
|
-
height: 160,
|
|
336
|
-
objectFit: 'cover',
|
|
337
|
-
borderRadius: '4px'
|
|
338
|
-
}} />
|
|
445
|
+
<CardContent sx={{
|
|
446
|
+
bgcolor: 'background.level1'
|
|
447
|
+
}}>
|
|
448
|
+
<AspectRatio ratio="16/9" sx={{
|
|
449
|
+
borderRadius: 'xs'
|
|
450
|
+
}}>
|
|
451
|
+
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=520" loading="lazy" alt="Profile" />
|
|
452
|
+
</AspectRatio>
|
|
339
453
|
</CardContent>
|
|
340
454
|
<CardContent>
|
|
341
455
|
<Typography level="title-md">John Doe</Typography>
|
|
342
456
|
<Typography level="body-sm">Software Engineer</Typography>
|
|
343
457
|
</CardContent>
|
|
344
458
|
<CardActions>
|
|
345
|
-
<Button size="sm" variant="soft">
|
|
346
|
-
|
|
347
|
-
</Button>
|
|
348
|
-
<Button size="sm" variant="solid">
|
|
349
|
-
메시지
|
|
350
|
-
</Button>
|
|
459
|
+
<Button size="sm" variant="soft">팔로우</Button>
|
|
460
|
+
<Button size="sm" variant="solid">메시지</Button>
|
|
351
461
|
</CardActions>
|
|
352
462
|
</Card>
|
|
353
|
-
</
|
|
463
|
+
</Box>
|
|
354
464
|
|
|
355
|
-
|
|
356
|
-
<div>
|
|
465
|
+
<Box>
|
|
357
466
|
<Typography level="body-sm" sx={{
|
|
358
467
|
mb: 2,
|
|
359
468
|
textAlign: 'center'
|
|
@@ -361,11 +470,11 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
361
470
|
CardOverflow 사용 (패딩 무시)
|
|
362
471
|
</Typography>
|
|
363
472
|
<Card variant="outlined" sx={{
|
|
364
|
-
|
|
473
|
+
width: 260
|
|
365
474
|
}}>
|
|
366
475
|
<CardOverflow>
|
|
367
|
-
<AspectRatio ratio="
|
|
368
|
-
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=
|
|
476
|
+
<AspectRatio ratio="16/9">
|
|
477
|
+
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=520" loading="lazy" alt="Profile" />
|
|
369
478
|
</AspectRatio>
|
|
370
479
|
</CardOverflow>
|
|
371
480
|
<CardContent>
|
|
@@ -375,24 +484,15 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
375
484
|
<CardOverflow variant="soft" sx={{
|
|
376
485
|
bgcolor: 'background.level1'
|
|
377
486
|
}}>
|
|
378
|
-
<CardActions
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
px: 2
|
|
382
|
-
}} buttonFlex={1}>
|
|
383
|
-
<Button size="sm" variant="soft">
|
|
384
|
-
팔로우
|
|
385
|
-
</Button>
|
|
386
|
-
<Button size="sm" variant="solid">
|
|
387
|
-
메시지
|
|
388
|
-
</Button>
|
|
487
|
+
<CardActions buttonFlex={1}>
|
|
488
|
+
<Button size="sm" variant="soft">팔로우</Button>
|
|
489
|
+
<Button size="sm" variant="solid">메시지</Button>
|
|
389
490
|
</CardActions>
|
|
390
491
|
</CardOverflow>
|
|
391
492
|
</Card>
|
|
392
|
-
</
|
|
493
|
+
</Box>
|
|
393
494
|
|
|
394
|
-
|
|
395
|
-
<div>
|
|
495
|
+
<Box>
|
|
396
496
|
<Typography level="body-sm" sx={{
|
|
397
497
|
mb: 2,
|
|
398
498
|
textAlign: 'center'
|
|
@@ -400,21 +500,20 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
400
500
|
다양한 CardOverflow 활용
|
|
401
501
|
</Typography>
|
|
402
502
|
<Card variant="outlined" sx={{
|
|
403
|
-
|
|
503
|
+
width: 260
|
|
404
504
|
}}>
|
|
405
505
|
<CardOverflow>
|
|
406
506
|
<AspectRatio ratio="3">
|
|
407
|
-
<
|
|
507
|
+
<Box sx={{
|
|
408
508
|
background: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
|
|
409
509
|
display: 'flex',
|
|
410
510
|
alignItems: 'center',
|
|
411
|
-
justifyContent: 'center'
|
|
412
|
-
color: 'white'
|
|
511
|
+
justifyContent: 'center'
|
|
413
512
|
}}>
|
|
414
513
|
<Typography level="title-lg" textColor="white">
|
|
415
514
|
HEADER OVERFLOW
|
|
416
515
|
</Typography>
|
|
417
|
-
</
|
|
516
|
+
</Box>
|
|
418
517
|
</AspectRatio>
|
|
419
518
|
</CardOverflow>
|
|
420
519
|
<CardContent sx={{
|
|
@@ -433,45 +532,54 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
433
532
|
py: 1.5
|
|
434
533
|
}}>
|
|
435
534
|
<Typography level="body-xs" textAlign="center" color="warning">
|
|
436
|
-
|
|
535
|
+
이 영역도 CardOverflow로 만들어졌습니다
|
|
437
536
|
</Typography>
|
|
438
537
|
</CardContent>
|
|
439
538
|
</CardOverflow>
|
|
440
539
|
</Card>
|
|
441
|
-
</
|
|
442
|
-
</
|
|
540
|
+
</Box>
|
|
541
|
+
</Stack>
|
|
443
542
|
```
|
|
444
543
|
|
|
445
|
-
|
|
544
|
+
```tsx
|
|
545
|
+
<Card>
|
|
546
|
+
<CardOverflow>
|
|
547
|
+
<AspectRatio ratio="4/3">
|
|
548
|
+
<img src="image.jpg" alt="Full width" />
|
|
549
|
+
</AspectRatio>
|
|
550
|
+
</CardOverflow>
|
|
551
|
+
<CardContent>...</CardContent>
|
|
552
|
+
</Card>
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
## Interactive Cards
|
|
446
556
|
|
|
447
|
-
|
|
557
|
+
Clickable cards with hover effects using CSS transitions.
|
|
448
558
|
|
|
449
559
|
```tsx
|
|
450
|
-
<
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
<Typography level="title-md">클릭 가능한 카드</Typography>
|
|
465
|
-
<Typography level="body-sm">이 카드를 클릭하면 액션이 실행됩니다. 호버 효과도 확인해보세요.</Typography>
|
|
466
|
-
</CardContent>
|
|
560
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
561
|
+
<Card variant="outlined" sx={{
|
|
562
|
+
width: 320,
|
|
563
|
+
cursor: 'pointer',
|
|
564
|
+
transition: 'box-shadow 0.2s, border-color 0.2s',
|
|
565
|
+
'&:hover': {
|
|
566
|
+
boxShadow: 'md',
|
|
567
|
+
borderColor: 'primary.outlinedHoverBorder'
|
|
568
|
+
}
|
|
569
|
+
}}>
|
|
570
|
+
<CardContent>
|
|
571
|
+
<Typography level="title-md">클릭 가능한 카드</Typography>
|
|
572
|
+
<Typography level="body-sm">이 카드를 클릭하면 액션이 실행됩니다. 호버 효과도 확인해보세요.</Typography>
|
|
573
|
+
</CardContent>
|
|
467
574
|
</Card>
|
|
468
575
|
|
|
469
576
|
<Card variant="soft" color="primary" sx={{
|
|
470
|
-
|
|
577
|
+
width: 320,
|
|
471
578
|
cursor: 'pointer',
|
|
472
|
-
transition: 'transform 0.2s',
|
|
579
|
+
transition: 'transform 0.2s, box-shadow 0.2s',
|
|
473
580
|
'&:hover': {
|
|
474
|
-
transform: 'translateY(-2px)'
|
|
581
|
+
transform: 'translateY(-2px)',
|
|
582
|
+
boxShadow: 'md'
|
|
475
583
|
}
|
|
476
584
|
}}>
|
|
477
585
|
<CardContent>
|
|
@@ -479,294 +587,335 @@ Interactive cards with click behavior and hover effects.
|
|
|
479
587
|
<Typography level="body-sm">마우스를 올리면 카드가 살짝 올라갑니다.</Typography>
|
|
480
588
|
</CardContent>
|
|
481
589
|
</Card>
|
|
482
|
-
</
|
|
590
|
+
</Stack>
|
|
483
591
|
```
|
|
484
592
|
|
|
485
|
-
|
|
593
|
+
## Media Cards
|
|
486
594
|
|
|
487
|
-
|
|
595
|
+
Product and food cards combining `CardOverflow`, `CardContent`, and `CardActions`.
|
|
488
596
|
|
|
489
597
|
```tsx
|
|
490
|
-
<
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}}>
|
|
495
|
-
<
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
<img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=320" loading="lazy" alt="Shoes" />
|
|
598
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
599
|
+
<Card sx={{
|
|
600
|
+
width: 320,
|
|
601
|
+
boxShadow: 'lg'
|
|
602
|
+
}}>
|
|
603
|
+
<CardOverflow>
|
|
604
|
+
<AspectRatio sx={{
|
|
605
|
+
minWidth: 200
|
|
606
|
+
}}>
|
|
607
|
+
<img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=640" loading="lazy" alt="Shoes" />
|
|
501
608
|
</AspectRatio>
|
|
502
609
|
</CardOverflow>
|
|
503
610
|
<CardContent>
|
|
504
611
|
<Typography level="title-lg">운동화</Typography>
|
|
505
|
-
<Typography level="body-
|
|
506
|
-
<Typography level="title-lg" sx={{
|
|
507
|
-
|
|
612
|
+
<Typography level="body-sm">편안하고 스타일리시한 운동화입니다.</Typography>
|
|
613
|
+
<Typography level="title-lg" color="primary" sx={{
|
|
614
|
+
mt: 0.5
|
|
508
615
|
}}>
|
|
509
616
|
₩129,000
|
|
510
617
|
</Typography>
|
|
511
618
|
</CardContent>
|
|
512
|
-
<
|
|
513
|
-
<
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
619
|
+
<CardOverflow>
|
|
620
|
+
<Divider inset="context" />
|
|
621
|
+
<CardContent orientation="horizontal" sx={{
|
|
622
|
+
justifyContent: 'space-between'
|
|
623
|
+
}}>
|
|
624
|
+
<Typography level="body-xs" color="neutral">무료배송</Typography>
|
|
625
|
+
<Typography level="body-xs" color="neutral">1,204 리뷰</Typography>
|
|
626
|
+
</CardContent>
|
|
627
|
+
</CardOverflow>
|
|
517
628
|
</Card>
|
|
518
629
|
|
|
519
630
|
<Card sx={{
|
|
520
|
-
|
|
631
|
+
width: 320,
|
|
632
|
+
boxShadow: 'lg'
|
|
521
633
|
}}>
|
|
522
634
|
<CardOverflow>
|
|
523
|
-
<AspectRatio
|
|
524
|
-
|
|
525
|
-
|
|
635
|
+
<AspectRatio sx={{
|
|
636
|
+
minWidth: 200
|
|
637
|
+
}}>
|
|
638
|
+
<img src="https://images.unsplash.com/photo-1551963831-b3b1ca40c98e?auto=format&fit=crop&w=640" loading="lazy" alt="Breakfast" />
|
|
639
|
+
</AspectRatio>
|
|
640
|
+
<IconButton variant="solid" color="danger" size="md" sx={{
|
|
641
|
+
position: 'absolute',
|
|
642
|
+
zIndex: 2,
|
|
643
|
+
borderRadius: '50%',
|
|
644
|
+
right: '1rem',
|
|
645
|
+
bottom: 0,
|
|
646
|
+
transform: 'translateY(50%)'
|
|
647
|
+
}}>
|
|
648
|
+
<FavoriteIcon />
|
|
649
|
+
</IconButton>
|
|
526
650
|
</CardOverflow>
|
|
527
651
|
<CardContent>
|
|
528
|
-
<
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
652
|
+
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
|
653
|
+
<Typography level="title-lg">맛있는 아침식사</Typography>
|
|
654
|
+
<IconButton variant="plain" color="neutral" size="sm">
|
|
655
|
+
<MoreVertIcon />
|
|
656
|
+
</IconButton>
|
|
657
|
+
</Stack>
|
|
658
|
+
<Typography level="body-xs" startDecorator={<LocationOnIcon />}>
|
|
659
|
+
서울, 한국
|
|
660
|
+
</Typography>
|
|
661
|
+
<Typography level="body-sm" sx={{
|
|
662
|
+
mt: 0.5
|
|
532
663
|
}}>
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
664
|
+
건강하고 맛있는 아침 식사로 하루를 시작해보세요.
|
|
665
|
+
</Typography>
|
|
666
|
+
</CardContent>
|
|
667
|
+
<CardOverflow>
|
|
668
|
+
<Divider inset="context" />
|
|
669
|
+
<CardContent orientation="horizontal" sx={{
|
|
670
|
+
justifyContent: 'space-between'
|
|
536
671
|
}}>
|
|
537
|
-
<
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}}>
|
|
544
|
-
<LocationOnIcon sx={{
|
|
672
|
+
<Typography level="body-xs" startDecorator={<FavoriteIcon sx={{
|
|
673
|
+
fontSize: 16
|
|
674
|
+
}} />}>
|
|
675
|
+
1.2K
|
|
676
|
+
</Typography>
|
|
677
|
+
<Typography level="body-xs" startDecorator={<ShareIcon sx={{
|
|
545
678
|
fontSize: 16
|
|
546
|
-
}} />
|
|
679
|
+
}} />}>
|
|
680
|
+
공유
|
|
547
681
|
</Typography>
|
|
548
|
-
<Typography level="body-md">건강하고 맛있는 아침 식사로 하루를 시작해보세요.</Typography>
|
|
549
682
|
</CardContent>
|
|
550
|
-
|
|
551
|
-
<Button size="sm" variant="plain" startDecorator={<FavoriteIcon />}>
|
|
552
|
-
좋아요
|
|
553
|
-
</Button>
|
|
554
|
-
<Button size="sm" variant="plain" startDecorator={<ShareIcon />}>
|
|
555
|
-
공유
|
|
556
|
-
</Button>
|
|
557
|
-
</CardActions>
|
|
683
|
+
</CardOverflow>
|
|
558
684
|
</Card>
|
|
559
|
-
</
|
|
685
|
+
</Stack>
|
|
560
686
|
```
|
|
561
687
|
|
|
562
|
-
|
|
688
|
+
## Complex Layout
|
|
563
689
|
|
|
564
|
-
A social-media-style card with
|
|
690
|
+
A social-media-style card with avatar, text, inline image, and engagement buttons.
|
|
565
691
|
|
|
566
692
|
```tsx
|
|
567
|
-
<div style={{
|
|
568
|
-
display: 'flex',
|
|
569
|
-
gap: '1rem',
|
|
570
|
-
flexWrap: 'wrap'
|
|
571
|
-
}}>
|
|
572
693
|
<Card sx={{
|
|
573
|
-
|
|
694
|
+
width: 400,
|
|
695
|
+
maxWidth: '100%'
|
|
574
696
|
}}>
|
|
575
|
-
<CardContent
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
<div style={{
|
|
579
|
-
display: 'flex',
|
|
580
|
-
alignItems: 'center',
|
|
581
|
-
gap: '1rem',
|
|
582
|
-
marginBottom: '1rem'
|
|
583
|
-
}}>
|
|
584
|
-
<Avatar size="sm" src="https://i.pravatar.cc/40?img=1" />
|
|
585
|
-
<div>
|
|
586
|
-
<Typography level="title-sm">김철수</Typography>
|
|
587
|
-
<Typography level="body-xs" sx={{
|
|
588
|
-
color: 'text.secondary'
|
|
697
|
+
<CardContent>
|
|
698
|
+
<Stack direction="row" spacing={1.5} alignItems="center" sx={{
|
|
699
|
+
mb: 1.5
|
|
589
700
|
}}>
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
<Typography level="
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
701
|
+
<Avatar size="sm" src="https://i.pravatar.cc/40?img=1" />
|
|
702
|
+
<Box sx={{
|
|
703
|
+
flex: 1
|
|
704
|
+
}}>
|
|
705
|
+
<Typography level="title-sm">김철수</Typography>
|
|
706
|
+
<Typography level="body-xs" color="neutral">5분 전</Typography>
|
|
707
|
+
</Box>
|
|
708
|
+
<IconButton variant="plain" color="neutral" size="sm">
|
|
709
|
+
<MoreVertIcon />
|
|
710
|
+
</IconButton>
|
|
711
|
+
</Stack>
|
|
712
|
+
<Typography level="body-md">
|
|
713
|
+
오늘 정말 좋은 하루였습니다! 새로운 프로젝트를 시작했는데 너무 흥미진진해요. 팀원들과의 협업도 잘 되고 있고,
|
|
714
|
+
앞으로가 기대됩니다.
|
|
599
715
|
</Typography>
|
|
600
716
|
</CardContent>
|
|
601
717
|
<CardOverflow>
|
|
602
718
|
<AspectRatio ratio="2">
|
|
603
|
-
<img src="https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=
|
|
719
|
+
<img src="https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=800" loading="lazy" alt="Team work" />
|
|
604
720
|
</AspectRatio>
|
|
605
721
|
</CardOverflow>
|
|
606
|
-
<CardContent
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
<
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
</Button>
|
|
620
|
-
<Typography level="body-xs" sx={{
|
|
621
|
-
ml: 'auto',
|
|
622
|
-
color: 'text.secondary'
|
|
623
|
-
}}>
|
|
624
|
-
댓글 3개
|
|
625
|
-
</Typography>
|
|
626
|
-
</div>
|
|
722
|
+
<CardContent>
|
|
723
|
+
<Stack direction="row" spacing={1} alignItems="center">
|
|
724
|
+
<IconButton variant="plain" color="neutral" size="sm">
|
|
725
|
+
<FavoriteIcon />
|
|
726
|
+
</IconButton>
|
|
727
|
+
<Typography level="body-xs">12</Typography>
|
|
728
|
+
<IconButton variant="plain" color="neutral" size="sm">
|
|
729
|
+
<ShareIcon />
|
|
730
|
+
</IconButton>
|
|
731
|
+
<Typography level="body-xs" sx={{
|
|
732
|
+
ml: 'auto'
|
|
733
|
+
}} color="neutral">댓글 3개</Typography>
|
|
734
|
+
</Stack>
|
|
627
735
|
</CardContent>
|
|
628
736
|
</Card>
|
|
629
|
-
</div>
|
|
630
737
|
```
|
|
631
738
|
|
|
632
|
-
## Card
|
|
633
|
-
|
|
634
|
-
Card is composed of several subcomponents:
|
|
635
|
-
|
|
636
|
-
### Card
|
|
637
|
-
|
|
638
|
-
The main card container.
|
|
639
|
-
|
|
640
|
-
```tsx
|
|
641
|
-
<Card variant="outlined" color="neutral" size="md">
|
|
642
|
-
{/* card content */}
|
|
643
|
-
</Card>
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
### CardContent
|
|
647
|
-
|
|
648
|
-
The area that contains the card's primary content.
|
|
739
|
+
## Product Card
|
|
649
740
|
|
|
650
741
|
```tsx
|
|
742
|
+
<Card sx={{
|
|
743
|
+
width: 320,
|
|
744
|
+
maxWidth: '100%',
|
|
745
|
+
boxShadow: 'lg'
|
|
746
|
+
}}>
|
|
747
|
+
<CardOverflow>
|
|
748
|
+
<AspectRatio sx={{
|
|
749
|
+
minWidth: 200
|
|
750
|
+
}}>
|
|
751
|
+
<img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=640" loading="lazy" alt="Shoes" />
|
|
752
|
+
</AspectRatio>
|
|
753
|
+
</CardOverflow>
|
|
651
754
|
<CardContent>
|
|
652
|
-
<
|
|
653
|
-
|
|
755
|
+
<Stack direction="row" justifyContent="space-between" alignItems="flex-start">
|
|
756
|
+
<Typography level="title-lg">운동화</Typography>
|
|
757
|
+
<IconButton variant="plain" color="neutral" size="sm">
|
|
758
|
+
<BookmarkAddIcon />
|
|
759
|
+
</IconButton>
|
|
760
|
+
</Stack>
|
|
761
|
+
<Typography level="body-sm">편안하고 스타일리시한 운동화입니다.</Typography>
|
|
762
|
+
<Typography level="title-lg" color="primary" sx={{
|
|
763
|
+
mt: 1
|
|
764
|
+
}}>
|
|
765
|
+
₩129,000
|
|
766
|
+
</Typography>
|
|
654
767
|
</CardContent>
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
### CardCover
|
|
658
|
-
|
|
659
|
-
Displays background media or an image that covers the entire card.
|
|
660
|
-
|
|
661
|
-
```tsx
|
|
662
|
-
<CardCover>
|
|
663
|
-
<img src="image.jpg" alt="Cover" />
|
|
664
|
-
</CardCover>
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
### CardActions
|
|
668
|
-
|
|
669
|
-
The area used to place action buttons.
|
|
670
|
-
|
|
671
|
-
```tsx
|
|
672
|
-
<CardActions>
|
|
673
|
-
<Button>확인</Button>
|
|
674
|
-
<Button>취소</Button>
|
|
675
|
-
</CardActions>
|
|
676
|
-
```
|
|
677
|
-
|
|
678
|
-
### CardOverflow
|
|
679
|
-
|
|
680
|
-
An area that ignores the card's padding and uses the full width.
|
|
681
|
-
|
|
682
|
-
```tsx
|
|
683
768
|
<CardOverflow>
|
|
684
|
-
<
|
|
685
|
-
|
|
686
|
-
|
|
769
|
+
<Button variant="solid" color="primary" size="lg" sx={{
|
|
770
|
+
borderRadius: 0
|
|
771
|
+
}}>
|
|
772
|
+
구매하기
|
|
773
|
+
</Button>
|
|
687
774
|
</CardOverflow>
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
## Common Use Cases
|
|
691
|
-
|
|
692
|
-
### Product Cards
|
|
693
|
-
|
|
694
|
-
```tsx
|
|
695
|
-
<Card sx={{ maxWidth: 320 }}>
|
|
696
|
-
<CardOverflow>
|
|
697
|
-
<AspectRatio ratio="1">
|
|
698
|
-
<img src="product.jpg" alt="Product" />
|
|
699
|
-
</AspectRatio>
|
|
700
|
-
</CardOverflow>
|
|
701
|
-
<CardContent>
|
|
702
|
-
<Typography level="title-lg">제품명</Typography>
|
|
703
|
-
<Typography level="body-md">제품 설명</Typography>
|
|
704
|
-
<Typography level="title-lg" color="primary">
|
|
705
|
-
₩199,000
|
|
706
|
-
</Typography>
|
|
707
|
-
</CardContent>
|
|
708
|
-
<CardActions>
|
|
709
|
-
<Button variant="solid" fullWidth>
|
|
710
|
-
구매하기
|
|
711
|
-
</Button>
|
|
712
|
-
</CardActions>
|
|
713
775
|
</Card>
|
|
714
776
|
```
|
|
715
777
|
|
|
716
|
-
|
|
778
|
+
## Profile Card
|
|
717
779
|
|
|
718
780
|
```tsx
|
|
719
|
-
<Card sx={{
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
<
|
|
726
|
-
<
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
781
|
+
<Card sx={{
|
|
782
|
+
width: 300,
|
|
783
|
+
maxWidth: '100%',
|
|
784
|
+
boxShadow: 'lg'
|
|
785
|
+
}}>
|
|
786
|
+
<CardOverflow>
|
|
787
|
+
<AspectRatio ratio="3">
|
|
788
|
+
<Box sx={{
|
|
789
|
+
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
|
|
790
|
+
}} />
|
|
791
|
+
</AspectRatio>
|
|
792
|
+
</CardOverflow>
|
|
793
|
+
<CardContent sx={{
|
|
794
|
+
alignItems: 'center',
|
|
795
|
+
textAlign: 'center',
|
|
796
|
+
mt: -5
|
|
797
|
+
}}>
|
|
798
|
+
<Avatar size="lg" src="https://i.pravatar.cc/80?img=3" sx={{
|
|
799
|
+
'--Avatar-size': '64px',
|
|
800
|
+
border: '3px solid',
|
|
801
|
+
borderColor: 'background.surface'
|
|
802
|
+
}} />
|
|
803
|
+
<Typography level="title-lg" sx={{
|
|
804
|
+
mt: 1
|
|
805
|
+
}}>Jane Smith</Typography>
|
|
806
|
+
<Typography level="body-sm" color="neutral">Product Designer</Typography>
|
|
807
|
+
<Stack direction="row" spacing={3} sx={{
|
|
808
|
+
mt: 1
|
|
809
|
+
}}>
|
|
810
|
+
<Box sx={{
|
|
811
|
+
textAlign: 'center'
|
|
812
|
+
}}>
|
|
813
|
+
<Typography level="title-sm">128</Typography>
|
|
814
|
+
<Typography level="body-xs" color="neutral">게시물</Typography>
|
|
815
|
+
</Box>
|
|
816
|
+
<Box sx={{
|
|
817
|
+
textAlign: 'center'
|
|
818
|
+
}}>
|
|
819
|
+
<Typography level="title-sm">1.2K</Typography>
|
|
820
|
+
<Typography level="body-xs" color="neutral">팔로워</Typography>
|
|
821
|
+
</Box>
|
|
822
|
+
<Box sx={{
|
|
823
|
+
textAlign: 'center'
|
|
824
|
+
}}>
|
|
825
|
+
<Typography level="title-sm">342</Typography>
|
|
826
|
+
<Typography level="body-xs" color="neutral">팔로잉</Typography>
|
|
827
|
+
</Box>
|
|
828
|
+
</Stack>
|
|
829
|
+
</CardContent>
|
|
830
|
+
<CardActions buttonFlex={1}>
|
|
831
|
+
<Button size="sm" variant="soft">팔로우</Button>
|
|
832
|
+
<Button size="sm" variant="solid">메시지</Button>
|
|
833
|
+
</CardActions>
|
|
733
834
|
</Card>
|
|
734
835
|
```
|
|
735
836
|
|
|
736
|
-
|
|
837
|
+
## News Card
|
|
737
838
|
|
|
738
839
|
```tsx
|
|
739
|
-
<Card sx={{
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
840
|
+
<Card sx={{
|
|
841
|
+
width: 400,
|
|
842
|
+
maxWidth: '100%'
|
|
843
|
+
}}>
|
|
844
|
+
<CardOverflow>
|
|
845
|
+
<AspectRatio ratio="2">
|
|
846
|
+
<img src="https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=800" loading="lazy" alt="Tech news" />
|
|
847
|
+
</AspectRatio>
|
|
848
|
+
</CardOverflow>
|
|
849
|
+
<CardContent>
|
|
850
|
+
<Stack direction="row" spacing={1} sx={{
|
|
851
|
+
mb: 0.5
|
|
852
|
+
}}>
|
|
853
|
+
<Chip variant="soft" color="primary" size="sm">Tech</Chip>
|
|
854
|
+
<Typography level="body-xs" color="neutral" sx={{
|
|
855
|
+
alignSelf: 'center'
|
|
856
|
+
}}>2 hours ago</Typography>
|
|
857
|
+
</Stack>
|
|
858
|
+
<Typography level="title-md">
|
|
859
|
+
<Link overlay underline="none" color="neutral" href="#" onClick={e => e.preventDefault()}>
|
|
860
|
+
새로운 프로젝트 시작
|
|
861
|
+
</Link>
|
|
862
|
+
</Typography>
|
|
863
|
+
<Typography level="body-sm">
|
|
864
|
+
팀원들과 협업하며 새로운 기술을 도입한 프로젝트가 성공적으로 시작되었습니다.
|
|
865
|
+
</Typography>
|
|
866
|
+
</CardContent>
|
|
752
867
|
</Card>
|
|
753
868
|
```
|
|
754
869
|
|
|
755
|
-
|
|
870
|
+
## Dashboard Widget
|
|
756
871
|
|
|
757
872
|
```tsx
|
|
758
|
-
<
|
|
873
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
874
|
+
<Card variant="soft" color="primary" sx={{
|
|
875
|
+
width: 200
|
|
876
|
+
}}>
|
|
759
877
|
<CardContent>
|
|
760
878
|
<Typography level="body-sm">총 사용자</Typography>
|
|
761
879
|
<Typography level="h2">1,234</Typography>
|
|
762
|
-
<
|
|
763
|
-
|
|
880
|
+
<Chip variant="soft" color="success" size="sm" startDecorator={<TrendingUpIcon sx={{
|
|
881
|
+
fontSize: 16
|
|
882
|
+
}} />}>
|
|
883
|
+
+12%
|
|
884
|
+
</Chip>
|
|
885
|
+
</CardContent>
|
|
886
|
+
</Card>
|
|
887
|
+
<Card variant="soft" color="success" sx={{
|
|
888
|
+
width: 200
|
|
889
|
+
}}>
|
|
890
|
+
<CardContent>
|
|
891
|
+
<Typography level="body-sm">완료된 주문</Typography>
|
|
892
|
+
<Typography level="h2">856</Typography>
|
|
893
|
+
<Chip variant="soft" color="success" size="sm" startDecorator={<TrendingUpIcon sx={{
|
|
894
|
+
fontSize: 16
|
|
895
|
+
}} />}>
|
|
896
|
+
+5%
|
|
897
|
+
</Chip>
|
|
898
|
+
</CardContent>
|
|
764
899
|
</Card>
|
|
900
|
+
<Card variant="soft" color="warning" sx={{
|
|
901
|
+
width: 200
|
|
902
|
+
}}>
|
|
903
|
+
<CardContent>
|
|
904
|
+
<Typography level="body-sm">대기 중</Typography>
|
|
905
|
+
<Typography level="h2">42</Typography>
|
|
906
|
+
<Chip variant="soft" color="danger" size="sm" startDecorator={<TrendingDownIcon sx={{
|
|
907
|
+
fontSize: 16
|
|
908
|
+
}} />}>
|
|
909
|
+
-3%
|
|
910
|
+
</Chip>
|
|
911
|
+
</CardContent>
|
|
912
|
+
</Card>
|
|
913
|
+
</Stack>
|
|
765
914
|
```
|
|
766
915
|
|
|
767
916
|
## Props and Customization
|
|
768
917
|
|
|
769
|
-
###
|
|
918
|
+
### Card Props
|
|
770
919
|
|
|
771
920
|
| Prop | Type | Default | Description |
|
|
772
921
|
| ---------------- | -------------------------------------------------------------- | ------------ | -------------------------------------------------------- |
|
|
@@ -776,9 +925,51 @@ An area that ignores the card's padding and uses the full width.
|
|
|
776
925
|
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
|
|
777
926
|
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | Card layout direction |
|
|
778
927
|
| `invertedColors` | `boolean` | `false` | Invert child component colors |
|
|
928
|
+
| `component` | `ElementType` | `'div'` | Root element type (e.g. `'a'`, `'button'`) |
|
|
779
929
|
| `sx` | `SxProps` | - | Custom styles |
|
|
780
930
|
|
|
781
|
-
> **Note**:
|
|
931
|
+
> **Note**: Also accepts all Joy UI Card props and Framer Motion props.
|
|
932
|
+
|
|
933
|
+
### CardContent Props
|
|
934
|
+
|
|
935
|
+
| Prop | Type | Default | Description |
|
|
936
|
+
| ------------- | ---------------------------- | ------------ | ----------------------------------- |
|
|
937
|
+
| `children` | `ReactNode` | - | Content elements (Typography, etc.) |
|
|
938
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | Content layout direction |
|
|
939
|
+
| `sx` | `SxProps` | - | Custom styles |
|
|
940
|
+
|
|
941
|
+
> **Note**: Also accepts all Joy UI CardContent props and Framer Motion props.
|
|
942
|
+
|
|
943
|
+
### CardCover Props
|
|
944
|
+
|
|
945
|
+
| Prop | Type | Default | Description |
|
|
946
|
+
| ---------- | ----------- | ------- | --------------------------------------------- |
|
|
947
|
+
| `children` | `ReactNode` | - | Cover media (img, video, or gradient element) |
|
|
948
|
+
| `sx` | `SxProps` | - | Custom styles |
|
|
949
|
+
|
|
950
|
+
> **Note**: Also accepts all Joy UI CardCover props and Framer Motion props.
|
|
951
|
+
|
|
952
|
+
### CardActions Props
|
|
953
|
+
|
|
954
|
+
| Prop | Type | Default | Description |
|
|
955
|
+
| ------------- | ---------------------------- | -------------- | ------------------------------------------ |
|
|
956
|
+
| `children` | `ReactNode` | - | Action elements (Button, IconButton, etc.) |
|
|
957
|
+
| `buttonFlex` | `number \| string` | - | Sets the `flex` property on child buttons |
|
|
958
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Actions layout direction |
|
|
959
|
+
| `sx` | `SxProps` | - | Custom styles |
|
|
960
|
+
|
|
961
|
+
> **Note**: Also accepts all Joy UI CardActions props and Framer Motion props.
|
|
962
|
+
|
|
963
|
+
### CardOverflow Props
|
|
964
|
+
|
|
965
|
+
| Prop | Type | Default | Description |
|
|
966
|
+
| ---------- | -------------------------------------------------------------- | ------- | ---------------------------------------- |
|
|
967
|
+
| `children` | `ReactNode` | - | Content that extends beyond card padding |
|
|
968
|
+
| `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | - | Overflow area visual style |
|
|
969
|
+
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | - | Overflow area color |
|
|
970
|
+
| `sx` | `SxProps` | - | Custom styles |
|
|
971
|
+
|
|
972
|
+
> **Note**: Also accepts all Joy UI CardOverflow props and Framer Motion props.
|
|
782
973
|
|
|
783
974
|
## Best Practices
|
|
784
975
|
|
|
@@ -790,13 +981,16 @@ An area that ignores the card's padding and uses the full width.
|
|
|
790
981
|
|
|
791
982
|
4. **Use proper spacing**: When listing multiple cards, keep enough space between them so each one is clearly distinguishable.
|
|
792
983
|
|
|
793
|
-
5. **
|
|
794
|
-
- Support keyboard navigation when cards are clickable
|
|
795
|
-
- Provide appropriate `alt` text for images
|
|
796
|
-
- Do not rely on color alone to communicate information
|
|
984
|
+
5. **Limit action buttons**: Include only primary actions directly related to the card in `CardActions`. Too many buttons can create confusion.
|
|
797
985
|
|
|
798
986
|
6. **Use responsive design**: Use `maxWidth` or responsive props so cards work well across different screen sizes.
|
|
799
987
|
|
|
800
988
|
7. **Handle loading states**: Use Skeleton components to represent loading states while data is being fetched.
|
|
801
989
|
|
|
802
|
-
|
|
990
|
+
## Accessibility
|
|
991
|
+
|
|
992
|
+
- When the entire card is clickable, use `component="a"` or `component="button"` so it is keyboard-focusable and announced correctly by screen readers.
|
|
993
|
+
- Always provide meaningful `alt` text for images inside `CardCover` and `CardOverflow`.
|
|
994
|
+
- Do not rely on color alone to convey information — pair color cues with text or icons.
|
|
995
|
+
- Ensure sufficient color contrast between text and background, especially when using `CardCover` with overlaid text.
|
|
996
|
+
- Support keyboard navigation: add `tabIndex={0}` and `onKeyDown` handlers when using non-semantic elements as interactive cards.
|