UNPKG

fundamental-ngx

Version:

SAP Fiori Fundamentals, implemented in Angular

1,654 lines (1,618 loc) 395 kB
import Popper from 'popper.js'; import { Subject, fromEvent } from 'rxjs'; import { animate, style, transition, trigger } from '@angular/animations'; import focusTrap from 'focus-trap'; import { Input, Directive, ElementRef, NgModule, Component, HostBinding, Injectable, ChangeDetectorRef, ViewChild, ComponentFactoryResolver, Type, ViewContainerRef, TemplateRef, Optional, Output, EventEmitter, ApplicationRef, Injector, Inject, LOCALE_ID, HostListener, forwardRef, ContentChild, Pipe, ContentChildren, ViewChildren, Renderer2, defineInjectable, inject } from '@angular/core'; import { CommonModule, FormStyle, getLocaleDayNames, getLocaleMonthNames, TranslationWidth } from '@angular/common'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* This abstract class allows the user to set their own custom styles on a Fundamental NGX directive, in addition to the styles the library needs to add itself. When library styles were added through the directive's host: {'[class]'} property, any styles the user added would be overwritten. By extending this class, we instead add library styles to the user's classList rather than replace them. */ /** * @hidden * @abstract */ class AbstractFdNgxClass { /** * @hidden * @protected * @param {?} elementRef */ constructor(elementRef) { this._elementRef = elementRef; this._setProperties(); } /** * @hidden * @param {?} className * @return {?} */ _addClassToElement(className) { ((/** @type {?} */ (this._elementRef.nativeElement))).classList.add(...className.split(' ')); } /** * @hidden * @param {?} attribute * @param {?} value * @return {?} */ _addStyleToElement(attribute, value) { ((/** @type {?} */ (this._elementRef.nativeElement))).style[attribute] = value; } /** * @hidden * @return {?} */ ngOnChanges() { /** @type {?} */ const classList = ((/** @type {?} */ (this._elementRef.nativeElement))).classList; while (classList.length > 0) { classList.remove(classList.item(0)); } if (this.class) { this._addClassToElement(this.class); } this._setProperties(); } /** * @hidden * @return {?} */ ngOnInit() { this._setProperties(); } } AbstractFdNgxClass.propDecorators = { class: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Button directive, used to enhance standard HTML buttons. * * ```html * <button fd-button>Button Text</button> * ``` */ class ButtonDirective extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; } // TODO: deprecated, leaving for backwards compatibility /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-button'); if (this.compact) { this._addClassToElement('fd-button--compact'); } if (this.glyph) { this._addClassToElement('sap-icon--' + this.glyph); } if (this.fdType) { this._addClassToElement('fd-button--' + this.fdType); } if (this.options) { if (typeof this.options === 'string') { this._addClassToElement('fd-button--' + this.options); } else if (Array.isArray(this.options)) { this.options.forEach((/** * @param {?} option * @return {?} */ option => { if (typeof option === 'string') { this._addClassToElement('fd-button--' + option); } })); } } } } ButtonDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: '[fd-button]' },] } ]; /** @nocollapse */ ButtonDirective.ctorParameters = () => [ { type: ElementRef } ]; ButtonDirective.propDecorators = { compact: [{ type: Input }], glyph: [{ type: Input }], fdType: [{ type: Input }], semantic: [{ type: Input }], options: [{ type: Input }], size: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ButtonModule { } ButtonModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [ButtonDirective], declarations: [ButtonDirective] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @hidden * The base class for the icon component * @type {?} */ const BASE_ICON_CLASS = 'sap-icon'; /** * @hidden * Prefix for icon prop classes * @type {?} */ const PREFIX_ICON_CLASS = BASE_ICON_CLASS + '--'; /** * The directive that represents an icon. * * ```html * <fd-icon [glyph]="cart-approval" [size]="'l'"></fd-icon> * ``` */ class IconDirective extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; /** * The size of the icon * The predefined values for the input size are *xs*, *s*, *l*, and *xl*. * *size* can accept any other string, for example *xxs*, which will be translated into class *sap-icon--xxs*. */ this.size = ''; } /** * @hidden * @return {?} */ _setProperties() { if (this.glyph) { this._addClassToElement(PREFIX_ICON_CLASS + this.glyph); } if (this.size) { this._addClassToElement(PREFIX_ICON_CLASS + this.size); } } } IconDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: 'fd-icon', host: { role: 'presentation' } },] } ]; /** @nocollapse */ IconDirective.ctorParameters = () => [ { type: ElementRef } ]; IconDirective.propDecorators = { glyph: [{ type: Input }], size: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class IconModule { } IconModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [IconDirective], declarations: [IconDirective] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The parent action bar component. * * Child components: * ```html * <fd-action-bar-actions> * <fd-action-bar-back> * <fd-action-bar-description> * <fd-action-bar-header> * ``` */ class ActionBarComponent { } ActionBarComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar', template: "<div class=\"fd-action-bar\">\n <ng-content></ng-content>\n</div>" }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar title component. * * ```html * <fd-action-bar> * <fd-action-bar-header> * <h1 fd-action-bar-title>Page Title</h1> * </fd-action-bar-header> * <fd-action-bar> * ``` */ class ActionBarTitleDirective { constructor() { /** * @hidden */ this.fdActionBarTitleClass = true; } } ActionBarTitleDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-title]' },] } ]; ActionBarTitleDirective.propDecorators = { fdActionBarTitleClass: [{ type: HostBinding, args: ['class.fd-action-bar__title',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar description. * * ```html * <fd-action-bar> * <fd-action-bar-header> * <fd-action-bar-description>Page Description</fd-action-bar-description> * </fd-action-bar-header> * <fd-action-bar> * ``` */ class ActionBarDescriptionComponent { } ActionBarDescriptionComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar-description', template: "<p class=\"fd-action-bar__description\">\n <ng-content></ng-content>\n</p>" }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar header, which contains the action bar's title and description components. * * ```html * <fd-action-bar> * <fd-action-bar-header> * </fd-action-bar-header> * <fd-action-bar> * ``` */ class ActionBarHeaderComponent extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; } /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-action-bar__header'); } } ActionBarHeaderComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar-header', template: "<ng-content></ng-content>\n<ng-content select=\"fd-action-bar-description\"></ng-content>\n" }] } ]; /** @nocollapse */ ActionBarHeaderComponent.ctorParameters = () => [ { type: ElementRef } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * This component holds the right-aligned action buttons for the action bar. * * ```html * <fd-action-bar> * <fd-action-bar-actions> * <button fd-button [fdType]="'primary'">Cancel</button> * <button fd-button [fdType]="'main'">Save</button> * </fd-action-bar-actions> * <fd-action-bar> * ``` */ class ActionBarActionsComponent extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; } /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-action-bar__actions'); } } ActionBarActionsComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar-actions', template: "<ng-content></ng-content>\n" }] } ]; /** @nocollapse */ ActionBarActionsComponent.ctorParameters = () => [ { type: ElementRef } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The left-aligned back button for the action bar. * * ```html * <fd-action-bar> * <fd-action-bar-back> * <button aria-label="back" fd-button [fdType]="'light'" [compact]="true" [glyph]="'nav-back'"></button> * </fd-action-bar-back> * <fd-action-bar> * ``` */ class ActionBarBackComponent extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; } /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-action-bar__back'); } } ActionBarBackComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar-back', template: "<ng-content></ng-content>" }] } ]; /** @nocollapse */ ActionBarBackComponent.ctorParameters = () => [ { type: ElementRef } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar mobile component. This component should wrap all other action bar components, including the <fd-action-bar>. * * ```html * <fd-action-bar-mobile> * <fd-action-bar> * </fd-action-bar> * <fd-action-bar-mobile> * ``` */ class ActionBarMobileComponent { } ActionBarMobileComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar-mobile', template: "<div style=\"width:319px\">\n <ng-content></ng-content>\n</div>" }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ActionBarModule { } ActionBarModule.decorators = [ { type: NgModule, args: [{ declarations: [ ActionBarComponent, ActionBarTitleDirective, ActionBarDescriptionComponent, ActionBarHeaderComponent, ActionBarActionsComponent, ActionBarBackComponent, ActionBarMobileComponent ], imports: [CommonModule, ButtonModule, IconModule], exports: [ ActionBarComponent, ActionBarTitleDirective, ActionBarDescriptionComponent, ActionBarHeaderComponent, ActionBarActionsComponent, ActionBarBackComponent, ActionBarMobileComponent ] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class HashService { /** * @return {?} */ hash() { return 'FUI' + Math.floor(Math.random() * 1000000); } } HashService.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class UtilsModule { } UtilsModule.decorators = [ { type: NgModule, args: [{ providers: [HashService] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Reference to an alert component generated via the AlertService. * It can be injected into the content component in the same way a service would be injected. * For a template, add let-alert to your ng-template tag. Now using *alert* in the template refers to this class. */ class AlertRef { constructor() { this._afterDismissed = new Subject(); /** * Observable that is triggered when the alert is dismissed. */ this.afterDismissed = this._afterDismissed.asObservable(); } /** * Dismisses the alert. * * @param {?=} reason Data passed back to the calling component through the AfterDismissed observable. * @return {?} */ dismiss(reason) { this._afterDismissed.next(reason); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const alertFadeNgIf = trigger('fadeAlertNgIf', [ transition(':enter', [ style({ opacity: 0 }), animate('250ms ease-in-out', style({ opacity: 1 })) ]), transition(':leave', [ style({ opacity: 1, marginTop: '*', paddingTop: '*', paddingBottom: '*', height: '*', overflow: 'hidden' }), animate('400ms ease-in-out', style({ opacity: 0, marginTop: 0, paddingTop: 0, paddingBottom: 0, height: 0, overflow: 'hidden' })) ]) ]); /** @type {?} */ const alertContainerNgIf = trigger('alertContainerNgIf', [ transition(':leave', [ style({ opacity: 1 }), animate('400ms ease-in-out', style({ opacity: 0 })) ]) ]); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The component that represents an alert. It can be only be used inline. * If the AlertService is used, this component is auto-generated. */ class AlertComponent extends AbstractFdNgxClass { /** * @hidden * @param {?} hasher * @param {?} elRef * @param {?} cdRef * @param {?} componentFactoryResolver * @param {?} alertRef */ constructor(hasher, elRef, cdRef, componentFactoryResolver, alertRef) { super(elRef); this.hasher = hasher; this.elRef = elRef; this.cdRef = cdRef; this.componentFactoryResolver = componentFactoryResolver; this.alertRef = alertRef; /** * Whether the alert is dismissible. */ this.dismissible = true; /** * Duration of time *in milliseconds* that the alert will be visible. Set to -1 for indefinite. */ this.duration = 10000; /** * Whether the alert should stay open if the mouse is hovering over it. */ this.mousePersist = false; /** * Id of the element that labels the alert. */ this.ariaLabelledBy = null; /** * Aria label for the alert component element. */ this.ariaLabel = null; /** * Aria label for the dismiss button. */ this.dismissLabel = 'Dismiss'; /** * Event fired when the alert is dismissed. */ this.onDismiss = new EventEmitter(); /** * @hidden */ this.mouseInAlert = false; } /** * @hidden * @return {?} */ ngOnInit() { if (!this.id) { this.id = this.hasher.hash(); } if (this.alertRef) { this.open(); } this._setProperties(); } /** * @hidden * @return {?} */ ngAfterViewInit() { if (this.childComponentType) { if (this.childComponentType instanceof Type) { this.loadFromComponent(this.childComponentType); } else if (this.childComponentType instanceof TemplateRef) { this.loadFromTemplate(this.childComponentType); } else { this.loadFromString(this.childComponentType); } this.cdRef.detectChanges(); } } /** * Dismisses the alert. If the alert was generated via the AlertService, it is removed from the DOM. * Otherwise, it sets the display value to none. Fires the onDismiss event. * * @param {?=} reason Data to pass back to the calling component. Only usable if alert is opened using the Service. * * @param {?=} manualDismiss Set to true to skip the dismiss animation. * @return {?} */ dismiss(reason, manualDismiss = false) { if (manualDismiss) { this.elRef.nativeElement.style.display = 'none'; } if (this.alertRef) { this.alertRef.dismiss(reason); } else { this.elRef.nativeElement.style.display = 'none'; } this.onDismiss.emit(); } /** * Opens the alert. * @return {?} */ open() { if (!this.alertRef) { if (this.elRef.nativeElement.style.display === 'block') { return; } this.elRef.nativeElement.style.display = 'block'; } if (this.duration >= 0) { setTimeout((/** * @return {?} */ () => { if (this.mousePersist) { /** @type {?} */ const wait = (/** * @return {?} */ () => { if (this.mouseInAlert === true) { setTimeout(wait, 500); } else { this.dismiss(); } }); wait(); } else { this.dismiss(); } }), this.duration); } } /** * @hidden * @param {?} event * @return {?} */ handleAlertMouseEvent(event) { if (event.type === 'mouseenter') { this.mouseInAlert = true; } else if (event.type === 'mouseleave') { this.mouseInAlert = false; } } /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-alert'); if (this.type) { this._addClassToElement('fd-alert--' + this.type); } } /** * @private * @param {?} template * @return {?} */ loadFromTemplate(template) { /** @type {?} */ const context = { $implicit: this.alertRef }; this.componentRef = this.containerRef.createEmbeddedView(template, context); } /** * @private * @param {?} componentType * @return {?} */ loadFromComponent(componentType) { /** @type {?} */ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType); this.containerRef.clear(); this.componentRef = this.containerRef.createComponent(componentFactory); } /** * @private * @param {?} contentString * @return {?} */ loadFromString(contentString) { this.containerRef.clear(); this.message = contentString; } } AlertComponent.decorators = [ { type: Component, args: [{ selector: 'fd-alert', template: "<button class=\"fd-alert__close\"\n *ngIf=\"dismissible\"\n (click)=\"dismiss(undefined, true)\"\n [attr.aria-controls]=\"id\"\n [attr.aria-label]=\"dismissLabel\">\n</button>\n<ng-container #container>{{message}}</ng-container>\n<ng-content></ng-content>\n", providers: [HashService], host: { '[attr.aria-labelledby]': 'ariaLabelledBy', '[attr.aria-label]': 'ariaLabel', '[style.width]': 'width', 'role': 'alert', '[attr.id]': 'id', '(mouseenter)': 'handleAlertMouseEvent($event)', '(mouseleave)': 'handleAlertMouseEvent($event)', '[@fadeAlertNgIf]': '' }, animations: [ alertFadeNgIf ], styles: [":host{display:block}.fd-alert .fd-popover__body{position:fixed;top:auto;left:auto}"] }] } ]; /** @nocollapse */ AlertComponent.ctorParameters = () => [ { type: HashService }, { type: ElementRef }, { type: ChangeDetectorRef }, { type: ComponentFactoryResolver }, { type: AlertRef, decorators: [{ type: Optional }] } ]; AlertComponent.propDecorators = { containerRef: [{ type: ViewChild, args: ['container', { read: ViewContainerRef },] }], dismissible: [{ type: Input }], type: [{ type: Input }], id: [{ type: Input }], duration: [{ type: Input }], mousePersist: [{ type: Input }], ariaLabelledBy: [{ type: Input }], ariaLabel: [{ type: Input }], dismissLabel: [{ type: Input }], width: [{ type: Input }], message: [{ type: Input }], onDismiss: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class AlertContainerComponent { } AlertContainerComponent.decorators = [ { type: Component, args: [{ selector: 'fd-alert-container', template: ``, host: { '[@alertContainerNgIf]': '' }, animations: [ alertContainerNgIf ], styles: [` :host { position: fixed; display: flex; flex-direction: column; z-index: 5000; align-items: center; top: 0; right: 50%; left: 50%; } `] }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Configuration for opening an alert with the AlertService. */ class AlertConfig { constructor() { /** * Whether the alert is dismissible. */ this.dismissible = true; /** * Width of the alert. */ this.width = '33vw'; /** * Duration of time *in milliseconds* that the alert will be visible. Set to -1 for indefinite. */ this.duration = 10000; /** * Whether the alert should stay open if the mouse is hovering over it. */ this.mousePersist = false; /** * Id of the element that labels the alert. */ this.ariaLabelledBy = null; /** * Aria label for the alert component element. */ this.ariaLabel = null; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class AlertInjector { /** * @param {?} _parentInjector * @param {?} _additionalTokens */ constructor(_parentInjector, _additionalTokens) { this._parentInjector = _parentInjector; this._additionalTokens = _additionalTokens; } /** * @param {?} token * @param {?=} notFoundValue * @param {?=} flags * @return {?} */ get(token, notFoundValue, flags) { /** @type {?} */ const value = this._additionalTokens.get(token); if (value) { return value; } return this._parentInjector.get(token, notFoundValue); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Service used to dynamically generate an alert as an overlay. */ class AlertService { /** * @hidden * @param {?} componentFactoryResolver * @param {?} appRef * @param {?} injector */ constructor(componentFactoryResolver, appRef, injector) { this.componentFactoryResolver = componentFactoryResolver; this.appRef = appRef; this.injector = injector; this.alerts = []; } /** * Returns true if there are some alerts currently open. False otherwise. * @return {?} */ hasOpenAlerts() { return this.alerts && this.alerts.length > 0; } /** * Opens an alert component with a content of type TemplateRef, Component Type or String. * @param {?} content Content of the alert component. * @param {?=} alertConfig Configuration of the alert component. * @return {?} */ open(content, alertConfig = new AlertConfig()) { // If empty or undefined alert array, create container if (!this.alerts || this.alerts.length === 0) { this.openAlertContainer(); } // Ensure default width if (alertConfig && !alertConfig.width) { alertConfig.width = '33vw'; } // Config setup /** @type {?} */ const configMap = new WeakMap(); /** @type {?} */ const alertRef = new AlertRef(); alertRef.data = (alertConfig ? alertConfig.data : undefined); configMap.set(AlertRef, alertRef); // Prepare new component /** @type {?} */ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(AlertComponent); /** @type {?} */ const componentRef = componentFactory.create(new AlertInjector(this.injector, configMap)); componentRef.location.nativeElement.style.marginTop = '10px'; this.appRef.attachView(componentRef.hostView); // Subscription to close alert from ref /** @type {?} */ const refSub = alertRef.afterDismissed.subscribe((/** * @return {?} */ () => { this.destroyAlertComponent(componentRef); refSub.unsubscribe(); })); // Prepare component data items /** @type {?} */ const configObj = Object.assign({}, alertConfig); Object.keys(configObj).forEach((/** * @param {?} key * @return {?} */ key => { if (key !== 'data') { componentRef.instance[key] = configObj[key]; } })); componentRef.instance.childComponentType = content; // Render new component /** @type {?} */ const domElem = (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView))).rootNodes[0])); this.alertContainerRef.location.nativeElement.appendChild(domElem); // Log new component this.alerts.push(componentRef); return alertRef; } /** * Dismisses all service-opened alerts. * @return {?} */ dismissAll() { this.alerts.forEach((/** * @param {?} ref * @return {?} */ ref => { this.destroyAlertComponent(ref); })); } /** * @private * @param {?} alert * @return {?} */ destroyAlertComponent(alert) { this.alerts[this.alerts.indexOf(alert)] = null; this.alerts = this.alerts.filter((/** * @param {?} item * @return {?} */ item => item !== null && item !== undefined)); this.appRef.detachView(alert.hostView); alert.destroy(); if (this.alertContainerRef && (!this.alerts || this.alerts.length === 0)) { this.destroyAlertContainer(); } } /** * @private * @return {?} */ openAlertContainer() { /** @type {?} */ const factory = this.componentFactoryResolver.resolveComponentFactory(AlertContainerComponent); /** @type {?} */ const componentRef = factory.create(this.injector); this.appRef.attachView(componentRef.hostView); /** @type {?} */ const domElement = (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView))).rootNodes[0])); document.body.appendChild(domElement); this.alertContainerRef = componentRef; } /** * @private * @return {?} */ destroyAlertContainer() { this.appRef.detachView(this.alertContainerRef.hostView); this.alertContainerRef.destroy(); this.alertContainerRef = undefined; } } AlertService.decorators = [ { type: Injectable } ]; /** @nocollapse */ AlertService.ctorParameters = () => [ { type: ComponentFactoryResolver }, { type: ApplicationRef }, { type: Injector } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class AlertModule { } AlertModule.decorators = [ { type: NgModule, args: [{ declarations: [AlertComponent, AlertContainerComponent], imports: [CommonModule, IconModule, UtilsModule], exports: [AlertComponent, AlertContainerComponent], entryComponents: [AlertContainerComponent, AlertComponent], providers: [AlertService] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Badge component, used to indicate status. * Colors, generally in combination with text, are used to easily highlight the state of an object. */ class BadgeComponent extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); } /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-badge'); if (this.status) { this._addClassToElement('fd-badge--' + this.status); } if (this.modifier) { this._addClassToElement('fd-badge--' + this.modifier); } } } BadgeComponent.decorators = [ { type: Component, args: [{ selector: 'fd-badge', template: "<span><ng-content></ng-content></span>\n" }] } ]; /** @nocollapse */ BadgeComponent.ctorParameters = () => [ { type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] } ]; BadgeComponent.propDecorators = { status: [{ type: Input }], modifier: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Badge component, used to indicate status. * Colors, generally in combination with text, are used to easily highlight the state of an object. */ class LabelComponent extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); /** * Color coded status for the label. Options are 'success', 'warning', and 'error'. Leave empty for default label. */ this.status = ''; /** * When set to 'true', the type of the label is 'Status Indicator Label'. Leave empty for default type. */ this.isStatusLabel = false; /** * Built-in status icon. Options include 'available', 'away', 'busy', and 'offline'. */ this.statusIcon = ''; /** * The icon used with the status indicator. See the icon page for the list of icons. */ this.icon = ''; } /** * @hidden * @return {?} */ _setProperties() { if (this.isStatusLabel) { this._addClassToElement('fd-status-label'); if (this.status) { this._addClassToElement('fd-status-label--' + this.status); } if (this.statusIcon) { this._addClassToElement('fd-status-label--' + this.statusIcon); } if (this.icon) { this._addClassToElement('sap-icon--' + this.icon); } } else { this._addClassToElement('fd-label'); if (this.status) { this._addClassToElement('fd-label--' + this.status); } } } } LabelComponent.decorators = [ { type: Component, args: [{ selector: 'fd-label', template: "<span><ng-content></ng-content></span>\n" }] } ]; /** @nocollapse */ LabelComponent.ctorParameters = () => [ { type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] } ]; LabelComponent.propDecorators = { status: [{ type: Input }], isStatusLabel: [{ type: Input }], statusIcon: [{ type: Input }], icon: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class BadgeLabelModule { } BadgeLabelModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [BadgeComponent, LabelComponent], declarations: [BadgeComponent, LabelComponent] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Breadcrumb parent wrapper directive. Must have breadcrumb item child directives. * * ```html * <fd-breadcrumb> * <fd-breadcrumb-item> * <a fd-breadcrumb-link [routerLink]="'#'">Breadcrumb Link</a> * </fd-breadcrumb-item> * </fd-breadcrumb> * ``` */ class BreadcrumbDirective { } BreadcrumbDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: 'fd-breadcrumb', host: { class: 'fd-breadcrumb' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Breadcrumb item directive. Must have child breadcrumb link directives. * * ```html * <fd-breadcrumb-item> * <a fd-breadcrumb-link [routerLink]="'#'">Breadcrumb Link</a> * </fd-breadcrumb-item> * ``` */ class BreadcrumbItemDirective { } BreadcrumbItemDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: 'fd-breadcrumb-item', host: { class: 'fd-breadcrumb__item' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Breadcrumb link directive. Use Angular router options (such as 'routerLink' and 'queryParams') with this directive. * * ```html * <a fd-breadcrumb-link [routerLink]="'some-url'" [queryParams]="'params'">Breadcrumb Link</a> * ``` */ class BreadcrumbLinkDirective { } BreadcrumbLinkDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: '[fd-breadcrumb-link]', host: { class: 'fd-breadcrumb__link' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class BreadcrumbModule { } BreadcrumbModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [BreadcrumbDirective, BreadcrumbItemDirective, BreadcrumbLinkDirective], declarations: [BreadcrumbDirective, BreadcrumbItemDirective, BreadcrumbLinkDirective] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Container for grouped buttons. * * ```html * <fd-button-group> * <button fd-button-grouped>Button</button> * </fd-button-group> * ``` */ class ButtonGroupComponent { constructor() { /** * @hidden */ this.fdButtonGroupClass = true; } } ButtonGroupComponent.decorators = [ { type: Component, args: [{ selector: 'fd-button-group', template: "<ng-content></ng-content>\n", host: { 'role': 'group' } }] } ]; ButtonGroupComponent.propDecorators = { fdButtonGroupClass: [{ type: HostBinding, args: ['class.fd-button-group',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Directive to be applied to buttons that are members of a button group. * * ```html * <button fd-button-grouped>Button</button> * ``` */ class ButtonGroupedDirective extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; /** * Whether the button should be in compact form. */ this.compact = false; /** * @hidden */ this.fdButtonGroupedClass = true; } /** * @hidden * @return {?} */ _setProperties() { if (this.size) { this._addClassToElement('fd-button--' + this.size); } if (this.glyph) { this._addClassToElement('sap-icon--' + this.glyph); } if (this.state) { this._addClassToElement('is-' + this.state); } } } ButtonGroupedDirective.decorators = [ { type: Directive, args: [{ // TODO to be discussed // tslint:disable-next-line:directive-selector selector: '[fd-button-grouped]' },] } ]; /** @nocollapse */ ButtonGroupedDirective.ctorParameters = () => [ { type: ElementRef } ]; ButtonGroupedDirective.propDecorators = { size: [{ type: Input }], glyph: [{ type: Input }], state: [{ type: Input }], compact: [{ type: Input }, { type: HostBinding, args: ['class.fd-button--compact',] }], fdButtonGroupedClass: [{ type: HostBinding, args: ['class.fd-button--grouped',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ButtonGroupModule { } ButtonGroupModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [ButtonGroupComponent, ButtonGroupedDirective], declarations: [ButtonGroupComponent, ButtonGroupedDirective] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} locale * @return {?} */ function CALENDAR_I18N_FACTORY(locale) { return new CalendarI18nDefault(locale); } /** * Abstract class which defines the behaviour calendar internationalization. See calendar examples for usage details. * @abstract */ class CalendarI18n { constructor() { /** * Stream to call if the values are changed dynamically. Calendar subscribes to this internally. */ this.i18nChange = new Subject(); } } CalendarI18n.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: CALENDAR_I18N_FACTORY, deps: [LOCALE_ID] },] } ]; /** @nocollapse */ CalendarI18n.ngInjectableDef = defineInjectable({ factory: function CalendarI18n_Factory() { return CALENDAR_I18N_FACTORY(inject(LOCALE_ID)); }, token: CalendarI18n, providedIn: "root" }); /** * Default implementation of the CalendarI18n service. It will get dates from the application locale if it is present. */ class CalendarI18nDefault extends CalendarI18n { /** * Constructor takes in a locale_id and gets the appropriate data from Angular. * @param {?} locale */ constructor(locale) { super(); this.locale = locale; this.weekdaysFallback = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; this.monthsFullFallback = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; this.monthsShortFallback = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; if (locale) { /** @type {?} */ const sundayStartWeekdays = getLocaleDayNames(locale, FormStyle.Standalone, TranslationWidth.Short); this.weekdaysShort = sundayStartWeekdays.map((/** * @param {?} day * @param {?} index * @return {?} */ (day, index) => sundayStartWeekdays[(index + 1) % 7])); this.monthsShort = getLocaleMonthNames(locale, FormStyle.Standalone, TranslationWidth.Abbreviated); this.monthsFull = getLocaleMonthNames(locale, FormStyle.Standalone, TranslationWidth.Wide); // Used to keep 0 = Sunday, 1 = Monday and so on. if (this.weekdaysShort) { this.weekdaysShort.unshift(this.weekdaysShort.pop()); } } this.checkForFallback(); } /** * Aria label for a specific date. Default implementation produces the label: {Date} {Month} {Year}. * * @param {?} date Native date object to use for the label. * @return {?} */ getDayAriaLabel(date) { return date.getDate() + ' ' + this.monthsFull[date.getMonth()] + ' ' + date.getFullYear(); } /** * Get all full month names. * @return {?} */ getAllFullMonthNames() { return this.monthsFull; } /** * Get all short month names, such as Nov for November. * @return {?} */ getAllShortMonthNames() { return this.monthsShort; } /** * Get all short week day names, such as Mo for Monday. * @return {?} */ getAllShortWeekdays() { return this.weekdaysShort; } /** * Checks if a fallback is needed. Older versions of Angular may need this. * @private * @return {?} */ checkForFallback() { if (!this.weekdaysShort || this.weekdaysShort.length === 0) { this.weekdaysShort = this.weekdaysFallback; } if (!this.monthsShort || this.monthsShort.length === 0) { this.monthsShort = this.monthsShortFallback; } if (!this.monthsFull || this.monthsFull.length === 0) { this.monthsFull = this.monthsFullFallback; } } } CalendarI18nDefault.decorators = [ { type: Injectable } ]; /** @nocollapse */ CalendarI18nDefault.ctorParameters = () => [ { type: String, decorators: [{ type: Optional }, { type: Inject, args: [LOCALE_ID,] }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Provides i18n support for labels inside the calendar component. */ class CalendarI18nLabels { constructor() { // This will be needed when we use OnPush change detection. // readonly labelsChange: Subject<void> = new Subject<void>(); /** * Year selection aria label. Used on the button to navigate to the years view. */ this.yearSelectionLabel = 'Year selection'; /** * Previous year aria label. Used on the button to switch to a previous year in the years view. */ this.previousYearLabel = 'Previous year'; /** * Next year aria label. Used on the button to switch to a next year in the years view. */ this.nextYearLabel = 'Next year'; /** * Month selection aria label. Used on the button to navigate to the months view. */ this.monthSelectionLabel = 'Month selection'; /** * Previous month aria label. Used on the button to switch to a previous month in the months view. */ this.previousMonthLabel = 'Previous month'; /** * Next month aria label. Used on the button to switch to a next month in the months view. */ this.nextMonthLabel = 'Next month'; } } CalendarI18nLabels.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ CalendarI18nLabels.ngInjectableDef = defineInjectable({ factory: function CalendarI18nLabels_Factory() { return new CalendarI18nLabels(); }, token: CalendarI18nLabels, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @return {?} */ function DATE_FORMAT_FACTORY() { return new DateFormatParserDefault(); } /** * Abstract class which defines the behaviour of the date format and parser. * @abstract */ class DateFormatParser { constructor() { /** * Delimiter for the range. This should not show up in the string representation of the dates. */ this.rangeDelimiter = ' - '; } } DateFormatParser.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: DATE_FORMAT_FACTORY },] } ]; /** @nocollapse */ DateFormatParser.ngInjectableDef = defineInjectable({ factory: DATE_FORMAT_FACTORY, token: DateFormatParser, providedIn: "root" }); /** * Default implementation of the DateForma