params-xng-breadcrumb-workspace v5.0.3
xng-breadcrumb
A lightweight, declarative and configurable breadcrumbs solution for Angular 6 and beyond. https://www.npmjs.com/package/xng-breadcrumb
About
- In applications with deep navigation hierarchy, it is essential to have breadcrumbs.
- Breadcrumbs easily allow going back to states higher up in the hierarchy.
Demo
Live Demo - A demo app showcasing xng-breadcrumb
usage in an Angular app. Navigate through different links to see breadcrumbs behavior.
Features
✅ Angular Router integration: Just add
<xng-breadcrumb></xng-breadcrumb>
anywhere in the app. Breadcrumb labels will be auto-generated even without any configuration.✅ Map Breadcrumb labels to Routes in Route Config: Define breadcrumbs in Application Route Config itself.
✅ Update labels dynamically: Change breadcrumbs dynamically using
BreadcrumbService.set()
. You can either use route path or breadcrumb alias to change breadcrumb for a route.✅ Skip Breadcrumbs for certain routes: Skip specific routes from displaying in breadcrumbs, conditionally.
✅ Customization: You can the customize breadcrumb template to show icons as label prefix, use pipes on text, add i18n, etc. Separator and Styles can also be customized with ease.
Quickstart
- Install via npm or yarn
npm install --save xng-breadcrumb
//------------- OR --------------
yarn add xng-breadcrumb
- Import 'BreadcrumbModule' in your Application
import {BreadcrumbModule} from 'xng-breadcrumb';
@NgModule({
...
imports: [BreadcrumbModule],
...
})
export class AppModule { }
- Add 'xng-breadcrumb' selector, wherever you plan to show breadcrumbs
<xng-breadcrumb></xng-breadcrumb>
- (Optional) Use BreadcrumbService, if you want to change breadcrumbs behavior(visibility, label, etc) dynamically.
import { BreadcrumbService } from 'xng-breadcrumb';
constructor(private breadcrumbService: BreadcrumbService) {}
// Code examples with BreadcrumbService are given below, under Usage section
🎉🎉 That's it. You should see auto-generated breadcrumbs appearing for each route.
Note: XngBreadcrumb has a peer dependency on @angular/router
. Include RouterModule
in App imports, if you haven't already.
Angular Version Compatibility
xng-breadcrumb | Angular |
---|---|
4.x.x | 6.x, 7.x |
5.x.x | 8.x, 9.x |
Setup Guide
Map Breadcrumb labels to Routes in Route Config
- define 'breadcrumb' within the data property of route.
- a 'breadcrumb' can be defined as a string OR as an object.
- Use breadcrumb as a string if you are just providing breadcrumb text
- Use breadcrumb as an object if you are providing additional properties like 'alias', 'skip', 'info'. In this case, 'label' property denotes breadcrumb text.
breadcrumb as a string
{
path: 'dashboard',
loadChildren: './dashboard/dashboard.module#DashboardModule',
data: { breadcrumb: 'Home' }
},
{
path: 'add',
component: MentorAddComponent,
data: { breadcrumb: 'New' }
}
breadcrumb as an object
{
path: 'dashboard',
loadChildren: './dashboard/dashboard.module#DashboardModule',
data: {
breadcrumb: {
label: 'Home',
info: { mydata: { icon: 'home', iconType: 'material' } }
}
}
},
{
path: 'add',
component: MentorAddComponent,
data: { breadcrumb: { skip: true, alias: 'mentorAdd' } }
}
Update labels dynamically
- Breadcrumb label can be updated based on route path or alias
- For simple routes, route path is enough. Ex:
breadcrumbService.set(<route path> , <breadcrumb label>)
- For long deep routes, you can use alias.
- Create an alias for a route in route config. Prefix alias with '@' while using the set() method. Ex:
breadcrumbService.set(@<alias> , <breadcrumb label>)
Update using route path
{
path: 'mentor',
component: MentorDetailsComponent,
children: [
{
path: ':id',
component: MentorEditComponent
}
]
}
// routepath can contain path and params similary how you defined in routes
breadcrumbService.set('mentor', 'Enabler'); // path for MentorDetailsComponent
breadcrumbService.set('mentor/:id', 'Uday Vunnam'); // path for MentorEditComponent contains param (:id)
Update using alias
{
path: 'mentor',
component: MentorDetailsComponent,
children: [
{
path: ':id',
component: MentorEditComponent
data: {
breadcrumb: {
alias: 'mentorName'
}
}
}
]
}
breadcrumbService.set('@mentorName', 'Uday Vunnam');
Skip Breadcrumbs for certain routes
You can skip a route from displaying in breadcrumbs in two ways
- make 'skip' as true for breadcrumb in route config
breadcrumb: { skip: true }
- Use the 'set()' method and pass second argument as an object with 'skip' as true
skip breadcrumb in route config
{
path: 'edit',
component: MentorEditComponent,
data: { breadcrumb: { skip: true } }
}
skip breadcrumb dynamically
breadcrumbService.set('mentor/:id/edit', { skip: true });
breadcrumbService.set('@mentorName', { skip: true }); // using alias '@mentorName'
//To make a hidden breadcrumb visible.
breadcrumbService.set('mentor/:id/edit', { skip: false });
breadcrumbService.set('@mentorName', { skip: false }); // using alias '@mentorName'
Customization
Custom Breadcrumb template (add icons, change text, add i18n ability, etc)
You can display whatever you want in the place of breadcrumb text by providing a custom template.
- Use *xngBreadcrumbItem directive to provide a custom template
- breadcrumb label is available implicitly in the template context
Change text case
{
path: '',
pathMatch: 'full',
component: HomeComponent,
data: {
breadcrumb: 'app home'
}
}
<xng-breadcrumb>
<ng-container *xngBreadcrumbItem="let breadcrumb">
<ng-container>{{ breadcrumb | titlecase }}</ng-container>
</ng-container>
</xng-breadcrumb>
Add icons in front of label
- define 'info' associated with breadcrumb in route config. 'info' has type . you can pass string or object as you need.
- 'info' is available in the context of *xngBreadcrumbItem.
- Additionally 'first' and 'last' are passed to identify 'first' and 'last' items respectively.
{
path: '',
pathMatch: 'full',
component: HomeComponent,
data: {
breadcrumb: {
label: 'app home',
info: 'home'
}
}
}
<xng-breadcrumb>
<ng-container *xngBreadcrumbItem="let breadcrumb; let info = info; let first = first">
<mat-icon *ngIf="info">{{ info }}</mat-icon>
<ng-container *ngIf="!first">{{ breadcrumb }}</ng-container>
</ng-container>
</xng-breadcrumb>
i18n ability
- Usually, internationalization is achieved in Angular using libraries like ngx-translate or transloco.
- These libraries provide a pipe to change text while language is changed.
- With ngx-translate you can change the language for breadcrumb text as shown below.
<xng-breadcrumb>
<ng-container *xngBreadcrumbItem="let breadcrumb">
<ng-container>{{ breadcrumb | translate }}</ng-container>
</ng-container>
</xng-breadcrumb>
Custom separator
- Breadcrumb uses '/' as the separator by default.
- To use custom separator pass separator as an input to
<xng-breadcrumb>
. - You can either use a simple string(>>, -, -->) or a component (mat-icon, fa-icon) as a separator.
string as separator
<xng-breadcrumb separator=">"></xng-breadcrumb>
icon or component as separator
<xng-breadcrumb [separator]="iconTemplate"></xng-breadcrumb>
<ng-template #iconTemplate>
<mat-icon>arrow_right</mat-icon>
</ng-template>
Custom Breadcrumb Styles
<xng-breadcrumb>
defines the least possible specificity for selectors, to make it easy to override them.- override styles by changing the CSS for corresponding classes. (Keep this styles in app root styles file if you don't want to use ::ng-deep)
- Below are classes visualization to help which class maps to which box
(Optional)xng-breadcrumb takes 'class' as input. This class will be applied to the root of the breadcrumb. This can be used to increase specificity when there are conflicting styles.
.xng-breadcrumb-root {
padding: 8px 16px;
display: inline-block;
border-radius: 4px;
background-color: #e7f1f1;
}
.xng-breadcrumb-separator {
padding: 0 4px;
}
Disable Auto Generation of breadcrumb labels
- Breadcrumbs are integrated with Angular Router and labels are auto-generated(if a label is not provided for a route).
- Auto-generated label is the same as route the path segment.
- If you want to disable this, set
[autoGenerate]=false
.
<xng-breadcrumb [autoGenerate]="false"></xng-breadcrumb>
API
Route Config
property | Description | Type | Default |
---|---|---|---|
breadcrumb | Breadcrumb data provided in App route config | string | Breadcrumb | undefined |
breadcrumb: {alias} | alias name for a route | string | undefined |
breadcrumb: {skip} | whether to skip route from showing in breadcrumbs | boolean | false |
breadcrumb: {info} | arbitrary info for a breadcrumb. | string | object | undefined |
breadcrumb: {label} | same as breadcrumb. Use label when breadcrumb is defined as object | string | undefined |
xng-breadcrumb
property | Description | Type | Default |
---|---|---|---|
separator | input: separator between breadcrumbs | string | TemplateRef<void> | / |
autoGenerate | input:whether to auto generate breacrumb labels | boolean | true |
*xngBreadcrumbItem | directive: to read context in custom breadcrumb templates | NA | NA |
BreadcrumbService.set(pathOrAlias, breadcrumb)
argument | Description | Type |
---|---|---|
pathOrAlias | full route path or alias prefixed with '@' | string |
breadcrumb | breadcrumb data to update for a route | string | Breadcrumb |
Where to define breadcrumbs, if Routes path have same Route specificity
- For the same route path, you can define breadcrumbs either on parent or any descendant with empty path.
- If both are defined, the children take the precedence.
With Component and its Children
// defining breadcrumb on Component Route
{
path: ':userId',
data: { breadcrumb: 'Declaraed on Parent Component' },
children: [
{ path: '', component: ShowUserComponent }
]
}
// defining breadcrumb on children with empty path
{
path: ':userId',
children: [
{ path: '', component: ShowUserComponent, data: { breadcrumb: 'Declaraed on child with empty path' }
]
}
With Module and its Children
// defining breadcrumb on Module route
{ path: 'home', loadChildren: './home/home.module#HomeModule', data: { breadcrumb: 'Declaraed on Parent Module' } }
// Within HomeModule Routes -
{ path: '', pathMatch: 'full', component: HomeComponent, data: { breadcrumb: 'Declaraed on child with empty path' }}
Accessibility
- A
<nav>
witharia-label="breadcrumb"
identifies type of navigation as breadcrumb by screen readers. - The breadcrumb links are structured using an ordered list
<ol>
. - The last
<li>
element represents the current page, so it doesn't have to be clickable. - Separators between links have
aria-hidden=true
. This prevents the screen reader announcement of visual separators.
Local Development
If you wish to contribute to this repository, below are the steps for local development.
- Clone the repository
git clone https://github.com/udayvunnam/xng-breadcrumb.git
- Run
npm install
to install the dependencies - Run
npm start
to build and watch both the library and the demo app. This opens the app athttp://localhost:4200/
automatically.
Build
Run npm run build
to build the library and demo app together. The build artifacts will be stored in the dist/
directory.
This step is used by CircleCI to build both the library and the demo app. After a successful build, a new semantic version of the library is published to npm and the demo app is deployed to Netlify.
Tests
Run ng test
to execute the unit tests via Karma.
Motivation 🎉🎉🎉
You can create your library with complete automated setup for build, tests, and release. Check this blog post for best practices and implementation details of this library blog post