@ceed/cds 1.24.1-next.2 → 1.24.1-next.3
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/dist/components/CurrencyInput/CurrencyInput.d.ts +1 -1
- package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
- package/dist/components/data-display/DataTable.md +1 -1
- package/dist/components/data-display/InfoSign.md +91 -74
- package/dist/components/data-display/Typography.md +94 -411
- package/dist/components/feedback/Dialog.md +62 -76
- package/dist/components/feedback/Modal.md +138 -430
- package/dist/components/feedback/llms.txt +0 -2
- package/dist/components/index.d.ts +0 -1
- package/dist/components/inputs/Autocomplete.md +107 -356
- package/dist/components/inputs/ButtonGroup.md +104 -115
- package/dist/components/inputs/CurrencyInput.md +5 -183
- package/dist/components/inputs/DatePicker.md +431 -108
- package/dist/components/inputs/DateRangePicker.md +492 -131
- package/dist/components/inputs/FilterableCheckboxGroup.md +19 -145
- package/dist/components/inputs/IconButton.md +88 -137
- package/dist/components/inputs/Input.md +73 -204
- package/dist/components/inputs/MonthPicker.md +422 -95
- package/dist/components/inputs/MonthRangePicker.md +466 -89
- package/dist/components/inputs/PercentageInput.md +16 -185
- package/dist/components/inputs/RadioButton.md +35 -163
- package/dist/components/inputs/Select.md +326 -222
- package/dist/components/inputs/Switch.md +376 -143
- package/dist/components/inputs/Textarea.md +10 -213
- package/dist/components/inputs/Uploader/Uploader.md +66 -145
- package/dist/components/inputs/llms.txt +0 -4
- package/dist/components/navigation/Breadcrumbs.md +308 -57
- package/dist/components/navigation/Drawer.md +0 -180
- package/dist/components/navigation/Dropdown.md +215 -98
- package/dist/components/navigation/IconMenuButton.md +502 -40
- package/dist/components/navigation/InsetDrawer.md +650 -281
- package/dist/components/navigation/Link.md +348 -31
- package/dist/components/navigation/Menu.md +285 -92
- package/dist/components/navigation/MenuButton.md +448 -55
- package/dist/components/navigation/Pagination.md +338 -47
- package/dist/components/navigation/Stepper.md +28 -160
- package/dist/components/navigation/Tabs.md +316 -57
- package/dist/components/surfaces/Accordions.md +804 -49
- package/dist/components/surfaces/Card.md +157 -97
- package/dist/components/surfaces/Divider.md +234 -83
- package/dist/components/surfaces/Sheet.md +328 -153
- package/dist/index.cjs +371 -617
- package/dist/index.d.ts +1 -1
- package/dist/index.js +342 -532
- package/dist/llms.txt +0 -9
- package/framer/index.js +163 -1
- package/package.json +24 -33
- package/README.md +0 -51
- package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
- package/dist/components/RadioTileGroup/RadioTileGroup.d.ts +0 -56
- package/dist/components/RadioTileGroup/index.d.ts +0 -3
- package/dist/components/feedback/CircularProgress.md +0 -257
- package/dist/components/feedback/Skeleton.md +0 -280
- package/dist/components/inputs/FormControl.md +0 -361
- package/dist/components/inputs/RadioList.md +0 -241
- package/dist/components/inputs/RadioTileGroup.md +0 -507
- package/dist/components/inputs/Slider.md +0 -334
- package/dist/guides/ThemeProvider.md +0 -89
- package/dist/guides/llms.txt +0 -9
- package/dist/index.browser.js +0 -224
- package/dist/index.browser.js.map +0 -7
|
@@ -4,25 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
The Modal component is a dialog overlay that appears on top of the main content, demanding user attention and interaction. Built on Joy UI's Modal, it is used for displaying critical information, capturing user input, or requiring confirmation before proceeding. Modals block interaction with the underlying page until dismissed, making them ideal for important actions that require focused attention.
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
<Button onClick={() => setOpen(true)}>Open Modal</Button>
|
|
10
|
-
<Modal open={open} onClose={() => setOpen(false)}>
|
|
11
|
-
<ModalDialog>
|
|
12
|
-
<ModalClose />
|
|
13
|
-
<DialogTitle>Modal Title</DialogTitle>
|
|
14
|
-
<DialogContent>This is the modal content. You can place any content here.</DialogContent>
|
|
15
|
-
<DialogActions>
|
|
16
|
-
<Button variant="solid" onClick={() => setOpen(false)}>
|
|
17
|
-
Confirm
|
|
18
|
-
</Button>
|
|
19
|
-
<Button variant="plain" color="neutral" onClick={() => setOpen(false)}>
|
|
20
|
-
Cancel
|
|
21
|
-
</Button>
|
|
22
|
-
</DialogActions>
|
|
23
|
-
</ModalDialog>
|
|
24
|
-
</Modal>
|
|
25
|
-
</>
|
|
7
|
+
```
|
|
8
|
+
<Canvas of={Modal.Playground} />
|
|
26
9
|
```
|
|
27
10
|
|
|
28
11
|
| Field | Description | Default |
|
|
@@ -41,7 +24,15 @@ The Modal component is a dialog overlay that appears on top of the main content,
|
|
|
41
24
|
## Usage
|
|
42
25
|
|
|
43
26
|
```tsx
|
|
44
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
Modal,
|
|
29
|
+
ModalDialog,
|
|
30
|
+
ModalClose,
|
|
31
|
+
DialogTitle,
|
|
32
|
+
DialogContent,
|
|
33
|
+
DialogActions,
|
|
34
|
+
Button,
|
|
35
|
+
} from '@ceed/cds';
|
|
45
36
|
|
|
46
37
|
function MyComponent() {
|
|
47
38
|
const [open, setOpen] = useState(false);
|
|
@@ -53,7 +44,9 @@ function MyComponent() {
|
|
|
53
44
|
<ModalDialog>
|
|
54
45
|
<ModalClose />
|
|
55
46
|
<DialogTitle>Modal Title</DialogTitle>
|
|
56
|
-
<DialogContent>
|
|
47
|
+
<DialogContent>
|
|
48
|
+
Place your content here.
|
|
49
|
+
</DialogContent>
|
|
57
50
|
<DialogActions>
|
|
58
51
|
<Button onClick={() => setOpen(false)}>Close</Button>
|
|
59
52
|
</DialogActions>
|
|
@@ -64,28 +57,6 @@ function MyComponent() {
|
|
|
64
57
|
}
|
|
65
58
|
```
|
|
66
59
|
|
|
67
|
-
### ModalFrame Usage
|
|
68
|
-
|
|
69
|
-
`ModalFrame` is a convenience component that combines `ModalDialog` + `ModalClose` + `DialogTitle` + `DialogContent` into a single composable unit.
|
|
70
|
-
It provides a concise way to build modals with a title, close button, and content area.
|
|
71
|
-
|
|
72
|
-
```tsx
|
|
73
|
-
import { Modal, ModalFrame } from '@ceed/cds';
|
|
74
|
-
|
|
75
|
-
function DetailModal({ open, onClose }) {
|
|
76
|
-
return (
|
|
77
|
-
<Modal open={open} onClose={onClose}>
|
|
78
|
-
<ModalFrame title="Detail" onClose={onClose}>
|
|
79
|
-
Content goes here.
|
|
80
|
-
</ModalFrame>
|
|
81
|
-
</Modal>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
> **Note**: Connect the same handler to both `Modal`'s `onClose` and `ModalFrame`'s `onClose`.
|
|
87
|
-
> `Modal` handles backdrop click and ESC key, while `ModalFrame` handles the X button click.
|
|
88
|
-
|
|
89
60
|
## Examples
|
|
90
61
|
|
|
91
62
|
### Basic Modal
|
|
@@ -93,32 +64,29 @@ function DetailModal({ open, onClose }) {
|
|
|
93
64
|
The basic modal with a simple Sheet for custom layouts.
|
|
94
65
|
|
|
95
66
|
```tsx
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
</
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
<code>aria-describedby</code> attribute.
|
|
118
|
-
</Typography>
|
|
67
|
+
<Modal aria-labelledby="modal-title" aria-describedby="modal-desc" open sx={{
|
|
68
|
+
display: 'flex',
|
|
69
|
+
justifyContent: 'center',
|
|
70
|
+
alignItems: 'center'
|
|
71
|
+
}}>
|
|
72
|
+
<Sheet variant="outlined" sx={{
|
|
73
|
+
maxWidth: 500,
|
|
74
|
+
borderRadius: 'md',
|
|
75
|
+
p: 3,
|
|
76
|
+
boxShadow: 'lg'
|
|
77
|
+
}}>
|
|
78
|
+
<ModalClose variant="plain" sx={{
|
|
79
|
+
m: 1
|
|
80
|
+
}} />
|
|
81
|
+
<Typography component="h2" id="modal-title" level="h4" textColor="inherit" fontWeight="lg" mb={2}>
|
|
82
|
+
This is the modal title
|
|
83
|
+
</Typography>
|
|
84
|
+
<Typography id="modal-desc" textColor="text.tertiary">
|
|
85
|
+
Make sure to use <code>aria-labelledby</code> on the modal dialog with an optional{' '}
|
|
86
|
+
<code>aria-describedby</code> attribute.
|
|
87
|
+
</Typography>
|
|
119
88
|
</Sheet>
|
|
120
89
|
</Modal>
|
|
121
|
-
</>
|
|
122
90
|
```
|
|
123
91
|
|
|
124
92
|
### Modal Dialog
|
|
@@ -126,34 +94,29 @@ The basic modal with a simple Sheet for custom layouts.
|
|
|
126
94
|
Use ModalDialog for structured dialogs with title, content, and actions.
|
|
127
95
|
|
|
128
96
|
```tsx
|
|
129
|
-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
</Stack>
|
|
152
|
-
</form>
|
|
153
|
-
</DialogContent>
|
|
154
|
-
</ModalDialog>
|
|
97
|
+
<Modal open>
|
|
98
|
+
<ModalDialog>
|
|
99
|
+
<DialogTitle>Create new project</DialogTitle>
|
|
100
|
+
<DialogContent>
|
|
101
|
+
Fill in the information of the project.
|
|
102
|
+
<form onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
}}>
|
|
105
|
+
<Stack spacing={4}>
|
|
106
|
+
<FormControl>
|
|
107
|
+
<FormLabel>Name</FormLabel>
|
|
108
|
+
<Input required />
|
|
109
|
+
</FormControl>
|
|
110
|
+
<FormControl>
|
|
111
|
+
<FormLabel>Description</FormLabel>
|
|
112
|
+
<Input required />
|
|
113
|
+
</FormControl>
|
|
114
|
+
<Button type="submit">Submit</Button>
|
|
115
|
+
</Stack>
|
|
116
|
+
</form>
|
|
117
|
+
</DialogContent>
|
|
118
|
+
</ModalDialog>
|
|
155
119
|
</Modal>
|
|
156
|
-
</>
|
|
157
120
|
```
|
|
158
121
|
|
|
159
122
|
### Variants
|
|
@@ -163,61 +126,49 @@ Modal dialogs support different visual variants.
|
|
|
163
126
|
#### Plain Variant
|
|
164
127
|
|
|
165
128
|
```tsx
|
|
166
|
-
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
<
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
</ModalDialog>
|
|
174
|
-
</Modal>
|
|
175
|
-
</>
|
|
129
|
+
<Modal open>
|
|
130
|
+
<ModalDialog variant="plain">
|
|
131
|
+
<ModalClose />
|
|
132
|
+
<DialogTitle>Modal Dialog</DialogTitle>
|
|
133
|
+
<DialogContent>This is a `plain` modal dialog.</DialogContent>
|
|
134
|
+
</ModalDialog>
|
|
135
|
+
</Modal>
|
|
176
136
|
```
|
|
177
137
|
|
|
178
138
|
#### Outlined Variant
|
|
179
139
|
|
|
180
140
|
```tsx
|
|
181
|
-
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
</ModalDialog>
|
|
189
|
-
</Modal>
|
|
190
|
-
</>
|
|
141
|
+
<Modal open>
|
|
142
|
+
<ModalDialog variant="outlined">
|
|
143
|
+
<ModalClose />
|
|
144
|
+
<DialogTitle>Modal Dialog</DialogTitle>
|
|
145
|
+
<DialogContent>This is an `outlined` modal dialog.</DialogContent>
|
|
146
|
+
</ModalDialog>
|
|
147
|
+
</Modal>
|
|
191
148
|
```
|
|
192
149
|
|
|
193
150
|
#### Soft Variant
|
|
194
151
|
|
|
195
152
|
```tsx
|
|
196
|
-
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
</ModalDialog>
|
|
204
|
-
</Modal>
|
|
205
|
-
</>
|
|
153
|
+
<Modal open>
|
|
154
|
+
<ModalDialog variant="soft">
|
|
155
|
+
<ModalClose />
|
|
156
|
+
<DialogTitle>Modal Dialog</DialogTitle>
|
|
157
|
+
<DialogContent>This is a `soft` modal dialog.</DialogContent>
|
|
158
|
+
</ModalDialog>
|
|
159
|
+
</Modal>
|
|
206
160
|
```
|
|
207
161
|
|
|
208
162
|
#### Solid Variant
|
|
209
163
|
|
|
210
164
|
```tsx
|
|
211
|
-
|
|
212
|
-
<
|
|
213
|
-
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
</ModalDialog>
|
|
219
|
-
</Modal>
|
|
220
|
-
</>
|
|
165
|
+
<Modal open>
|
|
166
|
+
<ModalDialog variant="solid">
|
|
167
|
+
<ModalClose />
|
|
168
|
+
<DialogTitle>Modal Dialog</DialogTitle>
|
|
169
|
+
<DialogContent>This is a `solid` modal dialog.</DialogContent>
|
|
170
|
+
</ModalDialog>
|
|
171
|
+
</Modal>
|
|
221
172
|
```
|
|
222
173
|
|
|
223
174
|
### Alert Dialog
|
|
@@ -225,29 +176,24 @@ Modal dialogs support different visual variants.
|
|
|
225
176
|
For critical confirmations that require explicit user decision.
|
|
226
177
|
|
|
227
178
|
```tsx
|
|
228
|
-
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
<
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
</Button>
|
|
247
|
-
</DialogActions>
|
|
248
|
-
</ModalDialog>
|
|
249
|
-
</Modal>
|
|
250
|
-
</>
|
|
179
|
+
<Modal open>
|
|
180
|
+
<ModalDialog variant="outlined" role="alertdialog">
|
|
181
|
+
<DialogTitle>
|
|
182
|
+
<WarningRoundedIcon />
|
|
183
|
+
Confirmation
|
|
184
|
+
</DialogTitle>
|
|
185
|
+
<Divider />
|
|
186
|
+
<DialogContent>Are you sure you want to discard all of your notes?</DialogContent>
|
|
187
|
+
<DialogActions>
|
|
188
|
+
<Button variant="solid" color="danger">
|
|
189
|
+
Discard notes
|
|
190
|
+
</Button>
|
|
191
|
+
<Button variant="plain" color="neutral">
|
|
192
|
+
Cancel
|
|
193
|
+
</Button>
|
|
194
|
+
</DialogActions>
|
|
195
|
+
</ModalDialog>
|
|
196
|
+
</Modal>
|
|
251
197
|
```
|
|
252
198
|
|
|
253
199
|
### Layouts
|
|
@@ -256,211 +202,16 @@ For critical confirmations that require explicit user decision.
|
|
|
256
202
|
|
|
257
203
|
For complex content that requires maximum screen space.
|
|
258
204
|
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
<Button onClick={() => setOpen(true)}>Open Fullscreen Modal</Button>
|
|
262
|
-
<Modal open={open} onClose={() => setOpen(false)}>
|
|
263
|
-
<ModalDialog layout="fullscreen">
|
|
264
|
-
<ModalClose />
|
|
265
|
-
<DialogTitle>Fullscreen Modal</DialogTitle>
|
|
266
|
-
<DialogContent>This modal takes up the entire screen.</DialogContent>
|
|
267
|
-
<DialogActions>
|
|
268
|
-
<Button variant="solid" onClick={() => setOpen(false)}>
|
|
269
|
-
Save
|
|
270
|
-
</Button>
|
|
271
|
-
</DialogActions>
|
|
272
|
-
</ModalDialog>
|
|
273
|
-
</Modal>
|
|
274
|
-
</>
|
|
205
|
+
```
|
|
206
|
+
<Canvas of={Modal.FullscreenLayout} />
|
|
275
207
|
```
|
|
276
208
|
|
|
277
209
|
### Nested Modals
|
|
278
210
|
|
|
279
211
|
Modals can be stacked on top of each other when necessary.
|
|
280
212
|
|
|
281
|
-
```tsx
|
|
282
|
-
<>
|
|
283
|
-
<Button onClick={() => setFirstOpen(true)}>Open First Modal</Button>
|
|
284
|
-
<Modal open={firstOpen} onClose={() => setFirstOpen(false)}>
|
|
285
|
-
<ModalDialog>
|
|
286
|
-
<ModalClose />
|
|
287
|
-
<DialogTitle>First Modal</DialogTitle>
|
|
288
|
-
<DialogContent>This is the first modal. Click the button below to open a nested modal.</DialogContent>
|
|
289
|
-
<DialogActions>
|
|
290
|
-
<Button onClick={() => setSecondOpen(true)}>Open Nested Modal</Button>
|
|
291
|
-
</DialogActions>
|
|
292
|
-
</ModalDialog>
|
|
293
|
-
</Modal>
|
|
294
|
-
<Modal open={secondOpen} onClose={() => setSecondOpen(false)}>
|
|
295
|
-
<ModalDialog>
|
|
296
|
-
<ModalClose />
|
|
297
|
-
<DialogTitle>Nested Modal</DialogTitle>
|
|
298
|
-
<DialogContent>This is a nested modal on top of the first one.</DialogContent>
|
|
299
|
-
<DialogActions>
|
|
300
|
-
<Button onClick={() => setSecondOpen(false)}>Close</Button>
|
|
301
|
-
</DialogActions>
|
|
302
|
-
</ModalDialog>
|
|
303
|
-
</Modal>
|
|
304
|
-
</>
|
|
305
213
|
```
|
|
306
|
-
|
|
307
|
-
### ModalFrame
|
|
308
|
-
|
|
309
|
-
ModalFrame is a convenience component that automatically provides a title, close button, and content area.
|
|
310
|
-
|
|
311
|
-
#### ModalFrame Playground
|
|
312
|
-
|
|
313
|
-
```tsx
|
|
314
|
-
<>
|
|
315
|
-
<Button onClick={() => setOpen(true)}>Open ModalFrame</Button>
|
|
316
|
-
<Modal open={open} onClose={() => setOpen(false)}>
|
|
317
|
-
<ModalFrame title="ModalFrame Title" onClose={() => setOpen(false)}>
|
|
318
|
-
<Typography>
|
|
319
|
-
ModalFrame automatically composes ModalDialog, ModalClose, DialogTitle, and DialogContent. You only need
|
|
320
|
-
to provide a title, onClose handler, and children.
|
|
321
|
-
</Typography>
|
|
322
|
-
</ModalFrame>
|
|
323
|
-
</Modal>
|
|
324
|
-
</>
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
#### titleStartDecorator
|
|
328
|
-
|
|
329
|
-
Display an icon or decorative element before the title.
|
|
330
|
-
|
|
331
|
-
```tsx
|
|
332
|
-
<>
|
|
333
|
-
<Button onClick={() => setOpen(true)}>With Decorator</Button>
|
|
334
|
-
<Modal open={open} onClose={() => setOpen(false)}>
|
|
335
|
-
<ModalFrame title="Details" titleStartDecorator={<InfoOutlinedIcon />} onClose={() => setOpen(false)}>
|
|
336
|
-
<Typography>
|
|
337
|
-
Use the <code>titleStartDecorator</code> prop to display an icon or element before the title.
|
|
338
|
-
</Typography>
|
|
339
|
-
</ModalFrame>
|
|
340
|
-
</Modal>
|
|
341
|
-
</>
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
#### Form Content
|
|
345
|
-
|
|
346
|
-
An inline form pattern where the submit button lives inside the content area.
|
|
347
|
-
|
|
348
|
-
```tsx
|
|
349
|
-
<>
|
|
350
|
-
<Button onClick={() => setOpen(true)}>Form in ModalFrame</Button>
|
|
351
|
-
<Modal open={open} onClose={() => setOpen(false)}>
|
|
352
|
-
<ModalFrame title="Create Project" onClose={() => setOpen(false)}>
|
|
353
|
-
<form onSubmit={(event: React.FormEvent<HTMLFormElement>) => {
|
|
354
|
-
event.preventDefault();
|
|
355
|
-
setOpen(false);
|
|
356
|
-
}}>
|
|
357
|
-
<Stack spacing={2}>
|
|
358
|
-
<FormControl>
|
|
359
|
-
<FormLabel>Name</FormLabel>
|
|
360
|
-
<Input required />
|
|
361
|
-
</FormControl>
|
|
362
|
-
<FormControl>
|
|
363
|
-
<FormLabel>Description</FormLabel>
|
|
364
|
-
<Input required />
|
|
365
|
-
</FormControl>
|
|
366
|
-
<Button type="submit">Submit</Button>
|
|
367
|
-
</Stack>
|
|
368
|
-
</form>
|
|
369
|
-
</ModalFrame>
|
|
370
|
-
</Modal>
|
|
371
|
-
</>
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
#### Sizes
|
|
375
|
-
|
|
376
|
-
Compare sm / md / lg sizes side by side.
|
|
377
|
-
|
|
378
|
-
```tsx
|
|
379
|
-
<Stack direction="row" spacing={2}>
|
|
380
|
-
<Button size="sm" onClick={() => setOpenSm(true)}>
|
|
381
|
-
Small
|
|
382
|
-
</Button>
|
|
383
|
-
<Button size="md" onClick={() => setOpenMd(true)}>
|
|
384
|
-
Medium
|
|
385
|
-
</Button>
|
|
386
|
-
<Button size="lg" onClick={() => setOpenLg(true)}>
|
|
387
|
-
Large
|
|
388
|
-
</Button>
|
|
389
|
-
<Modal open={openSm} onClose={() => setOpenSm(false)}>
|
|
390
|
-
<ModalFrame title="Small ModalFrame" size="sm" onClose={() => setOpenSm(false)}>
|
|
391
|
-
<Typography>This is a small ModalFrame.</Typography>
|
|
392
|
-
</ModalFrame>
|
|
393
|
-
</Modal>
|
|
394
|
-
<Modal open={openMd} onClose={() => setOpenMd(false)}>
|
|
395
|
-
<ModalFrame title="Medium ModalFrame" size="md" onClose={() => setOpenMd(false)}>
|
|
396
|
-
<Typography>This is a medium ModalFrame.</Typography>
|
|
397
|
-
</ModalFrame>
|
|
398
|
-
</Modal>
|
|
399
|
-
<Modal open={openLg} onClose={() => setOpenLg(false)}>
|
|
400
|
-
<ModalFrame title="Large ModalFrame" size="lg" onClose={() => setOpenLg(false)}>
|
|
401
|
-
<Typography>This is a large ModalFrame.</Typography>
|
|
402
|
-
</ModalFrame>
|
|
403
|
-
</Modal>
|
|
404
|
-
</Stack>
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
#### Custom Content
|
|
408
|
-
|
|
409
|
-
A layout example suited for displaying detailed information.
|
|
410
|
-
|
|
411
|
-
```tsx
|
|
412
|
-
<>
|
|
413
|
-
<Button onClick={() => setOpen(true)}>Custom Content</Button>
|
|
414
|
-
<Modal open={open} onClose={() => setOpen(false)}>
|
|
415
|
-
<ModalFrame title="Order Details" onClose={() => setOpen(false)}>
|
|
416
|
-
<Stack spacing={2}>
|
|
417
|
-
<Box>
|
|
418
|
-
<Typography level="title-sm">Order ID</Typography>
|
|
419
|
-
<Typography level="body-sm">ORD-2024-00123</Typography>
|
|
420
|
-
</Box>
|
|
421
|
-
<Divider />
|
|
422
|
-
<Box>
|
|
423
|
-
<Typography level="title-sm">Customer</Typography>
|
|
424
|
-
<Typography level="body-sm">John Doe</Typography>
|
|
425
|
-
</Box>
|
|
426
|
-
<Divider />
|
|
427
|
-
<Box>
|
|
428
|
-
<Typography level="title-sm">Status</Typography>
|
|
429
|
-
<Typography level="body-sm" color="success">
|
|
430
|
-
Completed
|
|
431
|
-
</Typography>
|
|
432
|
-
</Box>
|
|
433
|
-
</Stack>
|
|
434
|
-
</ModalFrame>
|
|
435
|
-
</Modal>
|
|
436
|
-
</>
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
#### Standalone
|
|
440
|
-
|
|
441
|
-
ModalFrame can be used without a Modal wrapper for embedding dialog-style layouts directly within a page.
|
|
442
|
-
|
|
443
|
-
> ⚠️ **Important** ⚠️
|
|
444
|
-
>
|
|
445
|
-
> When using ModalFrame without Modal, the parent container **must** meet the following requirements:
|
|
446
|
-
>
|
|
447
|
-
> - `position: 'relative'` — ModalFrame uses absolute positioning internally
|
|
448
|
-
> - Explicit `width` and `height` — `height` must be an absolute value (e.g., `300`, `'400px'`), not a relative value like `%` or `auto`
|
|
449
|
-
>
|
|
450
|
-
> ModalFrame inherits its dimensions from `ModalDialog`, which normally receives sizing from the Modal overlay. Without these constraints, the component will not render with correct dimensions.
|
|
451
|
-
|
|
452
|
-
```tsx
|
|
453
|
-
<Box sx={{
|
|
454
|
-
position: 'relative',
|
|
455
|
-
width: 480,
|
|
456
|
-
height: 300
|
|
457
|
-
}}>
|
|
458
|
-
<ModalFrame title="Standalone ModalFrame" onClose={() => console.log('close')}>
|
|
459
|
-
<Typography>
|
|
460
|
-
ModalFrame used without Modal. The parent container must provide explicit width and height.
|
|
461
|
-
</Typography>
|
|
462
|
-
</ModalFrame>
|
|
463
|
-
</Box>
|
|
214
|
+
<Canvas of={Modal.NestedModals} />
|
|
464
215
|
```
|
|
465
216
|
|
|
466
217
|
## When to Use
|
|
@@ -498,7 +249,8 @@ function DeleteConfirmation({ item, onDelete, onCancel }) {
|
|
|
498
249
|
</DialogTitle>
|
|
499
250
|
<Divider />
|
|
500
251
|
<DialogContent>
|
|
501
|
-
This action cannot be undone. All data associated with this item
|
|
252
|
+
This action cannot be undone. All data associated with this item
|
|
253
|
+
will be permanently removed.
|
|
502
254
|
</DialogContent>
|
|
503
255
|
<DialogActions>
|
|
504
256
|
<Button variant="solid" color="danger" onClick={onDelete}>
|
|
@@ -574,7 +326,8 @@ function TermsModal({ open, onAccept, onDecline }) {
|
|
|
574
326
|
<DialogTitle>Terms of Service</DialogTitle>
|
|
575
327
|
<DialogContent>
|
|
576
328
|
<Typography level="body-sm">
|
|
577
|
-
Please read and accept the following terms and conditions before
|
|
329
|
+
Please read and accept the following terms and conditions before
|
|
330
|
+
proceeding...
|
|
578
331
|
</Typography>
|
|
579
332
|
{/* Terms content */}
|
|
580
333
|
</DialogContent>
|
|
@@ -602,7 +355,11 @@ function ImagePreviewModal({ image, open, onClose }) {
|
|
|
602
355
|
<Modal open={open} onClose={onClose}>
|
|
603
356
|
<ModalDialog layout="center" sx={{ p: 0, overflow: 'hidden' }}>
|
|
604
357
|
<ModalClose sx={{ top: 8, right: 8, zIndex: 1 }} />
|
|
605
|
-
<img
|
|
358
|
+
<img
|
|
359
|
+
src={image.src}
|
|
360
|
+
alt={image.alt}
|
|
361
|
+
style={{ maxWidth: '90vw', maxHeight: '90vh', objectFit: 'contain' }}
|
|
362
|
+
/>
|
|
606
363
|
</ModalDialog>
|
|
607
364
|
</Modal>
|
|
608
365
|
);
|
|
@@ -633,69 +390,22 @@ function LoadingModal({ open, message }) {
|
|
|
633
390
|
Modal uses a composition pattern with multiple sub-components:
|
|
634
391
|
|
|
635
392
|
```tsx
|
|
636
|
-
<Modal>
|
|
637
|
-
{/*
|
|
638
|
-
|
|
639
|
-
{/*
|
|
640
|
-
<ModalClose /> {/* Close button (optional) */}
|
|
641
|
-
<DialogTitle>
|
|
642
|
-
{/* Header */}
|
|
393
|
+
<Modal> {/* Overlay and backdrop */}
|
|
394
|
+
<ModalDialog> {/* Dialog container */}
|
|
395
|
+
<ModalClose /> {/* Close button (optional) */}
|
|
396
|
+
<DialogTitle> {/* Header */}
|
|
643
397
|
Title
|
|
644
398
|
</DialogTitle>
|
|
645
|
-
<DialogContent>
|
|
646
|
-
{/* Body */}
|
|
399
|
+
<DialogContent> {/* Body */}
|
|
647
400
|
Content goes here
|
|
648
401
|
</DialogContent>
|
|
649
|
-
<DialogActions>
|
|
650
|
-
{/* Footer */}
|
|
402
|
+
<DialogActions> {/* Footer */}
|
|
651
403
|
<Button>Action</Button>
|
|
652
404
|
</DialogActions>
|
|
653
405
|
</ModalDialog>
|
|
654
406
|
</Modal>
|
|
655
407
|
```
|
|
656
408
|
|
|
657
|
-
## Component Roles
|
|
658
|
-
|
|
659
|
-
| Component | Role | When to Use |
|
|
660
|
-
| ----------------- | --------------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
661
|
-
| **Modal** | Overlay backdrop, open/close state management | Always required as the outermost wrapper |
|
|
662
|
-
| **ModalDialog** | Dialog container (variant/size/layout) | When you need direct control over layout |
|
|
663
|
-
| **ModalClose** | Close (X) button in the top-right corner | When users should be able to close via a button |
|
|
664
|
-
| **ModalOverflow** | Scrollable area | When content exceeds the viewport |
|
|
665
|
-
| **ModalFrame** | Combines ModalDialog + ModalClose + DialogTitle + DialogContent | When you only need a title + close + content (no action buttons) |
|
|
666
|
-
| **DialogTitle** | Header area (styled padding) | When composing manually |
|
|
667
|
-
| **DialogContent** | Body area (styled padding) | When composing manually |
|
|
668
|
-
| **DialogActions** | Footer action button area | When confirm/cancel buttons are needed |
|
|
669
|
-
|
|
670
|
-
## Choosing the Right Component
|
|
671
|
-
|
|
672
|
-
### ModalFrame vs DialogFrame
|
|
673
|
-
|
|
674
|
-
| | ModalFrame | DialogFrame |
|
|
675
|
-
| ------------------ | ----------------------------------------------- | --------------------------------------- |
|
|
676
|
-
| Close (X) button | Built-in | None |
|
|
677
|
-
| Title decorator | `titleStartDecorator` | None |
|
|
678
|
-
| Action button area | None | `actions` prop (required) |
|
|
679
|
-
| Fullscreen | `layout="fullscreen"` | `fullscreen` prop |
|
|
680
|
-
| Best for | Information display, detail views, inline forms | Confirm/cancel dialogs, decision-making |
|
|
681
|
-
|
|
682
|
-
### Use ModalFrame when
|
|
683
|
-
|
|
684
|
-
- You need an informational modal with a close button (detail views, previews)
|
|
685
|
-
- The form's submit button lives inside the content area
|
|
686
|
-
- You need an icon next to the title
|
|
687
|
-
|
|
688
|
-
### Use DialogFrame when
|
|
689
|
-
|
|
690
|
-
- Explicit action buttons (confirm/cancel) must be pinned to the bottom
|
|
691
|
-
- User decisions are required (delete confirmation, save confirmation)
|
|
692
|
-
- Only explicit choices should be allowed without a close (X) button
|
|
693
|
-
|
|
694
|
-
### Use manual composition when
|
|
695
|
-
|
|
696
|
-
- You need a custom layout that doesn't fit the ModalFrame/DialogFrame pattern
|
|
697
|
-
- You want to use both ModalClose and DialogActions together
|
|
698
|
-
|
|
699
409
|
## Props and Customization
|
|
700
410
|
|
|
701
411
|
### Modal Props
|
|
@@ -717,17 +427,6 @@ Modal uses a composition pattern with multiple sub-components:
|
|
|
717
427
|
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Dialog size |
|
|
718
428
|
| `layout` | `'center' \| 'fullscreen'` | `'center'` | Layout mode |
|
|
719
429
|
|
|
720
|
-
### ModalFrame Props
|
|
721
|
-
|
|
722
|
-
| Prop | Type | Default | Description |
|
|
723
|
-
| --------------------- | ------------ | ------- | ------------------------------------------ |
|
|
724
|
-
| `title` | `ReactNode` | - | Title displayed in the header |
|
|
725
|
-
| `children` | `ReactNode` | - | Body content |
|
|
726
|
-
| `titleStartDecorator` | `ReactNode` | - | Icon or element displayed before the title |
|
|
727
|
-
| `onClose` | `() => void` | - | Callback when the close button is clicked |
|
|
728
|
-
|
|
729
|
-
ModalFrame accepts all ModalDialog props (`variant`, `color`, `size`, `layout`, `sx`, etc.).
|
|
730
|
-
|
|
731
430
|
### Custom Styling
|
|
732
431
|
|
|
733
432
|
```tsx
|
|
@@ -766,10 +465,17 @@ Modal components include comprehensive accessibility features:
|
|
|
766
465
|
- `aria-describedby` connects to DialogContent
|
|
767
466
|
|
|
768
467
|
```tsx
|
|
769
|
-
<Modal
|
|
468
|
+
<Modal
|
|
469
|
+
open={open}
|
|
470
|
+
onClose={onClose}
|
|
471
|
+
aria-labelledby="modal-title"
|
|
472
|
+
aria-describedby="modal-description"
|
|
473
|
+
>
|
|
770
474
|
<ModalDialog>
|
|
771
475
|
<DialogTitle id="modal-title">Accessible Title</DialogTitle>
|
|
772
|
-
<DialogContent id="modal-description">
|
|
476
|
+
<DialogContent id="modal-description">
|
|
477
|
+
This content is read by screen readers.
|
|
478
|
+
</DialogContent>
|
|
773
479
|
</ModalDialog>
|
|
774
480
|
</Modal>
|
|
775
481
|
```
|
|
@@ -798,9 +504,7 @@ Modal components include comprehensive accessibility features:
|
|
|
798
504
|
```tsx
|
|
799
505
|
// ✅ Good: Clear action buttons
|
|
800
506
|
<DialogActions>
|
|
801
|
-
<Button variant="solid" color="danger">
|
|
802
|
-
Delete
|
|
803
|
-
</Button>
|
|
507
|
+
<Button variant="solid" color="danger">Delete</Button>
|
|
804
508
|
<Button variant="plain">Cancel</Button>
|
|
805
509
|
</DialogActions>
|
|
806
510
|
```
|
|
@@ -875,11 +579,15 @@ Use `keepMounted` only when the modal needs to preserve state between openings:
|
|
|
875
579
|
Memoize modal content when it depends on complex data:
|
|
876
580
|
|
|
877
581
|
```tsx
|
|
878
|
-
const modalContent = useMemo(() =>
|
|
582
|
+
const modalContent = useMemo(() => (
|
|
583
|
+
<ComplexContent data={data} />
|
|
584
|
+
), [data]);
|
|
879
585
|
|
|
880
586
|
<Modal open={open} onClose={onClose}>
|
|
881
|
-
<ModalDialog>
|
|
882
|
-
|
|
587
|
+
<ModalDialog>
|
|
588
|
+
{modalContent}
|
|
589
|
+
</ModalDialog>
|
|
590
|
+
</Modal>
|
|
883
591
|
```
|
|
884
592
|
|
|
885
593
|
Modal is a powerful component for focused user interactions. Use it thoughtfully to maintain a smooth user experience while capturing important decisions and inputs.
|