UNPKG

fundamental-ngx

Version:

SAP Fundamentals, implemented in Angular

1,619 lines (1,584 loc) 515 kB
import Popper from 'popper.js'; import { animate, style, transition, trigger } from '@angular/animations'; import focusTrap from 'focus-trap'; import { takeUntil, startWith, switchMap } from 'rxjs/operators'; import { Subject, fromEvent, defer, merge } from 'rxjs'; import { NG_VALIDATORS, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { CommonModule, FormStyle, getLocaleDayNames, getLocaleMonthNames, TranslationWidth } from '@angular/common'; import { Input, Directive, ElementRef, NgModule, Component, ViewEncapsulation, ChangeDetectorRef, ViewChild, ComponentFactoryResolver, Type, ViewContainerRef, TemplateRef, Optional, Output, EventEmitter, HostListener, HostBinding, Injectable, ApplicationRef, Injector, Inject, forwardRef, ContentChild, Pipe, isDevMode, ContentChildren, ViewChildren, Renderer2, LOCALE_ID, defineInjectable, inject } from '@angular/core'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,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,constantProperty,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,constantProperty,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,constantProperty,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 component that represents an icon. * * ```html * <fd-icon [glyph]="cart-approval" [size]="'l'"></fd-icon> * ``` */ class IconComponent 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); } } } IconComponent.decorators = [ { type: Component, args: [{ selector: 'fd-icon', template: ``, host: { role: 'presentation' }, encapsulation: ViewEncapsulation.None }] } ]; /** @nocollapse */ IconComponent.ctorParameters = () => [ { type: ElementRef } ]; IconComponent.propDecorators = { glyph: [{ type: Input }], size: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class IconModule { } IconModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [IconComponent], declarations: [IconComponent] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The parent action bar directive. * * Children usage: * ```html * <div fd-action-bar-actions> * <div fd-action-bar-back> * <div fd-action-bar-description> * <div fd-action-bar-header> * <div fd-action-bar-mobile> * <h1 fd-action-bar-title> * ``` */ class ActionBarDirective { } ActionBarDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar]', host: { class: 'fd-action-bar' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar title component. * * ```html * <fd-action-bar> * <div fd-action-bar-header> * <h1 fd-action-bar-title>Page Title</h1> * </div> * <fd-action-bar> * ``` */ class ActionBarTitleDirective { } ActionBarTitleDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-title]', host: { class: 'fd-action-bar__title' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar description. * * ```html * <div fd-action-bar> * <div fd-action-bar-header> * <div fd-action-bar-description>Page Description</div> * </div> * <div> * ``` */ class ActionBarDescriptionDirective { } ActionBarDescriptionDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-description]' },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The action bar header, which contains the action bar's title and description components. * * ```html * <div fd-action-bar> * <div fd-action-bar-header> * </div> * </div> * ``` */ class ActionBarHeaderDirective { } ActionBarHeaderDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-header]', host: { class: 'fd-action-bar__header' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * This component holds the right-aligned action buttons for the action bar. * * ```html * <div fd-action-bar> * <div fd-action-bar-actions> * <button fd-button [fdType]="'primary'">Cancel</button> * <button fd-button [fdType]="'main'">Save</button> * </div> * </div> * ``` */ class ActionBarActionsDirective { } ActionBarActionsDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-actions]', host: { class: 'fd-action-bar__actions' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The left-aligned back button for the action bar. * * ```html * <div fd-action-bar> * <div fd-action-bar-back> * <button aria-label="back" fd-button [fdType]="'light'" [compact]="true" [glyph]="'nav-back'"></button> * </div> * </div> * ``` */ class ActionBarBackDirective { } ActionBarBackDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-back]', host: { class: 'fd-action-bar__back' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,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 * <div fd-action-bar-mobile> * <div fd-action-bar> * </div> * </div> * ``` */ class ActionBarMobileDirective { } ActionBarMobileDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-action-bar-mobile]', host: { style: 'width: 319px;' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ActionBarModule { } ActionBarModule.decorators = [ { type: NgModule, args: [{ declarations: [ ActionBarDirective, ActionBarTitleDirective, ActionBarDescriptionDirective, ActionBarHeaderDirective, ActionBarActionsDirective, ActionBarBackDirective, ActionBarMobileDirective ], imports: [CommonModule, ButtonModule, IconModule], exports: [ ActionBarDirective, ActionBarTitleDirective, ActionBarDescriptionDirective, ActionBarHeaderDirective, ActionBarActionsDirective, ActionBarBackDirective, ActionBarMobileDirective ] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,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,constantProperty,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,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let alertUniqueId = 0; /** * 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 {?} elRef * @param {?} cdRef * @param {?} componentFactoryResolver * @param {?} alertRef */ constructor(elRef, cdRef, componentFactoryResolver, alertRef) { super(elRef); this.elRef = elRef; this.cdRef = cdRef; this.componentFactoryResolver = componentFactoryResolver; this.alertRef = alertRef; /** * Whether the alert is dismissible. */ this.dismissible = true; /** * Id for the alert component. If omitted, a unique one is generated. */ this.id = 'fd-alert-' + alertUniqueId++; /** * 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.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.classList.add('fd-has-display-none'); this.elRef.nativeElement.classList.remove('fd-has-display-block'); } if (this.alertRef) { this.alertRef.dismiss(reason); } else { this.elRef.nativeElement.classList.add('fd-has-display-none'); this.elRef.nativeElement.classList.remove('fd-has-display-block'); } this.onDismiss.emit(); } /** * Opens the alert. * @return {?} */ open() { if (!this.alertRef) { if (this.elRef.nativeElement.style.display === 'block') { return; } this.elRef.nativeElement.classList.remove('fd-has-display-none'); this.elRef.nativeElement.classList.add('fd-has-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); } if (this.dismissible) { this._addClassToElement('fd-alert--dismissible'); } } /** * @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", host: { '[attr.aria-labelledby]': 'ariaLabelledBy', '[attr.aria-label]': 'ariaLabel', '[style.width]': 'width', '[style.min-width]': 'minWidth', 'role': 'alert', '[attr.id]': 'id', '[@fadeAlertNgIf]': '' }, animations: [ alertFadeNgIf ], encapsulation: ViewEncapsulation.None, styles: [".fd-alert{display:block}"] }] } ]; /** @nocollapse */ AlertComponent.ctorParameters = () => [ { 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 }], minWidth: [{ type: Input }], message: [{ type: Input }], onDismiss: [{ type: Output }], handleAlertMouseEvent: [{ type: HostListener, args: ['mouseenter', ['$event'],] }, { type: HostListener, args: ['mouseleave', ['$event'],] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class AlertContainerComponent { constructor() { /** * @hidden */ this.fdAlertContainerClass = true; } } AlertContainerComponent.decorators = [ { type: Component, args: [{ selector: 'fd-alert-container', template: ``, host: { '[@alertContainerNgIf]': '' }, animations: [ alertContainerNgIf ], encapsulation: ViewEncapsulation.None, styles: [` .fd-alert-container { position: fixed; display: flex; flex-direction: column; z-index: 5000; align-items: center; top: 0; right: 50%; left: 50%; } `] }] } ]; AlertContainerComponent.propDecorators = { fdAlertContainerClass: [{ type: HostBinding, args: ['class.fd-alert-container',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,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'; /** * Minimum width of the alert. */ this.minWidth = '300px'; /** * 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,constantProperty,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,constantProperty,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(); } // Get default values from alert model alertConfig = Object.assign(new AlertConfig(), alertConfig); // 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,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class AlertModule { } AlertModule.decorators = [ { type: NgModule, args: [{ declarations: [AlertComponent, AlertContainerComponent], imports: [CommonModule, IconModule], exports: [AlertComponent, AlertContainerComponent], entryComponents: [AlertContainerComponent, AlertComponent], providers: [AlertService] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Badge directive, used to indicate status. * Colors, generally in combination with text, are used to easily highlight the state of an object. */ class BadgeDirective extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; /** * @hidden */ this.fdBadgeClass = true; } /** * @hidden * @return {?} */ _setProperties() { if (this.status) { this._addClassToElement('fd-badge--' + this.status); } if (this.modifier) { this._addClassToElement('fd-badge--' + this.modifier); } } } BadgeDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-badge]' },] } ]; /** @nocollapse */ BadgeDirective.ctorParameters = () => [ { type: ElementRef } ]; BadgeDirective.propDecorators = { status: [{ type: Input }], modifier: [{ type: Input }], fdBadgeClass: [{ type: HostBinding, args: ['class.fd-badge',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Label directive, used to indicate status, without any background or border * Colors, generally in combination with text, are used to easily highlight the state of an object. */ class LabelDirective extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; /** * Color coded status for the label. Options are 'success', 'warning', and 'error'. Leave empty for default label. */ this.status = ''; } /** * @hidden * @return {?} */ _setProperties() { this._addClassToElement('fd-label'); if (this.status) { this._addClassToElement('fd-label--' + this.status); } } } LabelDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-label]' },] } ]; /** @nocollapse */ LabelDirective.ctorParameters = () => [ { type: ElementRef } ]; LabelDirective.propDecorators = { status: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Status Label directive with some default icons based on status input used to indicate status. * Icons are used to easily highlight the state of an object. */ class StatusLabelDirective extends AbstractFdNgxClass { /** * @hidden * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.elementRef = elementRef; /** * Color coded status for the label. Options are 'success', 'warning', and 'error'. Leave empty for default label. */ this.status = ''; /** * 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() { 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); } } } StatusLabelDirective.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[fd-status-label]' },] } ]; /** @nocollapse */ StatusLabelDirective.ctorParameters = () => [ { type: ElementRef } ]; StatusLabelDirective.propDecorators = { status: [{ type: Input }], statusIcon: [{ type: Input }], icon: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class BadgeLabelModule { } BadgeLabelModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule], exports: [BadgeDirective, LabelDirective, StatusLabelDirective], declarations: [BadgeDirective, LabelDirective, StatusLabelDirective] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,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,constantProperty,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,constantProperty,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,constantProperty,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,constantProperty,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' }, encapsulation: ViewEncapsulation.None }] } ]; ButtonGroupComponent.propDecorators = { fdButtonGroupClass: [{ type: HostBinding, args: ['class.fd-button-group',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,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,constantProperty,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,constantProperty,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,constantProperty,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 % 7])); this.monthsShort = getLocaleMonthNames(locale, FormStyle.Standalone, TranslationWidth.Abbreviated); this.monthsFull = getLocaleMonthNames(locale, FormStyle.Standalone, TranslationWidth.Wide); } 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,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Internal use only. * Header of the calendar component. */ class CalendarHeaderComponent { /** * @param {?} calendarI18nLabels * @param {?} calendarI18n */ constructor(calendarI18nLabels, calendarI18n) { this.cale