From fc6e35eb44d7044af711af34b3cba92ce91541af Mon Sep 17 00:00:00 2001 From: Uday Vunnam Date: Tue, 5 Nov 2019 22:54:41 +0530 Subject: [PATCH] docs: update readme with latest features --- README.md | 367 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 260 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index ad17446..138ff84 100644 --- a/README.md +++ b/README.md @@ -12,34 +12,30 @@ ## About -In applications with deep navigation hierarchy, it is essential to have breadcrumb navigation. Breadcrumbs provides links back to each of the previous pages that the user navigated through and shows the current location in an application. - -Breadcrumbs are useful when the App has more than two levels of hierarchy. User can easily navigate back to any level. +In applications with deep navigation hierarchy, it is essential to have breadcrumbs. +Breadcrumbs easily allows going back to states higher up in the hierarchy. ## Demo -[Live Demo](https://xng-breadcrumb.netlify.com) - A demo app showcasing `xng-breadcrumb` library usage in Angular applications. Navigate through App to see the breadcrumb behaviour. Every route has a mapping code block that shows how breadcrumb is configured. +[Live Demo](https://xng-breadcrumb.netlify.com) - A demo app showcasing `xng-breadcrumb` library usage in an Angular app. Navigate through different links to see the breadcrumb behaviour. Every route has a mapping code block that shows how breadcrumb is configured. ![](https://user-images.githubusercontent.com/20707504/65815404-9e031d80-e20c-11e9-9052-0a195da6c244.gif) ## Features -- ✅ **Quickstart with default mapping**: Just add `` anywhere in the App. Breadcrumbs defaults to route segments even without any configuration. -- ✅ **Declarative mapping**: Each route can have an associated breadcrumb. You can define this while declaring App routes. Supports every variety of Angular route declaration. -- ✅ **Dynamic mapping**: Change breadcrumbs dynamically using `BreadcrumbService`. You can either use _route path_ or _breadcrumbAlias_ to access a path. -- ✅ **Skip Breadcrumb**: Skip specific routes from displaying in breadcrumbs, conditionally. -- ✅ **Schematics**: Use schematics to add and update the library with `ng add xng-breadcrumb` and `ng update xng-breadcrumb` +- ✅ **Angular Router Integration**: Just add `` anywhere in the app. Breadcrumb labels will be **auto generated** even without any configuration -### Angular Version Compatiblity +- ✅ **Declarative mapping**: Provide breadcrumb labels for routes in app route config itself. -| xng-breadcrumb | Angular | -| -------------- | -------- | -| 2.x.x | 6.x, 7.x | -| 3.x.x | 8.x, 9.x | +- ✅ **Dynamically update**: Change breadcrumbs dynamically using `BreadcrumbService.set()`. You can either use _route path_ or _breadcrumb alias_ to change breadcrumb for a route. -## Getting Started +- ✅ **Skip Breadcrumb**: Skip specific routes from displaying in breadcrumbs, conditionally. + +- ✅ **Customization**: You can customize breadcrumb template to show icons, use pipes etc. Separator and Styles can also be customized with ease. -1. Install xng-breadcrumb via npm or yarn +## Quick start + +1. Install via npm or yarn ```javascript npm install --save xng-breadcrumb @@ -47,7 +43,7 @@ npm install --save xng-breadcrumb yarn add xng-breadcrumb ``` -2. Import BreadcrumbModule in your Application +2. Import 'BreadcrumbModule' in your Application ```javascript import {BreadcrumbModule} from 'xng-breadcrumb'; @@ -59,13 +55,13 @@ import {BreadcrumbModule} from 'xng-breadcrumb'; export class AppModule { } ``` -3. Add Breadcrumb selector, wherever you plan to show breadcrumbs +3. Add 'xng-breadcrumb' selector, wherever you plan to show breadcrumbs ```html ``` -4. (Optional) Use BreadcrumbService, if you want to alter breadcrumbs behaviour(visibility, label) dynamically. +4. (Optional) Use BreadcrumbService, if you want to alter breadcrumbs behaviour(visibility, label etc) dynamically. ```javascript import { BreadcrumbService } from 'xng-breadcrumb'; @@ -74,19 +70,27 @@ constructor(private breadcrumbService: BreadcrumbService) {} // Code examples with BreadcrumbService are given below, under Usage section ``` +🎉🎉 Now you will 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. - +## Setup Guide -## Usage +#### Defining breadcrumb labels along with Route Configuration -**Define breadcrumb while declaring routes** +- define 'breadcrumb' within data property of route. +- breadcrumb can be provided 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 providng additional properties like 'alias', 'skip', 'info'. In this case 'label' property denotes breadcrumb text. + +**breadcrumb as a string** ```javascript { @@ -101,11 +105,34 @@ ng add xng-breadcrumb } ``` -**Define breadcrumb dynamically, by routepath** +**breadcrumb as an object** + +```javascript +{ + 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 breadcrumb label dynamically + +- Breadcrumb label can be updated based on _route path_ or _alias_ +- For simple routes _route path_ is enough. Ex: `breadcrumbService.set( , )` +- For long deep routes you can use _alias_. +- Create an _alias_ for a route in route config. Prefix alias with '@' while using set method. Ex: `breadcrumbService.set(@ , )` + +**Update using route path** - ```javascript -// Set a breadcrumb dynamically using `BreadcrumbService.set(routepath)` -// routepath can contain path and params similary how you defined in routes { path: 'mentor', component: MentorDetailsComponent, @@ -117,131 +144,255 @@ ng add xng-breadcrumb ] } + +// 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) ``` -**Define breadcrumb dynamically, by breadcrumbAlias** +**Update using alias** ```javascript -// declare `breadcrumbAlias` while defining routes, in order to access it later. -// Set a breadcrumb dynamically using `BreadcrumbService.setForAlias(breadcrumbAlias)` { - path: 'mentor', - component: MentorDetailsComponent, - children: [ - { - path: ':id', - component: MentorEditComponent - data: { - breadcrumbAlias: 'mentorName' - } + path: 'mentor', + component: MentorDetailsComponent, + children: [ + { + path: ':id', + component: MentorEditComponent + data: { + breadcrumb: { + alias: 'mentorName' + } } - ] - + } + ] } -breadcrumbService.setForAlias('mentorName', 'Uday Vunnam'); + +breadcrumbService.set('@mentorName', 'Uday Vunnam'); ``` -**Hide a specific route from displaying in breadcrumbs** +#### Skip a specific route from displaying in breadcrumbs + +- You can skip a route from breacrumbs either by declaring in route config or dynamically changing using set() method +- pass second arugument as an options object with 'skip' option as true + +**skip breadcrumb by defining in route config** ```javascript -// Hide a route from displaying in Breadcrumbs using `skipBreadcrumb` - declarative { path: 'edit', component: MentorEditComponent, - data: { skipBreadcrumb: true } + data: { breadcrumb: { skip: true } } } -// Hide a route from displaying in Breadcrumbs using breadcrumbService.hide() or breadcrumbService.hideForAlias() - dynamic -breadcrumbService.skip('mentor/:id/edit'); -breadcrumbService.skipForAlias('breadcrumbAlias'); +``` -// Pass the second parameter as `false` to make a hidden breadcrumb visible. -breadcrumbService.skip('mentor/:id/edit', false); -breadcrumbService.skipForAlias('breadcrumbAlias', false); +**skip breadcrumb dynamically** + +```javascript +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' ``` -**Define either on Children or Parent** +#### Customize breadcrumb template (Add icons, change text, i18n) + +You can display whatever you want in the place of breadcrumb text by providing a custom template. -You can define breadcrumbs either on _parent_ or _child with empty path_. If both are defined, the latter takes the precedence. +- Use _\*xngBreadcrumbItem_ directive to provide a custom template +- breadcrumb label defined is available implicitely in template context -- With Component - Children +**Change label case** ```javascript -// defining breadcrumb on Component Route { - path: ':userId', - data: { breadcrumb: 'My User declared on parent' }, - children: [ - { path: '', component: ShowUserComponent } - ] + path: '', + pathMatch: 'full', + component: HomeComponent, + data: { + breadcrumb: 'app home' + } } -// defining breadcrumb on children with empty path +``` + +```html + + + {{ breadcrumb | titlecase }} + + +``` + +**Add icons in front of label label case** + +- define info associated with breadcrumb in route config. +- info has type any. you can pass string or object as you need. +- info is avaliable in template context of _\*xngBreadcrumbItem_ . +- Additionally 'first' and 'last' are passed to identify corresponding items. + +```javascript { - path: ':userId', - children: [ - { path: '', component: ShowUserComponent, data: { breadcrumb: 'My User declared on empty child' } - ] + path: '', + pathMatch: 'full', + component: HomeComponent, + data: { + breadcrumb: { + label: 'app home', + info: 'home' + } + } } ``` -- With Module - Children +```html + + + {{ info }} + {{ breadcrumb }} + + +``` -```javascript -// defining breadcrumb on Module route - { path: 'home', loadChildren: './home/home.module#HomeModule', data: { breadcrumb: 'Dashboard' } } +**i18n support** -// defining breadcrumb on Module children with empty path - { path: 'home', loadChildren: './home/home.module#HomeModule' }, -// Within HomeModule Routes - - { path: '', pathMatch: 'full', component: HomeComponent, data: { breadcrumb: 'Dashboard' } } +- Usually, internationalization is achieved in Angular using libraries like ngx-translate or transloco. +- These libraies provide a pipe to change text while language is changed. +- With ngx-translate you can change language for breadcrumb label like below. +```html + + + {{ breadcrumb | translate }} + + ``` -## Customization +#### Custom separator + +- Breadcrumb by default uses '/' as the separator. +- To use custom seperator pass **separator** as input to the component. +- You can either use a simple string(>>, -, -->) or a component (mat-icon, fa-icon) as a separator. -**Custom separator** -Breadcrumb by default uses '/' as the separator. To use custom seperator pass it as input to the component like below. +**String as separator** +like below. ```html ``` -**Disabling default mapping of route to breadcrumb label** -To avoid breadcrumb labels showing by default even for routes that don't specify breadcrumbs, set `[defaultMapping]=false`. +**icon or component as separator** ```html - + + + + arrow_right + ``` -**Styling breadcrumbs** -`` defines the least possible specificity for selectors, in order to make it easy to override them. -you can override styles by changing the CSS for classes such as `.breadcrumb`, `.current-path`, `.separator` etc with `::ng-deep` +#### 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 same as route path segment. +- If you want to avoid labels showing by default even for routes that don't specify breadcrumbs, set `[autoGenerate]=false`. + +```html + +``` + +#### Customize Breadcrumb Styles + +- `` defines the least possible specificity for selectors, in order 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 root of the breadcrumb. This can be used to increase the specificity when there are conflicting styles. + + ![image](https://user-images.githubusercontent.com/20707504/68110000-f61af700-ff11-11e9-8834-bc754a46b39d.png) ```css -::ng-deep .breadcrumb { - background-color: bisque; - border: 1px solid; +.xng-breadcrumb-root { + padding: 8px 16px; + display: inline-block; + border-radius: 4px; + background-color: #e7f1f1; } -::ng-deep .seperator { - font-size: 2em; +.xng-breadcrumb-separator { + padding: 0 4px; } ``` ## API -| configuration | Usage | -| ---------------------------------------- | ------------------------------------------------------------------- | -| Declarative label - `breadcrumb` | `data: {breadcrumb: 'breadcrumbLabel'}` | -| Declarative alias - `breadcrumbAlias` | `data: {breadcrumbAlias: 'aliasName'}` | -| Declarative skip - `skipBreadcrumb` | `data: {[skipBreadcrumb]: true/false }` | -| Dynamic label by route path - `set()` | `breadcrumbService.set('routePath', 'breadcrumbLabel')` | -| Dynamic skip by route path - `skip()` | `breadcrumbService.skip('routePath', true/false(optional))` | -| Dynamic label by alias - `setForAlias()` | `breadcrumbService.setForAlias('aliasName', 'breadcrumbLabel')` | -| Dynamic skip by alias - `skipForAlias()` | `breadcrumbService.skipForAlias('aliasName', true/false(optional))` | +**Route Config** + +| property | Description | Type | Default | +| ---------- | -------------------------------------------------------- | --------------------- | ----------- | +| breadcrumb | Breadcrumb data provided in App route config | `string | Breadcrumb` | `undefined` | +| alias | alias name for a route | `string` | `undefined` | +| skip | whether to skip route from showing in breadcrumbs | `boolean` | `false` | +| info | arbitrary info for a breadcrumb. passed back to template | `string | object` | `undefined` | +| label | same as breadcrumb, if breadcrumb declared as string | `string` | `undefined` | + +**** +| property | Description | Type | Default | +| ------------- | ------------------------------------ | ---------------------------- | --- | +| separator | input: separator between breadcrumbs | `string | TemplateRef` | `/` | +| autoGenerate | whether to auto generate breacrumb labels | `boolean` | `true` | +| \*xngBreadcrumbItem | directive to read context in custom breadcrumb templates | `Boolean` | `false`| -That's it! You are now ready to use breadcrumbs in your App! 🎉 +**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 they have Route specificity - + +- For the same route, you can define breadcrumbs either on _parent_ or _any desendant with empty path_. +- If both are defined, the children takes the precedence. + +**With Component and it's Children** + +```javascript +// 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 it's Children** + +```javascript +// 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 `