@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,662 @@
|
|
|
1
|
+
# SlideOutPanel
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A slide-out panel component that provides an overlay interface sliding in from any edge of the screen. SlideOutPanel combines the functionality of a Modal with smooth slide-in animations and form integration capabilities. It's perfect for displaying detailed information, forms, or additional content without leaving the current page context. Can be used with traditional state management or the modern useModal hook for programmatic control.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- SlideOutPanel
|
|
10
|
+
- Slide Panel
|
|
11
|
+
- Side Panel
|
|
12
|
+
- Drawer Panel
|
|
13
|
+
|
|
14
|
+
## Props Breakdown
|
|
15
|
+
|
|
16
|
+
**Extends:** `ModalProps` (excluding `size`, `header`, `footer`, `component-variant`) + `FormProviderProps`
|
|
17
|
+
|
|
18
|
+
| Prop | Type | Default | Required | Description |
|
|
19
|
+
|------|------|---------|----------|-------------|
|
|
20
|
+
| `size` | `'Small' \| 'Medium' \| 'Large'` | `'Medium'` | No | Size of the slide-out panel |
|
|
21
|
+
| `direction` | `'Top' \| 'Left' \| 'Bottom' \| 'Right'` | `'Right'` | No | Direction from which the panel slides in |
|
|
22
|
+
| `isOpen` | `boolean` | `false` | No | Whether the panel is open |
|
|
23
|
+
| `onClose` | `() => void` | - | No | Callback when panel is closed |
|
|
24
|
+
| `children` | `ReactNode` | - | No | Panel content |
|
|
25
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
26
|
+
| `onSubmit` | `(data: any, setError: (error: string) => void) => void` | - | No | Form submission handler |
|
|
27
|
+
| `initialValues` | `Record<string, any>` | - | No | Initial form values |
|
|
28
|
+
| `validationSchema` | `any` | - | No | Form validation schema |
|
|
29
|
+
|
|
30
|
+
Plus all standard HTML div attributes (aria-*, data-*, etc.).
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
|
|
34
|
+
### Basic Slide-Out Panel
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { SlideOutPanel, Button, Text, useModal } from '@delightui/components';
|
|
38
|
+
|
|
39
|
+
const BasicPanel = ({ show, onCancel, content }) => (
|
|
40
|
+
<SlideOutPanel
|
|
41
|
+
show={show}
|
|
42
|
+
onHide={onCancel}
|
|
43
|
+
direction="Right"
|
|
44
|
+
size="Medium"
|
|
45
|
+
>
|
|
46
|
+
<div style={{ padding: '20px' }}>
|
|
47
|
+
<Text size="large">Panel Content</Text>
|
|
48
|
+
<Text>{content}</Text>
|
|
49
|
+
|
|
50
|
+
<Button
|
|
51
|
+
onClick={onCancel}
|
|
52
|
+
style={{ marginTop: '20px' }}
|
|
53
|
+
>
|
|
54
|
+
Close Panel
|
|
55
|
+
</Button>
|
|
56
|
+
</div>
|
|
57
|
+
</SlideOutPanel>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
function BasicSlideOutExample() {
|
|
61
|
+
const panel = useModal(BasicPanel);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Button onClick={() => panel.openModal({
|
|
65
|
+
content: 'This is a slide-out panel from the right side.'
|
|
66
|
+
})}>
|
|
67
|
+
Open Panel
|
|
68
|
+
</Button>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Different Directions
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { SlideOutPanel, Button, Text } from '@delightui/components';
|
|
77
|
+
|
|
78
|
+
function DirectionsExample() {
|
|
79
|
+
const [openPanels, setOpenPanels] = useState({
|
|
80
|
+
top: false,
|
|
81
|
+
right: false,
|
|
82
|
+
bottom: false,
|
|
83
|
+
left: false
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const openPanel = (direction: keyof typeof openPanels) => {
|
|
87
|
+
setOpenPanels(prev => ({ ...prev, [direction]: true }));
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const closePanel = (direction: keyof typeof openPanels) => {
|
|
91
|
+
setOpenPanels(prev => ({ ...prev, [direction]: false }));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
96
|
+
<Button onClick={() => openPanel('top')}>Top Panel</Button>
|
|
97
|
+
<Button onClick={() => openPanel('right')}>Right Panel</Button>
|
|
98
|
+
<Button onClick={() => openPanel('bottom')}>Bottom Panel</Button>
|
|
99
|
+
<Button onClick={() => openPanel('left')}>Left Panel</Button>
|
|
100
|
+
|
|
101
|
+
<SlideOutPanel
|
|
102
|
+
isOpen={openPanels.top}
|
|
103
|
+
onClose={() => closePanel('top')}
|
|
104
|
+
direction="Top"
|
|
105
|
+
size="Small"
|
|
106
|
+
>
|
|
107
|
+
<div style={{ padding: '20px', textAlign: 'center' }}>
|
|
108
|
+
<Text>Panel sliding from the top</Text>
|
|
109
|
+
</div>
|
|
110
|
+
</SlideOutPanel>
|
|
111
|
+
|
|
112
|
+
<SlideOutPanel
|
|
113
|
+
isOpen={openPanels.right}
|
|
114
|
+
onClose={() => closePanel('right')}
|
|
115
|
+
direction="Right"
|
|
116
|
+
size="Medium"
|
|
117
|
+
>
|
|
118
|
+
<div style={{ padding: '20px' }}>
|
|
119
|
+
<Text>Panel sliding from the right</Text>
|
|
120
|
+
</div>
|
|
121
|
+
</SlideOutPanel>
|
|
122
|
+
|
|
123
|
+
<SlideOutPanel
|
|
124
|
+
isOpen={openPanels.bottom}
|
|
125
|
+
onClose={() => closePanel('bottom')}
|
|
126
|
+
direction="Bottom"
|
|
127
|
+
size="Small"
|
|
128
|
+
>
|
|
129
|
+
<div style={{ padding: '20px', textAlign: 'center' }}>
|
|
130
|
+
<Text>Panel sliding from the bottom</Text>
|
|
131
|
+
</div>
|
|
132
|
+
</SlideOutPanel>
|
|
133
|
+
|
|
134
|
+
<SlideOutPanel
|
|
135
|
+
isOpen={openPanels.left}
|
|
136
|
+
onClose={() => closePanel('left')}
|
|
137
|
+
direction="Left"
|
|
138
|
+
size="Medium"
|
|
139
|
+
>
|
|
140
|
+
<div style={{ padding: '20px' }}>
|
|
141
|
+
<Text>Panel sliding from the left</Text>
|
|
142
|
+
</div>
|
|
143
|
+
</SlideOutPanel>
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Different Sizes
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
import { SlideOutPanel, Button, Text } from '@delightui/components';
|
|
153
|
+
|
|
154
|
+
function SizesExample() {
|
|
155
|
+
const [activeSize, setActiveSize] = useState<'Small' | 'Medium' | 'Large' | null>(null);
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<div>
|
|
159
|
+
<div style={{ display: 'flex', gap: '10px' }}>
|
|
160
|
+
<Button onClick={() => setActiveSize('Small')}>Small Panel</Button>
|
|
161
|
+
<Button onClick={() => setActiveSize('Medium')}>Medium Panel</Button>
|
|
162
|
+
<Button onClick={() => setActiveSize('Large')}>Large Panel</Button>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<SlideOutPanel
|
|
166
|
+
isOpen={activeSize !== null}
|
|
167
|
+
onClose={() => setActiveSize(null)}
|
|
168
|
+
direction="Right"
|
|
169
|
+
size={activeSize || 'Medium'}
|
|
170
|
+
>
|
|
171
|
+
<div style={{ padding: '20px' }}>
|
|
172
|
+
<Text size="large">{activeSize} Panel</Text>
|
|
173
|
+
<Text>
|
|
174
|
+
This is a {activeSize?.toLowerCase()} sized slide-out panel.
|
|
175
|
+
</Text>
|
|
176
|
+
</div>
|
|
177
|
+
</SlideOutPanel>
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### With Form Integration
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import { SlideOutPanel, FormField, Input, TextArea, Button, useModal } from '@delightui/components';
|
|
187
|
+
|
|
188
|
+
const ContactFormPanel = ({ show, onCancel, onSubmit, initialValues }) => {
|
|
189
|
+
const handleSubmit = (data: any, setError: (error: string) => void) => {
|
|
190
|
+
// Simulate validation
|
|
191
|
+
if (!data.email.includes('@')) {
|
|
192
|
+
setError('Please enter a valid email address');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
onSubmit(data);
|
|
197
|
+
onCancel(); // Close panel on success
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<SlideOutPanel
|
|
202
|
+
show={show}
|
|
203
|
+
onHide={onCancel}
|
|
204
|
+
direction="Right"
|
|
205
|
+
size="Medium"
|
|
206
|
+
onSubmit={handleSubmit}
|
|
207
|
+
initialValues={initialValues}
|
|
208
|
+
>
|
|
209
|
+
<div style={{ padding: '20px' }}>
|
|
210
|
+
<h2>Contact Us</h2>
|
|
211
|
+
|
|
212
|
+
<FormField name="name" label="Full Name" required>
|
|
213
|
+
<Input placeholder="Enter your name" />
|
|
214
|
+
</FormField>
|
|
215
|
+
|
|
216
|
+
<FormField name="email" label="Email" required>
|
|
217
|
+
<Input inputType="Email" placeholder="Enter your email" />
|
|
218
|
+
</FormField>
|
|
219
|
+
|
|
220
|
+
<FormField name="message" label="Message" required>
|
|
221
|
+
<TextArea
|
|
222
|
+
placeholder="Enter your message"
|
|
223
|
+
rows={4}
|
|
224
|
+
/>
|
|
225
|
+
</FormField>
|
|
226
|
+
|
|
227
|
+
<div style={{ display: 'flex', gap: '10px', marginTop: '20px' }}>
|
|
228
|
+
<Button actionType="submit">Send Message</Button>
|
|
229
|
+
<Button
|
|
230
|
+
type="Outlined"
|
|
231
|
+
onClick={onCancel}
|
|
232
|
+
>
|
|
233
|
+
Cancel
|
|
234
|
+
</Button>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</SlideOutPanel>
|
|
238
|
+
);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
function FormIntegrationExample() {
|
|
242
|
+
const contactPanel = useModal(ContactFormPanel);
|
|
243
|
+
|
|
244
|
+
const openContactForm = () => {
|
|
245
|
+
contactPanel.openModal({
|
|
246
|
+
initialValues: {
|
|
247
|
+
name: '',
|
|
248
|
+
email: '',
|
|
249
|
+
message: ''
|
|
250
|
+
},
|
|
251
|
+
onSubmit: (data) => {
|
|
252
|
+
console.log('Form submitted:', data);
|
|
253
|
+
// Handle form submission
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<Button onClick={openContactForm}>
|
|
260
|
+
Open Contact Form
|
|
261
|
+
</Button>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Navigation Panel
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
import { SlideOutPanel, Button, Nav, NavItem, NavLink } from '@delightui/components';
|
|
270
|
+
|
|
271
|
+
function NavigationPanelExample() {
|
|
272
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
273
|
+
|
|
274
|
+
const navigationItems = [
|
|
275
|
+
{ label: 'Dashboard', href: '/dashboard' },
|
|
276
|
+
{ label: 'Projects', href: '/projects' },
|
|
277
|
+
{ label: 'Tasks', href: '/tasks' },
|
|
278
|
+
{ label: 'Reports', href: '/reports' },
|
|
279
|
+
{ label: 'Settings', href: '/settings' }
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<div>
|
|
284
|
+
<Button onClick={() => setIsOpen(true)}>
|
|
285
|
+
☰ Menu
|
|
286
|
+
</Button>
|
|
287
|
+
|
|
288
|
+
<SlideOutPanel
|
|
289
|
+
isOpen={isOpen}
|
|
290
|
+
onClose={() => setIsOpen(false)}
|
|
291
|
+
direction="Left"
|
|
292
|
+
size="Small"
|
|
293
|
+
>
|
|
294
|
+
<div style={{ padding: '20px' }}>
|
|
295
|
+
<h3>Navigation</h3>
|
|
296
|
+
|
|
297
|
+
<Nav>
|
|
298
|
+
{navigationItems.map((item, index) => (
|
|
299
|
+
<NavItem key={index}>
|
|
300
|
+
<NavLink
|
|
301
|
+
href={item.href}
|
|
302
|
+
onClick={() => setIsOpen(false)}
|
|
303
|
+
>
|
|
304
|
+
{item.label}
|
|
305
|
+
</NavLink>
|
|
306
|
+
</NavItem>
|
|
307
|
+
))}
|
|
308
|
+
</Nav>
|
|
309
|
+
</div>
|
|
310
|
+
</SlideOutPanel>
|
|
311
|
+
</div>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Settings Panel
|
|
317
|
+
|
|
318
|
+
```tsx
|
|
319
|
+
import { SlideOutPanel, FormField, Toggle, Select, Button } from '@delightui/components';
|
|
320
|
+
|
|
321
|
+
function SettingsPanelExample() {
|
|
322
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
323
|
+
|
|
324
|
+
const handleSettingsSubmit = (data: any) => {
|
|
325
|
+
console.log('Settings updated:', data);
|
|
326
|
+
setIsOpen(false);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
<div>
|
|
331
|
+
<Button onClick={() => setIsOpen(true)}>
|
|
332
|
+
Settings
|
|
333
|
+
</Button>
|
|
334
|
+
|
|
335
|
+
<SlideOutPanel
|
|
336
|
+
isOpen={isOpen}
|
|
337
|
+
onClose={() => setIsOpen(false)}
|
|
338
|
+
direction="Right"
|
|
339
|
+
size="Medium"
|
|
340
|
+
onSubmit={handleSettingsSubmit}
|
|
341
|
+
initialValues={{
|
|
342
|
+
notifications: true,
|
|
343
|
+
theme: 'light',
|
|
344
|
+
language: 'en',
|
|
345
|
+
autoSave: false
|
|
346
|
+
}}
|
|
347
|
+
>
|
|
348
|
+
<div style={{ padding: '20px' }}>
|
|
349
|
+
<h2>Settings</h2>
|
|
350
|
+
|
|
351
|
+
<FormField name="notifications" label="Email Notifications">
|
|
352
|
+
<Toggle>Enable email notifications</Toggle>
|
|
353
|
+
</FormField>
|
|
354
|
+
|
|
355
|
+
<FormField name="theme" label="Theme">
|
|
356
|
+
<Select>
|
|
357
|
+
<option value="light">Light</option>
|
|
358
|
+
<option value="dark">Dark</option>
|
|
359
|
+
<option value="auto">Auto</option>
|
|
360
|
+
</Select>
|
|
361
|
+
</FormField>
|
|
362
|
+
|
|
363
|
+
<FormField name="language" label="Language">
|
|
364
|
+
<Select>
|
|
365
|
+
<option value="en">English</option>
|
|
366
|
+
<option value="es">Spanish</option>
|
|
367
|
+
<option value="fr">French</option>
|
|
368
|
+
</Select>
|
|
369
|
+
</FormField>
|
|
370
|
+
|
|
371
|
+
<FormField name="autoSave" label="Auto Save">
|
|
372
|
+
<Toggle>Automatically save changes</Toggle>
|
|
373
|
+
</FormField>
|
|
374
|
+
|
|
375
|
+
<div style={{ display: 'flex', gap: '10px', marginTop: '30px' }}>
|
|
376
|
+
<Button actionType="submit">Save Settings</Button>
|
|
377
|
+
<Button
|
|
378
|
+
type="Outlined"
|
|
379
|
+
onClick={() => setIsOpen(false)}
|
|
380
|
+
>
|
|
381
|
+
Cancel
|
|
382
|
+
</Button>
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
</SlideOutPanel>
|
|
386
|
+
</div>
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Detail View Panel
|
|
392
|
+
|
|
393
|
+
```tsx
|
|
394
|
+
import { SlideOutPanel, Button, Text, Image, Card } from '@delightui/components';
|
|
395
|
+
|
|
396
|
+
function DetailViewExample() {
|
|
397
|
+
const [selectedItem, setSelectedItem] = useState<any>(null);
|
|
398
|
+
|
|
399
|
+
const items = [
|
|
400
|
+
{
|
|
401
|
+
id: 1,
|
|
402
|
+
name: 'Product A',
|
|
403
|
+
description: 'High-quality product with excellent features.',
|
|
404
|
+
image: '/images/product-a.jpg',
|
|
405
|
+
price: '$99.99'
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: 2,
|
|
409
|
+
name: 'Product B',
|
|
410
|
+
description: 'Innovative solution for modern needs.',
|
|
411
|
+
image: '/images/product-b.jpg',
|
|
412
|
+
price: '$149.99'
|
|
413
|
+
}
|
|
414
|
+
];
|
|
415
|
+
|
|
416
|
+
return (
|
|
417
|
+
<div>
|
|
418
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '20px' }}>
|
|
419
|
+
{items.map(item => (
|
|
420
|
+
<Card key={item.id}>
|
|
421
|
+
<Text size="large">{item.name}</Text>
|
|
422
|
+
<Text>{item.price}</Text>
|
|
423
|
+
<Button
|
|
424
|
+
onClick={() => setSelectedItem(item)}
|
|
425
|
+
size="Small"
|
|
426
|
+
>
|
|
427
|
+
View Details
|
|
428
|
+
</Button>
|
|
429
|
+
</Card>
|
|
430
|
+
))}
|
|
431
|
+
</div>
|
|
432
|
+
|
|
433
|
+
<SlideOutPanel
|
|
434
|
+
isOpen={selectedItem !== null}
|
|
435
|
+
onClose={() => setSelectedItem(null)}
|
|
436
|
+
direction="Right"
|
|
437
|
+
size="Large"
|
|
438
|
+
>
|
|
439
|
+
{selectedItem && (
|
|
440
|
+
<div style={{ padding: '20px' }}>
|
|
441
|
+
<h2>{selectedItem.name}</h2>
|
|
442
|
+
|
|
443
|
+
<Image
|
|
444
|
+
src={selectedItem.image}
|
|
445
|
+
alt={selectedItem.name}
|
|
446
|
+
width="100%"
|
|
447
|
+
height={200}
|
|
448
|
+
fit="Cover"
|
|
449
|
+
style={{ marginBottom: '20px', borderRadius: '8px' }}
|
|
450
|
+
/>
|
|
451
|
+
|
|
452
|
+
<Text size="large" style={{ marginBottom: '10px' }}>
|
|
453
|
+
{selectedItem.price}
|
|
454
|
+
</Text>
|
|
455
|
+
|
|
456
|
+
<Text style={{ marginBottom: '20px' }}>
|
|
457
|
+
{selectedItem.description}
|
|
458
|
+
</Text>
|
|
459
|
+
|
|
460
|
+
<div style={{ display: 'flex', gap: '10px' }}>
|
|
461
|
+
<Button>Add to Cart</Button>
|
|
462
|
+
<Button type="Outlined">Add to Wishlist</Button>
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|
|
465
|
+
)}
|
|
466
|
+
</SlideOutPanel>
|
|
467
|
+
</div>
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Custom Styling
|
|
473
|
+
|
|
474
|
+
```tsx
|
|
475
|
+
import { SlideOutPanel, Button, Text } from '@delightui/components';
|
|
476
|
+
|
|
477
|
+
function CustomStyledExample() {
|
|
478
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
479
|
+
|
|
480
|
+
return (
|
|
481
|
+
<div>
|
|
482
|
+
<Button onClick={() => setIsOpen(true)}>
|
|
483
|
+
Open Styled Panel
|
|
484
|
+
</Button>
|
|
485
|
+
|
|
486
|
+
<SlideOutPanel
|
|
487
|
+
isOpen={isOpen}
|
|
488
|
+
onClose={() => setIsOpen(false)}
|
|
489
|
+
direction="Right"
|
|
490
|
+
size="Medium"
|
|
491
|
+
className="custom-slide-panel"
|
|
492
|
+
style={{
|
|
493
|
+
'--panel-background': '#f8f9fa',
|
|
494
|
+
'--panel-border': '1px solid #dee2e6'
|
|
495
|
+
}}
|
|
496
|
+
>
|
|
497
|
+
<div style={{
|
|
498
|
+
padding: '30px',
|
|
499
|
+
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
500
|
+
color: 'white',
|
|
501
|
+
minHeight: '100%'
|
|
502
|
+
}}>
|
|
503
|
+
<Text size="large" style={{ marginBottom: '20px' }}>
|
|
504
|
+
Custom Styled Panel
|
|
505
|
+
</Text>
|
|
506
|
+
<Text>
|
|
507
|
+
This panel has custom styling with a gradient background.
|
|
508
|
+
</Text>
|
|
509
|
+
</div>
|
|
510
|
+
</SlideOutPanel>
|
|
511
|
+
</div>
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
## Using with useModal Hook
|
|
517
|
+
|
|
518
|
+
SlideOutPanel can be used with the `useModal` hook for programmatic control. This approach provides better state management and allows opening panels from anywhere in your application.
|
|
519
|
+
|
|
520
|
+
### Basic useModal Setup
|
|
521
|
+
|
|
522
|
+
```tsx
|
|
523
|
+
import { SlideOutPanel, Button, Text, useModal } from '@delightui/components';
|
|
524
|
+
|
|
525
|
+
const SettingsPanel = ({ show, onCancel, userSettings, onSave }) => (
|
|
526
|
+
<SlideOutPanel
|
|
527
|
+
show={show}
|
|
528
|
+
onHide={onCancel}
|
|
529
|
+
direction="Right"
|
|
530
|
+
size="Medium"
|
|
531
|
+
>
|
|
532
|
+
<div style={{ padding: '20px' }}>
|
|
533
|
+
<h2>User Settings</h2>
|
|
534
|
+
<Text>Configure your preferences here.</Text>
|
|
535
|
+
|
|
536
|
+
<Button
|
|
537
|
+
onClick={() => onSave(userSettings)}
|
|
538
|
+
style={{ marginTop: '20px', marginRight: '10px' }}
|
|
539
|
+
>
|
|
540
|
+
Save Settings
|
|
541
|
+
</Button>
|
|
542
|
+
<Button
|
|
543
|
+
type="Outlined"
|
|
544
|
+
onClick={onCancel}
|
|
545
|
+
style={{ marginTop: '20px' }}
|
|
546
|
+
>
|
|
547
|
+
Cancel
|
|
548
|
+
</Button>
|
|
549
|
+
</div>
|
|
550
|
+
</SlideOutPanel>
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
function SettingsPage() {
|
|
554
|
+
const settingsPanel = useModal(SettingsPanel);
|
|
555
|
+
|
|
556
|
+
const openSettings = () => {
|
|
557
|
+
settingsPanel.openModal({
|
|
558
|
+
userSettings: { theme: 'dark', notifications: true },
|
|
559
|
+
onSave: (settings) => {
|
|
560
|
+
console.log('Settings saved:', settings);
|
|
561
|
+
settingsPanel.closeModal();
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
return (
|
|
567
|
+
<Button onClick={openSettings}>
|
|
568
|
+
Open Settings Panel
|
|
569
|
+
</Button>
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Multiple Panel Types
|
|
575
|
+
|
|
576
|
+
```tsx
|
|
577
|
+
import { useModal } from '@delightui/components';
|
|
578
|
+
|
|
579
|
+
function Dashboard() {
|
|
580
|
+
const settingsPanel = useModal(SettingsPanel);
|
|
581
|
+
const helpPanel = useModal(HelpPanel);
|
|
582
|
+
const profilePanel = useModal(ProfilePanel);
|
|
583
|
+
|
|
584
|
+
return (
|
|
585
|
+
<div>
|
|
586
|
+
<Button onClick={() => settingsPanel.openModal({})}>
|
|
587
|
+
Settings
|
|
588
|
+
</Button>
|
|
589
|
+
<Button onClick={() => helpPanel.openModal({})}>
|
|
590
|
+
Help
|
|
591
|
+
</Button>
|
|
592
|
+
<Button onClick={() => profilePanel.openModal({})}>
|
|
593
|
+
Profile
|
|
594
|
+
</Button>
|
|
595
|
+
</div>
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Programmatic Panel Control
|
|
601
|
+
|
|
602
|
+
```tsx
|
|
603
|
+
const NotificationPanel = ({ show, onCancel, notifications, onMarkAsRead }) => (
|
|
604
|
+
<SlideOutPanel show={show} onHide={onCancel} direction="Right" size="Medium">
|
|
605
|
+
<div style={{ padding: '20px' }}>
|
|
606
|
+
<h2>Notifications</h2>
|
|
607
|
+
{notifications.map(notification => (
|
|
608
|
+
<div key={notification.id} style={{ marginBottom: '10px' }}>
|
|
609
|
+
<Text>{notification.message}</Text>
|
|
610
|
+
<Button
|
|
611
|
+
size="Small"
|
|
612
|
+
onClick={() => onMarkAsRead(notification.id)}
|
|
613
|
+
>
|
|
614
|
+
Mark as Read
|
|
615
|
+
</Button>
|
|
616
|
+
</div>
|
|
617
|
+
))}
|
|
618
|
+
</div>
|
|
619
|
+
</SlideOutPanel>
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
function NotificationSystem() {
|
|
623
|
+
const notificationPanel = useModal(NotificationPanel);
|
|
624
|
+
|
|
625
|
+
const showNotifications = (notifications) => {
|
|
626
|
+
notificationPanel.openModal({
|
|
627
|
+
notifications,
|
|
628
|
+
onMarkAsRead: (id) => {
|
|
629
|
+
// Mark notification as read
|
|
630
|
+
console.log('Marking notification as read:', id);
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// This can be called from anywhere in your app
|
|
636
|
+
useEffect(() => {
|
|
637
|
+
// Example: Auto-open notifications panel when new notifications arrive
|
|
638
|
+
const newNotifications = [
|
|
639
|
+
{ id: 1, message: 'New message received' },
|
|
640
|
+
{ id: 2, message: 'Task completed' }
|
|
641
|
+
];
|
|
642
|
+
|
|
643
|
+
if (newNotifications.length > 0) {
|
|
644
|
+
showNotifications(newNotifications);
|
|
645
|
+
}
|
|
646
|
+
}, []);
|
|
647
|
+
|
|
648
|
+
return null; // This component doesn't render anything itself
|
|
649
|
+
}
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
## Requirements
|
|
653
|
+
|
|
654
|
+
- When using with `useModal`, the SlideOutPanel component must extend `ModalComponentProps`
|
|
655
|
+
- Requires `ModalProvider` to be wrapped around your application
|
|
656
|
+
- The `show` and `onCancel` props are automatically provided by the `useModal` hook
|
|
657
|
+
|
|
658
|
+
## Related Components
|
|
659
|
+
|
|
660
|
+
- **[Modal](../molecules/Modal.md)** - Base modal component that SlideOutPanel extends
|
|
661
|
+
- **[useModal](../molecules/useModal.md)** - Hook for programmatic modal management
|
|
662
|
+
- **[ModalProvider](../molecules/ModalProvider.md)** - Context provider for modal state
|