@delightui/components 0.1.104 → 0.1.106
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/Popover/Popover.presenter.d.ts +26 -0
- package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
- package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
- package/dist/cjs/components/molecules/index.d.ts +2 -0
- package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/cjs/components/utils/index.d.ts +2 -0
- package/dist/cjs/library.css +13 -0
- package/dist/cjs/library.js +2 -2
- 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/Popover/Popover.presenter.d.ts +26 -0
- package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
- package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/esm/components/molecules/Select/index.d.ts +2 -9
- package/dist/esm/components/molecules/index.d.ts +2 -0
- package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/esm/components/utils/index.d.ts +2 -0
- package/dist/esm/library.css +13 -0
- package/dist/esm/library.js +3 -3
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +156 -12
- 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,751 @@
|
|
|
1
|
+
# ToggleButton
|
|
2
|
+
|
|
3
|
+
A button component that maintains a pressed/unpressed state, functioning as a toggle between two states. It combines the visual appearance of a button with the state behavior of a toggle, making it perfect for scenarios where you need a button-like interface for binary choices or mode switches.
|
|
4
|
+
|
|
5
|
+
## Aliases
|
|
6
|
+
|
|
7
|
+
- ToggleButton
|
|
8
|
+
- PressButton
|
|
9
|
+
- StateButton
|
|
10
|
+
|
|
11
|
+
## Props Breakdown
|
|
12
|
+
|
|
13
|
+
**Extends:** `ButtonProps` (which extends `HTMLAttributes<HTMLButtonElement>` (excluding `style`), excluding `type` and `actionType`) and `ControlledFormComponentProps<boolean>`
|
|
14
|
+
|
|
15
|
+
| Prop | Type | Default | Required | Description |
|
|
16
|
+
|------|------|---------|----------|-------------|
|
|
17
|
+
| `defaultChecked` | `boolean` | `undefined` | No | Default value for uncontrolled component |
|
|
18
|
+
| `children` | `ReactNode` | `undefined` | No | Content of the button |
|
|
19
|
+
| `className` | `string` | `undefined` | No | Additional className for the toggle |
|
|
20
|
+
| `initialValue` | `boolean` | `undefined` | No | The initial value for the field |
|
|
21
|
+
| `checked` | `boolean` | `undefined` | No | The initial value for the field |
|
|
22
|
+
| `value` | `boolean` | `undefined` | No | The current value of the form field |
|
|
23
|
+
| `onValueChange` | `(value: boolean) => void` | `undefined` | No | Callback function that is called when the field value changes |
|
|
24
|
+
| `disabled` | `boolean` | `false` | No | Whether the form field is disabled and cannot be interacted with |
|
|
25
|
+
| `required` | `boolean` | `false` | No | Whether the form field must have a value |
|
|
26
|
+
| `invalid` | `boolean` | `false` | No | Whether the form field's current value is invalid |
|
|
27
|
+
| `id` | `string` | `undefined` | No | Id for the form field |
|
|
28
|
+
| `appearance` | `'Default' \| 'Inverse'` | `'Default'` | No | Appearance of the button |
|
|
29
|
+
| `style` | `'Primary' \| 'Secondary' \| 'Destructive'` | `'Primary'` | No | Style of the button |
|
|
30
|
+
| `size` | `'Small' \| 'Medium' \| 'Large'` | `'Medium'` | No | Size of the button |
|
|
31
|
+
| `loading` | `boolean` | `false` | No | Indicates if the button is in a loading state |
|
|
32
|
+
| `leadingIcon` | `ReactNode` | `undefined` | No | Icon to be displayed before the button's content |
|
|
33
|
+
| `trailingIcon` | `ReactNode` | `undefined` | No | Icon to be displayed after the button's content |
|
|
34
|
+
| `onClick` | `(event?: MouseEvent<HTMLElement>) => void` | `undefined` | No | Click event handler for the button |
|
|
35
|
+
|
|
36
|
+
Plus all standard HTML button attributes (id, title, aria-*, data-*, etc.).
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Basic ToggleButton
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { ToggleButton } from '@delightui/components';
|
|
44
|
+
|
|
45
|
+
function BasicToggleButtonExample() {
|
|
46
|
+
const [isPressed, setIsPressed] = useState(false);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div>
|
|
50
|
+
<p>Button state: {isPressed ? 'Pressed' : 'Not pressed'}</p>
|
|
51
|
+
<ToggleButton
|
|
52
|
+
value={isPressed}
|
|
53
|
+
onValueChange={setIsPressed}
|
|
54
|
+
>
|
|
55
|
+
Toggle Me
|
|
56
|
+
</ToggleButton>
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### ToggleButton with Icons
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { ToggleButton, Icon } from '@delightui/components';
|
|
66
|
+
|
|
67
|
+
function IconToggleButtonExample() {
|
|
68
|
+
const [isFavorite, setIsFavorite] = useState(false);
|
|
69
|
+
const [isBookmarked, setIsBookmarked] = useState(false);
|
|
70
|
+
const [isLiked, setIsLiked] = useState(false);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
|
|
74
|
+
<ToggleButton
|
|
75
|
+
value={isFavorite}
|
|
76
|
+
onValueChange={setIsFavorite}
|
|
77
|
+
leadingIcon={<Icon name={isFavorite ? 'CheckFilled' : 'CheckOutlined'} />}
|
|
78
|
+
style={isFavorite ? 'Primary' : 'Secondary'}
|
|
79
|
+
>
|
|
80
|
+
{isFavorite ? 'Favorited' : 'Favorite'}
|
|
81
|
+
</ToggleButton>
|
|
82
|
+
|
|
83
|
+
<ToggleButton
|
|
84
|
+
value={isBookmarked}
|
|
85
|
+
onValueChange={setIsBookmarked}
|
|
86
|
+
leadingIcon={<Icon name={isBookmarked ? 'AddFilled' : 'AddOutlined'} />}
|
|
87
|
+
style={isBookmarked ? 'Primary' : 'Secondary'}
|
|
88
|
+
>
|
|
89
|
+
{isBookmarked ? 'Saved' : 'Save'}
|
|
90
|
+
</ToggleButton>
|
|
91
|
+
|
|
92
|
+
<ToggleButton
|
|
93
|
+
value={isLiked}
|
|
94
|
+
onValueChange={setIsLiked}
|
|
95
|
+
leadingIcon={<Icon name={isLiked ? 'CheckFilled' : 'CheckOutlined'} />}
|
|
96
|
+
style={isLiked ? 'Primary' : 'Secondary'}
|
|
97
|
+
size="Small"
|
|
98
|
+
>
|
|
99
|
+
{isLiked ? 'Liked' : 'Like'}
|
|
100
|
+
</ToggleButton>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Different Sizes and Styles
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { ToggleButton } from '@delightui/components';
|
|
110
|
+
|
|
111
|
+
function SizedToggleButtonExample() {
|
|
112
|
+
const [states, setStates] = useState({
|
|
113
|
+
small: false,
|
|
114
|
+
medium: false,
|
|
115
|
+
large: false
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const updateState = (key: string, value: boolean) => {
|
|
119
|
+
setStates(prev => ({ ...prev, [key]: value }));
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
124
|
+
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
|
|
125
|
+
<ToggleButton
|
|
126
|
+
value={states.small}
|
|
127
|
+
onValueChange={(value) => updateState('small', value)}
|
|
128
|
+
size="Small"
|
|
129
|
+
>
|
|
130
|
+
Small
|
|
131
|
+
</ToggleButton>
|
|
132
|
+
|
|
133
|
+
<ToggleButton
|
|
134
|
+
value={states.medium}
|
|
135
|
+
onValueChange={(value) => updateState('medium', value)}
|
|
136
|
+
size="Medium"
|
|
137
|
+
>
|
|
138
|
+
Medium
|
|
139
|
+
</ToggleButton>
|
|
140
|
+
|
|
141
|
+
<ToggleButton
|
|
142
|
+
value={states.large}
|
|
143
|
+
onValueChange={(value) => updateState('large', value)}
|
|
144
|
+
size="Large"
|
|
145
|
+
>
|
|
146
|
+
Large
|
|
147
|
+
</ToggleButton>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
|
151
|
+
<ToggleButton
|
|
152
|
+
value={false}
|
|
153
|
+
style="Primary"
|
|
154
|
+
>
|
|
155
|
+
Primary
|
|
156
|
+
</ToggleButton>
|
|
157
|
+
|
|
158
|
+
<ToggleButton
|
|
159
|
+
value={false}
|
|
160
|
+
style="Secondary"
|
|
161
|
+
>
|
|
162
|
+
Secondary
|
|
163
|
+
</ToggleButton>
|
|
164
|
+
|
|
165
|
+
<ToggleButton
|
|
166
|
+
value={false}
|
|
167
|
+
style="Destructive"
|
|
168
|
+
>
|
|
169
|
+
Destructive
|
|
170
|
+
</ToggleButton>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Toolbar with ToggleButtons
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { ToggleButton, Icon } from '@delightui/components';
|
|
181
|
+
|
|
182
|
+
function ToolbarExample() {
|
|
183
|
+
const [formatting, setFormatting] = useState({
|
|
184
|
+
bold: false,
|
|
185
|
+
italic: false,
|
|
186
|
+
underline: false,
|
|
187
|
+
alignLeft: true,
|
|
188
|
+
alignCenter: false,
|
|
189
|
+
alignRight: false
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const updateFormatting = (key: string, value: boolean) => {
|
|
193
|
+
if (key.startsWith('align')) {
|
|
194
|
+
// Only one alignment can be active
|
|
195
|
+
setFormatting(prev => ({
|
|
196
|
+
...prev,
|
|
197
|
+
alignLeft: key === 'alignLeft' ? value : false,
|
|
198
|
+
alignCenter: key === 'alignCenter' ? value : false,
|
|
199
|
+
alignRight: key === 'alignRight' ? value : false
|
|
200
|
+
}));
|
|
201
|
+
} else {
|
|
202
|
+
setFormatting(prev => ({ ...prev, [key]: value }));
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<div style={{
|
|
208
|
+
display: 'flex',
|
|
209
|
+
gap: '4px',
|
|
210
|
+
padding: '8px',
|
|
211
|
+
border: '1px solid #ccc',
|
|
212
|
+
borderRadius: '8px',
|
|
213
|
+
backgroundColor: '#f8f9fa'
|
|
214
|
+
}}>
|
|
215
|
+
{/* Text formatting */}
|
|
216
|
+
<ToggleButton
|
|
217
|
+
value={formatting.bold}
|
|
218
|
+
onValueChange={(value) => updateFormatting('bold', value)}
|
|
219
|
+
size="Small"
|
|
220
|
+
leadingIcon={<Icon name="AddFilled" />}
|
|
221
|
+
title="Bold"
|
|
222
|
+
/>
|
|
223
|
+
|
|
224
|
+
<ToggleButton
|
|
225
|
+
value={formatting.italic}
|
|
226
|
+
onValueChange={(value) => updateFormatting('italic', value)}
|
|
227
|
+
size="Small"
|
|
228
|
+
leadingIcon={<Icon name="InfoFilled" />}
|
|
229
|
+
title="Italic"
|
|
230
|
+
/>
|
|
231
|
+
|
|
232
|
+
<ToggleButton
|
|
233
|
+
value={formatting.underline}
|
|
234
|
+
onValueChange={(value) => updateFormatting('underline', value)}
|
|
235
|
+
size="Small"
|
|
236
|
+
leadingIcon={<Icon name="AddFilled" />}
|
|
237
|
+
title="Underline"
|
|
238
|
+
/>
|
|
239
|
+
|
|
240
|
+
{/* Separator */}
|
|
241
|
+
<div style={{ width: '1px', backgroundColor: '#ccc', margin: '0 4px' }} />
|
|
242
|
+
|
|
243
|
+
{/* Alignment */}
|
|
244
|
+
<ToggleButton
|
|
245
|
+
value={formatting.alignLeft}
|
|
246
|
+
onValueChange={(value) => updateFormatting('alignLeft', value)}
|
|
247
|
+
size="Small"
|
|
248
|
+
leadingIcon={<Icon name="AddFilled" />}
|
|
249
|
+
title="Align Left"
|
|
250
|
+
/>
|
|
251
|
+
|
|
252
|
+
<ToggleButton
|
|
253
|
+
value={formatting.alignCenter}
|
|
254
|
+
onValueChange={(value) => updateFormatting('alignCenter', value)}
|
|
255
|
+
size="Small"
|
|
256
|
+
leadingIcon={<Icon name="AddFilled" />}
|
|
257
|
+
title="Align Center"
|
|
258
|
+
/>
|
|
259
|
+
|
|
260
|
+
<ToggleButton
|
|
261
|
+
value={formatting.alignRight}
|
|
262
|
+
onValueChange={(value) => updateFormatting('alignRight', value)}
|
|
263
|
+
size="Small"
|
|
264
|
+
leadingIcon={<Icon name="AddFilled" />}
|
|
265
|
+
title="Align Right"
|
|
266
|
+
/>
|
|
267
|
+
</div>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Filter Buttons
|
|
273
|
+
|
|
274
|
+
```tsx
|
|
275
|
+
import { ToggleButton, Text } from '@delightui/components';
|
|
276
|
+
|
|
277
|
+
function FilterButtonsExample() {
|
|
278
|
+
const [filters, setFilters] = useState({
|
|
279
|
+
all: true,
|
|
280
|
+
active: false,
|
|
281
|
+
completed: false,
|
|
282
|
+
overdue: false
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const [tasks] = useState([
|
|
286
|
+
{ id: 1, title: 'Complete project', status: 'active', dueDate: '2024-04-01' },
|
|
287
|
+
{ id: 2, title: 'Review documents', status: 'completed', dueDate: '2024-03-28' },
|
|
288
|
+
{ id: 3, title: 'Send report', status: 'overdue', dueDate: '2024-03-20' },
|
|
289
|
+
{ id: 4, title: 'Team meeting', status: 'active', dueDate: '2024-04-05' }
|
|
290
|
+
]);
|
|
291
|
+
|
|
292
|
+
const updateFilter = (key: string, value: boolean) => {
|
|
293
|
+
if (key === 'all' && value) {
|
|
294
|
+
setFilters({ all: true, active: false, completed: false, overdue: false });
|
|
295
|
+
} else {
|
|
296
|
+
const newFilters = { ...filters, [key]: value, all: false };
|
|
297
|
+
if (!Object.values(newFilters).some(Boolean)) {
|
|
298
|
+
newFilters.all = true;
|
|
299
|
+
}
|
|
300
|
+
setFilters(newFilters);
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const getFilteredTasks = () => {
|
|
305
|
+
if (filters.all) return tasks;
|
|
306
|
+
return tasks.filter(task => {
|
|
307
|
+
if (filters.active && task.status === 'active') return true;
|
|
308
|
+
if (filters.completed && task.status === 'completed') return true;
|
|
309
|
+
if (filters.overdue && task.status === 'overdue') return true;
|
|
310
|
+
return false;
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const filteredTasks = getFilteredTasks();
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<div>
|
|
318
|
+
<Text weight="bold" style={{ marginBottom: '16px' }}>
|
|
319
|
+
Task Filters
|
|
320
|
+
</Text>
|
|
321
|
+
|
|
322
|
+
<div style={{ display: 'flex', gap: '8px', marginBottom: '20px', flexWrap: 'wrap' }}>
|
|
323
|
+
<ToggleButton
|
|
324
|
+
value={filters.all}
|
|
325
|
+
onValueChange={(value) => updateFilter('all', value)}
|
|
326
|
+
size="Small"
|
|
327
|
+
>
|
|
328
|
+
All ({tasks.length})
|
|
329
|
+
</ToggleButton>
|
|
330
|
+
|
|
331
|
+
<ToggleButton
|
|
332
|
+
value={filters.active}
|
|
333
|
+
onValueChange={(value) => updateFilter('active', value)}
|
|
334
|
+
size="Small"
|
|
335
|
+
style="Primary"
|
|
336
|
+
>
|
|
337
|
+
Active ({tasks.filter(t => t.status === 'active').length})
|
|
338
|
+
</ToggleButton>
|
|
339
|
+
|
|
340
|
+
<ToggleButton
|
|
341
|
+
value={filters.completed}
|
|
342
|
+
onValueChange={(value) => updateFilter('completed', value)}
|
|
343
|
+
size="Small"
|
|
344
|
+
style="Secondary"
|
|
345
|
+
>
|
|
346
|
+
Completed ({tasks.filter(t => t.status === 'completed').length})
|
|
347
|
+
</ToggleButton>
|
|
348
|
+
|
|
349
|
+
<ToggleButton
|
|
350
|
+
value={filters.overdue}
|
|
351
|
+
onValueChange={(value) => updateFilter('overdue', value)}
|
|
352
|
+
size="Small"
|
|
353
|
+
style="Destructive"
|
|
354
|
+
>
|
|
355
|
+
Overdue ({tasks.filter(t => t.status === 'overdue').length})
|
|
356
|
+
</ToggleButton>
|
|
357
|
+
</div>
|
|
358
|
+
|
|
359
|
+
<div>
|
|
360
|
+
<Text weight="medium" style={{ marginBottom: '12px' }}>
|
|
361
|
+
Showing {filteredTasks.length} tasks
|
|
362
|
+
</Text>
|
|
363
|
+
|
|
364
|
+
{filteredTasks.map(task => (
|
|
365
|
+
<div key={task.id} style={{
|
|
366
|
+
padding: '12px',
|
|
367
|
+
border: '1px solid #eee',
|
|
368
|
+
borderRadius: '4px',
|
|
369
|
+
marginBottom: '8px'
|
|
370
|
+
}}>
|
|
371
|
+
<Text weight="medium">{task.title}</Text>
|
|
372
|
+
<Text size="small" color="secondary" style={{ display: 'block', marginTop: '4px' }}>
|
|
373
|
+
Status: {task.status} | Due: {task.dueDate}
|
|
374
|
+
</Text>
|
|
375
|
+
</div>
|
|
376
|
+
))}
|
|
377
|
+
</div>
|
|
378
|
+
</div>
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### View Mode Switcher
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
import { ToggleButton, Icon } from '@delightui/components';
|
|
387
|
+
|
|
388
|
+
function ViewModeSwitcherExample() {
|
|
389
|
+
const [viewMode, setViewMode] = useState('list');
|
|
390
|
+
|
|
391
|
+
const viewModes = [
|
|
392
|
+
{ id: 'list', label: 'List View', icon: 'AddFilled' },
|
|
393
|
+
{ id: 'grid', label: 'Grid View', icon: 'AddFilled' },
|
|
394
|
+
{ id: 'card', label: 'Card View', icon: 'AddFilled' }
|
|
395
|
+
];
|
|
396
|
+
|
|
397
|
+
const sampleData = [
|
|
398
|
+
{ id: 1, title: 'Item 1', description: 'Description for item 1' },
|
|
399
|
+
{ id: 2, title: 'Item 2', description: 'Description for item 2' },
|
|
400
|
+
{ id: 3, title: 'Item 3', description: 'Description for item 3' },
|
|
401
|
+
{ id: 4, title: 'Item 4', description: 'Description for item 4' }
|
|
402
|
+
];
|
|
403
|
+
|
|
404
|
+
const renderContent = () => {
|
|
405
|
+
switch (viewMode) {
|
|
406
|
+
case 'list':
|
|
407
|
+
return (
|
|
408
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
409
|
+
{sampleData.map(item => (
|
|
410
|
+
<div key={item.id} style={{
|
|
411
|
+
display: 'flex',
|
|
412
|
+
alignItems: 'center',
|
|
413
|
+
gap: '12px',
|
|
414
|
+
padding: '12px',
|
|
415
|
+
border: '1px solid #eee',
|
|
416
|
+
borderRadius: '4px'
|
|
417
|
+
}}>
|
|
418
|
+
<Text weight="medium">{item.title}</Text>
|
|
419
|
+
<Text size="small" color="secondary">{item.description}</Text>
|
|
420
|
+
</div>
|
|
421
|
+
))}
|
|
422
|
+
</div>
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
case 'grid':
|
|
426
|
+
return (
|
|
427
|
+
<div style={{
|
|
428
|
+
display: 'grid',
|
|
429
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
430
|
+
gap: '16px'
|
|
431
|
+
}}>
|
|
432
|
+
{sampleData.map(item => (
|
|
433
|
+
<div key={item.id} style={{
|
|
434
|
+
padding: '16px',
|
|
435
|
+
border: '1px solid #eee',
|
|
436
|
+
borderRadius: '8px',
|
|
437
|
+
textAlign: 'center'
|
|
438
|
+
}}>
|
|
439
|
+
<Text weight="medium" style={{ display: 'block', marginBottom: '8px' }}>
|
|
440
|
+
{item.title}
|
|
441
|
+
</Text>
|
|
442
|
+
<Text size="small" color="secondary">{item.description}</Text>
|
|
443
|
+
</div>
|
|
444
|
+
))}
|
|
445
|
+
</div>
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
case 'card':
|
|
449
|
+
return (
|
|
450
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
451
|
+
{sampleData.map(item => (
|
|
452
|
+
<div key={item.id} style={{
|
|
453
|
+
padding: '20px',
|
|
454
|
+
border: '1px solid #eee',
|
|
455
|
+
borderRadius: '12px',
|
|
456
|
+
backgroundColor: '#f8f9fa'
|
|
457
|
+
}}>
|
|
458
|
+
<Text weight="bold" size="large" style={{ display: 'block', marginBottom: '12px' }}>
|
|
459
|
+
{item.title}
|
|
460
|
+
</Text>
|
|
461
|
+
<Text>{item.description}</Text>
|
|
462
|
+
</div>
|
|
463
|
+
))}
|
|
464
|
+
</div>
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
default:
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
return (
|
|
473
|
+
<div>
|
|
474
|
+
<div style={{
|
|
475
|
+
display: 'flex',
|
|
476
|
+
justifyContent: 'space-between',
|
|
477
|
+
alignItems: 'center',
|
|
478
|
+
marginBottom: '20px'
|
|
479
|
+
}}>
|
|
480
|
+
<Text weight="bold">Content View</Text>
|
|
481
|
+
|
|
482
|
+
<div style={{ display: 'flex', gap: '4px' }}>
|
|
483
|
+
{viewModes.map(mode => (
|
|
484
|
+
<ToggleButton
|
|
485
|
+
key={mode.id}
|
|
486
|
+
value={viewMode === mode.id}
|
|
487
|
+
onValueChange={(value) => value && setViewMode(mode.id)}
|
|
488
|
+
size="Small"
|
|
489
|
+
leadingIcon={<Icon name={mode.icon} />}
|
|
490
|
+
title={mode.label}
|
|
491
|
+
/>
|
|
492
|
+
))}
|
|
493
|
+
</div>
|
|
494
|
+
</div>
|
|
495
|
+
|
|
496
|
+
{renderContent()}
|
|
497
|
+
</div>
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Settings Toggle Buttons
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
import { ToggleButton, Icon, Text } from '@delightui/components';
|
|
506
|
+
|
|
507
|
+
function SettingsToggleButtonsExample() {
|
|
508
|
+
const [settings, setSettings] = useState({
|
|
509
|
+
notifications: true,
|
|
510
|
+
autoSave: false,
|
|
511
|
+
darkMode: false,
|
|
512
|
+
compactView: false
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
const updateSetting = (key: string, value: boolean) => {
|
|
516
|
+
setSettings(prev => ({ ...prev, [key]: value }));
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
return (
|
|
520
|
+
<div style={{ maxWidth: '400px' }}>
|
|
521
|
+
<Text weight="bold" size="large" style={{ marginBottom: '20px' }}>
|
|
522
|
+
Quick Settings
|
|
523
|
+
</Text>
|
|
524
|
+
|
|
525
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
526
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
527
|
+
<div>
|
|
528
|
+
<Text weight="medium">Notifications</Text>
|
|
529
|
+
<Text size="small" color="secondary" style={{ display: 'block', marginTop: '2px' }}>
|
|
530
|
+
Receive push notifications
|
|
531
|
+
</Text>
|
|
532
|
+
</div>
|
|
533
|
+
<ToggleButton
|
|
534
|
+
value={settings.notifications}
|
|
535
|
+
onValueChange={(value) => updateSetting('notifications', value)}
|
|
536
|
+
size="Small"
|
|
537
|
+
leadingIcon={<Icon name={settings.notifications ? 'InfoFilled' : 'InfoOutlined'} />}
|
|
538
|
+
>
|
|
539
|
+
{settings.notifications ? 'On' : 'Off'}
|
|
540
|
+
</ToggleButton>
|
|
541
|
+
</div>
|
|
542
|
+
|
|
543
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
544
|
+
<div>
|
|
545
|
+
<Text weight="medium">Auto Save</Text>
|
|
546
|
+
<Text size="small" color="secondary" style={{ display: 'block', marginTop: '2px' }}>
|
|
547
|
+
Automatically save your work
|
|
548
|
+
</Text>
|
|
549
|
+
</div>
|
|
550
|
+
<ToggleButton
|
|
551
|
+
value={settings.autoSave}
|
|
552
|
+
onValueChange={(value) => updateSetting('autoSave', value)}
|
|
553
|
+
size="Small"
|
|
554
|
+
leadingIcon={<Icon name={settings.autoSave ? 'CheckFilled' : 'CheckOutlined'} />}
|
|
555
|
+
>
|
|
556
|
+
{settings.autoSave ? 'Enabled' : 'Disabled'}
|
|
557
|
+
</ToggleButton>
|
|
558
|
+
</div>
|
|
559
|
+
|
|
560
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
561
|
+
<div>
|
|
562
|
+
<Text weight="medium">Dark Mode</Text>
|
|
563
|
+
<Text size="small" color="secondary" style={{ display: 'block', marginTop: '2px' }}>
|
|
564
|
+
Switch to dark theme
|
|
565
|
+
</Text>
|
|
566
|
+
</div>
|
|
567
|
+
<ToggleButton
|
|
568
|
+
value={settings.darkMode}
|
|
569
|
+
onValueChange={(value) => updateSetting('darkMode', value)}
|
|
570
|
+
size="Small"
|
|
571
|
+
style={settings.darkMode ? 'Primary' : 'Secondary'}
|
|
572
|
+
>
|
|
573
|
+
{settings.darkMode ? '🌙 Dark' : '☀️ Light'}
|
|
574
|
+
</ToggleButton>
|
|
575
|
+
</div>
|
|
576
|
+
|
|
577
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
578
|
+
<div>
|
|
579
|
+
<Text weight="medium">Compact View</Text>
|
|
580
|
+
<Text size="small" color="secondary" style={{ display: 'block', marginTop: '2px' }}>
|
|
581
|
+
Use smaller spacing
|
|
582
|
+
</Text>
|
|
583
|
+
</div>
|
|
584
|
+
<ToggleButton
|
|
585
|
+
value={settings.compactView}
|
|
586
|
+
onValueChange={(value) => updateSetting('compactView', value)}
|
|
587
|
+
size="Small"
|
|
588
|
+
leadingIcon={<Icon name={settings.compactView ? 'AddFilled' : 'AddOutlined'} />}
|
|
589
|
+
>
|
|
590
|
+
{settings.compactView ? 'Compact' : 'Normal'}
|
|
591
|
+
</ToggleButton>
|
|
592
|
+
</div>
|
|
593
|
+
</div>
|
|
594
|
+
</div>
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Form Integration
|
|
600
|
+
|
|
601
|
+
```tsx
|
|
602
|
+
import { Form, FormField, ToggleButton, Button, Text } from '@delightui/components';
|
|
603
|
+
|
|
604
|
+
function FormToggleButtonExample() {
|
|
605
|
+
const handleSubmit = (data: any) => {
|
|
606
|
+
console.log('Form submitted:', data);
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
return (
|
|
610
|
+
<Form onSubmit={handleSubmit}>
|
|
611
|
+
<Text weight="bold" style={{ marginBottom: '16px' }}>
|
|
612
|
+
Subscription Preferences
|
|
613
|
+
</Text>
|
|
614
|
+
|
|
615
|
+
<FormField
|
|
616
|
+
name="newsletter"
|
|
617
|
+
label="Newsletter Subscription"
|
|
618
|
+
>
|
|
619
|
+
<ToggleButton
|
|
620
|
+
initialValue={true}
|
|
621
|
+
size="Small"
|
|
622
|
+
>
|
|
623
|
+
Subscribe to Newsletter
|
|
624
|
+
</ToggleButton>
|
|
625
|
+
</FormField>
|
|
626
|
+
|
|
627
|
+
<FormField
|
|
628
|
+
name="marketing"
|
|
629
|
+
label="Marketing Emails"
|
|
630
|
+
>
|
|
631
|
+
<ToggleButton
|
|
632
|
+
initialValue={false}
|
|
633
|
+
size="Small"
|
|
634
|
+
>
|
|
635
|
+
Receive Marketing Emails
|
|
636
|
+
</ToggleButton>
|
|
637
|
+
</FormField>
|
|
638
|
+
|
|
639
|
+
<FormField
|
|
640
|
+
name="urgent"
|
|
641
|
+
label="Urgent Notifications"
|
|
642
|
+
required
|
|
643
|
+
>
|
|
644
|
+
<ToggleButton
|
|
645
|
+
initialValue={true}
|
|
646
|
+
size="Small"
|
|
647
|
+
style="Primary"
|
|
648
|
+
>
|
|
649
|
+
Enable Urgent Notifications
|
|
650
|
+
</ToggleButton>
|
|
651
|
+
</FormField>
|
|
652
|
+
|
|
653
|
+
<Button type="submit">
|
|
654
|
+
Save Preferences
|
|
655
|
+
</Button>
|
|
656
|
+
</Form>
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Disabled States
|
|
662
|
+
|
|
663
|
+
```tsx
|
|
664
|
+
import { ToggleButton, Icon } from '@delightui/components';
|
|
665
|
+
|
|
666
|
+
function DisabledToggleButtonExample() {
|
|
667
|
+
return (
|
|
668
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
669
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
|
670
|
+
<ToggleButton value={false}>
|
|
671
|
+
Normal (Off)
|
|
672
|
+
</ToggleButton>
|
|
673
|
+
|
|
674
|
+
<ToggleButton value={true}>
|
|
675
|
+
Normal (On)
|
|
676
|
+
</ToggleButton>
|
|
677
|
+
</div>
|
|
678
|
+
|
|
679
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
|
680
|
+
<ToggleButton value={false} disabled>
|
|
681
|
+
Disabled (Off)
|
|
682
|
+
</ToggleButton>
|
|
683
|
+
|
|
684
|
+
<ToggleButton value={true} disabled>
|
|
685
|
+
Disabled (On)
|
|
686
|
+
</ToggleButton>
|
|
687
|
+
</div>
|
|
688
|
+
|
|
689
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
|
690
|
+
<ToggleButton
|
|
691
|
+
value={false}
|
|
692
|
+
disabled
|
|
693
|
+
leadingIcon={<Icon name="ErrorOutlined" />}
|
|
694
|
+
>
|
|
695
|
+
Disabled with Icon
|
|
696
|
+
</ToggleButton>
|
|
697
|
+
|
|
698
|
+
<ToggleButton
|
|
699
|
+
value={true}
|
|
700
|
+
disabled
|
|
701
|
+
leadingIcon={<Icon name="CheckFilled" />}
|
|
702
|
+
>
|
|
703
|
+
Disabled Active
|
|
704
|
+
</ToggleButton>
|
|
705
|
+
</div>
|
|
706
|
+
</div>
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
### Loading State
|
|
712
|
+
|
|
713
|
+
```tsx
|
|
714
|
+
import { ToggleButton, Spinner, Button } from '@delightui/components';
|
|
715
|
+
|
|
716
|
+
function LoadingToggleButtonExample() {
|
|
717
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
718
|
+
const [isToggled, setIsToggled] = useState(false);
|
|
719
|
+
|
|
720
|
+
const handleToggle = async (value: boolean) => {
|
|
721
|
+
setIsLoading(true);
|
|
722
|
+
// Simulate API call
|
|
723
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
724
|
+
setIsToggled(value);
|
|
725
|
+
setIsLoading(false);
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
return (
|
|
729
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
730
|
+
<ToggleButton
|
|
731
|
+
value={isToggled}
|
|
732
|
+
onValueChange={handleToggle}
|
|
733
|
+
loading={isLoading}
|
|
734
|
+
disabled={isLoading}
|
|
735
|
+
leadingIcon={isLoading ? <Spinner /> : undefined}
|
|
736
|
+
>
|
|
737
|
+
{isLoading ? 'Saving...' : isToggled ? 'Feature Enabled' : 'Enable Feature'}
|
|
738
|
+
</ToggleButton>
|
|
739
|
+
|
|
740
|
+
<Button
|
|
741
|
+
size="Small"
|
|
742
|
+
type="Outlined"
|
|
743
|
+
onClick={() => handleToggle(!isToggled)}
|
|
744
|
+
disabled={isLoading}
|
|
745
|
+
>
|
|
746
|
+
Toggle Programmatically
|
|
747
|
+
</Button>
|
|
748
|
+
</div>
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
```
|