UNPKG

carbon-components-angular

Version:
1,177 lines (1,161 loc) 64.8 kB
import * as i0 from '@angular/core'; import { EventEmitter, TemplateRef, Component, Optional, Input, Output, HostBinding, HostListener, NgModule, Directive, ContentChildren, ViewEncapsulation } from '@angular/core'; import * as i2$1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i1$2 from 'carbon-components-angular/button'; import { BaseIconButton, ButtonModule } from 'carbon-components-angular/button'; import * as i1 from 'carbon-components-angular/i18n'; import { I18nModule } from 'carbon-components-angular/i18n'; import * as i3 from 'carbon-components-angular/icon'; import { IconModule } from 'carbon-components-angular/icon'; import * as i1$1 from '@angular/platform-browser'; import * as i2 from '@angular/router'; import { RouterModule, RouterLinkWithHref } from '@angular/router'; import { keys } from 'lodash'; import { Subscription } from 'rxjs'; /** * A fixed header and navigation. * Header may contain a Hamburger menu to toggle the side navigation, navigation actions, * and global actions (generally in the form of `Panel`s). * * [See demo](../../?path=/story/components-ui-shell--header) */ class Header { constructor(i18n, domSanitizer, router) { this.i18n = i18n; this.domSanitizer = domSanitizer; this.router = router; /** * Top level branding. Defaults to "IBM" */ this.brand = "IBM"; /** * Use the routerLink attribute on <a> tag for navigation instead of using event handlers */ this.useRouter = false; /** * Emits the navigation status promise when the link is activated */ this.navigation = new EventEmitter(); this._href = "#"; } /** * Optional link for the header */ set href(v) { this._href = v; } get href() { return this.domSanitizer.bypassSecurityTrustUrl(this._href); } isTemplate(value) { return value instanceof TemplateRef; } navigate(event) { if (this.router && this.route) { event.preventDefault(); const status = this.router.navigate(this.route, this.routeExtras); this.navigation.emit(status); } else if (this._href === "#") { event.preventDefault(); } } } Header.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Header, deps: [{ token: i1.I18n }, { token: i1$1.DomSanitizer }, { token: i2.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component }); Header.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Header, selector: "cds-header, ibm-header", inputs: { skipTo: "skipTo", name: "name", brand: "brand", href: "href", route: "route", routeExtras: "routeExtras", useRouter: "useRouter" }, outputs: { navigation: "navigation" }, ngImport: i0, template: ` <header class="cds--header" [attr.aria-label]="brand + ' ' + name"> <a *ngIf="skipTo" class="cds--skip-to-content" [href]="skipTo" tabindex="0"> {{ i18n.get("UI_SHELL.SKIP_TO") | async }} </a> <ng-content select="cds-hamburger,ibm-hamburger"></ng-content> <ng-template *ngIf="isTemplate(brand)" [ngTemplateOutlet]="brand"> </ng-template> <ng-container *ngIf="!isTemplate(brand)" [ngSwitch]="useRouter"> <a *ngSwitchCase="false" class="cds--header__name" [href]="href" (click)="navigate($event)"> <span class="cds--header__name--prefix">{{brand}}&nbsp;</span> {{name}} </a> <a *ngSwitchCase="true" class="cds--header__name" [routerLink]="route"> <span class="cds--header__name--prefix">{{brand}}&nbsp;</span> {{name}} </a> </ng-container> <ng-content></ng-content> </header> `, isInline: true, dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Header, decorators: [{ type: Component, args: [{ selector: "cds-header, ibm-header", template: ` <header class="cds--header" [attr.aria-label]="brand + ' ' + name"> <a *ngIf="skipTo" class="cds--skip-to-content" [href]="skipTo" tabindex="0"> {{ i18n.get("UI_SHELL.SKIP_TO") | async }} </a> <ng-content select="cds-hamburger,ibm-hamburger"></ng-content> <ng-template *ngIf="isTemplate(brand)" [ngTemplateOutlet]="brand"> </ng-template> <ng-container *ngIf="!isTemplate(brand)" [ngSwitch]="useRouter"> <a *ngSwitchCase="false" class="cds--header__name" [href]="href" (click)="navigate($event)"> <span class="cds--header__name--prefix">{{brand}}&nbsp;</span> {{name}} </a> <a *ngSwitchCase="true" class="cds--header__name" [routerLink]="route"> <span class="cds--header__name--prefix">{{brand}}&nbsp;</span> {{name}} </a> </ng-container> <ng-content></ng-content> </header> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }, { type: i1$1.DomSanitizer }, { type: i2.Router, decorators: [{ type: Optional }] }]; }, propDecorators: { skipTo: [{ type: Input }], name: [{ type: Input }], brand: [{ type: Input }], href: [{ type: Input }], route: [{ type: Input }], routeExtras: [{ type: Input }], useRouter: [{ type: Input }], navigation: [{ type: Output }] } }); /** * Individual item in the header. May be used a direct child of `HeaderNavigation` or `HeaderMenu` */ class HeaderItem { constructor(domSanitizer, router) { this.domSanitizer = domSanitizer; this.router = router; this.role = "listitem"; /** * Use the routerLink attribute on <a> tag for navigation instead of using event handlers */ this.useRouter = false; /** * Emits the navigation status promise when the link is activated */ this.navigation = new EventEmitter(); this._href = "#"; } set href(v) { // Needed when component is created dynamically with a model. if (v === undefined) { return; } this._href = v; } get href() { return this.domSanitizer.bypassSecurityTrustUrl(this._href); } navigate(event) { if (this.router && this.route) { event.preventDefault(); const status = this.router.navigate(this.route, this.routeExtras); this.navigation.emit(status); } else if (this._href === "#") { event.preventDefault(); } } } HeaderItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderItem, deps: [{ token: i1$1.DomSanitizer }, { token: i2.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component }); HeaderItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HeaderItem, selector: "cds-header-item, ibm-header-item", inputs: { href: "href", useRouter: "useRouter", activeLinkClass: "activeLinkClass", isCurrentPage: "isCurrentPage", route: "route", routeExtras: "routeExtras" }, outputs: { navigation: "navigation" }, host: { properties: { "attr.role": "this.role" } }, ngImport: i0, template: ` <ng-container [ngSwitch]="useRouter"> <ng-template #content><ng-content></ng-content></ng-template> <a *ngSwitchCase="false" class="cds--header__menu-item" tabindex="0" [ngClass]="{'cds--header__menu-item--current' : isCurrentPage}" [href]="href" (click)="navigate($event)"> <ng-container *ngTemplateOutlet="content"></ng-container> </a> <a *ngSwitchCase="true" class="cds--header__menu-item" [routerLinkActive]="['cds--header__menu-item--current']" tabindex="0" [ngClass]="{'cds--header__menu-item--current' : isCurrentPage}" [routerLink]="route" [routerLinkActive]="activeLinkClass"> <ng-container *ngTemplateOutlet="content"></ng-container> </a> </ng-container> `, isInline: true, styles: [":host{display:list-item}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderItem, decorators: [{ type: Component, args: [{ selector: "cds-header-item, ibm-header-item", template: ` <ng-container [ngSwitch]="useRouter"> <ng-template #content><ng-content></ng-content></ng-template> <a *ngSwitchCase="false" class="cds--header__menu-item" tabindex="0" [ngClass]="{'cds--header__menu-item--current' : isCurrentPage}" [href]="href" (click)="navigate($event)"> <ng-container *ngTemplateOutlet="content"></ng-container> </a> <a *ngSwitchCase="true" class="cds--header__menu-item" [routerLinkActive]="['cds--header__menu-item--current']" tabindex="0" [ngClass]="{'cds--header__menu-item--current' : isCurrentPage}" [routerLink]="route" [routerLinkActive]="activeLinkClass"> <ng-container *ngTemplateOutlet="content"></ng-container> </a> </ng-container> `, styles: [":host{display:list-item}\n"] }] }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: i2.Router, decorators: [{ type: Optional }] }]; }, propDecorators: { role: [{ type: HostBinding, args: ["attr.role"] }], href: [{ type: Input }], useRouter: [{ type: Input }], activeLinkClass: [{ type: Input }], isCurrentPage: [{ type: Input }], route: [{ type: Input }], routeExtras: [{ type: Input }], navigation: [{ type: Output }] } }); /** * Dropdown menu container for navigation items. */ class HeaderMenu { constructor(domSanitizer, elementRef) { this.domSanitizer = domSanitizer; this.elementRef = elementRef; this.subMenu = true; this.role = "listitem"; this.trigger = "click"; this.expanded = false; this._href = "#"; } set href(v) { // Needed when component is created dynamically with a model. if (v === undefined) { return; } this._href = v; } get href() { return this.domSanitizer.bypassSecurityTrustUrl(this._href); } onClick() { if (this.trigger === "click") { this.expanded = !this.expanded; } } onMouseOver() { if (this.trigger === "mouseover") { this.expanded = true; } } onMouseOut() { if (this.trigger === "mouseover") { this.expanded = false; } } onFocusOut(event) { if (!this.elementRef.nativeElement.contains(event.relatedTarget)) { this.expanded = false; } } navigate(event) { if (this._href === "#") { event.preventDefault(); } } } HeaderMenu.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderMenu, deps: [{ token: i1$1.DomSanitizer }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); HeaderMenu.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HeaderMenu, selector: "cds-header-menu, ibm-header-menu", inputs: { title: "title", href: "href", trigger: "trigger", headerItems: "headerItems", icon: "icon" }, host: { listeners: { "click": "onClick()", "mouseover": "onMouseOver()", "mouseout": "onMouseOut()", "focusout": "onFocusOut($event)" }, properties: { "class.cds--header__submenu": "this.subMenu", "attr.role": "this.role" } }, ngImport: i0, template: ` <a class="cds--header__menu-item cds--header__menu-title" [href]="href" tabindex="0" aria-haspopup="menu" [attr.aria-expanded]="expanded" (click)="navigate($event)"> {{title}} <ng-template *ngIf="icon; else defaultIcon" [ngTemplateOutlet]="icon"></ng-template> <ng-template #defaultIcon> <svg class="cds--header__menu-arrow" width="12" height="7" aria-hidden="true"> <path d="M6.002 5.55L11.27 0l.726.685L6.003 7 0 .685.726 0z" /> </svg> </ng-template> </a> <div class="cds--header__menu" [attr.aria-label]="title"> <ng-content></ng-content> <ng-container *ngFor="let headerItem of headerItems"> <cds-header-item [href]="headerItem.href" [route]="headerItem.route" [routeExtras]="headerItem.routeExtras"> {{ headerItem.content }} </cds-header-item> </ng-container> </div> `, isInline: true, styles: [":host{display:list-item}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HeaderItem, selector: "cds-header-item, ibm-header-item", inputs: ["href", "useRouter", "activeLinkClass", "isCurrentPage", "route", "routeExtras"], outputs: ["navigation"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderMenu, decorators: [{ type: Component, args: [{ selector: "cds-header-menu, ibm-header-menu", template: ` <a class="cds--header__menu-item cds--header__menu-title" [href]="href" tabindex="0" aria-haspopup="menu" [attr.aria-expanded]="expanded" (click)="navigate($event)"> {{title}} <ng-template *ngIf="icon; else defaultIcon" [ngTemplateOutlet]="icon"></ng-template> <ng-template #defaultIcon> <svg class="cds--header__menu-arrow" width="12" height="7" aria-hidden="true"> <path d="M6.002 5.55L11.27 0l.726.685L6.003 7 0 .685.726 0z" /> </svg> </ng-template> </a> <div class="cds--header__menu" [attr.aria-label]="title"> <ng-content></ng-content> <ng-container *ngFor="let headerItem of headerItems"> <cds-header-item [href]="headerItem.href" [route]="headerItem.route" [routeExtras]="headerItem.routeExtras"> {{ headerItem.content }} </cds-header-item> </ng-container> </div> `, styles: [":host{display:list-item}\n"] }] }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: i0.ElementRef }]; }, propDecorators: { subMenu: [{ type: HostBinding, args: ["class.cds--header__submenu"] }], role: [{ type: HostBinding, args: ["attr.role"] }], title: [{ type: Input }], href: [{ type: Input }], trigger: [{ type: Input }], headerItems: [{ type: Input }], icon: [{ type: Input }], onClick: [{ type: HostListener, args: ["click"] }], onMouseOver: [{ type: HostListener, args: ["mouseover"] }], onMouseOut: [{ type: HostListener, args: ["mouseout"] }], onFocusOut: [{ type: HostListener, args: ["focusout", ["$event"]] }] } }); /** * Container for header navigation items */ class HeaderNavigation { constructor() { this.height = 100; } } HeaderNavigation.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderNavigation, deps: [], target: i0.ɵɵFactoryTarget.Component }); HeaderNavigation.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HeaderNavigation, selector: "cds-header-navigation, ibm-header-navigation", inputs: { ariaLabel: "ariaLabel", navigationItems: "navigationItems" }, host: { properties: { "style.height.%": "this.height" } }, ngImport: i0, template: ` <nav class="cds--header__nav" [attr.aria-label]="ariaLabel"> <div class="cds--header__menu-bar" role="list"> <ng-content></ng-content> <ng-container *ngFor="let navigationItem of navigationItems"> <cds-header-item *ngIf="navigationItem.type === 'item'" [href]="navigationItem.href" [route]="navigationItem.route" [routeExtras]="navigationItem.routeExtras" [isCurrentPage]="!!navigationItem.isCurrentPage"> {{ navigationItem.content }} </cds-header-item> <cds-header-menu *ngIf="navigationItem.type === 'menu'" [href]="navigationItem.href" [title]="navigationItem.title" [trigger]="navigationItem.trigger ? navigationItem.trigger : 'click'" [headerItems]="navigationItem.menuItems"> </cds-header-menu> </ng-container> </div> </nav> `, isInline: true, dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HeaderItem, selector: "cds-header-item, ibm-header-item", inputs: ["href", "useRouter", "activeLinkClass", "isCurrentPage", "route", "routeExtras"], outputs: ["navigation"] }, { kind: "component", type: HeaderMenu, selector: "cds-header-menu, ibm-header-menu", inputs: ["title", "href", "trigger", "headerItems", "icon"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderNavigation, decorators: [{ type: Component, args: [{ selector: "cds-header-navigation, ibm-header-navigation", template: ` <nav class="cds--header__nav" [attr.aria-label]="ariaLabel"> <div class="cds--header__menu-bar" role="list"> <ng-content></ng-content> <ng-container *ngFor="let navigationItem of navigationItems"> <cds-header-item *ngIf="navigationItem.type === 'item'" [href]="navigationItem.href" [route]="navigationItem.route" [routeExtras]="navigationItem.routeExtras" [isCurrentPage]="!!navigationItem.isCurrentPage"> {{ navigationItem.content }} </cds-header-item> <cds-header-menu *ngIf="navigationItem.type === 'menu'" [href]="navigationItem.href" [title]="navigationItem.title" [trigger]="navigationItem.trigger ? navigationItem.trigger : 'click'" [headerItems]="navigationItem.menuItems"> </cds-header-menu> </ng-container> </div> </nav> ` }] }], propDecorators: { height: [{ type: HostBinding, args: ["style.height.%"] }], ariaLabel: [{ type: Input }], navigationItems: [{ type: Input }] } }); /** * Container for `HeaderAction`s. */ class HeaderGlobal { constructor() { this.hostClass = true; } } HeaderGlobal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderGlobal, deps: [], target: i0.ɵɵFactoryTarget.Component }); HeaderGlobal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HeaderGlobal, selector: "cds-header-global, ibm-header-global", host: { properties: { "class.cds--header__global": "this.hostClass" } }, ngImport: i0, template: ` <ng-content></ng-content> `, isInline: true }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderGlobal, decorators: [{ type: Component, args: [{ selector: "cds-header-global, ibm-header-global", template: ` <ng-content></ng-content> ` }] }], propDecorators: { hostClass: [{ type: HostBinding, args: ["class.cds--header__global"] }] } }); /** * Contained by `HeaderGlobal`. Generally used to trigger `Panel`s */ class HeaderAction extends BaseIconButton { constructor() { super(...arguments); /** * Toggles the active state. May be used to toggle a `Panel`s active state. */ this.active = false; /** * "Change" emitter to allow double binding to the `active` Input. */ this.activeChange = new EventEmitter(); /** * Emits when the action has been clicked. */ this.selected = new EventEmitter(); } onClick() { this.active = !this.active; this.selected.emit(this.active); this.activeChange.emit(this.active); } } HeaderAction.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderAction, deps: null, target: i0.ɵɵFactoryTarget.Component }); HeaderAction.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: HeaderAction, selector: "cds-header-action, ibm-header-action", inputs: { description: "description", ariaLabel: "ariaLabel", active: "active" }, outputs: { activeChange: "activeChange", selected: "selected" }, usesInheritance: true, ngImport: i0, template: ` <cds-icon-button [buttonNgClass]="{ 'cds--header__action': true, 'cds--header__action--active': active }" (click)="onClick()" [align]="align" [caret]="caret" [dropShadow]="dropShadow" [highContrast]="highContrast" [isOpen]="isOpen" [enterDelayMs]="enterDelayMs" [leaveDelayMs]="leaveDelayMs" [description]="description" [buttonAttributes]="{ 'aria-label': ariaLabel }"> <ng-content></ng-content> </cds-icon-button> `, isInline: true, dependencies: [{ kind: "component", type: i1$2.IconButton, selector: "cds-icon-button, ibm-icon-button", inputs: ["buttonNgClass", "buttonAttributes", "buttonId", "kind", "size", "type", "isExpressive", "disabled", "description"], outputs: ["click", "focus", "blur", "tooltipClick"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderAction, decorators: [{ type: Component, args: [{ selector: "cds-header-action, ibm-header-action", template: ` <cds-icon-button [buttonNgClass]="{ 'cds--header__action': true, 'cds--header__action--active': active }" (click)="onClick()" [align]="align" [caret]="caret" [dropShadow]="dropShadow" [highContrast]="highContrast" [isOpen]="isOpen" [enterDelayMs]="enterDelayMs" [leaveDelayMs]="leaveDelayMs" [description]="description" [buttonAttributes]="{ 'aria-label': ariaLabel }"> <ng-content></ng-content> </cds-icon-button> ` }] }], propDecorators: { description: [{ type: Input }], ariaLabel: [{ type: Input }], active: [{ type: Input }], activeChange: [{ type: Output }], selected: [{ type: Output }] } }); /** * A toggle for the side navigation */ class Hamburger { constructor(i18n) { this.i18n = i18n; /** * Controls the active/selected state for the `Hamburger` menu. */ this.active = false; /** * Set the title text when the hamburger is active */ this.activeTitle = this.i18n.get().UI_SHELL.HEADER.CLOSE_MENU; /** * Set the title text when the hamburger is inactive */ this.inactiveTitle = this.i18n.get().UI_SHELL.HEADER.OPEN_MENU; /** * `EventEmitter` to notify parent components of menu click events. */ this.selected = new EventEmitter(); } /** * Emit the Hamburger click event upwards. */ doClick() { this.selected.emit(this.active); } } Hamburger.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Hamburger, deps: [{ token: i1.I18n }], target: i0.ɵɵFactoryTarget.Component }); Hamburger.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Hamburger, selector: "cds-hamburger, ibm-hamburger", inputs: { active: "active", activeTitle: "activeTitle", inactiveTitle: "inactiveTitle" }, outputs: { selected: "selected" }, ngImport: i0, template: ` <button type="button" (click)="doClick()" [ngClass]="{'cds--header__action--active': active}" class="cds--header__menu-trigger cds--header__action cds--header__menu-toggle" [attr.aria-label]="active ? activeTitle : inactiveTitle" [attr.title]="active ? activeTitle : inactiveTitle"> <svg *ngIf="!active" cdsIcon="menu" size="20"></svg> <svg *ngIf="active" cdsIcon="close" size="20"></svg> </button> `, isInline: true, dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Hamburger, decorators: [{ type: Component, args: [{ selector: "cds-hamburger, ibm-hamburger", template: ` <button type="button" (click)="doClick()" [ngClass]="{'cds--header__action--active': active}" class="cds--header__menu-trigger cds--header__action cds--header__menu-toggle" [attr.aria-label]="active ? activeTitle : inactiveTitle" [attr.title]="active ? activeTitle : inactiveTitle"> <svg *ngIf="!active" cdsIcon="menu" size="20"></svg> <svg *ngIf="active" cdsIcon="close" size="20"></svg> </button> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }]; }, propDecorators: { active: [{ type: Input }], activeTitle: [{ type: Input }], inactiveTitle: [{ type: Input }], selected: [{ type: Output }] } }); class HeaderModule { } HeaderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); HeaderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: HeaderModule, declarations: [Header, HeaderItem, HeaderMenu, HeaderNavigation, HeaderGlobal, HeaderAction, Hamburger], imports: [CommonModule, ButtonModule, I18nModule, IconModule, RouterModule], exports: [Header, HeaderItem, HeaderMenu, HeaderNavigation, HeaderGlobal, HeaderAction, Hamburger] }); HeaderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderModule, imports: [CommonModule, ButtonModule, I18nModule, IconModule, RouterModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HeaderModule, decorators: [{ type: NgModule, args: [{ declarations: [ Header, HeaderItem, HeaderMenu, HeaderNavigation, HeaderGlobal, HeaderAction, Hamburger ], imports: [ CommonModule, ButtonModule, I18nModule, IconModule, RouterModule ], exports: [ Header, HeaderItem, HeaderMenu, HeaderNavigation, HeaderGlobal, HeaderAction, Hamburger ] }] }] }); class RouterLinkExtendedDirective extends RouterLinkWithHref { ngOnChanges(changes) { if (changes.routeExtras && this.routeExtras) { keys(this.routeExtras).forEach(routeExtraProperty => this[routeExtraProperty] = this.routeExtras[routeExtraProperty]); } super.ngOnChanges(changes); } } RouterLinkExtendedDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RouterLinkExtendedDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); RouterLinkExtendedDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: RouterLinkExtendedDirective, selector: "[routerLink]", inputs: { routeExtras: "routeExtras" }, usesInheritance: true, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RouterLinkExtendedDirective, decorators: [{ type: Directive, args: [{ // tslint:disable-next-line selector: "[routerLink]" }] }], propDecorators: { routeExtras: [{ type: Input }] } }); /** * `SideNavItem` can either be a child of `SideNav` or `SideNavMenu` */ class SideNavItem { constructor(domSanitizer, router) { this.domSanitizer = domSanitizer; this.router = router; /** * Use the routerLink attribute on <a> tag for navigation instead of using event handlers */ this.useRouter = false; /** * Toggles the active (current page) state for the link. */ this.active = false; this.isSubMenu = false; /** * Emits the navigation status promise when the link is activated */ this.navigation = new EventEmitter(); /** * Emits when `active` input is changed. This is mainly used to indicate to any parent menu items that a * child sidenav item is active or not active. */ this.selected = new EventEmitter(); this.role = "listitem"; this._href = "#"; } /** * Link for the item. NOTE: *do not* pass unsafe or untrusted values, this has the potential to open you up to XSS attacks */ set href(v) { // Needed when component is created dynamically with a model. if (v === undefined) { return; } this._href = v; } get href() { return this.domSanitizer.bypassSecurityTrustUrl(this._href); } get sideNav() { return !this.isSubMenu; } get menuItem() { return this.isSubMenu; } ngOnChanges(changes) { if (changes.active) { this.selected.emit(this.active); } } navigate(event) { if (this.router && this.route) { event.preventDefault(); const status = this.router.navigate(this.route, this.routeExtras); this.navigation.emit(status); } else if (this._href === "#") { event.preventDefault(); } } } SideNavItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SideNavItem, deps: [{ token: i1$1.DomSanitizer }, { token: i2.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component }); SideNavItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SideNavItem, selector: "cds-sidenav-item, ibm-sidenav-item", inputs: { href: "href", useRouter: "useRouter", active: "active", route: "route", isSubMenu: "isSubMenu", routeExtras: "routeExtras", title: "title" }, outputs: { navigation: "navigation", selected: "selected" }, host: { properties: { "class.cds--side-nav__item": "this.sideNav", "class.cds--side-nav__menu-item": "this.menuItem", "attr.role": "this.role" } }, usesOnChanges: true, ngImport: i0, template: ` <a *ngIf="!useRouter; else sidenavItemRouterTpl" class="cds--side-nav__link" [ngClass]="{ 'cds--side-nav__item--active': active }" [href]="href" [attr.aria-current]="(active ? 'page' : null)" [attr.title]="title ? title : null" (click)="navigate($event)"> <ng-template [ngTemplateOutlet]="sidenavItemContentTpl"></ng-template> </a> <ng-template #sidenavItemRouterTpl> <a [attr.title]="title ? title : null" [routerLink]="route" [routeExtras]="routeExtras" routerLinkActive="cds--side-nav__item--active" ariaCurrentWhenActive="page" class="cds--side-nav__link"> <ng-template [ngTemplateOutlet]="sidenavItemContentTpl"></ng-template> </a> </ng-template> <ng-template #sidenavItemContentTpl> <div *ngIf="!isSubMenu" class="cds--side-nav__icon"> <ng-content select="svg, [icon]"></ng-content> </div> <span class="cds--side-nav__link-text"> <ng-content></ng-content> </span> </ng-template> `, isInline: true, styles: [":host{display:list-item}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: RouterLinkExtendedDirective, selector: "[routerLink]", inputs: ["routeExtras"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SideNavItem, decorators: [{ type: Component, args: [{ selector: "cds-sidenav-item, ibm-sidenav-item", template: ` <a *ngIf="!useRouter; else sidenavItemRouterTpl" class="cds--side-nav__link" [ngClass]="{ 'cds--side-nav__item--active': active }" [href]="href" [attr.aria-current]="(active ? 'page' : null)" [attr.title]="title ? title : null" (click)="navigate($event)"> <ng-template [ngTemplateOutlet]="sidenavItemContentTpl"></ng-template> </a> <ng-template #sidenavItemRouterTpl> <a [attr.title]="title ? title : null" [routerLink]="route" [routeExtras]="routeExtras" routerLinkActive="cds--side-nav__item--active" ariaCurrentWhenActive="page" class="cds--side-nav__link"> <ng-template [ngTemplateOutlet]="sidenavItemContentTpl"></ng-template> </a> </ng-template> <ng-template #sidenavItemContentTpl> <div *ngIf="!isSubMenu" class="cds--side-nav__icon"> <ng-content select="svg, [icon]"></ng-content> </div> <span class="cds--side-nav__link-text"> <ng-content></ng-content> </span> </ng-template> `, styles: [":host{display:list-item}\n"] }] }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: i2.Router, decorators: [{ type: Optional }] }]; }, propDecorators: { href: [{ type: Input }], useRouter: [{ type: Input }], sideNav: [{ type: HostBinding, args: ["class.cds--side-nav__item"] }], menuItem: [{ type: HostBinding, args: ["class.cds--side-nav__menu-item"] }], active: [{ type: Input }], route: [{ type: Input }], isSubMenu: [{ type: Input }], routeExtras: [{ type: Input }], title: [{ type: Input }], navigation: [{ type: Output }], selected: [{ type: Output }], role: [{ type: HostBinding, args: ["attr.role"] }] } }); /** * `SideNavMenu` provides a method to group `SideNavItem`s under a common heading. */ class SideNavMenu { constructor() { this.navItem = true; this.navItemIcon = true; this.role = "listitem"; /** * Use the routerLink attribute on <a> tag for navigation instead of using event handlers */ this.useRouter = false; /** * Controls the visibility of the child `SideNavItem`s */ this.expanded = false; /** * Controls the active status indicator on the menu if there is an active * child sidenav item. */ this.hasActiveChild = false; this.activeItemsSubscription = new Subscription(); } get navItemActive() { return this.hasActiveChild; } ngAfterContentInit() { setTimeout(() => { this.sidenavItems.forEach(item => { item.isSubMenu = true; this.findActiveChildren(); const activeItemSubscription = item.selected.subscribe(() => { this.findActiveChildren(); }); this.activeItemsSubscription.add(activeItemSubscription); }); this.sidenavItems.changes.subscribe(() => { this.sidenavItems.forEach(item => { item.isSubMenu = true; this.findActiveChildren(); const activeItemSubscription = item.selected.subscribe(() => { this.findActiveChildren(); }); this.activeItemsSubscription.add(activeItemSubscription); }); }); }); } ngOnDestroy() { this.activeItemsSubscription.unsubscribe(); } toggle() { this.expanded = !this.expanded; } findActiveChildren() { this.hasActiveChild = this.sidenavItems.some(item => item.active); } } SideNavMenu.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SideNavMenu, deps: [], target: i0.ɵɵFactoryTarget.Component }); SideNavMenu.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SideNavMenu, selector: "cds-sidenav-menu, ibm-sidenav-menu", inputs: { useRouter: "useRouter", title: "title", expanded: "expanded", hasActiveChild: "hasActiveChild", menuItems: "menuItems" }, host: { properties: { "class.cds--side-nav__item": "this.navItem", "class.cds--side-nav__item--icon": "this.navItemIcon", "class.cds--side-nav__item--active": "this.navItemActive", "attr.role": "this.role" } }, queries: [{ propertyName: "sidenavItems", predicate: SideNavItem }], ngImport: i0, template: ` <button (click)="toggle()" class="cds--side-nav__submenu" aria-haspopup="true" [attr.aria-expanded]="expanded" type="button"> <div class="cds--side-nav__icon"> <ng-content select="svg, [icon]"></ng-content> </div> <span class="cds--side-nav__submenu-title">{{title}}</span> <div class="cds--side-nav__icon cds--side-nav__icon--small cds--side-nav__submenu-chevron"> <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"> <path d="M16 22L6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path> </svg> </div> </button> <div class="cds--side-nav__menu" role="list"> <ng-content></ng-content> <ng-container *ngFor="let menuItem of menuItems"> <cds-sidenav-item [href]="menuItem.href" [route]="menuItem.route" [routeExtras]="menuItem.routeExtras" [useRouter]="useRouter" [isSubMenu]="true"> {{ menuItem.content }} </cds-sidenav-item> </ng-container> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: SideNavItem, selector: "cds-sidenav-item, ibm-sidenav-item", inputs: ["href", "useRouter", "active", "route", "isSubMenu", "routeExtras", "title"], outputs: ["navigation", "selected"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SideNavMenu, decorators: [{ type: Component, args: [{ selector: "cds-sidenav-menu, ibm-sidenav-menu", template: ` <button (click)="toggle()" class="cds--side-nav__submenu" aria-haspopup="true" [attr.aria-expanded]="expanded" type="button"> <div class="cds--side-nav__icon"> <ng-content select="svg, [icon]"></ng-content> </div> <span class="cds--side-nav__submenu-title">{{title}}</span> <div class="cds--side-nav__icon cds--side-nav__icon--small cds--side-nav__submenu-chevron"> <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"> <path d="M16 22L6 12l1.4-1.4 8.6 8.6 8.6-8.6L26 12z"></path> </svg> </div> </button> <div class="cds--side-nav__menu" role="list"> <ng-content></ng-content> <ng-container *ngFor="let menuItem of menuItems"> <cds-sidenav-item [href]="menuItem.href" [route]="menuItem.route" [routeExtras]="menuItem.routeExtras" [useRouter]="useRouter" [isSubMenu]="true"> {{ menuItem.content }} </cds-sidenav-item> </ng-container> </div> ` }] }], propDecorators: { navItem: [{ type: HostBinding, args: ["class.cds--side-nav__item"] }], navItemIcon: [{ type: HostBinding, args: ["class.cds--side-nav__item--icon"] }], navItemActive: [{ type: HostBinding, args: ["class.cds--side-nav__item--active"] }], role: [{ type: HostBinding, args: ["attr.role"] }], useRouter: [{ type: Input }], title: [{ type: Input }], expanded: [{ type: Input }], hasActiveChild: [{ type: Input }], menuItems: [{ type: Input }], sidenavItems: [{ type: ContentChildren, args: [SideNavItem] }] } }); /** * `Sidenav` is a fixed left navigation that may contain `SideNavItem`s or `SideNavMenu`s * * [See demo](../../?path=/story/components-ui-shell--side-navigation) */ class SideNav { constructor(i18n) { this.i18n = i18n; this.hostClass = true; this.ariaLabel = "Side navigation"; /** * Controls the expanded (`true`) or collapsed (`false`) state when on a small screen. */ this.expanded = true; /** * Controls the hidden (`true`) or visible (`false`) state */ this.hidden = false; this.rail = false; this.ux = true; this.allowExpansion = false; /** * Use the routerLink attribute on <a> tag for navigation instead of using event handlers */ this.useRouter = false; } toggle() { this.expanded = !this.expanded; } } SideNav.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SideNav, deps: [{ token: i1.I18n }], target: i0.ɵɵFactoryTarget.Component }); SideNav.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SideNav, selector: "cds-sidenav, ibm-sidenav", inputs: { ariaLabel: "ariaLabel", expanded: "expanded", hidden: "hidden", rail: "rail", allowExpansion: "allowExpansion", navigationItems: "navigationItems", useRouter: "useRouter" }, host: { properties: { "class.cds--side-nav": "this.hostClass", "class.cds--side-nav--expanded": "this.expanded", "class.cds--side-nav--hidden": "this.hidden", "class.cds--side-nav--rail": "this.rail", "class.cds--side-nav__navigation": "this.ux" } }, ngImport: i0, template: ` <nav class="cds--side-nav__items" [attr.aria-label]="ariaLabel"> <ng-content select="cds-sidenav-header,ibm-sidenav-header"></ng-content> <div role="list"> <div class="cds--side-nav__header-navigation cds--side-nav__header-divider"> <ng-container *ngFor="let navigationItem of navigationItems"> <cds-sidenav-item *ngIf="navigationItem.type === 'item'" [href]="navigationItem.href" [route]="navigationItem.route" [routeExtras]="navigationItem.routeExtras" [useRouter]="useRouter" [title]="navigationItem.title"> {{ navigationItem.content }} </cds-sidenav-item> <cds-sidenav-menu *ngIf="navigationItem.type === 'menu'" [title]="navigationItem.title" [useRouter]="useRouter" [menuItems]="navigationItem.menuItems"> </cds-sidenav-menu> </ng-container> </div> <ng-content></ng-content> </div> <footer class="cds--side-nav__footer"> <button *ngIf="allowExpansion" class="cds--side-nav__toggle" type="button" [title]="(expanded ? i18n.get('UI_SHELL.SIDE_NAV.TOGGLE_CLOSE') : i18n.get('UI_SHELL.SIDE_NAV.TOGGLE_OPEN')) | async" (click)="toggle()"> <div class="cds--side-nav__icon"> <svg *ngIf="expanded" focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"> <path d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4l6.6 6.6L8 22.6 9.4 24l6.6-6.6 6.6 6.6 1.4-1.4-6.6-6.6L24 9.4z"></path> </svg> <svg *ngIf="!expanded" focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"> <path d="M22 16L12 26l-1.4-1.4 8.6-8.6-8.6-8.6L12 6z"></path> </svg> </div> <span class="cds--assistive-text"> {{(expanded ? i18n.get('UI_SHELL.SIDE_NAV.TOGGLE_CLOSE') : i18n.get('UI_SHELL.SIDE_NAV.TOGGLE_OPEN')) | async}} </span> </button> </footer> </nav> `, isInline: true, dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SideNavItem, selector: "cds-sidenav-item, ibm-sidenav-item", inputs: ["href", "useRouter", "active", "route", "isSubMenu", "routeExtras", "title"], outputs: ["navigation", "selected"] }, { kind: "component", type: SideNavMenu, selector: "cds-sidenav-menu, ibm-sidenav-menu", inputs: ["useRouter", "title", "expanded", "hasActiveChild", "menuItems"] }, { kind: "pipe", type: i2$1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SideNav, decorators: [{ ty