@ceed/ads 1.29.1 → 1.30.0-next.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/CurrencyInput/CurrencyInput.d.ts +1 -1
- package/dist/components/CurrencyInput/hooks/use-currency-setting.d.ts +2 -2
- package/dist/components/ProfileMenu/ProfileMenu.d.ts +1 -1
- package/dist/components/SearchBar/SearchBar.d.ts +21 -0
- package/dist/components/SearchBar/index.d.ts +3 -0
- package/dist/components/data-display/Badge.md +39 -71
- package/dist/components/data-display/DataTable.md +1 -1
- package/dist/components/data-display/InfoSign.md +98 -74
- package/dist/components/data-display/Typography.md +97 -363
- package/dist/components/feedback/Dialog.md +62 -76
- package/dist/components/feedback/Modal.md +44 -259
- package/dist/components/feedback/llms.txt +0 -2
- package/dist/components/index.d.ts +2 -0
- package/dist/components/inputs/Autocomplete.md +107 -356
- package/dist/components/inputs/ButtonGroup.md +106 -115
- package/dist/components/inputs/Calendar.md +459 -98
- 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/FilterMenu.md +19 -169
- package/dist/components/inputs/FilterableCheckboxGroup.md +23 -123
- package/dist/components/inputs/IconButton.md +88 -137
- package/dist/components/inputs/Input.md +0 -5
- 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/RadioTileGroup.md +61 -150
- package/dist/components/inputs/SearchBar.md +44 -0
- package/dist/components/inputs/Select.md +326 -222
- package/dist/components/inputs/Switch.md +376 -136
- package/dist/components/inputs/Textarea.md +10 -213
- package/dist/components/inputs/Uploader/Uploader.md +66 -145
- package/dist/components/inputs/llms.txt +1 -3
- package/dist/components/navigation/Breadcrumbs.md +322 -80
- package/dist/components/navigation/Dropdown.md +221 -92
- package/dist/components/navigation/IconMenuButton.md +502 -40
- package/dist/components/navigation/InsetDrawer.md +738 -68
- package/dist/components/navigation/Link.md +298 -39
- 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/ProfileMenu.md +268 -45
- package/dist/components/navigation/Stepper.md +28 -160
- package/dist/components/navigation/Tabs.md +316 -57
- package/dist/components/surfaces/Sheet.md +334 -151
- package/dist/index.browser.js +15 -13
- package/dist/index.browser.js.map +4 -4
- package/dist/index.cjs +289 -288
- package/dist/index.d.ts +1 -1
- package/dist/index.js +426 -369
- package/dist/llms.txt +1 -8
- package/framer/index.js +1 -1
- package/package.json +16 -15
- package/dist/chunks/rehype-accent-FZRUD7VI.js +0 -39
- 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/Slider.md +0 -334
- package/dist/guides/ThemeProvider.md +0 -116
- package/dist/guides/llms.txt +0 -9
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
The Breadcrumbs component displays a navigation trail that helps users understand their current location within a
|
|
6
|
-
|
|
7
|
-
Breadcrumbs are essential for sites with deep navigation hierarchies -- they provide context at a glance, reduce the number of steps needed to return to higher-level pages, and improve overall wayfinding within an application.
|
|
5
|
+
The Breadcrumbs component displays a navigation trail that helps users understand their current location within a website's hierarchy and navigate back to previous levels. It shows the path from the homepage to the current page, with each level represented as a clickable link (except for the current page). Breadcrumbs improve user experience by providing context and enabling quick navigation.
|
|
8
6
|
|
|
9
7
|
```tsx
|
|
10
8
|
<Breadcrumbs
|
|
@@ -58,18 +56,18 @@ function MyComponent() {
|
|
|
58
56
|
{ label: 'Home', type: 'link', linkHref: '/' },
|
|
59
57
|
{ label: 'Products', type: 'link', linkHref: '/products' },
|
|
60
58
|
{ label: 'Electronics', type: 'link', linkHref: '/products/electronics' },
|
|
61
|
-
{ label: 'Laptops', type: 'text' },
|
|
59
|
+
{ label: 'Laptops', type: 'text' }, // Current page (not a link)
|
|
62
60
|
];
|
|
63
61
|
|
|
64
62
|
return <Breadcrumbs crumbs={crumbs} />;
|
|
65
63
|
}
|
|
66
64
|
```
|
|
67
65
|
|
|
68
|
-
##
|
|
66
|
+
## Examples
|
|
69
67
|
|
|
70
68
|
### Basic Breadcrumbs
|
|
71
69
|
|
|
72
|
-
A simple breadcrumb
|
|
70
|
+
A simple breadcrumb navigation with three levels.
|
|
73
71
|
|
|
74
72
|
```tsx
|
|
75
73
|
<Breadcrumbs
|
|
@@ -91,7 +89,7 @@ A simple breadcrumb trail with a few levels of hierarchy. The last item uses `ty
|
|
|
91
89
|
|
|
92
90
|
### Sizes
|
|
93
91
|
|
|
94
|
-
Breadcrumbs
|
|
92
|
+
Breadcrumbs support different sizes.
|
|
95
93
|
|
|
96
94
|
```tsx
|
|
97
95
|
<div>
|
|
@@ -101,9 +99,9 @@ Breadcrumbs are available in three sizes -- `sm`, `md`, and `lg` -- allowing you
|
|
|
101
99
|
</div>
|
|
102
100
|
```
|
|
103
101
|
|
|
104
|
-
### Custom Separator
|
|
102
|
+
### With Custom Separator
|
|
105
103
|
|
|
106
|
-
|
|
104
|
+
Customize the separator between breadcrumb items.
|
|
107
105
|
|
|
108
106
|
```tsx
|
|
109
107
|
<div style={{
|
|
@@ -152,7 +150,45 @@ The separator character between items can be customized via the `separator` prop
|
|
|
152
150
|
|
|
153
151
|
### Collapsed Breadcrumbs
|
|
154
152
|
|
|
155
|
-
|
|
153
|
+
For deep hierarchies, breadcrumbs can be collapsed with an ellipsis.
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
<Breadcrumbs
|
|
157
|
+
crumbs={[{
|
|
158
|
+
label: 'Home',
|
|
159
|
+
type: 'link',
|
|
160
|
+
linkHref: '/'
|
|
161
|
+
}, {
|
|
162
|
+
label: 'Catalog',
|
|
163
|
+
type: 'link',
|
|
164
|
+
linkHref: '/'
|
|
165
|
+
}, {
|
|
166
|
+
label: 'Category',
|
|
167
|
+
type: 'link',
|
|
168
|
+
linkHref: '/'
|
|
169
|
+
}, {
|
|
170
|
+
label: 'Subcategory',
|
|
171
|
+
type: 'link',
|
|
172
|
+
linkHref: '/'
|
|
173
|
+
}, {
|
|
174
|
+
label: 'Product',
|
|
175
|
+
type: 'link',
|
|
176
|
+
linkHref: '/'
|
|
177
|
+
}, {
|
|
178
|
+
label: 'Product Detail',
|
|
179
|
+
type: 'link',
|
|
180
|
+
linkHref: '/'
|
|
181
|
+
}, {
|
|
182
|
+
label: 'Owner',
|
|
183
|
+
type: 'text'
|
|
184
|
+
}]}
|
|
185
|
+
collapsed
|
|
186
|
+
/>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Collapsed Variants
|
|
190
|
+
|
|
191
|
+
Configure how many items show at the start and end when collapsed.
|
|
156
192
|
|
|
157
193
|
```tsx
|
|
158
194
|
<div style={{
|
|
@@ -215,9 +251,23 @@ When paths are deep, the component automatically collapses middle items behind a
|
|
|
215
251
|
</div>
|
|
216
252
|
```
|
|
217
253
|
|
|
254
|
+
### Single Crumb
|
|
255
|
+
|
|
256
|
+
When there's only one item in the path.
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
<Breadcrumbs
|
|
260
|
+
crumbs={[{
|
|
261
|
+
label: 'Home',
|
|
262
|
+
type: 'text'
|
|
263
|
+
}]}
|
|
264
|
+
collapsed
|
|
265
|
+
/>
|
|
266
|
+
```
|
|
267
|
+
|
|
218
268
|
### Expanded View
|
|
219
269
|
|
|
220
|
-
|
|
270
|
+
Show all breadcrumb items without collapsing.
|
|
221
271
|
|
|
222
272
|
```tsx
|
|
223
273
|
<Breadcrumbs
|
|
@@ -253,80 +303,105 @@ Setting `collapsed={false}` renders every item in the path without collapsing.
|
|
|
253
303
|
/>
|
|
254
304
|
```
|
|
255
305
|
|
|
256
|
-
|
|
306
|
+
## When to Use
|
|
257
307
|
|
|
258
|
-
|
|
308
|
+
### ✅ Good Use Cases
|
|
259
309
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
collapsed
|
|
267
|
-
/>
|
|
268
|
-
```
|
|
310
|
+
- **Deep hierarchies**: Sites with 3+ levels of navigation depth
|
|
311
|
+
- **E-commerce sites**: Product category → subcategory → product navigation
|
|
312
|
+
- **Documentation sites**: Section → topic → article navigation
|
|
313
|
+
- **File management**: Folder → subfolder → file navigation
|
|
314
|
+
- **Admin dashboards**: Module → submodule → detail view
|
|
315
|
+
- **Content management**: Categories and nested content structures
|
|
269
316
|
|
|
270
|
-
###
|
|
317
|
+
### ❌ When Not to Use
|
|
271
318
|
|
|
272
|
-
|
|
319
|
+
- **Flat sites**: Single-level navigation doesn't need breadcrumbs
|
|
320
|
+
- **Linear flows**: For sequential processes, use Stepper instead
|
|
321
|
+
- **Primary navigation**: Breadcrumbs supplement, not replace, main navigation
|
|
322
|
+
- **Mobile-first**: Consider if space allows; may need alternative patterns
|
|
323
|
+
- **Dynamic content**: When paths frequently change or are user-specific
|
|
324
|
+
|
|
325
|
+
## Common Use Cases
|
|
326
|
+
|
|
327
|
+
### E-commerce Product Page
|
|
273
328
|
|
|
274
329
|
```tsx
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
330
|
+
function ProductPage({ product, category, subcategory }) {
|
|
331
|
+
const crumbs = [
|
|
332
|
+
{ label: 'Home', type: 'link', linkHref: '/' },
|
|
333
|
+
{ label: 'Shop', type: 'link', linkHref: '/shop' },
|
|
334
|
+
{ label: category.name, type: 'link', linkHref: `/shop/${category.slug}` },
|
|
335
|
+
{ label: subcategory.name, type: 'link', linkHref: `/shop/${category.slug}/${subcategory.slug}` },
|
|
336
|
+
{ label: product.name, type: 'text' },
|
|
337
|
+
];
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<Box>
|
|
341
|
+
<Breadcrumbs crumbs={crumbs} />
|
|
342
|
+
<ProductDetails product={product} />
|
|
343
|
+
</Box>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
287
346
|
```
|
|
288
347
|
|
|
289
|
-
|
|
348
|
+
### Documentation Page
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
function DocPage({ section, topic, article }) {
|
|
352
|
+
const crumbs = [
|
|
353
|
+
{ label: 'Docs', type: 'link', linkHref: '/docs' },
|
|
354
|
+
{ label: section.title, type: 'link', linkHref: `/docs/${section.slug}` },
|
|
355
|
+
{ label: topic.title, type: 'link', linkHref: `/docs/${section.slug}/${topic.slug}` },
|
|
356
|
+
{ label: article.title, type: 'text' },
|
|
357
|
+
];
|
|
358
|
+
|
|
359
|
+
return (
|
|
360
|
+
<Stack spacing={2}>
|
|
361
|
+
<Breadcrumbs crumbs={crumbs} size="sm" />
|
|
362
|
+
<Typography level="h1">{article.title}</Typography>
|
|
363
|
+
<ArticleContent content={article.content} />
|
|
364
|
+
</Stack>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
```
|
|
290
368
|
|
|
291
|
-
###
|
|
369
|
+
### File Browser
|
|
292
370
|
|
|
293
371
|
```tsx
|
|
294
|
-
function
|
|
372
|
+
function FileBrowser({ path }) {
|
|
295
373
|
const crumbs = [
|
|
296
|
-
{ label: '
|
|
297
|
-
|
|
298
|
-
|
|
374
|
+
{ label: 'Root', type: 'link', linkHref: '/files' },
|
|
375
|
+
...path.map((folder, index) => ({
|
|
376
|
+
label: folder.name,
|
|
377
|
+
type: index === path.length - 1 ? 'text' : 'link',
|
|
378
|
+
linkHref: `/files/${path.slice(0, index + 1).map(f => f.id).join('/')}`,
|
|
379
|
+
})),
|
|
299
380
|
];
|
|
300
381
|
|
|
301
382
|
return (
|
|
302
383
|
<Box>
|
|
303
|
-
<Breadcrumbs crumbs={crumbs} />
|
|
304
|
-
<
|
|
384
|
+
<Breadcrumbs crumbs={crumbs} collapsed={path.length > 4} />
|
|
385
|
+
<FileList folderId={path[path.length - 1].id} />
|
|
305
386
|
</Box>
|
|
306
387
|
);
|
|
307
388
|
}
|
|
308
389
|
```
|
|
309
390
|
|
|
310
|
-
###
|
|
391
|
+
### Admin Dashboard
|
|
311
392
|
|
|
312
393
|
```tsx
|
|
313
|
-
function
|
|
394
|
+
function UserDetailPage({ user }) {
|
|
314
395
|
const crumbs = [
|
|
315
|
-
{ label: '
|
|
316
|
-
{ label: '
|
|
317
|
-
{ label:
|
|
318
|
-
{
|
|
319
|
-
label: subcategory.name,
|
|
320
|
-
type: 'link',
|
|
321
|
-
linkHref: `/shop/${category.slug}/${subcategory.slug}`,
|
|
322
|
-
},
|
|
323
|
-
{ label: product.name, type: 'text' },
|
|
396
|
+
{ label: 'Dashboard', type: 'link', linkHref: '/admin' },
|
|
397
|
+
{ label: 'Users', type: 'link', linkHref: '/admin/users' },
|
|
398
|
+
{ label: user.name, type: 'text' },
|
|
324
399
|
];
|
|
325
400
|
|
|
326
401
|
return (
|
|
327
402
|
<Box>
|
|
328
|
-
<Breadcrumbs crumbs={crumbs}
|
|
329
|
-
<
|
|
403
|
+
<Breadcrumbs crumbs={crumbs} />
|
|
404
|
+
<UserProfile user={user} />
|
|
330
405
|
</Box>
|
|
331
406
|
);
|
|
332
407
|
}
|
|
@@ -337,55 +412,222 @@ function ProductPage({ product, category, subcategory }) {
|
|
|
337
412
|
```tsx
|
|
338
413
|
function DynamicBreadcrumbs() {
|
|
339
414
|
const location = useLocation();
|
|
340
|
-
const pathnames = location.pathname.split('/').filter(
|
|
415
|
+
const pathnames = location.pathname.split('/').filter((x) => x);
|
|
341
416
|
|
|
342
417
|
const crumbs = [
|
|
343
418
|
{ label: 'Home', type: 'link', linkHref: '/' },
|
|
344
|
-
...pathnames.map((value, index) =>
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
419
|
+
...pathnames.map((value, index) => {
|
|
420
|
+
const href = `/${pathnames.slice(0, index + 1).join('/')}`;
|
|
421
|
+
const isLast = index === pathnames.length - 1;
|
|
422
|
+
|
|
423
|
+
return {
|
|
424
|
+
label: formatLabel(value),
|
|
425
|
+
type: isLast ? 'text' : 'link',
|
|
426
|
+
linkHref: href,
|
|
427
|
+
};
|
|
428
|
+
}),
|
|
349
429
|
];
|
|
350
430
|
|
|
351
431
|
return <Breadcrumbs crumbs={crumbs} />;
|
|
352
432
|
}
|
|
353
433
|
```
|
|
354
434
|
|
|
435
|
+
## Props and Customization
|
|
436
|
+
|
|
437
|
+
### Key Props
|
|
438
|
+
|
|
439
|
+
| Prop | Type | Default | Description |
|
|
440
|
+
| ----------------- | ---------------------- | ------- | ----------------------------------------------- |
|
|
441
|
+
| `crumbs` | `Crumb[]` | `[]` | Array of breadcrumb items |
|
|
442
|
+
| `collapsed` | `boolean` | `true` | Collapse middle items with ellipsis |
|
|
443
|
+
| `startCrumbCount` | `number` | `1` | Number of items to show at start when collapsed |
|
|
444
|
+
| `endCrumbCount` | `number` | `3` | Number of items to show at end when collapsed |
|
|
445
|
+
| `separator` | `string` | `'/'` | Separator between items |
|
|
446
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the breadcrumbs |
|
|
447
|
+
|
|
448
|
+
### Crumb Type
|
|
449
|
+
|
|
450
|
+
```tsx
|
|
451
|
+
interface Crumb {
|
|
452
|
+
label: string; // Display text
|
|
453
|
+
type: 'link' | 'text'; // Link or static text
|
|
454
|
+
linkHref?: string; // URL for link type
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Collapsed Behavior
|
|
459
|
+
|
|
460
|
+
When `collapsed` is true and there are more items than `startCrumbCount + endCrumbCount`, middle items are replaced with an ellipsis:
|
|
461
|
+
|
|
462
|
+
```tsx
|
|
463
|
+
// With startCrumbCount=1, endCrumbCount=2, and 6 crumbs:
|
|
464
|
+
// Home / ... / Category / Product
|
|
465
|
+
|
|
466
|
+
<Breadcrumbs
|
|
467
|
+
crumbs={crumbs}
|
|
468
|
+
collapsed={true}
|
|
469
|
+
startCrumbCount={1}
|
|
470
|
+
endCrumbCount={2}
|
|
471
|
+
/>
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Custom Styling
|
|
475
|
+
|
|
476
|
+
```tsx
|
|
477
|
+
<Breadcrumbs
|
|
478
|
+
crumbs={crumbs}
|
|
479
|
+
sx={{
|
|
480
|
+
'& .MuiBreadcrumbs-separator': {
|
|
481
|
+
mx: 1,
|
|
482
|
+
color: 'neutral.400',
|
|
483
|
+
},
|
|
484
|
+
'& a': {
|
|
485
|
+
color: 'primary.500',
|
|
486
|
+
textDecoration: 'none',
|
|
487
|
+
'&:hover': {
|
|
488
|
+
textDecoration: 'underline',
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
}}
|
|
492
|
+
/>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Accessibility
|
|
496
|
+
|
|
497
|
+
Breadcrumbs include important accessibility features:
|
|
498
|
+
|
|
499
|
+
### Semantic HTML
|
|
500
|
+
|
|
501
|
+
- Uses `<nav>` element with `aria-label="breadcrumb"`
|
|
502
|
+
- Structured as an ordered list (`<ol>`) to indicate sequence
|
|
503
|
+
- Current page marked with `aria-current="page"`
|
|
504
|
+
|
|
505
|
+
### ARIA Attributes
|
|
506
|
+
|
|
507
|
+
```tsx
|
|
508
|
+
// Generated HTML structure
|
|
509
|
+
<nav aria-label="breadcrumb">
|
|
510
|
+
<ol>
|
|
511
|
+
<li><a href="/">Home</a></li>
|
|
512
|
+
<li><a href="/products">Products</a></li>
|
|
513
|
+
<li aria-current="page">Current Page</li>
|
|
514
|
+
</ol>
|
|
515
|
+
</nav>
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Keyboard Navigation
|
|
519
|
+
|
|
520
|
+
- **Tab**: Navigate through breadcrumb links
|
|
521
|
+
- **Enter**: Activate the focused link
|
|
522
|
+
|
|
523
|
+
### Screen Reader Support
|
|
524
|
+
|
|
525
|
+
- Screen readers announce "breadcrumb navigation"
|
|
526
|
+
- Each link is announced with its position in the sequence
|
|
527
|
+
- Current page is identified as the current location
|
|
528
|
+
|
|
529
|
+
### SEO Benefits
|
|
530
|
+
|
|
531
|
+
Breadcrumbs provide:
|
|
532
|
+
|
|
533
|
+
- Clear site structure for search engines
|
|
534
|
+
- Enhanced search result display (rich snippets)
|
|
535
|
+
- Improved internal linking
|
|
536
|
+
|
|
355
537
|
## Best Practices
|
|
356
538
|
|
|
357
|
-
|
|
539
|
+
### ✅ Do
|
|
540
|
+
|
|
541
|
+
1. **Start with Home**: Always begin with a link to the homepage
|
|
358
542
|
|
|
359
543
|
```tsx
|
|
360
|
-
// Good
|
|
544
|
+
// ✅ Good: Starts with Home
|
|
361
545
|
const crumbs = [
|
|
362
546
|
{ label: 'Home', type: 'link', linkHref: '/' },
|
|
363
|
-
{ label: '
|
|
547
|
+
{ label: 'Products', type: 'link', linkHref: '/products' },
|
|
548
|
+
{ label: 'Laptops', type: 'text' },
|
|
364
549
|
];
|
|
365
|
-
|
|
366
|
-
// Bad -- missing root item
|
|
367
|
-
const crumbs = [{ label: 'Settings', type: 'text' }];
|
|
368
550
|
```
|
|
369
551
|
|
|
370
|
-
|
|
552
|
+
2. **Make current page non-clickable**: The last item should be text, not a link
|
|
371
553
|
|
|
372
554
|
```tsx
|
|
373
|
-
// Good
|
|
555
|
+
// ✅ Good: Current page is text
|
|
374
556
|
{ label: 'Current Page', type: 'text' }
|
|
375
557
|
|
|
376
|
-
// Bad
|
|
558
|
+
// ❌ Bad: Current page is a link
|
|
377
559
|
{ label: 'Current Page', type: 'link', linkHref: '/current' }
|
|
378
560
|
```
|
|
379
561
|
|
|
380
|
-
|
|
562
|
+
3. **Use clear, concise labels**: Keep labels short but descriptive
|
|
381
563
|
|
|
382
|
-
|
|
564
|
+
4. **Maintain consistency**: Use the same labels as page titles or navigation
|
|
383
565
|
|
|
384
|
-
|
|
566
|
+
5. **Position at top**: Place breadcrumbs near the top of the page, below the header
|
|
385
567
|
|
|
386
|
-
|
|
568
|
+
### ❌ Don't
|
|
569
|
+
|
|
570
|
+
1. **Don't use as primary navigation**: Breadcrumbs supplement main navigation
|
|
571
|
+
|
|
572
|
+
2. **Don't duplicate with page title**: If the current page title is visible, breadcrumbs can end with the parent
|
|
573
|
+
|
|
574
|
+
```tsx
|
|
575
|
+
// Consider ending at parent if title is displayed
|
|
576
|
+
const crumbs = [
|
|
577
|
+
{ label: 'Home', type: 'link', linkHref: '/' },
|
|
578
|
+
{ label: 'Products', type: 'link', linkHref: '/products' },
|
|
579
|
+
// Omit if "Laptops" is shown as page title
|
|
580
|
+
];
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
3. **Don't use for flat navigation**: Sites with only one or two levels don't need breadcrumbs
|
|
584
|
+
|
|
585
|
+
4. **Don't hide on mobile carelessly**: Either show a simplified version or omit entirely
|
|
586
|
+
|
|
587
|
+
## Performance Considerations
|
|
588
|
+
|
|
589
|
+
### Memoize Crumbs
|
|
590
|
+
|
|
591
|
+
When breadcrumbs are computed from props or state, memoize them:
|
|
592
|
+
|
|
593
|
+
```tsx
|
|
594
|
+
const crumbs = useMemo(() => [
|
|
595
|
+
{ label: 'Home', type: 'link', linkHref: '/' },
|
|
596
|
+
{ label: category.name, type: 'link', linkHref: `/category/${category.id}` },
|
|
597
|
+
{ label: product.name, type: 'text' },
|
|
598
|
+
], [category, product]);
|
|
599
|
+
|
|
600
|
+
<Breadcrumbs crumbs={crumbs} />
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### Use Collapsed for Deep Hierarchies
|
|
604
|
+
|
|
605
|
+
For paths with many levels, use collapsing to reduce DOM elements:
|
|
606
|
+
|
|
607
|
+
```tsx
|
|
608
|
+
<Breadcrumbs
|
|
609
|
+
crumbs={deepHierarchy}
|
|
610
|
+
collapsed={true}
|
|
611
|
+
startCrumbCount={1}
|
|
612
|
+
endCrumbCount={2}
|
|
613
|
+
/>
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### Lazy Load for Dynamic Breadcrumbs
|
|
617
|
+
|
|
618
|
+
If breadcrumb data requires fetching, ensure it doesn't block page render:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
function Page() {
|
|
622
|
+
const { data: breadcrumbData, isLoading } = useBreadcrumbPath();
|
|
623
|
+
|
|
624
|
+
return (
|
|
625
|
+
<Box>
|
|
626
|
+
{!isLoading && <Breadcrumbs crumbs={breadcrumbData} />}
|
|
627
|
+
<PageContent />
|
|
628
|
+
</Box>
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
```
|
|
387
632
|
|
|
388
|
-
|
|
389
|
-
- **Current page indicator**: The last item is automatically marked with `aria-current="page"` so screen readers announce the user's current location.
|
|
390
|
-
- **Keyboard navigation**: All link items are focusable with `Tab` and activated with `Enter`, following standard keyboard interaction patterns.
|
|
391
|
-
- **Screen readers**: The navigation landmark is announced as "breadcrumb navigation" and each link communicates its position within the path hierarchy.
|
|
633
|
+
Breadcrumbs are a simple but powerful navigation aid that helps users understand where they are and navigate efficiently. Use them consistently across your site to improve user experience and SEO.
|