@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,440 @@
|
|
|
1
|
+
# Accordion
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A collapsible content component that allows users to expand and collapse sections of information. Supports controlled and uncontrolled modes, custom icons, different sizes, and can be used individually or grouped together for organizing complex content hierarchies.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- Accordion
|
|
10
|
+
- Collapsible
|
|
11
|
+
- Expandable
|
|
12
|
+
- DropDown
|
|
13
|
+
- Disclosure
|
|
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 | Content of the accordion |
|
|
22
|
+
| `size` | `'Small' \| 'Medium' \| 'Large'` | `'Medium'` | No | Size variant of the accordion |
|
|
23
|
+
| `defaultExpanded` | `boolean` | `false` | No | Whether accordion is expanded by default |
|
|
24
|
+
| `expanded` | `boolean` | - | No | Controls expanded state in controlled mode |
|
|
25
|
+
| `onChange` | `(isOpen: boolean) => void` | - | No | Callback when accordion is expanded/collapsed |
|
|
26
|
+
| `name` | `string` | - | No | Unique identifier for the accordion |
|
|
27
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
28
|
+
|
|
29
|
+
**AccordionSummary Props:**
|
|
30
|
+
| Prop | Type | Default | Required | Description |
|
|
31
|
+
|------|------|---------|----------|-------------|
|
|
32
|
+
| `children` | `ReactNode` | - | Yes | Header content of the accordion |
|
|
33
|
+
| `expandIcon` | `ReactNode` | - | No | Custom expand/collapse icon |
|
|
34
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
35
|
+
|
|
36
|
+
**AccordionDetails Props:**
|
|
37
|
+
| Prop | Type | Default | Required | Description |
|
|
38
|
+
|------|------|---------|----------|-------------|
|
|
39
|
+
| `children` | `ReactNode` | - | Yes | Body content of the accordion |
|
|
40
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
45
|
+
```tsx
|
|
46
|
+
import { Accordion, AccordionSummary, AccordionDetails, Text } from '@delightui/components';
|
|
47
|
+
|
|
48
|
+
function BasicExample() {
|
|
49
|
+
return (
|
|
50
|
+
<Accordion>
|
|
51
|
+
<AccordionSummary>
|
|
52
|
+
<Text type="Heading6">What is your return policy?</Text>
|
|
53
|
+
</AccordionSummary>
|
|
54
|
+
<AccordionDetails>
|
|
55
|
+
<Text type="BodyMedium">
|
|
56
|
+
We offer a 30-day return policy for all items in original condition.
|
|
57
|
+
Returns must be initiated within 30 days of purchase.
|
|
58
|
+
</Text>
|
|
59
|
+
</AccordionDetails>
|
|
60
|
+
</Accordion>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Multiple Accordions
|
|
66
|
+
```tsx
|
|
67
|
+
function MultipleAccordionsExample() {
|
|
68
|
+
const faqs = [
|
|
69
|
+
{
|
|
70
|
+
id: 1,
|
|
71
|
+
question: "How do I create an account?",
|
|
72
|
+
answer: "Click the 'Sign Up' button and fill out the registration form with your email and password."
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 2,
|
|
76
|
+
question: "Can I change my subscription plan?",
|
|
77
|
+
answer: "Yes, you can upgrade or downgrade your plan at any time from your account settings."
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 3,
|
|
81
|
+
question: "Is my data secure?",
|
|
82
|
+
answer: "We use industry-standard encryption and security measures to protect your data."
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="faq-accordions">
|
|
88
|
+
{faqs.map(faq => (
|
|
89
|
+
<Accordion key={faq.id} name={`faq-${faq.id}`}>
|
|
90
|
+
<AccordionSummary>
|
|
91
|
+
<Text type="Heading6">{faq.question}</Text>
|
|
92
|
+
</AccordionSummary>
|
|
93
|
+
<AccordionDetails>
|
|
94
|
+
<Text type="BodyMedium">{faq.answer}</Text>
|
|
95
|
+
</AccordionDetails>
|
|
96
|
+
</Accordion>
|
|
97
|
+
))}
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Controlled Accordion
|
|
104
|
+
```tsx
|
|
105
|
+
function ControlledAccordionExample() {
|
|
106
|
+
const [expanded, setExpanded] = useState(false);
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div className="controlled-accordion">
|
|
110
|
+
<Button onClick={() => setExpanded(!expanded)}>
|
|
111
|
+
{expanded ? 'Collapse' : 'Expand'} Accordion
|
|
112
|
+
</Button>
|
|
113
|
+
|
|
114
|
+
<Accordion
|
|
115
|
+
expanded={expanded}
|
|
116
|
+
onChange={setExpanded}
|
|
117
|
+
>
|
|
118
|
+
<AccordionSummary>
|
|
119
|
+
<Text type="Heading6">Controlled Accordion</Text>
|
|
120
|
+
</AccordionSummary>
|
|
121
|
+
<AccordionDetails>
|
|
122
|
+
<Text type="BodyMedium">
|
|
123
|
+
This accordion's state is controlled by the button above.
|
|
124
|
+
You can also click on the header to toggle it.
|
|
125
|
+
</Text>
|
|
126
|
+
</AccordionDetails>
|
|
127
|
+
</Accordion>
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Accordion Sizes
|
|
134
|
+
```tsx
|
|
135
|
+
function AccordionSizesExample() {
|
|
136
|
+
return (
|
|
137
|
+
<div className="accordion-sizes">
|
|
138
|
+
<Accordion size="Small">
|
|
139
|
+
<AccordionSummary>
|
|
140
|
+
<Text type="BodyMedium">Small Accordion</Text>
|
|
141
|
+
</AccordionSummary>
|
|
142
|
+
<AccordionDetails>
|
|
143
|
+
<Text type="BodySmall">
|
|
144
|
+
This is a small accordion with compact spacing.
|
|
145
|
+
</Text>
|
|
146
|
+
</AccordionDetails>
|
|
147
|
+
</Accordion>
|
|
148
|
+
|
|
149
|
+
<Accordion size="Medium">
|
|
150
|
+
<AccordionSummary>
|
|
151
|
+
<Text type="Heading6">Medium Accordion</Text>
|
|
152
|
+
</AccordionSummary>
|
|
153
|
+
<AccordionDetails>
|
|
154
|
+
<Text type="BodyMedium">
|
|
155
|
+
This is a medium accordion with standard spacing.
|
|
156
|
+
</Text>
|
|
157
|
+
</AccordionDetails>
|
|
158
|
+
</Accordion>
|
|
159
|
+
|
|
160
|
+
<Accordion size="Large">
|
|
161
|
+
<AccordionSummary>
|
|
162
|
+
<Text type="Heading5">Large Accordion</Text>
|
|
163
|
+
</AccordionSummary>
|
|
164
|
+
<AccordionDetails>
|
|
165
|
+
<Text type="BodyMedium">
|
|
166
|
+
This is a large accordion with generous spacing.
|
|
167
|
+
</Text>
|
|
168
|
+
</AccordionDetails>
|
|
169
|
+
</Accordion>
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Custom Icons
|
|
176
|
+
```tsx
|
|
177
|
+
function CustomIconExample() {
|
|
178
|
+
return (
|
|
179
|
+
<div className="custom-icon-accordions">
|
|
180
|
+
<Accordion>
|
|
181
|
+
<AccordionSummary expandIcon={<Icon icon="Add" />}>
|
|
182
|
+
<Text type="Heading6">Custom Plus/Minus Icon</Text>
|
|
183
|
+
</AccordionSummary>
|
|
184
|
+
<AccordionDetails>
|
|
185
|
+
<Text type="BodyMedium">
|
|
186
|
+
This accordion uses a custom plus/minus icon.
|
|
187
|
+
</Text>
|
|
188
|
+
</AccordionDetails>
|
|
189
|
+
</Accordion>
|
|
190
|
+
|
|
191
|
+
<Accordion>
|
|
192
|
+
<AccordionSummary expandIcon={<Icon icon="ArrowForward" />}>
|
|
193
|
+
<Text type="Heading6">Arrow Icon</Text>
|
|
194
|
+
</AccordionSummary>
|
|
195
|
+
<AccordionDetails>
|
|
196
|
+
<Text type="BodyMedium">
|
|
197
|
+
This accordion uses an arrow icon that rotates.
|
|
198
|
+
</Text>
|
|
199
|
+
</AccordionDetails>
|
|
200
|
+
</Accordion>
|
|
201
|
+
</div>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Rich Content Accordion
|
|
207
|
+
```tsx
|
|
208
|
+
function RichContentExample() {
|
|
209
|
+
return (
|
|
210
|
+
<Accordion defaultExpanded>
|
|
211
|
+
<AccordionSummary>
|
|
212
|
+
<div className="rich-summary">
|
|
213
|
+
<Icon icon="Settings" />
|
|
214
|
+
<div className="summary-content">
|
|
215
|
+
<Text type="Heading6">Account Settings</Text>
|
|
216
|
+
<Text type="BodySmall">Manage your account preferences</Text>
|
|
217
|
+
</div>
|
|
218
|
+
<Chip size="Small" style="A">Pro</Chip>
|
|
219
|
+
</div>
|
|
220
|
+
</AccordionSummary>
|
|
221
|
+
<AccordionDetails>
|
|
222
|
+
<div className="rich-details">
|
|
223
|
+
<FormField name="notifications" label="Email Notifications">
|
|
224
|
+
<Checkbox>Receive email notifications</Checkbox>
|
|
225
|
+
</FormField>
|
|
226
|
+
|
|
227
|
+
<FormField name="theme" label="Theme Preference">
|
|
228
|
+
<RadioGroup>
|
|
229
|
+
<RadioButton value="light">Light Theme</RadioButton>
|
|
230
|
+
<RadioButton value="dark">Dark Theme</RadioButton>
|
|
231
|
+
<RadioButton value="auto">Auto</RadioButton>
|
|
232
|
+
</RadioGroup>
|
|
233
|
+
</FormField>
|
|
234
|
+
|
|
235
|
+
<FormField name="language" label="Language">
|
|
236
|
+
<Select>
|
|
237
|
+
<Option value="en">English</Option>
|
|
238
|
+
<Option value="es">Spanish</Option>
|
|
239
|
+
<Option value="fr">French</Option>
|
|
240
|
+
</Select>
|
|
241
|
+
</FormField>
|
|
242
|
+
|
|
243
|
+
<ButtonGroup>
|
|
244
|
+
<Button>Save Changes</Button>
|
|
245
|
+
<Button type="Outlined">Reset</Button>
|
|
246
|
+
</ButtonGroup>
|
|
247
|
+
</div>
|
|
248
|
+
</AccordionDetails>
|
|
249
|
+
</Accordion>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Nested Accordions
|
|
255
|
+
```tsx
|
|
256
|
+
function NestedAccordionsExample() {
|
|
257
|
+
return (
|
|
258
|
+
<Accordion>
|
|
259
|
+
<AccordionSummary>
|
|
260
|
+
<Text type="Heading5">Product Categories</Text>
|
|
261
|
+
</AccordionSummary>
|
|
262
|
+
<AccordionDetails>
|
|
263
|
+
<div className="nested-accordions">
|
|
264
|
+
<Accordion size="Small">
|
|
265
|
+
<AccordionSummary>
|
|
266
|
+
<Text type="Heading6">Electronics</Text>
|
|
267
|
+
</AccordionSummary>
|
|
268
|
+
<AccordionDetails>
|
|
269
|
+
<List
|
|
270
|
+
data={['Phones', 'Laptops', 'Tablets', 'Accessories']}
|
|
271
|
+
component={({ item }) => (
|
|
272
|
+
<ListItem>
|
|
273
|
+
<Text type="BodySmall">{item}</Text>
|
|
274
|
+
</ListItem>
|
|
275
|
+
)}
|
|
276
|
+
/>
|
|
277
|
+
</AccordionDetails>
|
|
278
|
+
</Accordion>
|
|
279
|
+
|
|
280
|
+
<Accordion size="Small">
|
|
281
|
+
<AccordionSummary>
|
|
282
|
+
<Text type="Heading6">Clothing</Text>
|
|
283
|
+
</AccordionSummary>
|
|
284
|
+
<AccordionDetails>
|
|
285
|
+
<List
|
|
286
|
+
data={['Shirts', 'Pants', 'Shoes', 'Accessories']}
|
|
287
|
+
component={({ item }) => (
|
|
288
|
+
<ListItem>
|
|
289
|
+
<Text type="BodySmall">{item}</Text>
|
|
290
|
+
</ListItem>
|
|
291
|
+
)}
|
|
292
|
+
/>
|
|
293
|
+
</AccordionDetails>
|
|
294
|
+
</Accordion>
|
|
295
|
+
</div>
|
|
296
|
+
</AccordionDetails>
|
|
297
|
+
</Accordion>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Accordion Group
|
|
303
|
+
```tsx
|
|
304
|
+
function AccordionGroupExample() {
|
|
305
|
+
const [openAccordion, setOpenAccordion] = useState(null);
|
|
306
|
+
|
|
307
|
+
const handleAccordionChange = (accordionName, isOpen) => {
|
|
308
|
+
if (isOpen) {
|
|
309
|
+
setOpenAccordion(accordionName);
|
|
310
|
+
} else {
|
|
311
|
+
setOpenAccordion(null);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const sections = [
|
|
316
|
+
{
|
|
317
|
+
name: 'getting-started',
|
|
318
|
+
title: 'Getting Started',
|
|
319
|
+
content: 'Learn the basics of using our platform.'
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: 'advanced-features',
|
|
323
|
+
title: 'Advanced Features',
|
|
324
|
+
content: 'Explore powerful features for advanced users.'
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: 'troubleshooting',
|
|
328
|
+
title: 'Troubleshooting',
|
|
329
|
+
content: 'Common issues and their solutions.'
|
|
330
|
+
}
|
|
331
|
+
];
|
|
332
|
+
|
|
333
|
+
return (
|
|
334
|
+
<div className="accordion-group">
|
|
335
|
+
{sections.map(section => (
|
|
336
|
+
<Accordion
|
|
337
|
+
key={section.name}
|
|
338
|
+
name={section.name}
|
|
339
|
+
expanded={openAccordion === section.name}
|
|
340
|
+
onChange={(isOpen) => handleAccordionChange(section.name, isOpen)}
|
|
341
|
+
>
|
|
342
|
+
<AccordionSummary>
|
|
343
|
+
<Text type="Heading6">{section.title}</Text>
|
|
344
|
+
</AccordionSummary>
|
|
345
|
+
<AccordionDetails>
|
|
346
|
+
<Text type="BodyMedium">{section.content}</Text>
|
|
347
|
+
</AccordionDetails>
|
|
348
|
+
</Accordion>
|
|
349
|
+
))}
|
|
350
|
+
</div>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Interactive Accordion
|
|
356
|
+
```tsx
|
|
357
|
+
function InteractiveAccordionExample() {
|
|
358
|
+
const [activeFeatures, setActiveFeatures] = useState([]);
|
|
359
|
+
|
|
360
|
+
const toggleFeature = (feature) => {
|
|
361
|
+
setActiveFeatures(prev =>
|
|
362
|
+
prev.includes(feature)
|
|
363
|
+
? prev.filter(f => f !== feature)
|
|
364
|
+
: [...prev, feature]
|
|
365
|
+
);
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
<Accordion>
|
|
370
|
+
<AccordionSummary>
|
|
371
|
+
<div className="interactive-summary">
|
|
372
|
+
<Text type="Heading6">Feature Selection</Text>
|
|
373
|
+
<Text type="BodySmall">
|
|
374
|
+
{activeFeatures.length} feature(s) selected
|
|
375
|
+
</Text>
|
|
376
|
+
</div>
|
|
377
|
+
</AccordionSummary>
|
|
378
|
+
<AccordionDetails>
|
|
379
|
+
<div className="feature-selection">
|
|
380
|
+
{['Analytics', 'Reporting', 'API Access', 'Custom Branding'].map(feature => (
|
|
381
|
+
<FormField key={feature} name={feature}>
|
|
382
|
+
<Checkbox
|
|
383
|
+
checked={activeFeatures.includes(feature)}
|
|
384
|
+
onValueChange={() => toggleFeature(feature)}
|
|
385
|
+
>
|
|
386
|
+
{feature}
|
|
387
|
+
</Checkbox>
|
|
388
|
+
</FormField>
|
|
389
|
+
))}
|
|
390
|
+
|
|
391
|
+
<Button
|
|
392
|
+
disabled={activeFeatures.length === 0}
|
|
393
|
+
onClick={() => console.log('Selected features:', activeFeatures)}
|
|
394
|
+
>
|
|
395
|
+
Apply Features
|
|
396
|
+
</Button>
|
|
397
|
+
</div>
|
|
398
|
+
</AccordionDetails>
|
|
399
|
+
</Accordion>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Loading Accordion
|
|
405
|
+
```tsx
|
|
406
|
+
function LoadingAccordionExample() {
|
|
407
|
+
const [loading, setLoading] = useState(false);
|
|
408
|
+
const [content, setContent] = useState(null);
|
|
409
|
+
|
|
410
|
+
const loadContent = async () => {
|
|
411
|
+
setLoading(true);
|
|
412
|
+
// Simulate API call
|
|
413
|
+
setTimeout(() => {
|
|
414
|
+
setContent('This content was loaded dynamically.');
|
|
415
|
+
setLoading(false);
|
|
416
|
+
}, 2000);
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
return (
|
|
420
|
+
<Accordion onChange={(isOpen) => isOpen && !content && loadContent()}>
|
|
421
|
+
<AccordionSummary>
|
|
422
|
+
<Text type="Heading6">Dynamic Content</Text>
|
|
423
|
+
{loading && <Spinner size="Small" />}
|
|
424
|
+
</AccordionSummary>
|
|
425
|
+
<AccordionDetails>
|
|
426
|
+
{loading ? (
|
|
427
|
+
<div className="loading-content">
|
|
428
|
+
<Spinner />
|
|
429
|
+
<Text type="BodyMedium">Loading content...</Text>
|
|
430
|
+
</div>
|
|
431
|
+
) : content ? (
|
|
432
|
+
<Text type="BodyMedium">{content}</Text>
|
|
433
|
+
) : (
|
|
434
|
+
<Text type="BodyMedium">Click to load content.</Text>
|
|
435
|
+
)}
|
|
436
|
+
</AccordionDetails>
|
|
437
|
+
</Accordion>
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
```
|