Breadcrumb
Shows the path to the current page in a hierarchy of pages.
- v1.0.0
- SSR
- Zoneless
- 0.7 kB gzip
import { Component } from '@angular/core';
import { NdIcon } from '@ndop/core';
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/ui/breadcrumb/breadcrumb';
/** A trail to the current page, with middle items collapsed. */
@Component({
selector: 'example-breadcrumb-demo',
imports: [
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
NdIcon,
],
template: `
<nav ndBreadcrumb>
<ol ndBreadcrumbList>
<li ndBreadcrumbItem><a ndBreadcrumbLink href="#home">Home</a></li>
<li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li>
<li ndBreadcrumbItem>
<span ndBreadcrumbEllipsis><svg ndIcon="ellipsis"></svg></span>
</li>
<li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li>
<li ndBreadcrumbItem>
<a ndBreadcrumbLink href="#components">Components</a>
</li>
<li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li>
<li ndBreadcrumbItem><span ndBreadcrumbPage>Breadcrumb</span></li>
</ol>
</nav>
`,
})
export class BreadcrumbDemoExample {}
A breadcrumb shows where the current page sits in the site's hierarchy,
with links back up. It's a nav landmark named "Breadcrumb" holding an
ordered list; the last item is the current page, marked
aria-current="page", and separators are hidden from screen readers.
Installation
npx @ndop/cli add breadcrumbpnpm dlx @ndop/cli add breadcrumbyarn dlx @ndop/cli add breadcrumbbunx @ndop/cli add breadcrumbInstall the dependencies
npm install @ndop/corepnpm add @ndop/coreyarn add @ndop/corebun add @ndop/coreCopy the code into your project
At the paths your
ndop.jsonaliases point to; these use the defaults.src/app/ui/breadcrumb/breadcrumb.tsimport { computed, Directive, input } from '@angular/core'; import { cn } from '@/lib/utils'; /** * A breadcrumb trail: the path from the top of a site to the current page, * as a `nav` landmark. * * @example * ```html * <nav ndBreadcrumb> * <ol ndBreadcrumbList> * <li ndBreadcrumbItem><a ndBreadcrumbLink href="/">Home</a></li> * <li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li> * <li ndBreadcrumbItem><span ndBreadcrumbPage>Settings</span></li> * </ol> * </nav> * ``` */ @Directive({ selector: 'nav[ndBreadcrumb]', host: { 'data-slot': 'breadcrumb', '[attr.aria-label]': 'label()' }, }) export class Breadcrumb { /** Name of the landmark. */ readonly label = input('Breadcrumb'); } /** * The ordered list of a breadcrumb's items and separators. * * @example * ```html * <ol ndBreadcrumbList>…</ol> * ``` */ @Directive({ selector: 'ol[ndBreadcrumbList]', host: { 'data-slot': 'breadcrumb-list', '[class]': 'classes()' }, }) export class BreadcrumbList { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn( 'flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5', this.class(), ), ); } /** * One step of a breadcrumb trail. * * @example * ```html * <li ndBreadcrumbItem><a ndBreadcrumbLink href="/docs">Docs</a></li> * ``` */ @Directive({ selector: 'li[ndBreadcrumbItem]', host: { 'data-slot': 'breadcrumb-item', '[class]': 'classes()' }, }) export class BreadcrumbItem { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn('inline-flex items-center gap-1.5', this.class()), ); } /** * A link to an ancestor page. With the router, add `routerLink` to the * same `a`. * * @example * ```html * <a ndBreadcrumbLink routerLink="/docs">Docs</a> * ``` */ @Directive({ selector: 'a[ndBreadcrumbLink]', host: { 'data-slot': 'breadcrumb-link', '[class]': 'classes()' }, }) export class BreadcrumbLink { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn('transition-colors hover:text-foreground', this.class()), ); } /** * The current page, last in the trail: plain text marked * `aria-current="page"`. * * @example * ```html * <span ndBreadcrumbPage>Settings</span> * ``` */ @Directive({ selector: '[ndBreadcrumbPage]', host: { 'data-slot': 'breadcrumb-page', 'aria-current': 'page', '[class]': 'classes()', }, }) export class BreadcrumbPage { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn('font-normal text-foreground', this.class()), ); } /** * The mark between two items, hidden from assistive technology. Put an * icon in it, such as `chevron-right`, which turns around in right-to-left * layouts. * * @example * ```html * <li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li> * ``` */ @Directive({ selector: 'li[ndBreadcrumbSeparator]', host: { 'data-slot': 'breadcrumb-separator', role: 'presentation', 'aria-hidden': 'true', '[class]': 'classes()', }, }) export class BreadcrumbSeparator { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn('[&>svg]:size-3.5', 'rtl:[&>svg]:rotate-180', this.class()), ); } /** * Stands for collapsed items in a long trail. Put an icon in it, such as * `ellipsis`; wrap it in a menu trigger to reveal the hidden items. * * @example * ```html * <span ndBreadcrumbEllipsis><svg ndIcon="ellipsis"></svg></span> * ``` */ @Directive({ selector: '[ndBreadcrumbEllipsis]', host: { 'data-slot': 'breadcrumb-ellipsis', role: 'presentation', 'aria-hidden': 'true', '[class]': 'classes()', }, }) export class BreadcrumbEllipsis { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn( 'flex size-9 items-center justify-center', '[&>svg]:size-4', this.class(), ), ); }src/app/lib/utils.ts/** * Class helpers used by every styled item. They come from `@ndop/core`; * this file is yours, so it is the place to customize them, for example by * wrapping `cn` with an extended tailwind-merge configuration for your own * utilities. * * @packageDocumentation */ export { cn, variants, type ClassValue, type VariantOf } from '@ndop/core';Update the import paths to match your project
The files import each other through the
@/uiand@/libaliases.
Usage
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/ui/breadcrumb/breadcrumb';<nav ndBreadcrumb>
<ol ndBreadcrumbList>
<li ndBreadcrumbItem><a ndBreadcrumbLink href="#home">Home</a></li>
<li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li>
<li ndBreadcrumbItem>
<span ndBreadcrumbEllipsis><svg ndIcon="ellipsis"></svg></span>
</li>
<li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li>
<li ndBreadcrumbItem>
<a ndBreadcrumbLink href="#components">Components</a>
</li>
<li ndBreadcrumbSeparator><svg ndIcon="chevron-right"></svg></li>
<li ndBreadcrumbItem><span ndBreadcrumbPage>Breadcrumb</span></li>
</ol>
</nav>Examples
Breadcrumb separator
A trail with slash separators.
import { Component } from '@angular/core';
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/ui/breadcrumb/breadcrumb';
/** A trail with slashes between the items. */
@Component({
selector: 'example-breadcrumb-separator',
imports: [
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
],
template: `
<nav ndBreadcrumb label="Settings breadcrumb">
<ol ndBreadcrumbList>
<li ndBreadcrumbItem><a ndBreadcrumbLink href="#home">Home</a></li>
<li ndBreadcrumbSeparator>/</li>
<li ndBreadcrumbItem>
<a ndBreadcrumbLink href="#settings">Settings</a>
</li>
<li ndBreadcrumbSeparator>/</li>
<li ndBreadcrumbItem><span ndBreadcrumbPage>Billing</span></li>
</ol>
</nav>
`,
})
export class BreadcrumbSeparatorExample {}
Accessibility
Breadcrumb has no keyboard interaction or focus handling of its own; it keeps the semantics of the element it's on.
API reference
Breadcrumb
nav[ndBreadcrumb]A breadcrumb trail: the path from the top of a site to the current page,
as a nav landmark.
| Breadcrumb binding | Type | Default |
|---|---|---|
[label]Name of the landmark. | string | 'Breadcrumb' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb |
BreadcrumbList
ol[ndBreadcrumbList]The ordered list of a breadcrumb's items and separators.
| BreadcrumbList binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb-list |
BreadcrumbItem
li[ndBreadcrumbItem]One step of a breadcrumb trail.
| BreadcrumbItem binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb-item |
BreadcrumbLink
a[ndBreadcrumbLink]A link to an ancestor page. With the router, add routerLink to the
same a.
| BreadcrumbLink binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb-link |
BreadcrumbPage
[ndBreadcrumbPage]The current page, last in the trail: plain text marked
aria-current="page".
| BreadcrumbPage binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb-page |
BreadcrumbSeparator
li[ndBreadcrumbSeparator]The mark between two items, hidden from assistive technology. Put an
icon in it, such as chevron-right, which turns around in right-to-left
layouts.
| BreadcrumbSeparator binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb-separator |
BreadcrumbEllipsis
[ndBreadcrumbEllipsis]Stands for collapsed items in a long trail. Put an icon in it, such as
ellipsis; wrap it in a menu trigger to reveal the hidden items.
| BreadcrumbEllipsis binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
| Data attribute | Values |
|---|---|
data-slot | breadcrumb-ellipsis |
Agent notes
Do
- Use
nav[ndBreadcrumb]withol[ndBreadcrumbList], andlifor items and separators. - End with
ndBreadcrumbPagefor the current page, as text, not a link. - Put a
chevron-rightor/in each separator; chevrons turn around in right-to-left layouts.
Don't
- Don't use a breadcrumb as the site's main navigation.
- Don't show it on flat sites, where every page sits at the top level.