@ceed/ads 1.20.0 → 1.20.1
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/data-display/Markdown.md +832 -0
- package/dist/components/feedback/Dialog.md +605 -3
- package/dist/components/feedback/Modal.md +656 -24
- package/dist/components/feedback/llms.txt +1 -1
- package/dist/components/inputs/Autocomplete.md +734 -2
- package/dist/components/inputs/Calendar.md +655 -1
- package/dist/components/inputs/DatePicker.md +699 -3
- package/dist/components/inputs/DateRangePicker.md +815 -1
- package/dist/components/inputs/MonthPicker.md +626 -4
- package/dist/components/inputs/MonthRangePicker.md +682 -4
- package/dist/components/inputs/Select.md +600 -0
- package/dist/components/layout/Container.md +507 -0
- package/dist/components/navigation/Breadcrumbs.md +582 -0
- package/dist/components/navigation/IconMenuButton.md +693 -0
- package/dist/components/navigation/InsetDrawer.md +1150 -3
- package/dist/components/navigation/Link.md +526 -0
- package/dist/components/navigation/MenuButton.md +632 -0
- package/dist/components/navigation/NavigationGroup.md +401 -1
- package/dist/components/navigation/NavigationItem.md +311 -0
- package/dist/components/navigation/Navigator.md +373 -0
- package/dist/components/navigation/Pagination.md +521 -0
- package/dist/components/navigation/ProfileMenu.md +605 -0
- package/dist/components/navigation/Tabs.md +609 -7
- package/dist/components/surfaces/Accordions.md +947 -3
- package/dist/llms.txt +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
+
NavigationGroup is an expandable container for organizing related navigation items in a sidebar. Built on Joy UI's Accordion component, it provides a collapsible section that can hold NavigationItems or nested Navigator components. NavigationGroup creates hierarchical navigation structures where users can expand and collapse sections to access nested items.
|
|
6
|
+
|
|
5
7
|
```text
|
|
6
8
|
// Unable to derive source for Default
|
|
7
9
|
```
|
|
@@ -13,5 +15,403 @@
|
|
|
13
15
|
## Usage
|
|
14
16
|
|
|
15
17
|
```tsx
|
|
16
|
-
import { NavigationGroup } from '@ceed/ads';
|
|
18
|
+
import { NavigationGroup, NavigationItem } from '@ceed/ads';
|
|
19
|
+
|
|
20
|
+
function Sidebar() {
|
|
21
|
+
return (
|
|
22
|
+
<NavigationGroup
|
|
23
|
+
title="User Management"
|
|
24
|
+
startDecorator={<PeopleIcon />}
|
|
25
|
+
defaultExpanded={true}
|
|
26
|
+
>
|
|
27
|
+
<NavigationItem id="users" level={1}>All Users</NavigationItem>
|
|
28
|
+
<NavigationItem id="roles" level={1}>Roles</NavigationItem>
|
|
29
|
+
<NavigationItem id="permissions" level={1}>Permissions</NavigationItem>
|
|
30
|
+
</NavigationGroup>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
### Default
|
|
38
|
+
|
|
39
|
+
Basic navigation group with a title and content.
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
// Unable to derive source for Default
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Nesting Levels
|
|
46
|
+
|
|
47
|
+
NavigationGroup supports different indentation levels for nested hierarchies.
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
// Unable to derive source for Level1
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
// Unable to derive source for Level2
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### With Start Decorator
|
|
58
|
+
|
|
59
|
+
Add an icon before the group title.
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
// Unable to derive source for WithStartDecorator
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Levels with Icons
|
|
66
|
+
|
|
67
|
+
Icons work at any nesting level.
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
// Unable to derive source for Level1WithStartDecorator
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
// Unable to derive source for Level2WithStartDecorator
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## When to Use
|
|
78
|
+
|
|
79
|
+
### ✅ Good Use Cases
|
|
80
|
+
|
|
81
|
+
- **Collapsible sidebar sections**: Organize navigation into expandable categories
|
|
82
|
+
- **Deep navigation hierarchies**: Group related items under collapsible headers
|
|
83
|
+
- **Admin interfaces**: Organize modules and sub-modules
|
|
84
|
+
- **Settings organization**: Group related settings under categories
|
|
85
|
+
- **File system navigation**: Folders containing nested items
|
|
86
|
+
|
|
87
|
+
### ❌ When Not to Use
|
|
88
|
+
|
|
89
|
+
- **Flat navigation**: When all items are at the same level
|
|
90
|
+
- **Tab-like navigation**: Use Tabs for switching between views
|
|
91
|
+
- **Simple menus**: For 5 or fewer items, consider flat NavigationItems
|
|
92
|
+
- **Modal dialogs**: Use proper modal patterns instead
|
|
93
|
+
- **Accordion content**: For non-navigation accordions, use Accordion directly
|
|
94
|
+
|
|
95
|
+
## Common Use Cases
|
|
96
|
+
|
|
97
|
+
### Admin Module Navigation
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
function AdminNavigation() {
|
|
101
|
+
return (
|
|
102
|
+
<>
|
|
103
|
+
<NavigationGroup
|
|
104
|
+
title="User Management"
|
|
105
|
+
startDecorator={<PeopleIcon />}
|
|
106
|
+
defaultExpanded={true}
|
|
107
|
+
>
|
|
108
|
+
<NavigationItem id="users" level={1}>
|
|
109
|
+
All Users
|
|
110
|
+
</NavigationItem>
|
|
111
|
+
<NavigationItem id="invite" level={1}>
|
|
112
|
+
Invite User
|
|
113
|
+
</NavigationItem>
|
|
114
|
+
<NavigationItem id="roles" level={1}>
|
|
115
|
+
Roles & Permissions
|
|
116
|
+
</NavigationItem>
|
|
117
|
+
</NavigationGroup>
|
|
118
|
+
|
|
119
|
+
<NavigationGroup
|
|
120
|
+
title="Content"
|
|
121
|
+
startDecorator={<ArticleIcon />}
|
|
122
|
+
>
|
|
123
|
+
<NavigationItem id="posts" level={1}>
|
|
124
|
+
Posts
|
|
125
|
+
</NavigationItem>
|
|
126
|
+
<NavigationItem id="categories" level={1}>
|
|
127
|
+
Categories
|
|
128
|
+
</NavigationItem>
|
|
129
|
+
<NavigationItem id="media" level={1}>
|
|
130
|
+
Media Library
|
|
131
|
+
</NavigationItem>
|
|
132
|
+
</NavigationGroup>
|
|
133
|
+
|
|
134
|
+
<NavigationGroup
|
|
135
|
+
title="Settings"
|
|
136
|
+
startDecorator={<SettingsIcon />}
|
|
137
|
+
>
|
|
138
|
+
<NavigationItem id="general" level={1}>
|
|
139
|
+
General
|
|
140
|
+
</NavigationItem>
|
|
141
|
+
<NavigationItem id="security" level={1}>
|
|
142
|
+
Security
|
|
143
|
+
</NavigationItem>
|
|
144
|
+
<NavigationItem id="integrations" level={1}>
|
|
145
|
+
Integrations
|
|
146
|
+
</NavigationItem>
|
|
147
|
+
</NavigationGroup>
|
|
148
|
+
</>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Nested Groups
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
function NestedNavigation() {
|
|
157
|
+
return (
|
|
158
|
+
<NavigationGroup
|
|
159
|
+
title="E-commerce"
|
|
160
|
+
startDecorator={<ShoppingCartIcon />}
|
|
161
|
+
defaultExpanded={true}
|
|
162
|
+
>
|
|
163
|
+
<NavigationItem id="dashboard" level={1}>
|
|
164
|
+
Dashboard
|
|
165
|
+
</NavigationItem>
|
|
166
|
+
|
|
167
|
+
<NavigationGroup
|
|
168
|
+
title="Products"
|
|
169
|
+
level={1}
|
|
170
|
+
defaultExpanded={true}
|
|
171
|
+
>
|
|
172
|
+
<NavigationItem id="all-products" level={2}>
|
|
173
|
+
All Products
|
|
174
|
+
</NavigationItem>
|
|
175
|
+
<NavigationItem id="add-product" level={2}>
|
|
176
|
+
Add Product
|
|
177
|
+
</NavigationItem>
|
|
178
|
+
<NavigationItem id="categories" level={2}>
|
|
179
|
+
Categories
|
|
180
|
+
</NavigationItem>
|
|
181
|
+
</NavigationGroup>
|
|
182
|
+
|
|
183
|
+
<NavigationGroup
|
|
184
|
+
title="Orders"
|
|
185
|
+
level={1}
|
|
186
|
+
>
|
|
187
|
+
<NavigationItem id="all-orders" level={2}>
|
|
188
|
+
All Orders
|
|
189
|
+
</NavigationItem>
|
|
190
|
+
<NavigationItem id="pending" level={2}>
|
|
191
|
+
Pending
|
|
192
|
+
</NavigationItem>
|
|
193
|
+
<NavigationItem id="completed" level={2}>
|
|
194
|
+
Completed
|
|
195
|
+
</NavigationItem>
|
|
196
|
+
</NavigationGroup>
|
|
197
|
+
</NavigationGroup>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Documentation Sidebar
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
function DocsSidebar({ sections, currentPath }) {
|
|
206
|
+
return (
|
|
207
|
+
<nav>
|
|
208
|
+
{sections.map((section) => (
|
|
209
|
+
<NavigationGroup
|
|
210
|
+
key={section.id}
|
|
211
|
+
title={section.title}
|
|
212
|
+
startDecorator={<BookIcon />}
|
|
213
|
+
defaultExpanded={currentPath.startsWith(section.basePath)}
|
|
214
|
+
>
|
|
215
|
+
{section.pages.map((page) => (
|
|
216
|
+
<NavigationItem
|
|
217
|
+
key={page.id}
|
|
218
|
+
id={page.id}
|
|
219
|
+
level={1}
|
|
220
|
+
selected={currentPath === page.path}
|
|
221
|
+
onClick={() => navigate(page.path)}
|
|
222
|
+
>
|
|
223
|
+
{page.title}
|
|
224
|
+
</NavigationItem>
|
|
225
|
+
))}
|
|
226
|
+
</NavigationGroup>
|
|
227
|
+
))}
|
|
228
|
+
</nav>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
17
231
|
```
|
|
232
|
+
|
|
233
|
+
## Props and Customization
|
|
234
|
+
|
|
235
|
+
### Key Props
|
|
236
|
+
|
|
237
|
+
| Prop | Type | Default | Description |
|
|
238
|
+
| ----------------- | --------------------- | ------- | ----------------------------- |
|
|
239
|
+
| `title` | `string \| ReactNode` | - | Group header title |
|
|
240
|
+
| `children` | `ReactNode` | - | Content shown when expanded |
|
|
241
|
+
| `startDecorator` | `ReactNode` | - | Icon before the title |
|
|
242
|
+
| `level` | `number` | `0` | Nesting level for indentation |
|
|
243
|
+
| `defaultExpanded` | `boolean` | `false` | Initial expanded state |
|
|
244
|
+
|
|
245
|
+
### Accordion Props
|
|
246
|
+
|
|
247
|
+
NavigationGroup extends Joy UI's Accordion, so you can use additional Accordion props:
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
<NavigationGroup
|
|
251
|
+
title="Settings"
|
|
252
|
+
expanded={isExpanded}
|
|
253
|
+
onChange={(event, expanded) => setIsExpanded(expanded)}
|
|
254
|
+
>
|
|
255
|
+
{/* Content */}
|
|
256
|
+
</NavigationGroup>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Custom Styling
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
<NavigationGroup
|
|
263
|
+
title="Custom Section"
|
|
264
|
+
sx={{
|
|
265
|
+
'& .NavigationGroup-Summary': {
|
|
266
|
+
fontWeight: 600,
|
|
267
|
+
},
|
|
268
|
+
'& .NavigationGroup-Details': {
|
|
269
|
+
backgroundColor: 'background.level2',
|
|
270
|
+
},
|
|
271
|
+
}}
|
|
272
|
+
>
|
|
273
|
+
{/* Content */}
|
|
274
|
+
</NavigationGroup>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Accessibility
|
|
278
|
+
|
|
279
|
+
NavigationGroup leverages Joy UI's Accordion accessibility features:
|
|
280
|
+
|
|
281
|
+
### ARIA Attributes
|
|
282
|
+
|
|
283
|
+
- `role="button"` on the expandable header
|
|
284
|
+
- `aria-expanded` indicates the current state
|
|
285
|
+
- `aria-controls` links header to content
|
|
286
|
+
- Content region has proper `role="region"`
|
|
287
|
+
|
|
288
|
+
### Keyboard Navigation
|
|
289
|
+
|
|
290
|
+
- **Tab**: Focus the group header
|
|
291
|
+
- **Enter/Space**: Toggle expanded state
|
|
292
|
+
- **Arrow Down**: Move to first item when expanded
|
|
293
|
+
- **Arrow Up**: Move to header from first item
|
|
294
|
+
|
|
295
|
+
### Screen Reader Support
|
|
296
|
+
|
|
297
|
+
```tsx
|
|
298
|
+
// Expansion state is announced
|
|
299
|
+
<NavigationGroup title="Settings" defaultExpanded={true}>
|
|
300
|
+
{/* "Settings, expanded, button" */}
|
|
301
|
+
</NavigationGroup>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Best Practices
|
|
305
|
+
|
|
306
|
+
### ✅ Do
|
|
307
|
+
|
|
308
|
+
1. **Use descriptive titles**: Group titles should clearly indicate the content category
|
|
309
|
+
|
|
310
|
+
```tsx
|
|
311
|
+
// ✅ Good: Descriptive title
|
|
312
|
+
<NavigationGroup title="User Management">
|
|
313
|
+
|
|
314
|
+
// ❌ Bad: Vague title
|
|
315
|
+
<NavigationGroup title="More">
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
2. **Expand active sections**: Auto-expand groups containing the current page
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
<NavigationGroup
|
|
322
|
+
title="Products"
|
|
323
|
+
defaultExpanded={currentPath.startsWith('/products')}
|
|
324
|
+
>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
3. **Limit group children**: Keep 3-7 items per group for easy scanning
|
|
328
|
+
|
|
329
|
+
4. **Use consistent icons**: If using icons, apply them to all groups
|
|
330
|
+
|
|
331
|
+
### ❌ Don't
|
|
332
|
+
|
|
333
|
+
1. **Don't over-nest**: Maximum 2-3 levels of nesting
|
|
334
|
+
|
|
335
|
+
```tsx
|
|
336
|
+
// ❌ Bad: Too deep
|
|
337
|
+
<NavigationGroup>
|
|
338
|
+
<NavigationGroup level={1}>
|
|
339
|
+
<NavigationGroup level={2}>
|
|
340
|
+
<NavigationGroup level={3}> {/* Too deep */}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
2. **Don't mix patterns**: Be consistent with structure across all groups
|
|
344
|
+
|
|
345
|
+
3. **Don't put actions in groups**: Navigation only, not buttons or forms
|
|
346
|
+
|
|
347
|
+
4. **Don't hide critical navigation**: Important items should be easily discoverable
|
|
348
|
+
|
|
349
|
+
## Performance Considerations
|
|
350
|
+
|
|
351
|
+
### Lazy Load Content
|
|
352
|
+
|
|
353
|
+
For groups with heavy content, consider lazy loading:
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
function LazyNavigationGroup({ title, loadContent }) {
|
|
357
|
+
const [expanded, setExpanded] = useState(false);
|
|
358
|
+
const [content, setContent] = useState(null);
|
|
359
|
+
|
|
360
|
+
const handleChange = async (event, isExpanded) => {
|
|
361
|
+
setExpanded(isExpanded);
|
|
362
|
+
if (isExpanded && !content) {
|
|
363
|
+
const loadedContent = await loadContent();
|
|
364
|
+
setContent(loadedContent);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
<NavigationGroup
|
|
370
|
+
title={title}
|
|
371
|
+
expanded={expanded}
|
|
372
|
+
onChange={handleChange}
|
|
373
|
+
>
|
|
374
|
+
{content || <Skeleton />}
|
|
375
|
+
</NavigationGroup>
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Controlled Expansion
|
|
381
|
+
|
|
382
|
+
For complex navigation, control expansion at the parent level:
|
|
383
|
+
|
|
384
|
+
```tsx
|
|
385
|
+
function SidebarNavigation() {
|
|
386
|
+
const [expandedGroups, setExpandedGroups] = useState(['products']);
|
|
387
|
+
|
|
388
|
+
const handleGroupChange = (groupId) => (event, isExpanded) => {
|
|
389
|
+
setExpandedGroups((prev) =>
|
|
390
|
+
isExpanded
|
|
391
|
+
? [...prev, groupId]
|
|
392
|
+
: prev.filter((id) => id !== groupId)
|
|
393
|
+
);
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
return (
|
|
397
|
+
<>
|
|
398
|
+
<NavigationGroup
|
|
399
|
+
title="Products"
|
|
400
|
+
expanded={expandedGroups.includes('products')}
|
|
401
|
+
onChange={handleGroupChange('products')}
|
|
402
|
+
>
|
|
403
|
+
{/* Items */}
|
|
404
|
+
</NavigationGroup>
|
|
405
|
+
<NavigationGroup
|
|
406
|
+
title="Orders"
|
|
407
|
+
expanded={expandedGroups.includes('orders')}
|
|
408
|
+
onChange={handleGroupChange('orders')}
|
|
409
|
+
>
|
|
410
|
+
{/* Items */}
|
|
411
|
+
</NavigationGroup>
|
|
412
|
+
</>
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
NavigationGroup provides the structure for organizing hierarchical sidebar navigation. Combine it with NavigationItem for individual links, or use it within Navigator for a complete navigation solution.
|