xng-breadcrumb
Version:
A declarative and reactive breadcrumb approach for Angular 6 and beyond https://www.npmjs.com/package/xng-breadcrumb
254 lines (248 loc) • 10.4 kB
TypeScript
import * as i0 from '@angular/core';
import { OnInit, TemplateRef } from '@angular/core';
import * as rxjs from 'rxjs';
import { Observable } from 'rxjs';
type BreadcrumbConfig = BreadcrumbObject | BreadcrumbFunction | string;
type BreadcrumbDefinition = Breadcrumb & BreadcrumbObject;
/**
* Breadcrumb item built internally, private to this module
*/
interface Breadcrumb {
/**
* actual route path with resolved param. Ex /mentor/2, connect/edit
*/
routeLink?: string;
/**
* route with path params converted to a RegExp
* path '/mentor/:id' becomes routeRegex '/mentor/[^/]+', which can be matched against when needed
*/
routeRegex?: string;
/**
* This is additional info on each breadcrumb item whether label is auto generated or user specified
* isAutoGeneratedLabel has to be present at component level but not at the service,
* since we may need to support multiple breadcrumb components in same app
*/
isAutoGeneratedLabel?: boolean;
/**
* Query params in string form.
*/
queryParams?: unknown;
fragment?: string;
routeInterceptor?: (routeLink: string, breadcrumb: Breadcrumb) => string;
}
/**
* Breadcrumb config provided as part of App Route Config
*/
interface BreadcrumbObject {
/**
* breadcrumb label for a route
*/
label?: string | BreadcrumbFunction;
/**
* unique alias name for a route path that can be used to dynamically update a route's breadcrumb label via breadcrumbService.set()
*/
alias?: string;
/**
* hide or show the breadcrumb item
*/
skip?: boolean;
/**
* disable a certain breadcrumb in the list. Not clickable.
* It may be needed when the routing has the path, but navigating to that path is of no use
*/
disable?: boolean;
/**
* custom data for each breadcrumb that is passed back to ng-template
*/
info?: unknown;
/**
* Interceptor for breadcrumb click action that returns the dynamic path
* Consumers can change the breadcrumb routing dynamically with this approach
*/
routeInterceptor?: (routeLink: string, breadcrumb: Breadcrumb) => string;
}
type BreadcrumbFunction = (resolvedLabel?: string) => string;
declare class BreadcrumbComponent implements OnInit {
breadcrumbs$: Observable<BreadcrumbDefinition[]>;
separatorTemplate: TemplateRef<void>;
private _separator;
/**
* Breadcrumb item can be customized with this template
* Template context is provided label, additional info, first and last indexes
* Use cases:
* 1) Add an icon along with label
* 2) i18n. {{breadcrumb | translate}} or {{breadcrumb | transloco}}
* 3) Change text case {{breadcrumb | titlecase}}
*/
itemTemplate: any;
/**
* If true, breadcrumb is auto generated even without any mapping label
* Default label is same as route segment
*/
autoGenerate: boolean;
/**
* By default query params will be preserved with breadcrumbs
*/
preserveQueryParams: boolean;
/**
* By default query fragments will be preserved with breadcrumbs
*/
preserveFragment: boolean;
/**
* custom class provided by consumer to increase specificity
* This will benefit to override styles that are conflicting
*/
class: string;
/**
* anchorTarget = "_blank" makes the breadcrumb link open in a new tab
*/
anchorTarget: '_blank' | undefined;
/**
* separator between breadcrumbs, defaults to '/'.
* User can customize separator either by passing a String or Template
*
* String --> Ex: <xng-breadcrumb separator="-"> </xng-breadcrumb>
*
* Template --> Ex: <xng-breadcrumb [separator]="separatorTemplate"> </xng-breadcrumb>
* <ng-template #separatorTemplate><mat-icon>arrow_right</mat-icon></ng-template>
*/
set separator(value: string | TemplateRef<void>);
get separator(): string | TemplateRef<void>;
setupMessage: string;
someParameterValue: any;
private readonly breadcrumbService;
private readonly activateRoute;
constructor();
setupComponent(someParam: any): void;
ngOnInit(): void;
static ɵfac: i0.ɵɵFactoryDeclaration<BreadcrumbComponent, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<BreadcrumbComponent, "xng-breadcrumb", never, { "autoGenerate": { "alias": "autoGenerate"; "required": false; }; "preserveQueryParams": { "alias": "preserveQueryParams"; "required": false; }; "preserveFragment": { "alias": "preserveFragment"; "required": false; }; "class": { "alias": "class"; "required": false; }; "anchorTarget": { "alias": "anchorTarget"; "required": false; }; "separator": { "alias": "separator"; "required": false; }; }, {}, ["itemTemplate"], never, true, never>;
}
/**
* This directive is used to customize the breadcrumb label behavior
* *xngBreadcrumbItem directive can be used in the child element of xng-breadcrumb
* Usage: refer to the demo - app.component.html
*/
declare class BreadcrumbItemDirective {
static ɵfac: i0.ɵɵFactoryDeclaration<BreadcrumbItemDirective, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<BreadcrumbItemDirective, "[xngBreadcrumbItem]", never, {}, {}, never, never, true, never>;
}
declare class BreadcrumbService {
private baseHref;
/**
* dynamicBreadcrumbStore holds information about dynamically updated breadcrumbs.
* Breadcrumbs can be set from anywhere (component, service) in the app.
* On every breadcrumb update check this store and use the info if available.
*/
private dynamicBreadcrumbStore;
/**
* breadcrumbList for the current route
* When breadcrumb info is changed dynamically, check if the currentBreadcrumbs is effected
* If effected, update the change and emit a new stream
*/
private currentBreadcrumbs;
private previousBreadcrumbs;
/**
* Breadcrumbs observable to be subscribed by BreadcrumbComponent
* Emits on every route change OR dynamic update of breadcrumb
*/
private breadcrumbs;
breadcrumbs$: rxjs.Observable<BreadcrumbDefinition[]>;
private readonly activatedRoute;
private readonly router;
constructor();
/**
* Whenever route changes build breadcrumb list again
*/
private detectRouteChanges;
private setupBreadcrumbs;
private getRootBreadcrumb;
private prepareBreadcrumbItem;
private prepareBreadcrumbList;
private getFromStore;
/**
* use exact match instead of regexp.test
* for /mentor/[^/]+ we should match '/mentor/12' but not '/mentor/12/abc'
*/
private matchRegex;
/**
* if the path segment has route params, read the param value from url
* for each segment of route this gets called
*
* for mentor/:id/view - it gets called with mentor, :id, view 3 times
*/
private resolvePathSegment;
/**
* queryParams & fragments for previous breadcrumb path are copied over to new list
*/
private getQueryParamsFromPreviousList;
/**
* set current activated route query params to the last breadcrumb item
*/
private setQueryParamsForActiveBreadcrumb;
/**
* For a specific route, breadcrumb can be defined either on parent OR it's child(which has empty path)
* When both are defined, child takes precedence
*
* Ex: Below we are setting breadcrumb on both parent and child.
* So, child takes precedence and "Defined On Child" is displayed for the route 'home'
* { path: 'home', loadChildren: () => import('./home/home.module').then((m) => m.HomeModule) , data: {breadcrumb: "Defined On Module"}}
* AND
* children: [
* { path: '', component: ShowUserComponent, data: {breadcrumb: "Defined On Child" }
* ]
*/
private parseRouteData;
/**
* get empty children of a module or Component. Empty child is the one with path: ''
* When parent and it's children (that has empty route path) define data merge them both with child taking precedence
*/
private mergeWithBaseChildData;
/**
* Update breadcrumb dynamically
*
* key can be a path | alias
*
* 1) Using complete route path. route can be passed the same way you define angular routes
* - path can be passed as 'exact path(routeLink)' or 'path with params(routeRegex)'
* - update label Ex: set('/mentor', 'Mentor'), set('/mentor/:id', 'Mentor Details')
* - change visibility Ex: set('/mentor/:id/edit', { skip: true })
* ------------------------------------------ OR ------------------------------------------
* 2) Using route alias (prefixed with '@'). alias should be unique for a route
* - update label Ex: set('@mentor', 'Enabler')
* - change visibility Ex: set('@mentorEdit', { skip: true })
*
*
* value can be string | BreadcrumbObject | BreadcrumbFunction
*/
set(key: string, breadcrumb: string | BreadcrumbObject): void;
/**
* Update the store to reuse for dynamic declarations
* If the store already has this route definition update it, else add
*/
private updateStore;
/**
* If breadcrumb is present in current breadcrumbs update it and emit new stream
*/
private updateCurrentBreadcrumbs;
/**
* For a route with path param, we create regex dynamically from angular route syntax
* '/mentor/:id' becomes '/mentor/[^/]',
* breadcrumbService.set('/mentor/:id', 'Uday') should update 'Uday' as label for '/mentor/2' OR 'mentor/ada'
*/
private buildRegex;
private ensureLeadingSlash;
/**
* In App's RouteConfig, breadcrumb can be defined as a string OR a function OR an object
*
* string: simple static breadcrumb label for a path
* function: callback that gets invoked with resolved path param
* object: additional data defined along with breadcrumb label that gets passed to *xngBreadcrumbItem directive
*/
private extractLabel;
private extractObject;
static ɵfac: i0.ɵɵFactoryDeclaration<BreadcrumbService, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<BreadcrumbService>;
}
export { BreadcrumbComponent, BreadcrumbItemDirective, BreadcrumbService };
export type { Breadcrumb, BreadcrumbConfig, BreadcrumbDefinition, BreadcrumbFunction, BreadcrumbObject };