fundamental-ngx
Version:
SAP Fiori Fundamentals, implemented in Angular
1,614 lines (1,578 loc) • 346 kB
JavaScript
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