@ceed/cds 1.29.0 → 1.30.0

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.
Files changed (62) hide show
  1. package/dist/Overview.md +5 -5
  2. package/dist/components/Calendar/utils/index.d.ts +1 -0
  3. package/dist/components/DatePicker/DatePicker.d.ts +4 -0
  4. package/dist/components/DateRangePicker/DateRangePicker.d.ts +4 -0
  5. package/dist/components/MonthRangePicker/MonthRangePicker.d.ts +8 -0
  6. package/dist/components/data-display/Avatar.md +110 -69
  7. package/dist/components/data-display/Badge.md +91 -39
  8. package/dist/components/data-display/Chip.md +49 -20
  9. package/dist/components/data-display/DataTable.md +93 -0
  10. package/dist/components/data-display/InfoSign.md +12 -0
  11. package/dist/components/data-display/Table.md +72 -55
  12. package/dist/components/data-display/Tooltip.md +40 -40
  13. package/dist/components/data-display/Typography.md +53 -70
  14. package/dist/components/feedback/Alert.md +88 -72
  15. package/dist/components/feedback/CircularProgress.md +17 -0
  16. package/dist/components/feedback/Skeleton.md +17 -0
  17. package/dist/components/inputs/Button.md +94 -68
  18. package/dist/components/inputs/ButtonGroup.md +17 -0
  19. package/dist/components/inputs/Calendar.md +118 -457
  20. package/dist/components/inputs/Checkbox.md +185 -430
  21. package/dist/components/inputs/CurrencyInput.md +22 -0
  22. package/dist/components/inputs/DatePicker.md +59 -5
  23. package/dist/components/inputs/DateRangePicker.md +46 -5
  24. package/dist/components/inputs/FilterableCheckboxGroup.md +20 -3
  25. package/dist/components/inputs/FormControl.md +32 -2
  26. package/dist/components/inputs/IconButton.md +18 -0
  27. package/dist/components/inputs/Input.md +198 -136
  28. package/dist/components/inputs/MonthPicker.md +59 -5
  29. package/dist/components/inputs/MonthRangePicker.md +44 -5
  30. package/dist/components/inputs/PercentageInput.md +25 -0
  31. package/dist/components/inputs/RadioButton.md +23 -0
  32. package/dist/components/inputs/RadioList.md +20 -1
  33. package/dist/components/inputs/RadioTileGroup.md +37 -3
  34. package/dist/components/inputs/Select.md +56 -0
  35. package/dist/components/inputs/Slider.md +23 -0
  36. package/dist/components/inputs/Switch.md +20 -0
  37. package/dist/components/inputs/Textarea.md +32 -8
  38. package/dist/components/inputs/Uploader/Uploader.md +21 -0
  39. package/dist/components/layout/Box.md +52 -41
  40. package/dist/components/layout/Grid.md +87 -81
  41. package/dist/components/layout/Stack.md +88 -68
  42. package/dist/components/navigation/Breadcrumbs.md +57 -46
  43. package/dist/components/navigation/Drawer.md +17 -0
  44. package/dist/components/navigation/Dropdown.md +13 -0
  45. package/dist/components/navigation/IconMenuButton.md +17 -0
  46. package/dist/components/navigation/InsetDrawer.md +130 -292
  47. package/dist/components/navigation/Link.md +78 -0
  48. package/dist/components/navigation/Menu.md +17 -0
  49. package/dist/components/navigation/MenuButton.md +18 -0
  50. package/dist/components/navigation/Pagination.md +13 -0
  51. package/dist/components/navigation/Stepper.md +15 -0
  52. package/dist/components/navigation/Tabs.md +27 -0
  53. package/dist/components/surfaces/Accordions.md +804 -49
  54. package/dist/components/surfaces/Card.md +173 -97
  55. package/dist/components/surfaces/Divider.md +246 -82
  56. package/dist/components/surfaces/Sheet.md +15 -0
  57. package/dist/index.browser.js +4 -4
  58. package/dist/index.browser.js.map +3 -3
  59. package/dist/index.cjs +99 -39
  60. package/dist/index.js +99 -39
  61. package/framer/index.js +1 -1
  62. package/package.json +1 -1
@@ -6,124 +6,8 @@ InsetDrawer is a slide-out panel that appears from any edge of the screen, provi
6
6
 
7
7
  It is commonly used for mobile navigation menus, filter panels, configuration sidebars, and detail views. The component supports four anchor positions (left, right, top, bottom) and three size presets, making it adaptable to a wide range of layout requirements.
8
8
 
9
- ```tsx
10
- <InsetDrawer {...args}>
11
- <Sheet sx={{
12
- borderRadius: 'md',
13
- p: 2,
14
- display: 'flex',
15
- flexDirection: 'column',
16
- gap: 2,
17
- height: '100%',
18
- overflow: 'auto'
19
- }}>
20
- <DialogTitle>Filters</DialogTitle>
21
- <ModalClose />
22
- <Divider sx={{
23
- mt: 'auto'
24
- }} />
25
- <DialogContent>
26
- <FormControl>
27
- <FormLabel sx={{
28
- typography: 'title-md',
29
- fontWeight: 'bold'
30
- }}>Property type</FormLabel>
31
- <RadioGroup>
32
- <Box sx={{
33
- display: 'grid',
34
- gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
35
- gap: 1.5
36
- }}>
37
- {[{
38
- name: 'House',
39
- icon: <HomeRoundedIcon />
40
- }, {
41
- name: 'Apartment',
42
- icon: <ApartmentRoundedIcon />
43
- }, {
44
- name: 'Guesthouse',
45
- icon: <MeetingRoomRoundedIcon />
46
- }, {
47
- name: 'Hotel',
48
- icon: <HotelRoundedIcon />
49
- }].map(item => <Card key={item.name} sx={{
50
- boxShadow: 'none',
51
- '&:hover': {
52
- bgcolor: 'background.level1'
53
- }
54
- }}>
55
- <CardContent>
56
- {item.icon}
57
- <Typography level="title-md">{item.name}</Typography>
58
- </CardContent>
59
- <Radio disableIcon overlay variant="outlined" color="neutral" value={item.name} sx={{
60
- mt: -2
61
- }} slotProps={{
62
- action: {
63
- sx: {
64
- '&:hover': {
65
- bgcolor: 'transparent'
66
- }
67
- }
68
- }
69
- }} />
70
- </Card>)}
71
- </Box>
72
- </RadioGroup>
73
- </FormControl>
74
-
75
- <Typography level="title-md" fontWeight="bold" sx={{
76
- mt: 2
77
- }}>
78
- Booking options
79
- </Typography>
80
- <FormControl orientation="horizontal">
81
- <Box sx={{
82
- flex: 1,
83
- pr: 1
84
- }}>
85
- <FormLabel sx={{
86
- typography: 'title-sm'
87
- }}>Instant booking</FormLabel>
88
- <FormHelperText sx={{
89
- typography: 'body-sm'
90
- }}>
91
- Listings that you can book without waiting for host approval.
92
- </FormHelperText>
93
- </Box>
94
- <Switch />
95
- </FormControl>
96
-
97
- <FormControl orientation="horizontal">
98
- <Box sx={{
99
- flex: 1,
100
- mt: 1,
101
- mr: 1
102
- }}>
103
- <FormLabel sx={{
104
- typography: 'title-sm'
105
- }}>Self check-in</FormLabel>
106
- <FormHelperText sx={{
107
- typography: 'body-sm'
108
- }}>
109
- Easy access to the property when you arrive.
110
- </FormHelperText>
111
- </Box>
112
- <Switch />
113
- </FormControl>
114
- </DialogContent>
115
-
116
- <Divider sx={{
117
- mt: 'auto'
118
- }} />
119
- <Stack direction="row" justifyContent="space-between" useFlexGap spacing={1}>
120
- <Button variant="outlined" color="neutral">
121
- Clear
122
- </Button>
123
- <Button>Show 165 properties</Button>
124
- </Stack>
125
- </Sheet>
126
- </InsetDrawer>
9
+ ```
10
+ <Canvas of={InsetDrawer.Playground} />
127
11
  ```
128
12
 
129
13
  | Field | Description | Default |
@@ -155,220 +39,145 @@ function FilterDrawer() {
155
39
  }
156
40
  ```
157
41
 
158
- ## Default
42
+ ## Anchor Positions
159
43
 
160
- The default InsetDrawer with a filter panel layout, demonstrating the component's structure with `DialogTitle`, `ModalClose`, `DialogContent`, and action buttons.
44
+ InsetDrawer supports four anchor positions. Use `left` for navigation, `right` for details or filters, `top` for search bars, and `bottom` for mobile action sheets.
161
45
 
162
- ```tsx
163
- <InsetDrawer {...args}>
164
- <Sheet sx={{
165
- borderRadius: 'md',
166
- p: 2,
167
- display: 'flex',
168
- flexDirection: 'column',
169
- gap: 2,
170
- height: '100%',
171
- overflow: 'auto'
172
- }}>
173
- <DialogTitle>Filters</DialogTitle>
174
- <ModalClose />
175
- <Divider sx={{
176
- mt: 'auto'
177
- }} />
178
- <DialogContent>
179
- <FormControl>
180
- <FormLabel sx={{
181
- typography: 'title-md',
182
- fontWeight: 'bold'
183
- }}>Property type</FormLabel>
184
- <RadioGroup>
185
- <Box sx={{
186
- display: 'grid',
187
- gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
188
- gap: 1.5
189
- }}>
190
- {[{
191
- name: 'House',
192
- icon: <HomeRoundedIcon />
193
- }, {
194
- name: 'Apartment',
195
- icon: <ApartmentRoundedIcon />
196
- }, {
197
- name: 'Guesthouse',
198
- icon: <MeetingRoomRoundedIcon />
199
- }, {
200
- name: 'Hotel',
201
- icon: <HotelRoundedIcon />
202
- }].map(item => <Card key={item.name} sx={{
203
- boxShadow: 'none',
204
- '&:hover': {
205
- bgcolor: 'background.level1'
206
- }
207
- }}>
208
- <CardContent>
209
- {item.icon}
210
- <Typography level="title-md">{item.name}</Typography>
211
- </CardContent>
212
- <Radio disableIcon overlay variant="outlined" color="neutral" value={item.name} sx={{
213
- mt: -2
214
- }} slotProps={{
215
- action: {
216
- sx: {
217
- '&:hover': {
218
- bgcolor: 'transparent'
219
- }
220
- }
221
- }
222
- }} />
223
- </Card>)}
224
- </Box>
225
- </RadioGroup>
226
- </FormControl>
227
-
228
- <Typography level="title-md" fontWeight="bold" sx={{
229
- mt: 2
230
- }}>
231
- Booking options
232
- </Typography>
233
- <FormControl orientation="horizontal">
234
- <Box sx={{
235
- flex: 1,
236
- pr: 1
237
- }}>
238
- <FormLabel sx={{
239
- typography: 'title-sm'
240
- }}>Instant booking</FormLabel>
241
- <FormHelperText sx={{
242
- typography: 'body-sm'
243
- }}>
244
- Listings that you can book without waiting for host approval.
245
- </FormHelperText>
246
- </Box>
247
- <Switch />
248
- </FormControl>
249
-
250
- <FormControl orientation="horizontal">
251
- <Box sx={{
252
- flex: 1,
253
- mt: 1,
254
- mr: 1
255
- }}>
256
- <FormLabel sx={{
257
- typography: 'title-sm'
258
- }}>Self check-in</FormLabel>
259
- <FormHelperText sx={{
260
- typography: 'body-sm'
261
- }}>
262
- Easy access to the property when you arrive.
263
- </FormHelperText>
264
- </Box>
265
- <Switch />
266
- </FormControl>
267
- </DialogContent>
268
-
269
- <Divider sx={{
270
- mt: 'auto'
271
- }} />
272
- <Stack direction="row" justifyContent="space-between" useFlexGap spacing={1}>
273
- <Button variant="outlined" color="neutral">
274
- Clear
275
- </Button>
276
- <Button>Show 165 properties</Button>
277
- </Stack>
278
- </Sheet>
279
- </InsetDrawer>
46
+ ```
47
+ <Canvas of={InsetDrawer.Anchors} />
48
+ ```
49
+
50
+ ## Sizes
51
+
52
+ Three size presets are available: `sm`, `md`, and `lg`. The size controls width for left/right anchors and height for top/bottom anchors.
53
+
54
+ ```
55
+ <Canvas of={InsetDrawer.Sizes} />
56
+ ```
57
+
58
+ ## Navigation Menu
59
+
60
+ A typical mobile navigation menu pattern using InsetDrawer anchored to the left with a compact size.
61
+
62
+ ```
63
+ <Canvas of={InsetDrawer.NavigationMenu} />
64
+ ```
65
+
66
+ ## Filter Panel
67
+
68
+ A filter panel that slides in from the right, containing form controls for refining search results.
69
+
70
+ ```
71
+ <Canvas of={InsetDrawer.FilterPanel} />
280
72
  ```
281
73
 
282
74
  ## Common Use Cases
283
75
 
284
- ### Navigation Drawer
76
+ ### Settings Drawer
285
77
 
286
78
  ```tsx
287
- function NavigationDrawer({ open, onClose, currentPath }) {
288
- const navItems = [
289
- { label: 'Dashboard', path: '/dashboard', icon: <DashboardIcon /> },
290
- { label: 'Users', path: '/users', icon: <PeopleIcon /> },
291
- { label: 'Settings', path: '/settings', icon: <SettingsIcon /> },
292
- ];
79
+ function SettingsDrawer({ open, onClose }) {
80
+ const [settings, setSettings] = useState({
81
+ notifications: true,
82
+ darkMode: false,
83
+ language: 'en',
84
+ });
293
85
 
294
86
  return (
295
- <InsetDrawer open={open} onClose={onClose} anchor="left">
296
- <Sheet sx={{ width: 280, height: '100%', p: 2 }}>
297
- <Stack gap={1}>
298
- <Typography level="title-lg">My App</Typography>
299
- <Divider />
300
- <List>
301
- {navItems.map((item) => (
302
- <ListItem key={item.path}>
303
- <ListItemButton
304
- selected={currentPath === item.path}
305
- onClick={() => { navigate(item.path); onClose(); }}
306
- >
307
- <ListItemDecorator>{item.icon}</ListItemDecorator>
308
- {item.label}
309
- </ListItemButton>
310
- </ListItem>
311
- ))}
312
- </List>
313
- </Stack>
87
+ <InsetDrawer open={open} onClose={onClose} anchor="right" size="sm">
88
+ <Sheet sx={{ height: '100%', p: 2 }}>
89
+ <DialogTitle>Settings</DialogTitle>
90
+ <ModalClose />
91
+ <Divider sx={{ my: 2 }} />
92
+ <DialogContent>
93
+ <Stack gap={3}>
94
+ <FormControl orientation="horizontal">
95
+ <Box sx={{ flex: 1 }}>
96
+ <FormLabel>Notifications</FormLabel>
97
+ <FormHelperText>Receive push notifications</FormHelperText>
98
+ </Box>
99
+ <Switch
100
+ checked={settings.notifications}
101
+ onChange={(e) =>
102
+ setSettings({ ...settings, notifications: e.target.checked })
103
+ }
104
+ />
105
+ </FormControl>
106
+ <FormControl orientation="horizontal">
107
+ <Box sx={{ flex: 1 }}>
108
+ <FormLabel>Dark Mode</FormLabel>
109
+ <FormHelperText>Use dark color theme</FormHelperText>
110
+ </Box>
111
+ <Switch
112
+ checked={settings.darkMode}
113
+ onChange={(e) =>
114
+ setSettings({ ...settings, darkMode: e.target.checked })
115
+ }
116
+ />
117
+ </FormControl>
118
+ </Stack>
119
+ </DialogContent>
314
120
  </Sheet>
315
121
  </InsetDrawer>
316
122
  );
317
123
  }
318
124
  ```
319
125
 
320
- ### Filter Panel
126
+ ### Detail View Drawer
321
127
 
322
128
  ```tsx
323
- function ProductFilters({ open, onClose, onApply }) {
324
- const [localFilters, setLocalFilters] = useState({});
129
+ function DetailDrawer({ open, onClose, itemId }) {
130
+ const [data, setData] = useState(null);
131
+
132
+ useEffect(() => {
133
+ if (open && itemId) {
134
+ fetchItemDetails(itemId).then(setData);
135
+ }
136
+ }, [open, itemId]);
325
137
 
326
138
  return (
327
- <InsetDrawer open={open} onClose={onClose} anchor="right" size="md">
139
+ <InsetDrawer open={open} onClose={onClose} anchor="right" size="lg">
328
140
  <Sheet sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
329
141
  <Box sx={{ p: 2, borderBottom: '1px solid', borderColor: 'divider' }}>
330
- <DialogTitle>Filters</DialogTitle>
142
+ <DialogTitle>Item Details</DialogTitle>
331
143
  <ModalClose />
332
144
  </Box>
333
145
  <DialogContent sx={{ flex: 1, overflow: 'auto', p: 2 }}>
334
- {/* Filter form controls */}
146
+ {data ? <ItemDetails data={data} /> : <Skeleton variant="text" />}
335
147
  </DialogContent>
336
- <Box sx={{ p: 2, borderTop: '1px solid', borderColor: 'divider' }}>
337
- <Stack direction="row" gap={1} justifyContent="space-between">
338
- <Button variant="outlined" color="neutral" onClick={() => setLocalFilters({})}>
339
- Clear All
340
- </Button>
341
- <Button onClick={() => { onApply(localFilters); onClose(); }}>
342
- Apply Filters
343
- </Button>
344
- </Stack>
345
- </Box>
346
148
  </Sheet>
347
149
  </InsetDrawer>
348
150
  );
349
151
  }
350
152
  ```
351
153
 
352
- ### Bottom Sheet for Mobile
154
+ ### Bottom Sheet for Mobile Actions
353
155
 
354
156
  ```tsx
355
157
  function ActionSheet({ open, onClose, onAction }) {
158
+ const actions = [
159
+ { id: 'edit', label: 'Edit', icon: <EditIcon /> },
160
+ { id: 'share', label: 'Share', icon: <ShareIcon /> },
161
+ { id: 'delete', label: 'Delete', icon: <DeleteIcon />, color: 'danger' },
162
+ ];
163
+
356
164
  return (
357
165
  <InsetDrawer open={open} onClose={onClose} anchor="bottom">
358
166
  <Sheet sx={{ borderRadius: 'lg lg 0 0', p: 2 }}>
359
167
  <List>
360
- <ListItem>
361
- <ListItemButton onClick={() => { onAction('edit'); onClose(); }}>
362
- Edit
363
- </ListItemButton>
364
- </ListItem>
365
- <ListItem>
366
- <ListItemButton onClick={() => { onAction('delete'); onClose(); }}>
367
- Delete
368
- </ListItemButton>
369
- </ListItem>
168
+ {actions.map((action) => (
169
+ <ListItem key={action.id}>
170
+ <ListItemButton
171
+ color={action.color}
172
+ onClick={() => { onAction(action.id); onClose(); }}
173
+ >
174
+ <ListItemDecorator>{action.icon}</ListItemDecorator>
175
+ {action.label}
176
+ </ListItemButton>
177
+ </ListItem>
178
+ ))}
370
179
  </List>
371
- <Button variant="soft" color="neutral" fullWidth onClick={onClose}>
180
+ <Button variant="soft" color="neutral" fullWidth sx={{ mt: 1 }} onClick={onClose}>
372
181
  Cancel
373
182
  </Button>
374
183
  </Sheet>
@@ -377,6 +186,19 @@ function ActionSheet({ open, onClose, onAction }) {
377
186
  }
378
187
  ```
379
188
 
189
+ ## Props and Customization
190
+
191
+ ### Key Props
192
+
193
+ | Prop | Type | Default | Description |
194
+ | ---------- | -------------------------------------------------------------- | ----------- | -------------- |
195
+ | `children` | `ReactNode` | - | Drawer content |
196
+ | `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | `'plain'` | Visual style |
197
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
198
+ | `sx` | `SxProps` | - | Custom styles |
199
+
200
+ > **Note**: InsetDrawer is a styled Sheet component designed for sidebar layouts. It accepts all Joy UI Sheet props.
201
+
380
202
  ## Best Practices
381
203
 
382
204
  1. **Use appropriate anchor positions**: Match the drawer position to the content type for intuitive UX.
@@ -402,6 +224,22 @@ function ActionSheet({ open, onClose, onAction }) {
402
224
 
403
225
  3. **Structure content consistently**: Use a header/body/footer layout with clear dividers so users can quickly scan the drawer's content.
404
226
 
227
+ ```tsx
228
+ // ✅ Good: Clear header/body/footer structure
229
+ <Sheet sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
230
+ <Box sx={{ p: 2, borderBottom: '1px solid', borderColor: 'divider' }}>
231
+ <DialogTitle>Title</DialogTitle>
232
+ <ModalClose />
233
+ </Box>
234
+ <DialogContent sx={{ flex: 1, overflow: 'auto', p: 2 }}>
235
+ {/* Scrollable content */}
236
+ </DialogContent>
237
+ <Box sx={{ p: 2, borderTop: '1px solid', borderColor: 'divider' }}>
238
+ <Button>Save</Button>
239
+ </Box>
240
+ </Sheet>
241
+ ```
242
+
405
243
  4. **Do not nest drawers**: Opening a drawer inside another drawer creates a confusing experience.
406
244
 
407
245
  ```tsx
@@ -43,6 +43,64 @@ function MyComponent() {
43
43
  }
44
44
  ```
45
45
 
46
+ ## Features
47
+
48
+ ### Variants
49
+
50
+ Links support four visual styles through the `variant` prop: `plain`, `outlined`, `soft`, and `solid`.
51
+
52
+ ```
53
+ <Canvas of={Link.Variants} />
54
+ ```
55
+
56
+ ### Colors
57
+
58
+ Apply semantic colors to communicate different purposes -- `primary`, `neutral`, `success`, `warning`, and `danger`.
59
+
60
+ ```
61
+ <Canvas of={Link.Colors} />
62
+ ```
63
+
64
+ ### Underline Styles
65
+
66
+ Control the underline behavior with three options: `none` (never shown), `hover` (shown on hover), and `always` (permanently visible).
67
+
68
+ ```
69
+ <Canvas of={Link.Underline} />
70
+ ```
71
+
72
+ ### Typography Levels
73
+
74
+ Links can adopt any typography level from the design system, enabling consistent text hierarchies when links appear alongside headings or body text.
75
+
76
+ ```
77
+ <Canvas of={Link.Levels} />
78
+ ```
79
+
80
+ ### Disabled State
81
+
82
+ Links can be disabled to prevent interaction while remaining visible in the layout.
83
+
84
+ ```
85
+ <Canvas of={Link.Disabled} />
86
+ ```
87
+
88
+ ### External Links
89
+
90
+ For links that navigate away from your application, include `target="_blank"` and `rel="noopener noreferrer"` for security.
91
+
92
+ ```
93
+ <Canvas of={Link.ExternalLink} />
94
+ ```
95
+
96
+ ### Inline with Text
97
+
98
+ Links integrate seamlessly within paragraph text, inheriting the surrounding font styles.
99
+
100
+ ```
101
+ <Canvas of={Link.InlineWithText} />
102
+ ```
103
+
46
104
  ## Common Use Cases
47
105
 
48
106
  ### Inline Text Links
@@ -93,6 +151,26 @@ function AppNavigation() {
93
151
  }
94
152
  ```
95
153
 
154
+ ## Props and Customization
155
+
156
+ ### Key Props
157
+
158
+ | Prop | Type | Default | Description |
159
+ | ---------------- | -------------------------------------------------------------- | ----------- | -------------------------------------- |
160
+ | `children` | `ReactNode` | - | Link content |
161
+ | `href` | `string` | - | Link URL |
162
+ | `level` | Typography level | `'body-md'` | Text size (inherits Typography levels) |
163
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'primary'` | Link color |
164
+ | `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | - | Visual style |
165
+ | `underline` | `'none' \| 'hover' \| 'always'` | `'hover'` | Underline behavior |
166
+ | `disabled` | `boolean` | `false` | Disables the link |
167
+ | `startDecorator` | `ReactNode` | - | Content before link text |
168
+ | `endDecorator` | `ReactNode` | - | Content after link text |
169
+ | `component` | `ElementType` | `'a'` | Root element type (polymorphic) |
170
+ | `sx` | `SxProps` | - | Custom styles |
171
+
172
+ > **Note**: Link also accepts all Joy UI Link props.
173
+
96
174
  ## Best Practices
97
175
 
98
176
  - **Use descriptive link text.** The text should clearly communicate the destination. Avoid generic labels such as "click here" or "read more".
@@ -719,6 +719,23 @@ Menu can contain non-MenuItem elements like Box, Typography, and progress indica
719
719
  </Dropdown>
720
720
  ```
721
721
 
722
+ ## Props and Customization
723
+
724
+ ### Key Props
725
+
726
+ | Prop | Type | Default | Description |
727
+ | ----------- | -------------------------------------------------------------- | ---------------- | ---------------------------------------- |
728
+ | `children` | `ReactNode` | - | Menu items (MenuItem, ListDivider, etc.) |
729
+ | `open` | `boolean` | - | Controlled open state |
730
+ | `onClose` | `() => void` | - | Callback when the menu closes |
731
+ | `placement` | `Placement` | `'bottom-start'` | Menu position relative to trigger |
732
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Menu size |
733
+ | `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | `'outlined'` | Visual style |
734
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
735
+ | `sx` | `SxProps` | - | Custom styles |
736
+
737
+ > **Note**: Menu also accepts all Joy UI Menu props and Framer Motion props.
738
+
722
739
  ## Best Practices
723
740
 
724
741
  - **Use ListDivider to group related items.** Logical grouping helps users scan the menu faster. Place destructive actions (like Delete) in their own group at the bottom.
@@ -233,6 +233,24 @@ function ToolbarActions({ selectedItems, onAction }) {
233
233
  }
234
234
  ```
235
235
 
236
+ ## Props and Customization
237
+
238
+ ### Key Props
239
+
240
+ | Prop | Type | Default | Description |
241
+ | ----------------- | -------------------------------------------------------------- | ---------------- | ------------------------------------ |
242
+ | `buttonText` | `string` | (required) | Text displayed in the trigger button |
243
+ | `items` | `{ text: string; onClick?: () => void }[]` | (required) | Menu item list |
244
+ | `variant` | `'solid' \| 'soft' \| 'outlined' \| 'plain'` | `'outlined'` | Button visual style |
245
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Button size |
246
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Button color |
247
+ | `disabled` | `boolean` | `false` | Disables the button |
248
+ | `startDecorator` | `ReactNode` | - | Content before button text |
249
+ | `endDecorator` | `ReactNode` | - | Content after button text |
250
+ | `showIcon` | `boolean` | `true` | Show dropdown arrow icon |
251
+ | `placement` | `Placement` | `'bottom-start'` | Menu position |
252
+ | `buttonComponent` | `ElementType` | - | Custom trigger element |
253
+
236
254
  ## Best Practices
237
255
 
238
256
  - **Use descriptive button text.** The button label should clearly indicate what kind of options the menu contains. Avoid vague labels like "More" or "Options" -- prefer specific labels like "Export Options" or "User Actions".
@@ -214,6 +214,19 @@ function URLPaginatedList() {
214
214
  }
215
215
  ```
216
216
 
217
+ ## Props and Customization
218
+
219
+ ### Key Props
220
+
221
+ | Prop | Type | Default | Description |
222
+ | ------------------------ | ------------------------------------ | --------------------------- | -------------------------- |
223
+ | `paginationModel` | `{ page: number; pageSize: number }` | (required) | Current page and page size |
224
+ | `defaultPaginationModel` | `{ page: number; pageSize: number }` | `{ page: 1, pageSize: 25 }` | Initial pagination state |
225
+ | `rowCount` | `number` | (required) | Total number of rows |
226
+ | `onPageChange` | `(newPage: number) => void` | (required) | Callback when page changes |
227
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Pagination control size |
228
+ | `variant` | `'standard' \| 'compact'` | `'standard'` | Pagination display mode |
229
+
217
230
  ## Best Practices
218
231
 
219
232
  - **Always show context.** Display the total item count and current range (for example "Showing 1--25 of 250") alongside the pagination controls so users understand the scope of the data.
@@ -204,6 +204,21 @@ function CompactProgress({ currentStep, totalSteps }) {
204
204
  }
205
205
  ```
206
206
 
207
+ ## Props and Customization
208
+
209
+ ### Key Props
210
+
211
+ | Prop | Type | Default | Description |
212
+ | ------------------- | --------------------------------------------------------------------------------- | --------------- | -------------------------------------------- |
213
+ | `steps` | `{ indicatorContent?: ReactNode; label?: ReactNode; extraContent?: ReactNode }[]` | (required) | Step definitions |
214
+ | `activeStep` | `number` | (required) | Currently active step index (0-based) |
215
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Stepper layout direction |
216
+ | `stepOrientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Individual step content orientation |
217
+ | `activeColor` | `string` | `'primary.500'` | Color for active/completed step indicators |
218
+ | `inactiveColor` | `string` | `'neutral.400'` | Color for inactive step indicators |
219
+ | `activeLineColor` | `string` | `'primary.500'` | Color for connector lines of completed steps |
220
+ | `inactiveLineColor` | `string` | `'neutral.300'` | Color for connector lines of future steps |
221
+
207
222
  ## Best Practices
208
223
 
209
224
  1. **Keep step count manageable**: Limit the number of steps to 3-7 for optimal user comprehension. If more steps are needed, consider grouping them.