@ceed/ads 1.32.1 → 1.32.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 -458
- 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 +3 -2
|
@@ -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,24 +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
|
-
##
|
|
43
|
+
## Basic Usage
|
|
42
44
|
|
|
43
|
-
The most basic
|
|
45
|
+
The most basic card with a title and body text.
|
|
44
46
|
|
|
45
47
|
```tsx
|
|
46
|
-
<div style={{
|
|
47
|
-
display: 'flex',
|
|
48
|
-
gap: '1rem',
|
|
49
|
-
flexWrap: 'wrap'
|
|
50
|
-
}}>
|
|
51
48
|
<Card sx={{
|
|
52
49
|
maxWidth: 300
|
|
53
50
|
}}>
|
|
@@ -58,172 +55,277 @@ The most basic way to use a card.
|
|
|
58
55
|
</Typography>
|
|
59
56
|
</CardContent>
|
|
60
57
|
</Card>
|
|
61
|
-
</div>
|
|
62
58
|
```
|
|
63
59
|
|
|
64
|
-
##
|
|
60
|
+
## Variants
|
|
65
61
|
|
|
66
|
-
|
|
62
|
+
Four visual styles are available: `solid`, `soft`, `outlined` (default), and `plain`.
|
|
67
63
|
|
|
68
64
|
```tsx
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
}}>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<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>
|
|
80
76
|
</CardContent>
|
|
81
|
-
</Card>
|
|
77
|
+
</Card>)}
|
|
78
|
+
</Stack>
|
|
79
|
+
```
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
maxWidth: 300
|
|
85
|
-
}}>
|
|
86
|
-
<CardContent>
|
|
87
|
-
<Typography level="title-md">Soft</Typography>
|
|
88
|
-
<Typography level="body-sm">Soft 스타일 카드</Typography>
|
|
89
|
-
</CardContent>
|
|
90
|
-
</Card>
|
|
81
|
+
## Colors
|
|
91
82
|
|
|
92
|
-
|
|
93
|
-
maxWidth: 300
|
|
94
|
-
}}>
|
|
95
|
-
<CardContent>
|
|
96
|
-
<Typography level="title-md">Outlined</Typography>
|
|
97
|
-
<Typography level="body-sm">Outlined 스타일 카드</Typography>
|
|
98
|
-
</CardContent>
|
|
99
|
-
</Card>
|
|
83
|
+
Apply a color scheme to match your UI context.
|
|
100
84
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<
|
|
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>
|
|
107
97
|
</CardContent>
|
|
108
|
-
</Card>
|
|
109
|
-
</
|
|
98
|
+
</Card>)}
|
|
99
|
+
</Stack>
|
|
110
100
|
```
|
|
111
101
|
|
|
112
|
-
##
|
|
102
|
+
## Sizes
|
|
113
103
|
|
|
114
|
-
|
|
104
|
+
Three sizes control the card's internal padding: `sm`, `md` (default), and `lg`.
|
|
115
105
|
|
|
116
106
|
```tsx
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<CardContent>
|
|
126
|
-
<Typography level="title-md">Primary</Typography>
|
|
127
|
-
<Typography level="body-sm">Primary 색상 카드</Typography>
|
|
128
|
-
</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>
|
|
129
115
|
</Card>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
maxWidth: 300
|
|
116
|
+
<Card size="md" sx={{
|
|
117
|
+
width: 260
|
|
133
118
|
}}>
|
|
134
119
|
<CardContent>
|
|
135
|
-
<Typography level="title-md">
|
|
136
|
-
<Typography level="body-sm"
|
|
120
|
+
<Typography level="title-md">Medium</Typography>
|
|
121
|
+
<Typography level="body-sm">중간 크기의 카드입니다.</Typography>
|
|
137
122
|
</CardContent>
|
|
138
123
|
</Card>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
maxWidth: 300
|
|
124
|
+
<Card size="lg" sx={{
|
|
125
|
+
width: 300
|
|
142
126
|
}}>
|
|
143
127
|
<CardContent>
|
|
144
|
-
<Typography level="title-
|
|
145
|
-
<Typography level="body-
|
|
128
|
+
<Typography level="title-lg">Large</Typography>
|
|
129
|
+
<Typography level="body-md">큰 크기의 카드입니다.</Typography>
|
|
146
130
|
</CardContent>
|
|
147
131
|
</Card>
|
|
132
|
+
</Stack>
|
|
133
|
+
```
|
|
148
134
|
|
|
149
|
-
|
|
150
|
-
|
|
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
|
|
151
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>
|
|
152
151
|
<CardContent>
|
|
153
|
-
<Typography level="title-md"
|
|
154
|
-
<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>
|
|
155
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>
|
|
156
170
|
</Card>
|
|
157
171
|
|
|
158
|
-
<Card
|
|
159
|
-
|
|
160
|
-
|
|
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>
|
|
161
180
|
<CardContent>
|
|
162
|
-
<Typography level="title-
|
|
163
|
-
<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>
|
|
164
188
|
</CardContent>
|
|
165
189
|
</Card>
|
|
166
|
-
</
|
|
190
|
+
</Stack>
|
|
167
191
|
```
|
|
168
192
|
|
|
169
|
-
##
|
|
193
|
+
## Inverted Colors
|
|
170
194
|
|
|
171
|
-
|
|
195
|
+
The `invertedColors` prop automatically applies an inverted color scheme to child components (Typography, Button, etc.) — useful for dark-background solid cards.
|
|
172
196
|
|
|
173
197
|
```tsx
|
|
174
|
-
<
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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>
|
|
186
256
|
</CardContent>
|
|
187
257
|
</Card>
|
|
188
258
|
|
|
189
|
-
<Card
|
|
190
|
-
|
|
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'
|
|
191
273
|
}}>
|
|
192
|
-
<
|
|
193
|
-
<
|
|
194
|
-
|
|
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>
|
|
195
291
|
</CardContent>
|
|
196
292
|
</Card>
|
|
293
|
+
</Stack>
|
|
294
|
+
```
|
|
197
295
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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>
|
|
205
306
|
</Card>
|
|
206
|
-
</div>
|
|
207
307
|
```
|
|
208
308
|
|
|
209
|
-
##
|
|
309
|
+
## CardCover
|
|
210
310
|
|
|
211
|
-
|
|
311
|
+
`CardCover` displays background media (image, video, or gradient) that covers the full card area. Place it before `CardContent` so content renders on top.
|
|
212
312
|
|
|
213
313
|
```tsx
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}}>
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
<CardCover
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
<CardContent
|
|
226
|
-
|
|
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">
|
|
227
329
|
Beautiful Night View
|
|
228
330
|
</Typography>
|
|
229
331
|
<Typography level="body-sm" textColor="neutral.300">
|
|
@@ -233,11 +335,15 @@ A card that uses the `CardCover` component to display an image as the background
|
|
|
233
335
|
</Card>
|
|
234
336
|
|
|
235
337
|
<Card sx={{
|
|
236
|
-
|
|
338
|
+
width: 320,
|
|
339
|
+
boxShadow: 'lg'
|
|
237
340
|
}}>
|
|
238
341
|
<CardCover>
|
|
239
|
-
<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" />
|
|
240
343
|
</CardCover>
|
|
344
|
+
<CardCover sx={{
|
|
345
|
+
background: 'linear-gradient(to top, rgba(0,0,0,0.6), rgba(0,0,0,0) 200px)'
|
|
346
|
+
}} />
|
|
241
347
|
<CardContent sx={{
|
|
242
348
|
justifyContent: 'flex-end'
|
|
243
349
|
}}>
|
|
@@ -249,43 +355,50 @@ A card that uses the `CardCover` component to display an image as the background
|
|
|
249
355
|
</Typography>
|
|
250
356
|
</CardContent>
|
|
251
357
|
</Card>
|
|
252
|
-
</
|
|
358
|
+
</Stack>
|
|
253
359
|
```
|
|
254
360
|
|
|
255
|
-
|
|
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
|
+
```
|
|
256
371
|
|
|
257
|
-
|
|
372
|
+
## CardActions
|
|
373
|
+
|
|
374
|
+
`CardActions` places action buttons at the bottom of the card. Use `buttonFlex={1}` to make buttons expand equally.
|
|
258
375
|
|
|
259
376
|
```tsx
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
<
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
</
|
|
274
|
-
<
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
</
|
|
281
|
-
<Button variant="soft" size="sm">
|
|
282
|
-
더보기
|
|
283
|
-
</Button>
|
|
284
|
-
</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>
|
|
285
398
|
</Card>
|
|
286
399
|
|
|
287
400
|
<Card sx={{
|
|
288
|
-
|
|
401
|
+
width: 320
|
|
289
402
|
}}>
|
|
290
403
|
<CardContent>
|
|
291
404
|
<Typography level="title-lg">설정</Typography>
|
|
@@ -300,58 +413,56 @@ You can place action buttons at the bottom.
|
|
|
300
413
|
</Button>
|
|
301
414
|
</CardActions>
|
|
302
415
|
</Card>
|
|
303
|
-
</
|
|
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>
|
|
304
427
|
```
|
|
305
428
|
|
|
306
|
-
##
|
|
429
|
+
## CardOverflow
|
|
307
430
|
|
|
308
|
-
|
|
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.
|
|
309
432
|
|
|
310
433
|
```tsx
|
|
311
|
-
<
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}}>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
<
|
|
320
|
-
|
|
321
|
-
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
|
|
322
444
|
}}>
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=280" loading="lazy" alt="Profile" style={{
|
|
332
|
-
width: '100%',
|
|
333
|
-
height: 160,
|
|
334
|
-
objectFit: 'cover',
|
|
335
|
-
borderRadius: '4px'
|
|
336
|
-
}} />
|
|
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>
|
|
337
453
|
</CardContent>
|
|
338
454
|
<CardContent>
|
|
339
455
|
<Typography level="title-md">John Doe</Typography>
|
|
340
456
|
<Typography level="body-sm">Software Engineer</Typography>
|
|
341
457
|
</CardContent>
|
|
342
458
|
<CardActions>
|
|
343
|
-
<Button size="sm" variant="soft">
|
|
344
|
-
|
|
345
|
-
</Button>
|
|
346
|
-
<Button size="sm" variant="solid">
|
|
347
|
-
메시지
|
|
348
|
-
</Button>
|
|
459
|
+
<Button size="sm" variant="soft">팔로우</Button>
|
|
460
|
+
<Button size="sm" variant="solid">메시지</Button>
|
|
349
461
|
</CardActions>
|
|
350
462
|
</Card>
|
|
351
|
-
</
|
|
463
|
+
</Box>
|
|
352
464
|
|
|
353
|
-
|
|
354
|
-
<div>
|
|
465
|
+
<Box>
|
|
355
466
|
<Typography level="body-sm" sx={{
|
|
356
467
|
mb: 2,
|
|
357
468
|
textAlign: 'center'
|
|
@@ -359,11 +470,11 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
359
470
|
CardOverflow 사용 (패딩 무시)
|
|
360
471
|
</Typography>
|
|
361
472
|
<Card variant="outlined" sx={{
|
|
362
|
-
|
|
473
|
+
width: 260
|
|
363
474
|
}}>
|
|
364
475
|
<CardOverflow>
|
|
365
|
-
<AspectRatio ratio="
|
|
366
|
-
<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" />
|
|
367
478
|
</AspectRatio>
|
|
368
479
|
</CardOverflow>
|
|
369
480
|
<CardContent>
|
|
@@ -373,24 +484,15 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
373
484
|
<CardOverflow variant="soft" sx={{
|
|
374
485
|
bgcolor: 'background.level1'
|
|
375
486
|
}}>
|
|
376
|
-
<CardActions
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
px: 2
|
|
380
|
-
}} buttonFlex={1}>
|
|
381
|
-
<Button size="sm" variant="soft">
|
|
382
|
-
팔로우
|
|
383
|
-
</Button>
|
|
384
|
-
<Button size="sm" variant="solid">
|
|
385
|
-
메시지
|
|
386
|
-
</Button>
|
|
487
|
+
<CardActions buttonFlex={1}>
|
|
488
|
+
<Button size="sm" variant="soft">팔로우</Button>
|
|
489
|
+
<Button size="sm" variant="solid">메시지</Button>
|
|
387
490
|
</CardActions>
|
|
388
491
|
</CardOverflow>
|
|
389
492
|
</Card>
|
|
390
|
-
</
|
|
493
|
+
</Box>
|
|
391
494
|
|
|
392
|
-
|
|
393
|
-
<div>
|
|
495
|
+
<Box>
|
|
394
496
|
<Typography level="body-sm" sx={{
|
|
395
497
|
mb: 2,
|
|
396
498
|
textAlign: 'center'
|
|
@@ -398,21 +500,20 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
398
500
|
다양한 CardOverflow 활용
|
|
399
501
|
</Typography>
|
|
400
502
|
<Card variant="outlined" sx={{
|
|
401
|
-
|
|
503
|
+
width: 260
|
|
402
504
|
}}>
|
|
403
505
|
<CardOverflow>
|
|
404
506
|
<AspectRatio ratio="3">
|
|
405
|
-
<
|
|
507
|
+
<Box sx={{
|
|
406
508
|
background: 'linear-gradient(45deg, #2196F3 30%, #21CBF3 90%)',
|
|
407
509
|
display: 'flex',
|
|
408
510
|
alignItems: 'center',
|
|
409
|
-
justifyContent: 'center'
|
|
410
|
-
color: 'white'
|
|
511
|
+
justifyContent: 'center'
|
|
411
512
|
}}>
|
|
412
513
|
<Typography level="title-lg" textColor="white">
|
|
413
514
|
HEADER OVERFLOW
|
|
414
515
|
</Typography>
|
|
415
|
-
</
|
|
516
|
+
</Box>
|
|
416
517
|
</AspectRatio>
|
|
417
518
|
</CardOverflow>
|
|
418
519
|
<CardContent sx={{
|
|
@@ -431,45 +532,54 @@ Use `CardOverflow` to display content that extends beyond the card's padded boun
|
|
|
431
532
|
py: 1.5
|
|
432
533
|
}}>
|
|
433
534
|
<Typography level="body-xs" textAlign="center" color="warning">
|
|
434
|
-
|
|
535
|
+
이 영역도 CardOverflow로 만들어졌습니다
|
|
435
536
|
</Typography>
|
|
436
537
|
</CardContent>
|
|
437
538
|
</CardOverflow>
|
|
438
539
|
</Card>
|
|
439
|
-
</
|
|
440
|
-
</
|
|
540
|
+
</Box>
|
|
541
|
+
</Stack>
|
|
441
542
|
```
|
|
442
543
|
|
|
443
|
-
|
|
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
|
|
444
556
|
|
|
445
|
-
|
|
557
|
+
Clickable cards with hover effects using CSS transitions.
|
|
446
558
|
|
|
447
559
|
```tsx
|
|
448
|
-
<
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
<Typography level="title-md">클릭 가능한 카드</Typography>
|
|
463
|
-
<Typography level="body-sm">이 카드를 클릭하면 액션이 실행됩니다. 호버 효과도 확인해보세요.</Typography>
|
|
464
|
-
</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>
|
|
465
574
|
</Card>
|
|
466
575
|
|
|
467
576
|
<Card variant="soft" color="primary" sx={{
|
|
468
|
-
|
|
577
|
+
width: 320,
|
|
469
578
|
cursor: 'pointer',
|
|
470
|
-
transition: 'transform 0.2s',
|
|
579
|
+
transition: 'transform 0.2s, box-shadow 0.2s',
|
|
471
580
|
'&:hover': {
|
|
472
|
-
transform: 'translateY(-2px)'
|
|
581
|
+
transform: 'translateY(-2px)',
|
|
582
|
+
boxShadow: 'md'
|
|
473
583
|
}
|
|
474
584
|
}}>
|
|
475
585
|
<CardContent>
|
|
@@ -477,292 +587,335 @@ Interactive cards with click behavior and hover effects.
|
|
|
477
587
|
<Typography level="body-sm">마우스를 올리면 카드가 살짝 올라갑니다.</Typography>
|
|
478
588
|
</CardContent>
|
|
479
589
|
</Card>
|
|
480
|
-
</
|
|
590
|
+
</Stack>
|
|
481
591
|
```
|
|
482
592
|
|
|
483
|
-
##
|
|
593
|
+
## Media Cards
|
|
484
594
|
|
|
485
|
-
|
|
595
|
+
Product and food cards combining `CardOverflow`, `CardContent`, and `CardActions`.
|
|
486
596
|
|
|
487
597
|
```tsx
|
|
488
|
-
<
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}}>
|
|
493
|
-
<
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
<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" />
|
|
499
608
|
</AspectRatio>
|
|
500
609
|
</CardOverflow>
|
|
501
610
|
<CardContent>
|
|
502
611
|
<Typography level="title-lg">운동화</Typography>
|
|
503
|
-
<Typography level="body-
|
|
504
|
-
<Typography level="title-lg" sx={{
|
|
505
|
-
|
|
612
|
+
<Typography level="body-sm">편안하고 스타일리시한 운동화입니다.</Typography>
|
|
613
|
+
<Typography level="title-lg" color="primary" sx={{
|
|
614
|
+
mt: 0.5
|
|
506
615
|
}}>
|
|
507
616
|
₩129,000
|
|
508
617
|
</Typography>
|
|
509
618
|
</CardContent>
|
|
510
|
-
<
|
|
511
|
-
<
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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>
|
|
515
628
|
</Card>
|
|
516
629
|
|
|
517
630
|
<Card sx={{
|
|
518
|
-
|
|
631
|
+
width: 320,
|
|
632
|
+
boxShadow: 'lg'
|
|
519
633
|
}}>
|
|
520
634
|
<CardOverflow>
|
|
521
|
-
<AspectRatio
|
|
522
|
-
|
|
523
|
-
|
|
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>
|
|
524
650
|
</CardOverflow>
|
|
525
651
|
<CardContent>
|
|
526
|
-
<
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
|
530
663
|
}}>
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
664
|
+
건강하고 맛있는 아침 식사로 하루를 시작해보세요.
|
|
665
|
+
</Typography>
|
|
666
|
+
</CardContent>
|
|
667
|
+
<CardOverflow>
|
|
668
|
+
<Divider inset="context" />
|
|
669
|
+
<CardContent orientation="horizontal" sx={{
|
|
670
|
+
justifyContent: 'space-between'
|
|
534
671
|
}}>
|
|
535
|
-
<
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
}}>
|
|
542
|
-
<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={{
|
|
543
678
|
fontSize: 16
|
|
544
|
-
}} />
|
|
679
|
+
}} />}>
|
|
680
|
+
공유
|
|
545
681
|
</Typography>
|
|
546
|
-
<Typography level="body-md">건강하고 맛있는 아침 식사로 하루를 시작해보세요.</Typography>
|
|
547
682
|
</CardContent>
|
|
548
|
-
|
|
549
|
-
<Button size="sm" variant="plain" startDecorator={<FavoriteIcon />}>
|
|
550
|
-
좋아요
|
|
551
|
-
</Button>
|
|
552
|
-
<Button size="sm" variant="plain" startDecorator={<ShareIcon />}>
|
|
553
|
-
공유
|
|
554
|
-
</Button>
|
|
555
|
-
</CardActions>
|
|
683
|
+
</CardOverflow>
|
|
556
684
|
</Card>
|
|
557
|
-
</
|
|
685
|
+
</Stack>
|
|
558
686
|
```
|
|
559
687
|
|
|
560
|
-
##
|
|
688
|
+
## Complex Layout
|
|
561
689
|
|
|
562
|
-
A social-media-style card with
|
|
690
|
+
A social-media-style card with avatar, text, inline image, and engagement buttons.
|
|
563
691
|
|
|
564
692
|
```tsx
|
|
565
|
-
<div style={{
|
|
566
|
-
display: 'flex',
|
|
567
|
-
gap: '1rem',
|
|
568
|
-
flexWrap: 'wrap'
|
|
569
|
-
}}>
|
|
570
693
|
<Card sx={{
|
|
571
|
-
|
|
694
|
+
width: 400,
|
|
695
|
+
maxWidth: '100%'
|
|
572
696
|
}}>
|
|
573
|
-
<CardContent
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
<div style={{
|
|
577
|
-
display: 'flex',
|
|
578
|
-
alignItems: 'center',
|
|
579
|
-
gap: '1rem',
|
|
580
|
-
marginBottom: '1rem'
|
|
581
|
-
}}>
|
|
582
|
-
<Avatar size="sm" src="https://i.pravatar.cc/40?img=1" />
|
|
583
|
-
<div>
|
|
584
|
-
<Typography level="title-sm">김철수</Typography>
|
|
585
|
-
<Typography level="body-xs" sx={{
|
|
586
|
-
color: 'text.secondary'
|
|
697
|
+
<CardContent>
|
|
698
|
+
<Stack direction="row" spacing={1.5} alignItems="center" sx={{
|
|
699
|
+
mb: 1.5
|
|
587
700
|
}}>
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
<Typography level="
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
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
|
+
앞으로가 기대됩니다.
|
|
597
715
|
</Typography>
|
|
598
716
|
</CardContent>
|
|
599
717
|
<CardOverflow>
|
|
600
718
|
<AspectRatio ratio="2">
|
|
601
|
-
<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" />
|
|
602
720
|
</AspectRatio>
|
|
603
721
|
</CardOverflow>
|
|
604
|
-
<CardContent
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
<
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
</Button>
|
|
618
|
-
<Typography level="body-xs" sx={{
|
|
619
|
-
ml: 'auto',
|
|
620
|
-
color: 'text.secondary'
|
|
621
|
-
}}>
|
|
622
|
-
댓글 3개
|
|
623
|
-
</Typography>
|
|
624
|
-
</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>
|
|
625
735
|
</CardContent>
|
|
626
736
|
</Card>
|
|
627
|
-
</div>
|
|
628
737
|
```
|
|
629
738
|
|
|
630
|
-
## Card
|
|
631
|
-
|
|
632
|
-
Card is composed of several subcomponents:
|
|
633
|
-
|
|
634
|
-
### Card
|
|
635
|
-
|
|
636
|
-
The main card container.
|
|
637
|
-
|
|
638
|
-
```tsx
|
|
639
|
-
<Card variant="outlined" color="neutral" size="md">
|
|
640
|
-
{/* card content */}
|
|
641
|
-
</Card>
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
### CardContent
|
|
645
|
-
|
|
646
|
-
The area that contains the card's primary content.
|
|
739
|
+
## Product Card
|
|
647
740
|
|
|
648
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>
|
|
649
754
|
<CardContent>
|
|
650
|
-
<
|
|
651
|
-
|
|
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>
|
|
652
767
|
</CardContent>
|
|
653
|
-
```
|
|
654
|
-
|
|
655
|
-
### CardCover
|
|
656
|
-
|
|
657
|
-
Displays background media or an image that covers the entire card.
|
|
658
|
-
|
|
659
|
-
```tsx
|
|
660
|
-
<CardCover>
|
|
661
|
-
<img src="image.jpg" alt="Cover" />
|
|
662
|
-
</CardCover>
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
### CardActions
|
|
666
|
-
|
|
667
|
-
The area used to place action buttons.
|
|
668
|
-
|
|
669
|
-
```tsx
|
|
670
|
-
<CardActions>
|
|
671
|
-
<Button>확인</Button>
|
|
672
|
-
<Button>취소</Button>
|
|
673
|
-
</CardActions>
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
### CardOverflow
|
|
677
|
-
|
|
678
|
-
An area that ignores the card's padding and uses the full width.
|
|
679
|
-
|
|
680
|
-
```tsx
|
|
681
768
|
<CardOverflow>
|
|
682
|
-
<
|
|
683
|
-
|
|
684
|
-
|
|
769
|
+
<Button variant="solid" color="primary" size="lg" sx={{
|
|
770
|
+
borderRadius: 0
|
|
771
|
+
}}>
|
|
772
|
+
구매하기
|
|
773
|
+
</Button>
|
|
685
774
|
</CardOverflow>
|
|
686
|
-
```
|
|
687
|
-
|
|
688
|
-
## Product Cards
|
|
689
|
-
|
|
690
|
-
```tsx
|
|
691
|
-
<Card sx={{ maxWidth: 320 }}>
|
|
692
|
-
<CardOverflow>
|
|
693
|
-
<AspectRatio ratio="1">
|
|
694
|
-
<img src="product.jpg" alt="Product" />
|
|
695
|
-
</AspectRatio>
|
|
696
|
-
</CardOverflow>
|
|
697
|
-
<CardContent>
|
|
698
|
-
<Typography level="title-lg">제품명</Typography>
|
|
699
|
-
<Typography level="body-md">제품 설명</Typography>
|
|
700
|
-
<Typography level="title-lg" color="primary">
|
|
701
|
-
₩199,000
|
|
702
|
-
</Typography>
|
|
703
|
-
</CardContent>
|
|
704
|
-
<CardActions>
|
|
705
|
-
<Button variant="solid" fullWidth>
|
|
706
|
-
구매하기
|
|
707
|
-
</Button>
|
|
708
|
-
</CardActions>
|
|
709
775
|
</Card>
|
|
710
776
|
```
|
|
711
777
|
|
|
712
|
-
##
|
|
778
|
+
## Profile Card
|
|
713
779
|
|
|
714
780
|
```tsx
|
|
715
|
-
<Card sx={{
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
<
|
|
722
|
-
<
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
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>
|
|
729
834
|
</Card>
|
|
730
835
|
```
|
|
731
836
|
|
|
732
|
-
## News
|
|
837
|
+
## News Card
|
|
733
838
|
|
|
734
839
|
```tsx
|
|
735
|
-
<Card sx={{
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
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>
|
|
748
867
|
</Card>
|
|
749
868
|
```
|
|
750
869
|
|
|
751
|
-
## Dashboard Widget
|
|
870
|
+
## Dashboard Widget
|
|
752
871
|
|
|
753
872
|
```tsx
|
|
754
|
-
<
|
|
873
|
+
<Stack direction="row" spacing={2} flexWrap="wrap">
|
|
874
|
+
<Card variant="soft" color="primary" sx={{
|
|
875
|
+
width: 200
|
|
876
|
+
}}>
|
|
755
877
|
<CardContent>
|
|
756
878
|
<Typography level="body-sm">총 사용자</Typography>
|
|
757
879
|
<Typography level="h2">1,234</Typography>
|
|
758
|
-
<
|
|
759
|
-
|
|
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>
|
|
760
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>
|
|
761
914
|
```
|
|
762
915
|
|
|
763
916
|
## Props and Customization
|
|
764
917
|
|
|
765
|
-
###
|
|
918
|
+
### Card Props
|
|
766
919
|
|
|
767
920
|
| Prop | Type | Default | Description |
|
|
768
921
|
| ---------------- | -------------------------------------------------------------- | ------------ | -------------------------------------------------------- |
|
|
@@ -772,9 +925,51 @@ An area that ignores the card's padding and uses the full width.
|
|
|
772
925
|
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
|
|
773
926
|
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | Card layout direction |
|
|
774
927
|
| `invertedColors` | `boolean` | `false` | Invert child component colors |
|
|
928
|
+
| `component` | `ElementType` | `'div'` | Root element type (e.g. `'a'`, `'button'`) |
|
|
775
929
|
| `sx` | `SxProps` | - | Custom styles |
|
|
776
930
|
|
|
777
|
-
> **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.
|
|
778
973
|
|
|
779
974
|
## Best Practices
|
|
780
975
|
|
|
@@ -786,13 +981,16 @@ An area that ignores the card's padding and uses the full width.
|
|
|
786
981
|
|
|
787
982
|
4. **Use proper spacing**: When listing multiple cards, keep enough space between them so each one is clearly distinguishable.
|
|
788
983
|
|
|
789
|
-
5. **
|
|
790
|
-
- Support keyboard navigation when cards are clickable
|
|
791
|
-
- Provide appropriate `alt` text for images
|
|
792
|
-
- 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.
|
|
793
985
|
|
|
794
986
|
6. **Use responsive design**: Use `maxWidth` or responsive props so cards work well across different screen sizes.
|
|
795
987
|
|
|
796
988
|
7. **Handle loading states**: Use Skeleton components to represent loading states while data is being fetched.
|
|
797
989
|
|
|
798
|
-
|
|
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.
|