UNPKG

fundamental-ngx

Version:

SAP Fiori Fundamentals, implemented in Angular

1,614 lines (1,578 loc) 346 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 { Injectable, Component, ElementRef, Input, Inject, Directive, Output, EventEmitter, HostListener, HostBinding, forwardRef, ContentChild, TemplateRef, ViewContainerRef, ViewChild, NgModule, ChangeDetectorRef, ContentChildren, ViewChildren, Type, ComponentFactoryResolver, Optional, ApplicationRef, Injector, Renderer2, defineInjectable } from '@angular/core'; import { CommonModule } 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 */ class FundamentalNgxService { constructor() { } } FundamentalNgxService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ FundamentalNgxService.ctorParameters = () => []; /** @nocollapse */ FundamentalNgxService.ngInjectableDef = defineInjectable({ factory: function FundamentalNgxService_Factory() { return new FundamentalNgxService(); }, token: FundamentalNgxService, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class FundamentalNgxComponent { constructor() { } /** * @return {?} */ ngOnInit() { } } FundamentalNgxComponent.decorators = [ { type: Component, args: [{ selector: 'fd-fundamental-ngx', template: ` <p> fundamental-ngx works! </p> ` }] } ]; /** @nocollapse */ FundamentalNgxComponent.ctorParameters = () => []; /** * @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 */ class ButtonDirective extends AbstractFdNgxClass { /** * @param {?} elementRef */ constructor(elementRef) { super(elementRef); } // TODO: deprecated, leaving for backwards compatibility /** * @return {?} */ _setProperties() { this._addClassToElement('fd-button'); if (this.compact) { this._addClassToElement('fd-button--compact'); } if (this.size) { this._addClassToElement('fd-button--' + this.size); } if (this.glyph) { this._addClassToElement('sap-icon--' + this.glyph); } if (this.fdType) { this._addClassToElement('fd-button--' + this.fdType); } if (this.semantic) { this._addClassToElement('fd-button--' + this.semantic); } if (this.state) { this._addClassToElement('is-' + this.state); } 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, decorators: [{ type: Inject, args: [ElementRef,] }] } ]; ButtonDirective.propDecorators = { compact: [{ type: Input }], glyph: [{ type: Input }], fdType: [{ type: Input }], semantic: [{ type: Input }], state: [{ 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 */ /** * The base class for the icon component * @type {?} */ const BASE_ICON_CLASS = 'sap-icon'; /** * Prefix for icon prop classes * @type {?} */ const PREFIX_ICON_CLASS = BASE_ICON_CLASS + '--'; class IconDirective extends AbstractFdNgxClass { /** * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.size = ''; } /** * @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, decorators: [{ type: Inject, args: [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> * <fd-action-bar-title> * ``` */ 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> * <fd-action-bar-title>Page Title</fd-action-bar-title> * </fd-action-bar-header> * <fd-action-bar> * ``` */ class ActionBarTitleComponent { } ActionBarTitleComponent.decorators = [ { type: Component, args: [{ selector: 'fd-action-bar-title', template: "<h1 class=\"fd-action-bar__title\">\n <ng-content></ng-content>\n</h1>\n" }] } ]; /** * @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 select=\"fd-action-bar-title\"></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, ActionBarTitleComponent, ActionBarDescriptionComponent, ActionBarHeaderComponent, ActionBarActionsComponent, ActionBarBackComponent, ActionBarMobileComponent ], imports: [CommonModule, ButtonModule, IconModule], exports: [ ActionBarComponent, ActionBarTitleComponent, 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. * @return {?} */ dismiss() { this._afterDismissed.next(); } } /** * @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; /** * \@Input Whether the alert is dismissible. */ this.dismissible = true; /** * \@Input Duration of time *in milliseconds* that the alert will be visible. Set to -1 for indefinite. */ this.duration = 10000; /** * \@Input Whether the alert should stay open if the mouse is hovering over it. */ this.mousePersist = false; /** * \@Input Id of the element that labels the alert. */ this.ariaLabelledBy = null; /** * \@Input Aria label for the alert component element. */ this.ariaLabel = null; /** * \@Output 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 {?=} manualDismiss Set to true to skip the dismiss animation. * @return {?} */ dismiss(manualDismiss = false) { if (manualDismiss) { this.elRef.nativeElement.style.display = 'none'; } if (this.alertRef) { this.alertRef.dismiss(); } 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(true)\"\n [attr.aria-controls]=\"id\"\n aria-label=\"Dismiss\">\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 }], 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 */ class BadgeComponent extends AbstractFdNgxClass { /** * @param {?} elementRef */ constructor(elementRef) { super(elementRef); } /** * @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 */ class LabelComponent extends AbstractFdNgxClass { /** * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.status = ''; this.isStatusLabel = false; this.statusIcon = ''; this.indicator = ''; this.icon = ''; this.semantic = ''; } /** * @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 }], indicator: [{ type: Input }], icon: [{ type: Input }], semantic: [{ 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 */ 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 */ 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 */ 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 */ class ButtonGroupComponent { } ButtonGroupComponent.decorators = [ { type: Component, args: [{ selector: 'fd-button-group', template: "<ng-content></ng-content>\n", host: { 'role': 'group', 'aria-label': 'Group label', class: 'fd-button-group' } }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ButtonGroupedDirective extends AbstractFdNgxClass { /** * @param {?} elementRef */ constructor(elementRef) { super(elementRef); this.compact = false; } /** * @return {?} */ _setProperties() { this._addClassToElement('fd-button--grouped'); if (this.size) { this._addClassToElement('fd-button--' + this.size); } if (this.glyph) { this._addClassToElement('sap-icon--' + this.glyph); } if (this.compact) { this._addClassToElement('fd-button--compact'); } 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, decorators: [{ type: Inject, args: [ElementRef,] }] } ]; ButtonGroupedDirective.propDecorators = { id: [{ type: Input }], size: [{ type: Input }], glyph: [{ type: Input }], state: [{ type: Input }], compact: [{ type: Input }] }; /** * @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 */ class CalendarComponent { /** * @param {?} hasher * @param {?} eRef * @param {?} cd */ constructor(hasher, eRef, cd) { this.hasher = hasher; this.eRef = eRef; this.cd = cd; this.init = false; this.calType = 'single'; this.mondayStartOfWeek = false; this.isInvalidDateInput = new EventEmitter(); this.isDateTimePicker = false; this.invalidDate = false; this.showCalendarMonths = false; this.showCalendarYears = false; this.showCalendarDates = true; this.monthsShortName = [ 'Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.' ]; this.monthsFullName = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; this.daysPerMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; this.calendarGrid = []; this.calendarYearsList = []; this.today = new Date(); this.todayMonth = this.today.getMonth(); this.todayYear = this.today.getFullYear(); this.date = new Date(); this.month = this.date.getMonth(); this.monthName = this.monthsFullName[this.month]; this.year = this.date.getFullYear(); this.day = this.date.getDate(); this.firstYearCalendarList = this.year; this.selectCounter = 0; this.selectedDay = { date: null }; this.selectedDayChange = new EventEmitter(); this.selectedRangeFirst = { date: null }; this.selectedRangeFirstChange = new EventEmitter(); this.selectedRangeLast = { date: null }; this.selectedRangeLastChange = new EventEmitter(); this.emittedDate = { selectedDay: this.selectedDay, selectedFirstDay: this.selectedRangeFirst, selectedLastDay: this.selectedRangeLast }; this.closeCalendar = new EventEmitter(); this.disableFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); this.blockFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); this.onChange = (/** * @return {?} */ () => { }); this.onTouched = (/** * @return {?} */ () => { }); // A function that determines the number of days in a particular month this.determineDaysInMonth = (/** * @param {?} month * @param {?} year * @return {?} */ function (month, year) { if (month === 1) { if ((year % 100 !== 0 && year % 4 === 0) || year % 400 === 0) { return 29; } else { return this.daysPerMonth[month]; } } else { return this.daysPerMonth[month]; } }); } /** * @param {?} calendarMonth * @return {?} */ getPreviousMonthDays(calendarMonth) { // Previous month days /** @type {?} */ let prevMonthLastDate; if (this.mondayStartOfWeek) { prevMonthLastDate = new Date(this.date.getFullYear(), this.date.getMonth(), -1); } else { prevMonthLastDate = new Date(this.date.getFullYear(), this.date.getMonth(), 0); } /** @type {?} */ const prevMonth = prevMonthLastDate.getMonth(); /** @type {?} */ const prevMonthYear = prevMonthLastDate.getFullYear(); /** @type {?} */ const prevMonthLastDay = prevMonthLastDate.getDate(); /** @type {?} */ let prevMonthLastWeekDay = prevMonthLastDate.getDay(); if (prevMonthLastWeekDay < 6) { while (prevMonthLastWeekDay >= 0) { /** @type {?} */ const prevMonthDay = prevMonthLastDay - prevMonthLastWeekDay; /** @type {?} */ const calDate = new Date(prevMonthYear, prevMonth, prevMonthDay); /** @type {?} */ const previousMonthCalendarDay = { date: calDate, day: calDate.getDate(), weekDay: calDate.getDay(), monthStatus: 'previous', disabled: this.disableFunction(calDate), blocked: this.blockFunction(calDate), selected: (this.selectedDay.date && calDate.toDateString() === this.selectedDay.date.toDateString()) || (this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString()) || (this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString()), selectedFirst: this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString(), selectedLast: this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString(), selectedRange: this.selectedRangeFirst.date && calDate.getTime() > this.selectedRangeFirst.date.getTime() && this.selectedRangeLast.date && calDate.getTime() < this.selectedRangeLast.date.getTime() }; calendarMonth.push(previousMonthCalendarDay); prevMonthLastWeekDay--; } } return calendarMonth; } /** * @param {?} calendarMonth * @return {?} */ getCurrentMonthDays(calendarMonth) { /** @type {?} */ const numOfDaysInCurrentMonth = this.determineDaysInMonth(this.month, this.year); // Current month days /** @type {?} */ let foundSelected = false; for (let d = 1; d <= numOfDaysInCurrentMonth; d++) { /** @type {?} */ const calDate = new Date(this.date.getFullYear(), this.date.getMonth(), d); /** @type {?} */ const currMonthCalendarDay = { date: calDate, day: calDate.getDate(), weekDay: calDate.getDay(), monthStatus: 'current', disabled: this.disableFunction(calDate), blocked: this.blockFunction(calDate), selected: (this.selectedDay.date && calDate.toDateString() === this.selectedDay.date.toDateString()) || (this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString()) || (this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString()), selectedFirst: this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString(), selectedLast: this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString(), selectedRange: this.selectedRangeFirst.date && calDate.getTime() > this.selectedRangeFirst.date.getTime() && this.selectedRangeLast.date && calDate.getTime() < this.selectedRangeLast.date.getTime(), today: calDate.toDateString() === this.today.toDateString(), isTabIndexed: false }; // if a day is selected, it should be tab indexed if (currMonthCalendarDay.selected) { foundSelected = true; currMonthCalendarDay.isTabIndexed = true; } calendarMonth.push(currMonthCalendarDay); } if (!foundSelected) { /** @type {?} */ let foundToday = false; for (let d = 0; d < numOfDaysInCurrentMonth; d++) { // if no day is selected, tab index today if (calendarMonth[d] && calendarMonth[d].today) { fo