@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,756 @@
|
|
|
1
|
+
# ModalHeader
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A specialized header component designed for modal dialogs that provides structured title display and optional icon button functionality. Offers consistent styling and layout for modal titles with support for action buttons like close controls, creating a cohesive modal experience.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- ModalHeader
|
|
10
|
+
- DialogHeader
|
|
11
|
+
- ModalTitle
|
|
12
|
+
- DialogTitle
|
|
13
|
+
- ModalTop
|
|
14
|
+
|
|
15
|
+
## Props Breakdown
|
|
16
|
+
|
|
17
|
+
**Extends:** Standalone interface (no HTML element inheritance)
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Required | Description |
|
|
20
|
+
|------|------|---------|----------|-------------|
|
|
21
|
+
| `title` | `string` | - | No | The title text displayed in the header |
|
|
22
|
+
| `iconButton` | `ReactNode` | - | No | Optional icon button element (typically close button) |
|
|
23
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
24
|
+
| `children` | `ReactNode` | - | No | Custom content overriding title prop |
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
### Basic Modal Header
|
|
29
|
+
```tsx
|
|
30
|
+
import { Modal, ModalHeader, ModalFooter, Button, Text } from '@delightui/components';
|
|
31
|
+
|
|
32
|
+
function BasicHeaderExample() {
|
|
33
|
+
const [showModal, setShowModal] = useState(false);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
<Button onClick={() => setShowModal(true)}>
|
|
38
|
+
Open Modal
|
|
39
|
+
</Button>
|
|
40
|
+
|
|
41
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
42
|
+
<ModalHeader title="Welcome to Our App" />
|
|
43
|
+
|
|
44
|
+
<div className="modal-content">
|
|
45
|
+
<Text>This is a basic modal with a simple header title.</Text>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<ModalFooter
|
|
49
|
+
type="1Button"
|
|
50
|
+
primaryButton={
|
|
51
|
+
<Button onClick={() => setShowModal(false)}>
|
|
52
|
+
Close
|
|
53
|
+
</Button>
|
|
54
|
+
}
|
|
55
|
+
/>
|
|
56
|
+
</Modal>
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Header with Close Button
|
|
63
|
+
```tsx
|
|
64
|
+
function HeaderWithCloseExample() {
|
|
65
|
+
const [showModal, setShowModal] = useState(false);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<>
|
|
69
|
+
<Button onClick={() => setShowModal(true)}>
|
|
70
|
+
Open Modal with Close
|
|
71
|
+
</Button>
|
|
72
|
+
|
|
73
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
74
|
+
<ModalHeader
|
|
75
|
+
title="Settings"
|
|
76
|
+
iconButton={
|
|
77
|
+
<IconButton
|
|
78
|
+
onClick={() => setShowModal(false)}
|
|
79
|
+
aria-label="Close modal"
|
|
80
|
+
>
|
|
81
|
+
<Icon icon="Close" />
|
|
82
|
+
</IconButton>
|
|
83
|
+
}
|
|
84
|
+
/>
|
|
85
|
+
|
|
86
|
+
<div className="modal-content">
|
|
87
|
+
<Text>Modal content with a close button in the header.</Text>
|
|
88
|
+
|
|
89
|
+
<FormField label="Username">
|
|
90
|
+
<Input placeholder="Enter username" />
|
|
91
|
+
</FormField>
|
|
92
|
+
|
|
93
|
+
<FormField label="Email">
|
|
94
|
+
<Input type="email" placeholder="Enter email" />
|
|
95
|
+
</FormField>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<ModalFooter
|
|
99
|
+
type="2Buttons"
|
|
100
|
+
secondaryButton={
|
|
101
|
+
<Button type="Outlined" onClick={() => setShowModal(false)}>
|
|
102
|
+
Cancel
|
|
103
|
+
</Button>
|
|
104
|
+
}
|
|
105
|
+
primaryButton={
|
|
106
|
+
<Button>Save Changes</Button>
|
|
107
|
+
}
|
|
108
|
+
/>
|
|
109
|
+
</Modal>
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Custom Header Content
|
|
116
|
+
```tsx
|
|
117
|
+
function CustomHeaderExample() {
|
|
118
|
+
const [showModal, setShowModal] = useState(false);
|
|
119
|
+
const [step, setStep] = useState(1);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<>
|
|
123
|
+
<Button onClick={() => setShowModal(true)}>
|
|
124
|
+
Open Multi-Step Modal
|
|
125
|
+
</Button>
|
|
126
|
+
|
|
127
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
128
|
+
<ModalHeader>
|
|
129
|
+
<div className="custom-header">
|
|
130
|
+
<div className="header-main">
|
|
131
|
+
<Text type="Heading4">Setup Wizard</Text>
|
|
132
|
+
<Text type="BodySmall">Step {step} of 3</Text>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<div className="header-actions">
|
|
136
|
+
<IconButton
|
|
137
|
+
size="Small"
|
|
138
|
+
onClick={() => setShowModal(false)}
|
|
139
|
+
aria-label="Close wizard"
|
|
140
|
+
>
|
|
141
|
+
<Icon icon="Close" />
|
|
142
|
+
</IconButton>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</ModalHeader>
|
|
146
|
+
|
|
147
|
+
<div className="modal-content">
|
|
148
|
+
<div className="progress-indicator">
|
|
149
|
+
{[1, 2, 3].map(stepNumber => (
|
|
150
|
+
<div
|
|
151
|
+
key={stepNumber}
|
|
152
|
+
className={`progress-step ${stepNumber <= step ? 'active' : ''}`}
|
|
153
|
+
>
|
|
154
|
+
{stepNumber}
|
|
155
|
+
</div>
|
|
156
|
+
))}
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<Text>Content for step {step}</Text>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<ModalFooter
|
|
163
|
+
type="2Buttons"
|
|
164
|
+
secondaryButton={
|
|
165
|
+
<Button
|
|
166
|
+
type="Outlined"
|
|
167
|
+
onClick={() => step > 1 ? setStep(step - 1) : setShowModal(false)}
|
|
168
|
+
>
|
|
169
|
+
{step > 1 ? 'Previous' : 'Cancel'}
|
|
170
|
+
</Button>
|
|
171
|
+
}
|
|
172
|
+
primaryButton={
|
|
173
|
+
<Button onClick={() => step < 3 ? setStep(step + 1) : setShowModal(false)}>
|
|
174
|
+
{step < 3 ? 'Next' : 'Finish'}
|
|
175
|
+
</Button>
|
|
176
|
+
}
|
|
177
|
+
/>
|
|
178
|
+
</Modal>
|
|
179
|
+
</>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Header with Status Indicator
|
|
185
|
+
```tsx
|
|
186
|
+
function StatusHeaderExample() {
|
|
187
|
+
const [showModal, setShowModal] = useState(false);
|
|
188
|
+
const [status, setStatus] = useState('pending');
|
|
189
|
+
|
|
190
|
+
const getStatusConfig = (status) => {
|
|
191
|
+
switch (status) {
|
|
192
|
+
case 'success':
|
|
193
|
+
return { color: 'green', icon: 'CheckCircle', text: 'Success' };
|
|
194
|
+
case 'error':
|
|
195
|
+
return { color: 'red', icon: 'Error', text: 'Error' };
|
|
196
|
+
case 'warning':
|
|
197
|
+
return { color: 'orange', icon: 'Warning', text: 'Warning' };
|
|
198
|
+
default:
|
|
199
|
+
return { color: 'blue', icon: 'Info', text: 'Processing' };
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const statusConfig = getStatusConfig(status);
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<>
|
|
207
|
+
<div className="status-controls">
|
|
208
|
+
<Button onClick={() => setShowModal(true)}>
|
|
209
|
+
Open Status Modal
|
|
210
|
+
</Button>
|
|
211
|
+
|
|
212
|
+
<ButtonGroup>
|
|
213
|
+
<Button
|
|
214
|
+
size="Small"
|
|
215
|
+
type={status === 'pending' ? 'Primary' : 'Outlined'}
|
|
216
|
+
onClick={() => setStatus('pending')}
|
|
217
|
+
>
|
|
218
|
+
Pending
|
|
219
|
+
</Button>
|
|
220
|
+
<Button
|
|
221
|
+
size="Small"
|
|
222
|
+
type={status === 'success' ? 'Primary' : 'Outlined'}
|
|
223
|
+
onClick={() => setStatus('success')}
|
|
224
|
+
>
|
|
225
|
+
Success
|
|
226
|
+
</Button>
|
|
227
|
+
<Button
|
|
228
|
+
size="Small"
|
|
229
|
+
type={status === 'error' ? 'Primary' : 'Outlined'}
|
|
230
|
+
onClick={() => setStatus('error')}
|
|
231
|
+
>
|
|
232
|
+
Error
|
|
233
|
+
</Button>
|
|
234
|
+
<Button
|
|
235
|
+
size="Small"
|
|
236
|
+
type={status === 'warning' ? 'Primary' : 'Outlined'}
|
|
237
|
+
onClick={() => setStatus('warning')}
|
|
238
|
+
>
|
|
239
|
+
Warning
|
|
240
|
+
</Button>
|
|
241
|
+
</ButtonGroup>
|
|
242
|
+
</div>
|
|
243
|
+
|
|
244
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
245
|
+
<ModalHeader>
|
|
246
|
+
<div className="status-header">
|
|
247
|
+
<div className="status-info">
|
|
248
|
+
<Icon
|
|
249
|
+
icon={statusConfig.icon}
|
|
250
|
+
className={`status-icon ${statusConfig.color}`}
|
|
251
|
+
/>
|
|
252
|
+
<div>
|
|
253
|
+
<Text type="Heading5">Operation Status</Text>
|
|
254
|
+
<Text type="BodySmall" className={`status-text ${statusConfig.color}`}>
|
|
255
|
+
{statusConfig.text}
|
|
256
|
+
</Text>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<IconButton onClick={() => setShowModal(false)}>
|
|
261
|
+
<Icon icon="Close" />
|
|
262
|
+
</IconButton>
|
|
263
|
+
</div>
|
|
264
|
+
</ModalHeader>
|
|
265
|
+
|
|
266
|
+
<div className="modal-content">
|
|
267
|
+
<Text>Current operation status: {statusConfig.text}</Text>
|
|
268
|
+
<Text type="BodySmall">
|
|
269
|
+
This modal demonstrates different header states based on operation status.
|
|
270
|
+
</Text>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<ModalFooter
|
|
274
|
+
type="1Button"
|
|
275
|
+
primaryButton={
|
|
276
|
+
<Button onClick={() => setShowModal(false)}>
|
|
277
|
+
Close
|
|
278
|
+
</Button>
|
|
279
|
+
}
|
|
280
|
+
/>
|
|
281
|
+
</Modal>
|
|
282
|
+
</>
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Header with Navigation
|
|
288
|
+
```tsx
|
|
289
|
+
function NavigationHeaderExample() {
|
|
290
|
+
const [showModal, setShowModal] = useState(false);
|
|
291
|
+
const [currentView, setCurrentView] = useState('profile');
|
|
292
|
+
|
|
293
|
+
const views = {
|
|
294
|
+
profile: { title: 'Profile Settings', icon: 'Person' },
|
|
295
|
+
security: { title: 'Security & Privacy', icon: 'Security' },
|
|
296
|
+
notifications: { title: 'Notifications', icon: 'Notifications' },
|
|
297
|
+
billing: { title: 'Billing & Plans', icon: 'CreditCard' }
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
<>
|
|
302
|
+
<Button onClick={() => setShowModal(true)}>
|
|
303
|
+
Open Settings
|
|
304
|
+
</Button>
|
|
305
|
+
|
|
306
|
+
<Modal show={showModal} onHide={() => setShowModal(false)} size="Large">
|
|
307
|
+
<ModalHeader>
|
|
308
|
+
<div className="navigation-header">
|
|
309
|
+
<div className="header-nav">
|
|
310
|
+
<Icon icon={views[currentView].icon} />
|
|
311
|
+
<Text type="Heading4">{views[currentView].title}</Text>
|
|
312
|
+
</div>
|
|
313
|
+
|
|
314
|
+
<div className="header-actions">
|
|
315
|
+
<ButtonGroup size="Small">
|
|
316
|
+
{Object.entries(views).map(([key, view]) => (
|
|
317
|
+
<Button
|
|
318
|
+
key={key}
|
|
319
|
+
type={currentView === key ? 'Primary' : 'Ghost'}
|
|
320
|
+
size="Small"
|
|
321
|
+
onClick={() => setCurrentView(key)}
|
|
322
|
+
>
|
|
323
|
+
<Icon icon={view.icon} />
|
|
324
|
+
</Button>
|
|
325
|
+
))}
|
|
326
|
+
</ButtonGroup>
|
|
327
|
+
|
|
328
|
+
<IconButton onClick={() => setShowModal(false)}>
|
|
329
|
+
<Icon icon="Close" />
|
|
330
|
+
</IconButton>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
</ModalHeader>
|
|
334
|
+
|
|
335
|
+
<div className="modal-content">
|
|
336
|
+
<Text>Content for {views[currentView].title}</Text>
|
|
337
|
+
|
|
338
|
+
{currentView === 'profile' && (
|
|
339
|
+
<div>
|
|
340
|
+
<FormField label="Display Name">
|
|
341
|
+
<Input placeholder="Your display name" />
|
|
342
|
+
</FormField>
|
|
343
|
+
<FormField label="Bio">
|
|
344
|
+
<TextArea placeholder="Tell us about yourself" />
|
|
345
|
+
</FormField>
|
|
346
|
+
</div>
|
|
347
|
+
)}
|
|
348
|
+
|
|
349
|
+
{currentView === 'security' && (
|
|
350
|
+
<div>
|
|
351
|
+
<FormField label="Current Password">
|
|
352
|
+
<Password placeholder="Enter current password" />
|
|
353
|
+
</FormField>
|
|
354
|
+
<FormField label="New Password">
|
|
355
|
+
<Password placeholder="Enter new password" />
|
|
356
|
+
</FormField>
|
|
357
|
+
</div>
|
|
358
|
+
)}
|
|
359
|
+
|
|
360
|
+
{currentView === 'notifications' && (
|
|
361
|
+
<div>
|
|
362
|
+
<FormField label="Email Notifications">
|
|
363
|
+
<Toggle />
|
|
364
|
+
</FormField>
|
|
365
|
+
<FormField label="Push Notifications">
|
|
366
|
+
<Toggle />
|
|
367
|
+
</FormField>
|
|
368
|
+
</div>
|
|
369
|
+
)}
|
|
370
|
+
|
|
371
|
+
{currentView === 'billing' && (
|
|
372
|
+
<div>
|
|
373
|
+
<Text>Billing information and subscription details</Text>
|
|
374
|
+
</div>
|
|
375
|
+
)}
|
|
376
|
+
</div>
|
|
377
|
+
|
|
378
|
+
<ModalFooter
|
|
379
|
+
type="2Buttons"
|
|
380
|
+
secondaryButton={
|
|
381
|
+
<Button type="Outlined" onClick={() => setShowModal(false)}>
|
|
382
|
+
Cancel
|
|
383
|
+
</Button>
|
|
384
|
+
}
|
|
385
|
+
primaryButton={
|
|
386
|
+
<Button>Save Changes</Button>
|
|
387
|
+
}
|
|
388
|
+
/>
|
|
389
|
+
</Modal>
|
|
390
|
+
</>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Header with Search
|
|
396
|
+
```tsx
|
|
397
|
+
function SearchHeaderExample() {
|
|
398
|
+
const [showModal, setShowModal] = useState(false);
|
|
399
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
400
|
+
const [searchMode, setSearchMode] = useState(false);
|
|
401
|
+
|
|
402
|
+
const items = [
|
|
403
|
+
'Apple iPhone 14',
|
|
404
|
+
'Samsung Galaxy S23',
|
|
405
|
+
'Google Pixel 7',
|
|
406
|
+
'iPad Pro',
|
|
407
|
+
'MacBook Air',
|
|
408
|
+
'Dell XPS 13'
|
|
409
|
+
];
|
|
410
|
+
|
|
411
|
+
const filteredItems = items.filter(item =>
|
|
412
|
+
item.toLowerCase().includes(searchQuery.toLowerCase())
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
return (
|
|
416
|
+
<>
|
|
417
|
+
<Button onClick={() => setShowModal(true)}>
|
|
418
|
+
Open Product List
|
|
419
|
+
</Button>
|
|
420
|
+
|
|
421
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
422
|
+
<ModalHeader>
|
|
423
|
+
<div className="search-header">
|
|
424
|
+
{!searchMode ? (
|
|
425
|
+
<>
|
|
426
|
+
<Text type="Heading4">Product Catalog</Text>
|
|
427
|
+
<div className="header-actions">
|
|
428
|
+
<IconButton
|
|
429
|
+
onClick={() => setSearchMode(true)}
|
|
430
|
+
aria-label="Search products"
|
|
431
|
+
>
|
|
432
|
+
<Icon icon="Search" />
|
|
433
|
+
</IconButton>
|
|
434
|
+
<IconButton onClick={() => setShowModal(false)}>
|
|
435
|
+
<Icon icon="Close" />
|
|
436
|
+
</IconButton>
|
|
437
|
+
</div>
|
|
438
|
+
</>
|
|
439
|
+
) : (
|
|
440
|
+
<>
|
|
441
|
+
<div className="search-input-container">
|
|
442
|
+
<Input
|
|
443
|
+
value={searchQuery}
|
|
444
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
445
|
+
placeholder="Search products..."
|
|
446
|
+
autoFocus
|
|
447
|
+
leadingIcon={<Icon icon="Search" />}
|
|
448
|
+
/>
|
|
449
|
+
</div>
|
|
450
|
+
<IconButton
|
|
451
|
+
onClick={() => {
|
|
452
|
+
setSearchMode(false);
|
|
453
|
+
setSearchQuery('');
|
|
454
|
+
}}
|
|
455
|
+
aria-label="Close search"
|
|
456
|
+
>
|
|
457
|
+
<Icon icon="Close" />
|
|
458
|
+
</IconButton>
|
|
459
|
+
</>
|
|
460
|
+
)}
|
|
461
|
+
</div>
|
|
462
|
+
</ModalHeader>
|
|
463
|
+
|
|
464
|
+
<div className="modal-content">
|
|
465
|
+
{searchMode && searchQuery && (
|
|
466
|
+
<Text type="BodySmall">
|
|
467
|
+
Found {filteredItems.length} result{filteredItems.length !== 1 ? 's' : ''} for "{searchQuery}"
|
|
468
|
+
</Text>
|
|
469
|
+
)}
|
|
470
|
+
|
|
471
|
+
<List>
|
|
472
|
+
{(searchMode ? filteredItems : items).map((item, index) => (
|
|
473
|
+
<ListItem key={index}>
|
|
474
|
+
<Text>{item}</Text>
|
|
475
|
+
</ListItem>
|
|
476
|
+
))}
|
|
477
|
+
</List>
|
|
478
|
+
|
|
479
|
+
{searchMode && filteredItems.length === 0 && (
|
|
480
|
+
<div className="no-results">
|
|
481
|
+
<Text>No products found matching "{searchQuery}"</Text>
|
|
482
|
+
</div>
|
|
483
|
+
)}
|
|
484
|
+
</div>
|
|
485
|
+
|
|
486
|
+
<ModalFooter
|
|
487
|
+
type="1Button"
|
|
488
|
+
primaryButton={
|
|
489
|
+
<Button onClick={() => setShowModal(false)}>
|
|
490
|
+
Close
|
|
491
|
+
</Button>
|
|
492
|
+
}
|
|
493
|
+
/>
|
|
494
|
+
</Modal>
|
|
495
|
+
</>
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Header with Breadcrumbs
|
|
501
|
+
```tsx
|
|
502
|
+
function BreadcrumbHeaderExample() {
|
|
503
|
+
const [showModal, setShowModal] = useState(false);
|
|
504
|
+
const [currentPath, setCurrentPath] = useState(['Home', 'Settings', 'Profile']);
|
|
505
|
+
|
|
506
|
+
const navigateToPath = (index) => {
|
|
507
|
+
setCurrentPath(prev => prev.slice(0, index + 1));
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
return (
|
|
511
|
+
<>
|
|
512
|
+
<Button onClick={() => setShowModal(true)}>
|
|
513
|
+
Open Navigation Modal
|
|
514
|
+
</Button>
|
|
515
|
+
|
|
516
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
517
|
+
<ModalHeader>
|
|
518
|
+
<div className="breadcrumb-header">
|
|
519
|
+
<div className="breadcrumb-nav">
|
|
520
|
+
<Breadcrumbs>
|
|
521
|
+
{currentPath.map((crumb, index) => (
|
|
522
|
+
<Breadcrumb
|
|
523
|
+
key={index}
|
|
524
|
+
onClick={() => navigateToPath(index)}
|
|
525
|
+
isActive={index === currentPath.length - 1}
|
|
526
|
+
>
|
|
527
|
+
{crumb}
|
|
528
|
+
</Breadcrumb>
|
|
529
|
+
))}
|
|
530
|
+
</Breadcrumbs>
|
|
531
|
+
</div>
|
|
532
|
+
|
|
533
|
+
<IconButton onClick={() => setShowModal(false)}>
|
|
534
|
+
<Icon icon="Close" />
|
|
535
|
+
</IconButton>
|
|
536
|
+
</div>
|
|
537
|
+
</ModalHeader>
|
|
538
|
+
|
|
539
|
+
<div className="modal-content">
|
|
540
|
+
<Text type="Heading5">Current Location: {currentPath.join(' > ')}</Text>
|
|
541
|
+
|
|
542
|
+
<div className="navigation-options">
|
|
543
|
+
<Button
|
|
544
|
+
type="Outlined"
|
|
545
|
+
onClick={() => setCurrentPath([...currentPath, 'Security'])}
|
|
546
|
+
disabled={currentPath.includes('Security')}
|
|
547
|
+
>
|
|
548
|
+
Go to Security Settings
|
|
549
|
+
</Button>
|
|
550
|
+
|
|
551
|
+
<Button
|
|
552
|
+
type="Outlined"
|
|
553
|
+
onClick={() => setCurrentPath([...currentPath, 'Notifications'])}
|
|
554
|
+
disabled={currentPath.includes('Notifications')}
|
|
555
|
+
>
|
|
556
|
+
Go to Notifications
|
|
557
|
+
</Button>
|
|
558
|
+
|
|
559
|
+
<Button
|
|
560
|
+
type="Outlined"
|
|
561
|
+
onClick={() => setCurrentPath(['Home'])}
|
|
562
|
+
disabled={currentPath.length === 1}
|
|
563
|
+
>
|
|
564
|
+
Back to Home
|
|
565
|
+
</Button>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
|
|
569
|
+
<ModalFooter
|
|
570
|
+
type="1Button"
|
|
571
|
+
primaryButton={
|
|
572
|
+
<Button onClick={() => setShowModal(false)}>
|
|
573
|
+
Close
|
|
574
|
+
</Button>
|
|
575
|
+
}
|
|
576
|
+
/>
|
|
577
|
+
</Modal>
|
|
578
|
+
</>
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Header with Actions Menu
|
|
584
|
+
```tsx
|
|
585
|
+
function ActionsHeaderExample() {
|
|
586
|
+
const [showModal, setShowModal] = useState(false);
|
|
587
|
+
const [showActionsMenu, setShowActionsMenu] = useState(false);
|
|
588
|
+
|
|
589
|
+
const actions = [
|
|
590
|
+
{ id: 'edit', label: 'Edit', icon: 'Edit' },
|
|
591
|
+
{ id: 'duplicate', label: 'Duplicate', icon: 'Copy' },
|
|
592
|
+
{ id: 'share', label: 'Share', icon: 'Share' },
|
|
593
|
+
{ id: 'export', label: 'Export', icon: 'Download' },
|
|
594
|
+
{ id: 'delete', label: 'Delete', icon: 'Delete', style: 'destructive' }
|
|
595
|
+
];
|
|
596
|
+
|
|
597
|
+
const handleAction = (actionId) => {
|
|
598
|
+
console.log('Action:', actionId);
|
|
599
|
+
setShowActionsMenu(false);
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
return (
|
|
603
|
+
<>
|
|
604
|
+
<Button onClick={() => setShowModal(true)}>
|
|
605
|
+
Open Document
|
|
606
|
+
</Button>
|
|
607
|
+
|
|
608
|
+
<Modal show={showModal} onHide={() => setShowModal(false)}>
|
|
609
|
+
<ModalHeader>
|
|
610
|
+
<div className="actions-header">
|
|
611
|
+
<div className="document-info">
|
|
612
|
+
<Icon icon="Document" />
|
|
613
|
+
<div>
|
|
614
|
+
<Text type="Heading5">Annual Report 2024</Text>
|
|
615
|
+
<Text type="BodySmall">Last modified: 2 hours ago</Text>
|
|
616
|
+
</div>
|
|
617
|
+
</div>
|
|
618
|
+
|
|
619
|
+
<div className="header-actions">
|
|
620
|
+
<Popover
|
|
621
|
+
show={showActionsMenu}
|
|
622
|
+
onHide={() => setShowActionsMenu(false)}
|
|
623
|
+
trigger={
|
|
624
|
+
<IconButton
|
|
625
|
+
onClick={() => setShowActionsMenu(!showActionsMenu)}
|
|
626
|
+
aria-label="More actions"
|
|
627
|
+
>
|
|
628
|
+
<Icon icon="MoreVert" />
|
|
629
|
+
</IconButton>
|
|
630
|
+
}
|
|
631
|
+
>
|
|
632
|
+
<List>
|
|
633
|
+
{actions.map(action => (
|
|
634
|
+
<ListItem
|
|
635
|
+
key={action.id}
|
|
636
|
+
onClick={() => handleAction(action.id)}
|
|
637
|
+
className={action.style === 'destructive' ? 'destructive' : ''}
|
|
638
|
+
>
|
|
639
|
+
<Icon icon={action.icon} />
|
|
640
|
+
<Text>{action.label}</Text>
|
|
641
|
+
</ListItem>
|
|
642
|
+
))}
|
|
643
|
+
</List>
|
|
644
|
+
</Popover>
|
|
645
|
+
|
|
646
|
+
<IconButton onClick={() => setShowModal(false)}>
|
|
647
|
+
<Icon icon="Close" />
|
|
648
|
+
</IconButton>
|
|
649
|
+
</div>
|
|
650
|
+
</div>
|
|
651
|
+
</ModalHeader>
|
|
652
|
+
|
|
653
|
+
<div className="modal-content">
|
|
654
|
+
<Text>Document content would be displayed here.</Text>
|
|
655
|
+
<Text type="BodySmall">
|
|
656
|
+
Use the actions menu in the header to perform operations on this document.
|
|
657
|
+
</Text>
|
|
658
|
+
</div>
|
|
659
|
+
|
|
660
|
+
<ModalFooter
|
|
661
|
+
type="1Button"
|
|
662
|
+
primaryButton={
|
|
663
|
+
<Button onClick={() => setShowModal(false)}>
|
|
664
|
+
Close
|
|
665
|
+
</Button>
|
|
666
|
+
}
|
|
667
|
+
/>
|
|
668
|
+
</Modal>
|
|
669
|
+
</>
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Minimizable Header
|
|
675
|
+
```tsx
|
|
676
|
+
function MinimizableHeaderExample() {
|
|
677
|
+
const [showModal, setShowModal] = useState(false);
|
|
678
|
+
const [isMinimized, setIsMinimized] = useState(false);
|
|
679
|
+
|
|
680
|
+
return (
|
|
681
|
+
<>
|
|
682
|
+
<Button onClick={() => setShowModal(true)}>
|
|
683
|
+
Open Minimizable Modal
|
|
684
|
+
</Button>
|
|
685
|
+
|
|
686
|
+
<Modal
|
|
687
|
+
show={showModal}
|
|
688
|
+
onHide={() => setShowModal(false)}
|
|
689
|
+
className={isMinimized ? 'minimized-modal' : ''}
|
|
690
|
+
>
|
|
691
|
+
<ModalHeader>
|
|
692
|
+
<div className="minimizable-header">
|
|
693
|
+
<div className="header-title">
|
|
694
|
+
<Icon icon="Chat" />
|
|
695
|
+
<Text type="Heading5">Chat Support</Text>
|
|
696
|
+
{isMinimized && (
|
|
697
|
+
<Chip size="Small" className="notification-chip">
|
|
698
|
+
3 new messages
|
|
699
|
+
</Chip>
|
|
700
|
+
)}
|
|
701
|
+
</div>
|
|
702
|
+
|
|
703
|
+
<div className="window-controls">
|
|
704
|
+
<IconButton
|
|
705
|
+
size="Small"
|
|
706
|
+
onClick={() => setIsMinimized(!isMinimized)}
|
|
707
|
+
aria-label={isMinimized ? 'Restore window' : 'Minimize window'}
|
|
708
|
+
>
|
|
709
|
+
<Icon icon={isMinimized ? 'Maximize' : 'Minimize'} />
|
|
710
|
+
</IconButton>
|
|
711
|
+
|
|
712
|
+
<IconButton
|
|
713
|
+
size="Small"
|
|
714
|
+
onClick={() => setShowModal(false)}
|
|
715
|
+
aria-label="Close window"
|
|
716
|
+
>
|
|
717
|
+
<Icon icon="Close" />
|
|
718
|
+
</IconButton>
|
|
719
|
+
</div>
|
|
720
|
+
</div>
|
|
721
|
+
</ModalHeader>
|
|
722
|
+
|
|
723
|
+
{!isMinimized && (
|
|
724
|
+
<>
|
|
725
|
+
<div className="modal-content">
|
|
726
|
+
<div className="chat-messages">
|
|
727
|
+
<div className="message support">
|
|
728
|
+
<Text type="BodySmall">Support Agent</Text>
|
|
729
|
+
<Text>Hello! How can I help you today?</Text>
|
|
730
|
+
</div>
|
|
731
|
+
|
|
732
|
+
<div className="message user">
|
|
733
|
+
<Text type="BodySmall">You</Text>
|
|
734
|
+
<Text>I need help with my account settings.</Text>
|
|
735
|
+
</div>
|
|
736
|
+
|
|
737
|
+
<div className="message support">
|
|
738
|
+
<Text type="BodySmall">Support Agent</Text>
|
|
739
|
+
<Text>I'd be happy to help you with that. What specific setting would you like to change?</Text>
|
|
740
|
+
</div>
|
|
741
|
+
</div>
|
|
742
|
+
|
|
743
|
+
<div className="chat-input">
|
|
744
|
+
<Input placeholder="Type your message..." />
|
|
745
|
+
<IconButton>
|
|
746
|
+
<Icon icon="Send" />
|
|
747
|
+
</IconButton>
|
|
748
|
+
</div>
|
|
749
|
+
</div>
|
|
750
|
+
</>
|
|
751
|
+
)}
|
|
752
|
+
</Modal>
|
|
753
|
+
</>
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
```
|