@delightui/components 0.1.105 → 0.1.107
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/README.md +104 -1
- package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
- package/dist/cjs/components/molecules/index.d.ts +2 -0
- package/dist/cjs/library.css +19 -6
- package/dist/cjs/library.js +3 -3
- package/dist/cjs/library.js.map +1 -1
- package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
- package/dist/esm/components/molecules/index.d.ts +2 -0
- package/dist/esm/library.css +19 -6
- package/dist/esm/library.js +3 -3
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +108 -2
- package/docs/README.md +264 -0
- package/docs/components/atoms/ActionImage.md +119 -0
- package/docs/components/atoms/Button.md +197 -0
- package/docs/components/atoms/Checkbox.md +299 -0
- package/docs/components/atoms/CheckboxItem.md +314 -0
- package/docs/components/atoms/Chip.md +380 -0
- package/docs/components/atoms/CustomToggle.md +270 -0
- package/docs/components/atoms/Icon.md +365 -0
- package/docs/components/atoms/IconButton.md +407 -0
- package/docs/components/atoms/Image.md +448 -0
- package/docs/components/atoms/Input.md +430 -0
- package/docs/components/atoms/ListItem.md +502 -0
- package/docs/components/atoms/Password.md +472 -0
- package/docs/components/atoms/RadioButton.md +614 -0
- package/docs/components/atoms/RadioButtonItem.md +588 -0
- package/docs/components/atoms/ResponsiveComponent.md +612 -0
- package/docs/components/atoms/SelectListItem.md +609 -0
- package/docs/components/atoms/Slider.md +605 -0
- package/docs/components/atoms/Spinner.md +605 -0
- package/docs/components/atoms/Text.md +463 -0
- package/docs/components/atoms/TextArea.md +670 -0
- package/docs/components/atoms/ToastNotification.md +668 -0
- package/docs/components/atoms/Toggle.md +737 -0
- package/docs/components/atoms/ToggleButton.md +751 -0
- package/docs/components/atoms/Tooltip.md +391 -0
- package/docs/components/molecules/Accordion.md +440 -0
- package/docs/components/molecules/AccordionGroup.md +547 -0
- package/docs/components/molecules/ActionCard.md +546 -0
- package/docs/components/molecules/Breadcrumb.md +403 -0
- package/docs/components/molecules/Breadcrumbs.md +485 -0
- package/docs/components/molecules/ButtonGroup.md +383 -0
- package/docs/components/molecules/Card.md +298 -0
- package/docs/components/molecules/ChipInput.md +646 -0
- package/docs/components/molecules/ContextMenu.md +768 -0
- package/docs/components/molecules/CustomTimeSelector.md +116 -0
- package/docs/components/molecules/DatePicker.md +516 -0
- package/docs/components/molecules/DateTimeSelector.md +166 -0
- package/docs/components/molecules/FormField.md +312 -0
- package/docs/components/molecules/Grid.md +577 -0
- package/docs/components/molecules/GridItem.md +834 -0
- package/docs/components/molecules/GridList.md +244 -0
- package/docs/components/molecules/List.md +485 -0
- package/docs/components/molecules/Modal.md +470 -0
- package/docs/components/molecules/ModalFooter.md +702 -0
- package/docs/components/molecules/ModalHeader.md +756 -0
- package/docs/components/molecules/ModalProvider.md +205 -0
- package/docs/components/molecules/Nav.md +530 -0
- package/docs/components/molecules/NavItem.md +572 -0
- package/docs/components/molecules/NavLink.md +499 -0
- package/docs/components/molecules/Option.md +521 -0
- package/docs/components/molecules/Pagination.md +592 -0
- package/docs/components/molecules/PaginationNumberField.md +722 -0
- package/docs/components/molecules/Popover.md +516 -0
- package/docs/components/molecules/ProgressBar.md +624 -0
- package/docs/components/molecules/RadioGroup.md +831 -0
- package/docs/components/molecules/RepeaterList.md +185 -0
- package/docs/components/molecules/Select.md +402 -0
- package/docs/components/molecules/SortableTrigger.md +82 -0
- package/docs/components/molecules/useModal.md +379 -0
- package/docs/components/organisms/Dropzone.md +346 -0
- package/docs/components/organisms/DropzoneClear.md +135 -0
- package/docs/components/organisms/DropzoneContent.md +216 -0
- package/docs/components/organisms/DropzoneFilename.md +191 -0
- package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
- package/docs/components/organisms/DropzoneTrigger.md +209 -0
- package/docs/components/organisms/Form.md +533 -0
- package/docs/components/organisms/SlideOutPanel.md +662 -0
- package/docs/components/organisms/TabContent.md +902 -0
- package/docs/components/organisms/TabItem.md +1091 -0
- package/docs/components/organisms/Table.md +611 -0
- package/docs/components/organisms/TableBody.md +679 -0
- package/docs/components/organisms/TableCell.md +482 -0
- package/docs/components/organisms/TableHeader.md +513 -0
- package/docs/components/organisms/TableHeaderCell.md +661 -0
- package/docs/components/organisms/TableRow.md +715 -0
- package/docs/components/organisms/Tabs.md +1330 -0
- package/docs/components/utils/ConditionalView.md +568 -0
- package/docs/components/utils/RenderStateView.md +726 -0
- package/docs/components/utils/WrapTextNodes.md +614 -0
- package/package.json +3 -2
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# ButtonGroup
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A container component that groups related buttons together with consistent spacing and styling. Supports horizontal and vertical layouts with different visual treatments to create cohesive button collections for actions, navigation, and selection interfaces.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- ButtonGroup
|
|
10
|
+
- ActionGroup
|
|
11
|
+
- ButtonSet
|
|
12
|
+
- ToolbarGroup
|
|
13
|
+
- ButtonCluster
|
|
14
|
+
|
|
15
|
+
## Props Breakdown
|
|
16
|
+
|
|
17
|
+
**Extends:** Standalone interface (no HTML element inheritance)
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Required | Description |
|
|
20
|
+
|------|------|---------|----------|-------------|
|
|
21
|
+
| `children` | `ReactNode \| ReactNode[]` | - | Yes | Button components to group together |
|
|
22
|
+
| `align` | `'Horizontal' \| 'Vertical'` | `'Horizontal'` | No | Layout direction for the button group |
|
|
23
|
+
| `type` | `'Outlined' \| 'Ghost'` | `'Filled'` | No | Visual style variant for the group |
|
|
24
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### Basic Usage
|
|
29
|
+
```tsx
|
|
30
|
+
import { ButtonGroup, Button } from '@delightui/components';
|
|
31
|
+
|
|
32
|
+
function BasicExample() {
|
|
33
|
+
return (
|
|
34
|
+
<ButtonGroup>
|
|
35
|
+
<Button>First</Button>
|
|
36
|
+
<Button>Second</Button>
|
|
37
|
+
<Button>Third</Button>
|
|
38
|
+
</ButtonGroup>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Horizontal vs Vertical Layout
|
|
44
|
+
```tsx
|
|
45
|
+
function LayoutExample() {
|
|
46
|
+
return (
|
|
47
|
+
<div className="layout-examples">
|
|
48
|
+
<div className="horizontal-group">
|
|
49
|
+
<Text type="Heading6">Horizontal Group</Text>
|
|
50
|
+
<ButtonGroup align="Horizontal">
|
|
51
|
+
<Button>Save</Button>
|
|
52
|
+
<Button type="Outlined">Cancel</Button>
|
|
53
|
+
<Button style="Destructive">Delete</Button>
|
|
54
|
+
</ButtonGroup>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div className="vertical-group">
|
|
58
|
+
<Text type="Heading6">Vertical Group</Text>
|
|
59
|
+
<ButtonGroup align="Vertical">
|
|
60
|
+
<Button>Edit Profile</Button>
|
|
61
|
+
<Button>Change Password</Button>
|
|
62
|
+
<Button>Privacy Settings</Button>
|
|
63
|
+
<Button style="Destructive">Delete Account</Button>
|
|
64
|
+
</ButtonGroup>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Button Group Types
|
|
72
|
+
```tsx
|
|
73
|
+
function TypesExample() {
|
|
74
|
+
return (
|
|
75
|
+
<div className="button-group-types">
|
|
76
|
+
<ButtonGroup type="Outlined">
|
|
77
|
+
<Button>Option A</Button>
|
|
78
|
+
<Button>Option B</Button>
|
|
79
|
+
<Button>Option C</Button>
|
|
80
|
+
</ButtonGroup>
|
|
81
|
+
|
|
82
|
+
<ButtonGroup type="Ghost">
|
|
83
|
+
<Button>Home</Button>
|
|
84
|
+
<Button>About</Button>
|
|
85
|
+
<Button>Contact</Button>
|
|
86
|
+
</ButtonGroup>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Action Groups
|
|
93
|
+
```tsx
|
|
94
|
+
function ActionGroupExample() {
|
|
95
|
+
const [selectedAction, setSelectedAction] = useState('edit');
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div className="action-groups">
|
|
99
|
+
<ButtonGroup>
|
|
100
|
+
<Button
|
|
101
|
+
type={selectedAction === 'edit' ? 'Filled' : 'Outlined'}
|
|
102
|
+
onClick={() => setSelectedAction('edit')}
|
|
103
|
+
leadingIcon={<Icon icon="Edit" />}
|
|
104
|
+
>
|
|
105
|
+
Edit
|
|
106
|
+
</Button>
|
|
107
|
+
<Button
|
|
108
|
+
type={selectedAction === 'copy' ? 'Filled' : 'Outlined'}
|
|
109
|
+
onClick={() => setSelectedAction('copy')}
|
|
110
|
+
leadingIcon={<Icon icon="Copy" />}
|
|
111
|
+
>
|
|
112
|
+
Copy
|
|
113
|
+
</Button>
|
|
114
|
+
<Button
|
|
115
|
+
type={selectedAction === 'delete' ? 'Filled' : 'Outlined'}
|
|
116
|
+
onClick={() => setSelectedAction('delete')}
|
|
117
|
+
leadingIcon={<Icon icon="Delete" />}
|
|
118
|
+
style="Destructive"
|
|
119
|
+
>
|
|
120
|
+
Delete
|
|
121
|
+
</Button>
|
|
122
|
+
</ButtonGroup>
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Navigation Group
|
|
129
|
+
```tsx
|
|
130
|
+
function NavigationGroupExample() {
|
|
131
|
+
const [currentPage, setCurrentPage] = useState('dashboard');
|
|
132
|
+
|
|
133
|
+
const navItems = [
|
|
134
|
+
{ id: 'dashboard', label: 'Dashboard', icon: 'Dashboard' },
|
|
135
|
+
{ id: 'projects', label: 'Projects', icon: 'Folder' },
|
|
136
|
+
{ id: 'team', label: 'Team', icon: 'People' },
|
|
137
|
+
{ id: 'settings', label: 'Settings', icon: 'Settings' }
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<ButtonGroup align="Vertical" type="Ghost">
|
|
142
|
+
<List
|
|
143
|
+
data={navItems}
|
|
144
|
+
component={({ id, label, icon }) => (
|
|
145
|
+
<Button
|
|
146
|
+
type={currentPage === id ? 'Filled' : 'Ghost'}
|
|
147
|
+
onClick={() => setCurrentPage(id)}
|
|
148
|
+
leadingIcon={<Icon icon={icon} />}
|
|
149
|
+
>
|
|
150
|
+
{label}
|
|
151
|
+
</Button>
|
|
152
|
+
)}
|
|
153
|
+
keyExtractor={(item) => item.id}
|
|
154
|
+
/>
|
|
155
|
+
</ButtonGroup>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Toggle Group
|
|
161
|
+
```tsx
|
|
162
|
+
function ToggleGroupExample() {
|
|
163
|
+
const [selectedOptions, setSelectedOptions] = useState(['bold']);
|
|
164
|
+
|
|
165
|
+
const toggleOption = (option) => {
|
|
166
|
+
setSelectedOptions(prev =>
|
|
167
|
+
prev.includes(option)
|
|
168
|
+
? prev.filter(o => o !== option)
|
|
169
|
+
: [...prev, option]
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<div className="toggle-groups">
|
|
175
|
+
<Text type="Heading6">Text Formatting</Text>
|
|
176
|
+
<ButtonGroup type="Outlined">
|
|
177
|
+
<Button
|
|
178
|
+
type={selectedOptions.includes('bold') ? 'Filled' : 'Outlined'}
|
|
179
|
+
onClick={() => toggleOption('bold')}
|
|
180
|
+
leadingIcon={<Icon icon="FormatBold" />}
|
|
181
|
+
>
|
|
182
|
+
Bold
|
|
183
|
+
</Button>
|
|
184
|
+
<Button
|
|
185
|
+
type={selectedOptions.includes('italic') ? 'Filled' : 'Outlined'}
|
|
186
|
+
onClick={() => toggleOption('italic')}
|
|
187
|
+
leadingIcon={<Icon icon="FormatItalic" />}
|
|
188
|
+
>
|
|
189
|
+
Italic
|
|
190
|
+
</Button>
|
|
191
|
+
<Button
|
|
192
|
+
type={selectedOptions.includes('underline') ? 'Filled' : 'Outlined'}
|
|
193
|
+
onClick={() => toggleOption('underline')}
|
|
194
|
+
leadingIcon={<Icon icon="FormatUnderline" />}
|
|
195
|
+
>
|
|
196
|
+
Underline
|
|
197
|
+
</Button>
|
|
198
|
+
</ButtonGroup>
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Form Button Groups
|
|
205
|
+
```tsx
|
|
206
|
+
function FormButtonGroupExample() {
|
|
207
|
+
const handleSave = () => {
|
|
208
|
+
console.log('Saving...');
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const handleCancel = () => {
|
|
212
|
+
console.log('Cancelling...');
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const handleReset = () => {
|
|
216
|
+
console.log('Resetting...');
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<Form>
|
|
221
|
+
<FormField name="title" label="Title" required>
|
|
222
|
+
<Input placeholder="Enter title" />
|
|
223
|
+
</FormField>
|
|
224
|
+
|
|
225
|
+
<FormField name="description" label="Description">
|
|
226
|
+
<TextArea placeholder="Enter description" rows={4} />
|
|
227
|
+
</FormField>
|
|
228
|
+
|
|
229
|
+
<ButtonGroup>
|
|
230
|
+
<Button onClick={handleSave}>Save</Button>
|
|
231
|
+
<Button type="Outlined" onClick={handleCancel}>Cancel</Button>
|
|
232
|
+
<Button type="Ghost" onClick={handleReset}>Reset</Button>
|
|
233
|
+
</ButtonGroup>
|
|
234
|
+
</Form>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Icon Button Groups
|
|
240
|
+
```tsx
|
|
241
|
+
function IconButtonGroupExample() {
|
|
242
|
+
const [view, setView] = useState('grid');
|
|
243
|
+
|
|
244
|
+
return (
|
|
245
|
+
<div className="icon-button-groups">
|
|
246
|
+
<Text type="Heading6">View Options</Text>
|
|
247
|
+
<ButtonGroup type="Outlined">
|
|
248
|
+
<Button
|
|
249
|
+
type={view === 'list' ? 'Filled' : 'Outlined'}
|
|
250
|
+
onClick={() => setView('list')}
|
|
251
|
+
aria-label="List view"
|
|
252
|
+
>
|
|
253
|
+
<Icon icon="List" />
|
|
254
|
+
</Button>
|
|
255
|
+
<Button
|
|
256
|
+
type={view === 'grid' ? 'Filled' : 'Outlined'}
|
|
257
|
+
onClick={() => setView('grid')}
|
|
258
|
+
aria-label="Grid view"
|
|
259
|
+
>
|
|
260
|
+
<Icon icon="Grid" />
|
|
261
|
+
</Button>
|
|
262
|
+
<Button
|
|
263
|
+
type={view === 'card' ? 'Filled' : 'Outlined'}
|
|
264
|
+
onClick={() => setView('card')}
|
|
265
|
+
aria-label="Card view"
|
|
266
|
+
>
|
|
267
|
+
<Icon icon="Card" />
|
|
268
|
+
</Button>
|
|
269
|
+
</ButtonGroup>
|
|
270
|
+
</div>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Loading States
|
|
276
|
+
```tsx
|
|
277
|
+
function LoadingStatesExample() {
|
|
278
|
+
const [loadingStates, setLoadingStates] = useState({
|
|
279
|
+
save: false,
|
|
280
|
+
publish: false,
|
|
281
|
+
delete: false
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
const handleAction = async (action) => {
|
|
285
|
+
setLoadingStates(prev => ({ ...prev, [action]: true }));
|
|
286
|
+
|
|
287
|
+
// Simulate async operation
|
|
288
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
289
|
+
|
|
290
|
+
setLoadingStates(prev => ({ ...prev, [action]: false }));
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
<ButtonGroup>
|
|
295
|
+
<Button
|
|
296
|
+
loading={loadingStates.save}
|
|
297
|
+
onClick={() => handleAction('save')}
|
|
298
|
+
disabled={Object.values(loadingStates).some(Boolean)}
|
|
299
|
+
>
|
|
300
|
+
Save Draft
|
|
301
|
+
</Button>
|
|
302
|
+
<Button
|
|
303
|
+
loading={loadingStates.publish}
|
|
304
|
+
onClick={() => handleAction('publish')}
|
|
305
|
+
disabled={Object.values(loadingStates).some(Boolean)}
|
|
306
|
+
>
|
|
307
|
+
Publish
|
|
308
|
+
</Button>
|
|
309
|
+
<Button
|
|
310
|
+
style="Destructive"
|
|
311
|
+
loading={loadingStates.delete}
|
|
312
|
+
onClick={() => handleAction('delete')}
|
|
313
|
+
disabled={Object.values(loadingStates).some(Boolean)}
|
|
314
|
+
>
|
|
315
|
+
Delete
|
|
316
|
+
</Button>
|
|
317
|
+
</ButtonGroup>
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Responsive Button Groups
|
|
323
|
+
```tsx
|
|
324
|
+
function ResponsiveButtonGroupExample() {
|
|
325
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
326
|
+
|
|
327
|
+
useEffect(() => {
|
|
328
|
+
const checkScreenSize = () => {
|
|
329
|
+
setIsMobile(window.innerWidth < 768);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
checkScreenSize();
|
|
333
|
+
window.addEventListener('resize', checkScreenSize);
|
|
334
|
+
return () => window.removeEventListener('resize', checkScreenSize);
|
|
335
|
+
}, []);
|
|
336
|
+
|
|
337
|
+
return (
|
|
338
|
+
<ButtonGroup align={isMobile ? 'Vertical' : 'Horizontal'}>
|
|
339
|
+
<Button>Action 1</Button>
|
|
340
|
+
<Button>Action 2</Button>
|
|
341
|
+
<Button>Action 3</Button>
|
|
342
|
+
</ButtonGroup>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Button Group with Dropdowns
|
|
348
|
+
```tsx
|
|
349
|
+
function DropdownButtonGroupExample() {
|
|
350
|
+
const [showDropdown, setShowDropdown] = useState(false);
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<div className="dropdown-button-group">
|
|
354
|
+
<ButtonGroup>
|
|
355
|
+
<Button onClick={() => console.log('Primary action')}>
|
|
356
|
+
Save
|
|
357
|
+
</Button>
|
|
358
|
+
<Button
|
|
359
|
+
type="Outlined"
|
|
360
|
+
onClick={() => setShowDropdown(!showDropdown)}
|
|
361
|
+
trailingIcon={<Icon icon="ExpandMore" />}
|
|
362
|
+
>
|
|
363
|
+
Options
|
|
364
|
+
</Button>
|
|
365
|
+
</ButtonGroup>
|
|
366
|
+
|
|
367
|
+
{showDropdown && (
|
|
368
|
+
<div className="dropdown-menu">
|
|
369
|
+
<Button type="Ghost" onClick={() => console.log('Save as...')}>
|
|
370
|
+
Save as...
|
|
371
|
+
</Button>
|
|
372
|
+
<Button type="Ghost" onClick={() => console.log('Save and publish')}>
|
|
373
|
+
Save and Publish
|
|
374
|
+
</Button>
|
|
375
|
+
<Button type="Ghost" onClick={() => console.log('Save template')}>
|
|
376
|
+
Save as Template
|
|
377
|
+
</Button>
|
|
378
|
+
</div>
|
|
379
|
+
)}
|
|
380
|
+
</div>
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
```
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A flexible container component that groups related content and actions in a coherent unit. Cards provide structure and visual hierarchy for presenting information, making them ideal for displaying content blocks, product information, user profiles, and interactive elements.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- Card
|
|
10
|
+
- Panel
|
|
11
|
+
- Container
|
|
12
|
+
- Content Block
|
|
13
|
+
- Info Card
|
|
14
|
+
|
|
15
|
+
## Props Breakdown
|
|
16
|
+
|
|
17
|
+
**Extends:** Standalone interface (no HTML element inheritance)
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Required | Description |
|
|
20
|
+
|------|------|---------|----------|-------------|
|
|
21
|
+
| `children` | `ReactNode` | - | Yes | The content to be displayed within the card |
|
|
22
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
### Basic Usage
|
|
27
|
+
```tsx
|
|
28
|
+
import { Card, Text } from '@delightui/components';
|
|
29
|
+
|
|
30
|
+
function BasicExample() {
|
|
31
|
+
return (
|
|
32
|
+
<Card>
|
|
33
|
+
<Text type="Heading3">Welcome</Text>
|
|
34
|
+
<Text>This is a simple card with some content inside.</Text>
|
|
35
|
+
</Card>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Card with Header and Content
|
|
41
|
+
```tsx
|
|
42
|
+
import { Card, Text, Button } from '@delightui/components';
|
|
43
|
+
|
|
44
|
+
function HeaderContentExample() {
|
|
45
|
+
return (
|
|
46
|
+
<Card>
|
|
47
|
+
<div className="card-header">
|
|
48
|
+
<Text type="Heading4">Project Overview</Text>
|
|
49
|
+
<Text type="BodySmall" className="card-subtitle">
|
|
50
|
+
Last updated 2 hours ago
|
|
51
|
+
</Text>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div className="card-content">
|
|
55
|
+
<Text>
|
|
56
|
+
This project includes a comprehensive component library
|
|
57
|
+
with design system integration and accessibility features.
|
|
58
|
+
</Text>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div className="card-actions">
|
|
62
|
+
<Button size="Small">View Details</Button>
|
|
63
|
+
<Button size="Small" type="Outlined">Edit</Button>
|
|
64
|
+
</div>
|
|
65
|
+
</Card>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Product Card
|
|
71
|
+
```tsx
|
|
72
|
+
import { Card, Image, Text, Button, Chip } from '@delightui/components';
|
|
73
|
+
|
|
74
|
+
function ProductCardExample() {
|
|
75
|
+
return (
|
|
76
|
+
<Card className="product-card">
|
|
77
|
+
<Image
|
|
78
|
+
src="/product-image.jpg"
|
|
79
|
+
alt="Product"
|
|
80
|
+
aspectRatio="16/9"
|
|
81
|
+
/>
|
|
82
|
+
|
|
83
|
+
<div className="card-body">
|
|
84
|
+
<div className="card-header">
|
|
85
|
+
<Text type="Heading5">Premium Headphones</Text>
|
|
86
|
+
<Chip size="Small" style="A">New</Chip>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<Text type="BodySmall" className="card-description">
|
|
90
|
+
Wireless noise-cancelling headphones with premium sound quality
|
|
91
|
+
and 30-hour battery life.
|
|
92
|
+
</Text>
|
|
93
|
+
|
|
94
|
+
<div className="card-pricing">
|
|
95
|
+
<Text type="Heading6">$299.99</Text>
|
|
96
|
+
<Text type="BodySmall" className="original-price">$399.99</Text>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<div className="card-actions">
|
|
100
|
+
<Button>Add to Cart</Button>
|
|
101
|
+
<Button type="Outlined">View Details</Button>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</Card>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### User Profile Card
|
|
110
|
+
```tsx
|
|
111
|
+
import { Card, Image, Text, Button, Icon } from '@delightui/components';
|
|
112
|
+
|
|
113
|
+
function UserProfileExample() {
|
|
114
|
+
return (
|
|
115
|
+
<Card className="profile-card">
|
|
116
|
+
<div className="profile-header">
|
|
117
|
+
<Image
|
|
118
|
+
src="/avatar.jpg"
|
|
119
|
+
alt="User Avatar"
|
|
120
|
+
className="profile-avatar"
|
|
121
|
+
/>
|
|
122
|
+
|
|
123
|
+
<div className="profile-info">
|
|
124
|
+
<Text type="Heading5">John Doe</Text>
|
|
125
|
+
<Text type="BodySmall">Senior Developer</Text>
|
|
126
|
+
<Text type="BodySmall" className="profile-location">
|
|
127
|
+
<Icon icon="Location" size="Small" />
|
|
128
|
+
San Francisco, CA
|
|
129
|
+
</Text>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div className="profile-stats">
|
|
134
|
+
<div className="stat">
|
|
135
|
+
<Text type="Heading6">127</Text>
|
|
136
|
+
<Text type="BodySmall">Projects</Text>
|
|
137
|
+
</div>
|
|
138
|
+
<div className="stat">
|
|
139
|
+
<Text type="Heading6">1.2k</Text>
|
|
140
|
+
<Text type="BodySmall">Followers</Text>
|
|
141
|
+
</div>
|
|
142
|
+
<div className="stat">
|
|
143
|
+
<Text type="Heading6">89</Text>
|
|
144
|
+
<Text type="BodySmall">Following</Text>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div className="card-actions">
|
|
149
|
+
<Button>Follow</Button>
|
|
150
|
+
<Button type="Outlined">Message</Button>
|
|
151
|
+
</div>
|
|
152
|
+
</Card>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Interactive Card
|
|
158
|
+
```tsx
|
|
159
|
+
function InteractiveCardExample() {
|
|
160
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<Card className="interactive-card">
|
|
164
|
+
<div
|
|
165
|
+
className="card-clickable-header"
|
|
166
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
167
|
+
>
|
|
168
|
+
<Text type="Heading5">Expandable Content</Text>
|
|
169
|
+
<Icon
|
|
170
|
+
icon={isExpanded ? "ExpandLess" : "ExpandMore"}
|
|
171
|
+
className="expand-icon"
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
{isExpanded && (
|
|
176
|
+
<div className="card-expandable-content">
|
|
177
|
+
<Text>
|
|
178
|
+
This content is revealed when the card header is clicked.
|
|
179
|
+
You can include any content here including forms, lists,
|
|
180
|
+
or other interactive elements.
|
|
181
|
+
</Text>
|
|
182
|
+
|
|
183
|
+
<div className="card-actions">
|
|
184
|
+
<Button size="Small">Action 1</Button>
|
|
185
|
+
<Button size="Small" type="Outlined">Action 2</Button>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
)}
|
|
189
|
+
</Card>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Card Grid Layout
|
|
195
|
+
```tsx
|
|
196
|
+
function CardGridExample() {
|
|
197
|
+
const items = [
|
|
198
|
+
{ title: "Analytics", description: "View detailed analytics", icon: "BarChart" },
|
|
199
|
+
{ title: "Settings", description: "Manage your preferences", icon: "Settings" },
|
|
200
|
+
{ title: "Help", description: "Get support and documentation", icon: "Help" },
|
|
201
|
+
{ title: "Profile", description: "Update your profile information", icon: "Person" }
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div className="card-grid">
|
|
206
|
+
{items.map((item, index) => (
|
|
207
|
+
<Card key={index} className="feature-card">
|
|
208
|
+
<div className="card-icon">
|
|
209
|
+
<Icon icon={item.icon} size="Large" />
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
<div className="card-content">
|
|
213
|
+
<Text type="Heading6">{item.title}</Text>
|
|
214
|
+
<Text type="BodySmall">{item.description}</Text>
|
|
215
|
+
</div>
|
|
216
|
+
|
|
217
|
+
<div className="card-action">
|
|
218
|
+
<Button size="Small" type="Ghost">
|
|
219
|
+
<Icon icon="ArrowForward" size="Small" />
|
|
220
|
+
</Button>
|
|
221
|
+
</div>
|
|
222
|
+
</Card>
|
|
223
|
+
))}
|
|
224
|
+
</div>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Card with Form
|
|
230
|
+
```tsx
|
|
231
|
+
import { Card, Text, FormField, Input, Button, Form } from '@delightui/components';
|
|
232
|
+
|
|
233
|
+
function FormCardExample() {
|
|
234
|
+
const handleSubmit = (values, setError) => {
|
|
235
|
+
console.log('Form submitted:', values);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<Card className="form-card">
|
|
240
|
+
<div className="card-header">
|
|
241
|
+
<Text type="Heading4">Contact Us</Text>
|
|
242
|
+
<Text type="BodySmall">
|
|
243
|
+
We'd love to hear from you. Send us a message!
|
|
244
|
+
</Text>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<Form onSubmit={handleSubmit}>
|
|
248
|
+
<FormField name="name" label="Name" required>
|
|
249
|
+
<Input placeholder="Your name" />
|
|
250
|
+
</FormField>
|
|
251
|
+
|
|
252
|
+
<FormField name="email" label="Email" required>
|
|
253
|
+
<Input inputType="Email" placeholder="your@email.com" />
|
|
254
|
+
</FormField>
|
|
255
|
+
|
|
256
|
+
<FormField name="message" label="Message" required>
|
|
257
|
+
<TextArea
|
|
258
|
+
placeholder="Your message..."
|
|
259
|
+
rows={4}
|
|
260
|
+
/>
|
|
261
|
+
</FormField>
|
|
262
|
+
|
|
263
|
+
<div className="card-actions">
|
|
264
|
+
<Button actionType="submit">Send Message</Button>
|
|
265
|
+
<Button type="Outlined" actionType="reset">Clear</Button>
|
|
266
|
+
</div>
|
|
267
|
+
</Form>
|
|
268
|
+
</Card>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Custom Styled Cards
|
|
274
|
+
```tsx
|
|
275
|
+
function CustomStyledExample() {
|
|
276
|
+
return (
|
|
277
|
+
<div className="custom-cards">
|
|
278
|
+
<Card className="success-card">
|
|
279
|
+
<Icon icon="Check" className="status-icon" />
|
|
280
|
+
<Text type="Heading6">Success!</Text>
|
|
281
|
+
<Text type="BodySmall">Your action was completed successfully.</Text>
|
|
282
|
+
</Card>
|
|
283
|
+
|
|
284
|
+
<Card className="warning-card">
|
|
285
|
+
<Icon icon="Warning" className="status-icon" />
|
|
286
|
+
<Text type="Heading6">Warning</Text>
|
|
287
|
+
<Text type="BodySmall">Please review before proceeding.</Text>
|
|
288
|
+
</Card>
|
|
289
|
+
|
|
290
|
+
<Card className="error-card">
|
|
291
|
+
<Icon icon="Error" className="status-icon" />
|
|
292
|
+
<Text type="Heading6">Error</Text>
|
|
293
|
+
<Text type="BodySmall">Something went wrong. Please try again.</Text>
|
|
294
|
+
</Card>
|
|
295
|
+
</div>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
```
|