theme-lib
Version:
This is a simple example Angular Library published to npm.
1,625 lines (1,606 loc) • 1.51 MB
JavaScript
import { InjectionToken, Inject, Injectable, Optional, NgModule, NgZone, ApplicationRef, ComponentFactoryResolver, Directive, Injector, Component, Input, HostBinding, ViewChild, TemplateRef, Type, ChangeDetectionStrategy, forwardRef, EventEmitter, Output, ChangeDetectorRef, ElementRef, HostListener, ViewChildren, ViewContainerRef, ContentChildren, PLATFORM_ID, ContentChild, Renderer2, Host, LOCALE_ID, defineInjectable, inject } from '@angular/core';
import { ReplaySubject, Subject, Observable, fromEvent, merge, BehaviorSubject, of, forkJoin, interval, timer, defer } from 'rxjs';
import { map, filter, pairwise, distinctUntilChanged, startWith, share, debounceTime, delay, repeat, switchMap, takeUntil, takeWhile, take } from 'rxjs/operators';
import { CommonModule, isPlatformBrowser, DOCUMENT, Location, DatePipe, getLocaleFirstDayOfWeek, TranslationWidth, getLocaleMonthNames, FormStyle, getLocaleDayNames } from '@angular/common';
import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators } from '@angular/forms';
import { RouterModule, NavigationEnd, Router, ActivatedRoute } from '@angular/router';
import { FocusTrap, FocusTrapFactory, InteractivityChecker } from '@angular/cdk/a11y';
import { CdkPortal, CdkPortalOutlet, ComponentPortal, DomPortalOutlet, PortalInjector, PortalModule, TemplatePortal } from '@angular/cdk/portal';
import { FlexibleConnectedPositionStrategy, Overlay, OverlayConfig, OverlayContainer, OverlayKeyboardDispatcher, OverlayModule, OverlayPositionBuilder, OverlayRef, ScrollStrategyOptions, ViewportRuler, GlobalPositionStrategy, ScrollDispatcher, BlockScrollStrategy } from '@angular/cdk/overlay';
import { Platform } from '@angular/cdk/platform';
import { Directionality } from '@angular/cdk/bidi';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { DomSanitizer } from '@angular/platform-browser';
import 'intersection-observer';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const NB_THEME_OPTIONS = new InjectionToken('Nebular Theme Options');
/** @type {?} */
const NB_MEDIA_BREAKPOINTS = new InjectionToken('Nebular Media Breakpoints');
/** @type {?} */
const NB_BUILT_IN_JS_THEMES = new InjectionToken('Nebular Built-in JS Themes');
/** @type {?} */
const NB_JS_THEMES = new InjectionToken('Nebular JS Themes');
/*
* We're providing browser apis with tokens to improve testing capabilities.
* */
/** @type {?} */
const NB_WINDOW = new InjectionToken('Window');
/** @type {?} */
const NB_DOCUMENT = new InjectionToken('Document');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NbColorHelper {
/**
* @param {?} color
* @param {?} weight
* @return {?}
*/
static shade(color, weight) {
return NbColorHelper.mix('#000000', color, weight);
}
/**
* @param {?} color
* @param {?} weight
* @return {?}
*/
static tint(color, weight) {
return NbColorHelper.mix('#ffffff', color, weight);
}
/**
* @param {?} color1
* @param {?} color2
* @param {?} weight
* @return {?}
*/
static mix(color1, color2, weight) {
/** @type {?} */
const d2h = (d) => d.toString(16);
/** @type {?} */
const h2d = (h) => parseInt(h, 16);
/** @type {?} */
let result = '#';
for (let i = 1; i < 7; i += 2) {
/** @type {?} */
const firstPart = h2d(color1.substr(i, 2));
/** @type {?} */
const secondPart = h2d(color2.substr(i, 2));
/** @type {?} */
const resultPart = d2h(Math.floor(secondPart + (firstPart - secondPart) * (weight / 100.0)));
result += ('0' + resultPart).slice(-2);
}
return result;
}
/**
* @param {?} hex
* @param {?} alpha
* @return {?}
*/
static hexToRgbA(hex, alpha) {
/** @type {?} */
let c;
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
c = hex.substring(1).split('');
if (c.length === 3) {
c = [c[0], c[0], c[1], c[1], c[2], c[2]];
}
c = '0x' + c.join('');
return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',' + alpha + ')';
}
throw new Error('Bad Hex');
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const palette = {
primary: '#8a7fff',
success: '#40dc7e',
info: '#4ca6ff',
warning: '#ffa100',
danger: '#ff4c6a',
};
/** @type {?} */
const DEFAULT_THEME = {
name: 'default',
variables: {
fontMain: '"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
fontSecondary: '"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
bg: '#ffffff',
fg: '#a4abb3',
fgHeading: '#2a2a2a',
fgText: '#3b3b3b',
fgHighlight: '#41d974',
layoutBg: '#ebeff5',
separator: '#ebeef2',
primary: palette.primary,
success: palette.success,
info: palette.info,
warning: palette.warning,
danger: palette.danger,
primaryLight: NbColorHelper.tint(palette.primary, 15),
successLight: NbColorHelper.tint(palette.success, 15),
infoLight: NbColorHelper.tint(palette.info, 15),
warningLight: NbColorHelper.tint(palette.warning, 15),
dangerLight: NbColorHelper.tint(palette.danger, 15),
},
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const palette$1 = {
primary: '#7659ff',
success: '#00d977',
info: '#0088ff',
warning: '#ffa100',
danger: '#ff386a',
};
/** @type {?} */
const COSMIC_THEME = {
name: 'cosmic',
base: 'default',
variables: {
bg: '#3d3780',
fg: '#a1a1e5',
fgHeading: '#ffffff',
fgText: '#d1d1ff',
fgHighlight: '#00f9a6',
layoutBg: '#2f296b',
separator: '#342e73',
primary: palette$1.primary,
success: palette$1.success,
info: palette$1.info,
warning: palette$1.warning,
danger: palette$1.danger,
primaryLight: NbColorHelper.tint(palette$1.primary, 20),
successLight: NbColorHelper.tint(palette$1.success, 20),
infoLight: NbColorHelper.tint(palette$1.info, 20),
warningLight: NbColorHelper.tint(palette$1.warning, 20),
dangerLight: NbColorHelper.tint(palette$1.danger, 20),
},
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const palette$2 = {
primary: '#73a1ff',
success: '#5dcfe3',
info: '#ba7fec',
warning: '#ffa36b',
danger: '#ff6b83',
};
/** @type {?} */
const CORPORATE_THEME = {
name: 'corporate',
base: 'default',
variables: {
fg: '#f1f5f8',
bg: '#ffffff',
fgHeading: '#181818',
fgText: '#4b4b4b',
fgHighlight: '#a4abb3',
layoutBg: '#f1f5f8',
separator: '#cdd5dc',
primary: palette$2.primary,
success: palette$2.success,
info: palette$2.info,
warning: palette$2.warning,
danger: palette$2.danger,
primaryLight: NbColorHelper.tint(palette$2.primary, 15),
successLight: NbColorHelper.tint(palette$2.success, 15),
infoLight: NbColorHelper.tint(palette$2.info, 15),
warningLight: NbColorHelper.tint(palette$2.warning, 15),
dangerLight: NbColorHelper.tint(palette$2.danger, 15),
},
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const BUILT_IN_THEMES = [
DEFAULT_THEME,
COSMIC_THEME,
CORPORATE_THEME,
];
/*
* Js Themes registry - provides access to the JS themes' variables.
* Usually shouldn't be used directly, but through the NbThemeService class methods (getJsTheme).
*/
class NbJSThemesRegistry {
/**
* @param {?} builtInThemes
* @param {?=} newThemes
*/
constructor(builtInThemes, newThemes = []) {
this.themes = {};
/** @type {?} */
const themes = this.combineByNames(newThemes, builtInThemes);
themes.forEach((theme) => {
this.register(theme, theme.name, theme.base);
});
}
/*
* Registers a new JS theme
* @param config any
* @param themeName string
* @param baseTheme string
*/
/**
* @param {?} config
* @param {?} themeName
* @param {?} baseTheme
* @return {?}
*/
register(config, themeName, baseTheme) {
/** @type {?} */
const base = this.has(baseTheme) ? this.get(baseTheme) : {};
this.themes[themeName] = this.mergeDeep({}, base, config);
}
/*
* Checks whether the theme is registered
* @param themeName
* @returns boolean
*/
/**
* @param {?} themeName
* @return {?}
*/
has(themeName) {
return !!this.themes[themeName];
}
/*
* Return a theme
* @param themeName
* @returns NbJSThemeOptions
*/
/**
* @param {?} themeName
* @return {?}
*/
get(themeName) {
if (!this.themes[themeName]) {
throw Error(`NbThemeConfig: no theme '${themeName}' found registered.`);
}
return JSON.parse(JSON.stringify(this.themes[themeName]));
}
/**
* @private
* @param {?} newThemes
* @param {?} oldThemes
* @return {?}
*/
combineByNames(newThemes, oldThemes) {
if (newThemes) {
/** @type {?} */
const mergedThemes = [];
newThemes.forEach((theme) => {
/** @type {?} */
const sameOld = oldThemes.find((tm) => tm.name === theme.name)
|| (/** @type {?} */ ({}));
/** @type {?} */
const mergedTheme = this.mergeDeep({}, sameOld, theme);
mergedThemes.push(mergedTheme);
});
oldThemes.forEach((theme) => {
if (!mergedThemes.find((tm) => tm.name === theme.name)) {
mergedThemes.push(theme);
}
});
return mergedThemes;
}
return oldThemes;
}
/**
* @private
* @param {?} item
* @return {?}
*/
isObject(item) {
return item && typeof item === 'object' && !Array.isArray(item);
}
// TODO: move to helpers
/**
* @private
* @param {?} target
* @param {...?} sources
* @return {?}
*/
mergeDeep(target, ...sources) {
if (!sources.length) {
return target;
}
/** @type {?} */
const source = sources.shift();
if (this.isObject(target) && this.isObject(source)) {
for (const key in source) {
if (this.isObject(source[key])) {
if (!target[key]) {
Object.assign(target, { [key]: {} });
}
this.mergeDeep(target[key], source[key]);
}
else {
Object.assign(target, { [key]: source[key] });
}
}
}
return this.mergeDeep(target, ...sources);
}
}
NbJSThemesRegistry.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbJSThemesRegistry.ctorParameters = () => [
{ type: Array, decorators: [{ type: Inject, args: [NB_BUILT_IN_JS_THEMES,] }] },
{ type: Array, decorators: [{ type: Inject, args: [NB_JS_THEMES,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const DEFAULT_MEDIA_BREAKPOINTS = [
{
name: 'xs',
width: 0,
},
{
name: 'is',
width: 400,
},
{
name: 'sm',
width: 576,
},
{
name: 'md',
width: 768,
},
{
name: 'lg',
width: 992,
},
{
name: 'xl',
width: 1200,
},
{
name: 'xxl',
width: 1400,
},
{
name: 'xxxl',
width: 1600,
},
];
/*
* Manages media breakpoints
*
* Provides access to available media breakpoints to convert window width to a configured breakpoint,
* e.g. 200px - *xs* breakpoint
*/
class NbMediaBreakpointsService {
/**
* @param {?} breakpoints
*/
constructor(breakpoints) {
this.breakpoints = breakpoints;
this.breakpointsMap = this.breakpoints.reduce((res, b) => {
res[b.name] = b.width;
return res;
}, {});
}
/*
* Returns a configured breakpoint by width
* @param width number
* @returns {Z|{name: string, width: number}}
*/
/**
* @param {?} width
* @return {?}
*/
getByWidth(width) {
/** @type {?} */
const unknown = { name: 'unknown', width: width };
/** @type {?} */
const breakpoints = this.getBreakpoints();
return breakpoints
.find((point, index) => {
/** @type {?} */
const next = breakpoints[index + 1];
return width >= point.width && (!next || width < next.width);
}) || unknown;
}
/*
* Returns a configured breakpoint by name
* @param name string
* @returns NbMediaBreakpoint
*/
/**
* @param {?} name
* @return {?}
*/
getByName(name) {
/** @type {?} */
const unknown = { name: 'unknown', width: NaN };
/** @type {?} */
const breakpoints = this.getBreakpoints();
return breakpoints.find((point) => name === point.name) || unknown;
}
/*
* Returns a list of configured breakpoints for the theme
* @returns NbMediaBreakpoint[]
*/
/**
* @return {?}
*/
getBreakpoints() {
return this.breakpoints;
}
/*
* Returns a map of configured breakpoints for the theme
* @returns {[p: string]: number}
*/
/**
* @return {?}
*/
getBreakpointsMap() {
return this.breakpointsMap;
}
}
NbMediaBreakpointsService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbMediaBreakpointsService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_MEDIA_BREAKPOINTS,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* Main Nebular service. Includes various helper methods.
*/
class NbThemeService {
/**
* @param {?} options
* @param {?} breakpointService
* @param {?} jsThemesRegistry
*/
constructor(options, breakpointService, jsThemesRegistry) {
this.options = options;
this.breakpointService = breakpointService;
this.jsThemesRegistry = jsThemesRegistry;
this.themeChanges$ = new ReplaySubject(1);
this.appendLayoutClass$ = new Subject();
this.removeLayoutClass$ = new Subject();
this.changeWindowWidth$ = new ReplaySubject(2);
if (options && options.name) {
this.changeTheme(options.name);
}
}
/*
* Change current application theme
* @param {string} name
*/
/**
* @param {?} name
* @return {?}
*/
changeTheme(name) {
this.themeChanges$.next({ name, previous: this.currentTheme });
this.currentTheme = name;
}
/**
* @param {?} width
* @return {?}
*/
changeWindowWidth(width) {
this.changeWindowWidth$.next(width);
}
/*
* Returns a theme object with variables (color/paddings/etc) on a theme change.
* Once subscribed - returns current theme.
*
* @returns {Observable<NbJSThemeOptions>}
*/
/**
* @return {?}
*/
getJsTheme() {
return this.onThemeChange().pipe(map((theme) => {
return this.jsThemesRegistry.get(theme.name);
}));
}
/*
* Triggers media query breakpoint change
* Returns a pair where the first item is previous media breakpoint and the second item is current breakpoit.
* ```ts
* [{ name: 'xs', width: 0 }, { name: 'md', width: 768 }] // change from `xs` to `md`
* ```
* @returns {Observable<[NbMediaBreakpoint, NbMediaBreakpoint]>}
*/
/**
* @return {?}
*/
onMediaQueryChange() {
return this.changeWindowWidth$
.pipe(startWith(undefined), pairwise(), map(([prevWidth, width]) => {
return [
this.breakpointService.getByWidth(prevWidth),
this.breakpointService.getByWidth(width),
];
}), filter(([prevPoint, point]) => {
return prevPoint.name !== point.name;
}), distinctUntilChanged(null, params => params[0].name + params[1].name), share());
}
/*
* Triggered when current theme is changed
* @returns {Observable<any>}
*/
/**
* @return {?}
*/
onThemeChange() {
return this.themeChanges$.pipe(share());
}
/*
* Append a class to nb-layout
* @param {string} className
*/
/**
* @param {?} className
* @return {?}
*/
appendLayoutClass(className) {
this.appendLayoutClass$.next(className);
}
/*
* Triggered when a new class is added to nb-layout through `appendLayoutClass` method
* @returns {Observable<any>}
*/
/**
* @return {?}
*/
onAppendLayoutClass() {
return this.appendLayoutClass$.pipe(share());
}
/*
* Removes a class from nb-layout
* @param {string} className
*/
/**
* @param {?} className
* @return {?}
*/
removeLayoutClass(className) {
this.removeLayoutClass$.next(className);
}
/*
* Triggered when a class is removed from nb-layout through `removeLayoutClass` method
* @returns {Observable<any>}
*/
/**
* @return {?}
*/
onRemoveLayoutClass() {
return this.removeLayoutClass$.pipe(share());
}
}
NbThemeService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbThemeService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_THEME_OPTIONS,] }] },
{ type: NbMediaBreakpointsService },
{ type: NbJSThemesRegistry }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* Service to control the global page spinner.
*/
class NbSpinnerService {
/**
* @param {?} document
*/
constructor(document) {
this.document = document;
this.loaders = [];
this.selector = 'nb-global-spinner';
}
/*
* Appends new loader to the list of loader to be completed before
* spinner will be hidden
* @param method Promise<any>
*/
/**
* @param {?} method
* @return {?}
*/
registerLoader(method) {
this.loaders.push(method);
}
/*
* Clears the list of loader
*/
/**
* @return {?}
*/
clear() {
this.loaders = [];
}
/*
* Start the loader process, show spinnder and execute loaders
*/
/**
* @return {?}
*/
load() {
this.showSpinner();
this.executeAll();
}
/**
* @private
* @param {?=} done
* @return {?}
*/
executeAll(done = () => { }) {
Promise.all(this.loaders).then((values) => {
this.hideSpinner();
done.call(null, values);
})
.catch((error) => {
// TODO: Promise.reject
console.error(error);
});
}
// TODO is there any better way of doing this?
/**
* @private
* @return {?}
*/
showSpinner() {
/** @type {?} */
const el = this.getSpinnerElement();
if (el) {
el.style['display'] = 'block';
}
}
/**
* @private
* @return {?}
*/
hideSpinner() {
/** @type {?} */
const el = this.getSpinnerElement();
if (el) {
el.style['display'] = 'none';
}
}
/**
* @private
* @return {?}
*/
getSpinnerElement() {
return this.document.getElementById(this.selector);
}
}
NbSpinnerService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbSpinnerService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const NbLayoutDirection = {
LTR: 'ltr',
RTL: 'rtl',
};
/*
* Layout direction setting injection token.
* */
/** @type {?} */
const NB_LAYOUT_DIRECTION = new InjectionToken('Layout direction');
/*
* Layout Direction Service.
* Allows to set or get layout direction and listen to its changes
*/
class NbLayoutDirectionService {
/**
* @param {?=} direction
*/
constructor(direction = NbLayoutDirection.LTR) {
this.direction = direction;
this.$directionChange = new ReplaySubject(1);
this.setDirection(direction);
}
/*
* Returns true if layout direction set to left to right.
* @returns boolean.
* */
/**
* @return {?}
*/
isLtr() {
return this.direction === NbLayoutDirection.LTR;
}
/*
* Returns true if layout direction set to right to left.
* @returns boolean.
* */
/**
* @return {?}
*/
isRtl() {
return this.direction === NbLayoutDirection.RTL;
}
/*
* Returns current layout direction.
* @returns NbLayoutDirection.
* */
/**
* @return {?}
*/
getDirection() {
return this.direction;
}
/*
* Sets layout direction
* @param {NbLayoutDirection} direction
*/
/**
* @param {?} direction
* @return {?}
*/
setDirection(direction) {
this.direction = direction;
this.$directionChange.next(direction);
}
/*
* Triggered when direction was changed.
* @returns Observable<NbLayoutDirection>.
*/
/**
* @return {?}
*/
onDirectionChange() {
return this.$directionChange.pipe(share());
}
}
NbLayoutDirectionService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbLayoutDirectionService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NB_LAYOUT_DIRECTION,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* Layout scroll service. Provides information about current scroll position,
* as well as methods to update position of the scroll.
*
* The reason we added this service is that in Nebular there are two scroll modes:
* - the default mode when scroll is on body
* - and the `withScroll` mode, when scroll is removed from the body and moved to an element inside of the
* `nb-layout` component
*/
class NbLayoutScrollService {
constructor() {
this.scrollPositionReq$ = new Subject();
this.manualScroll$ = new Subject();
this.scroll$ = new Subject();
}
/*
* Returns scroll position
*
* @returns {Observable<NbScrollPosition>}
*/
/**
* @return {?}
*/
getPosition() {
return Observable.create((observer) => {
/** @type {?} */
const listener = new Subject();
listener.subscribe(observer);
this.scrollPositionReq$.next({ listener });
return () => listener.complete();
});
}
/*
* Sets scroll position
*
* @param {number} x
* @param {number} y
*/
/**
* @param {?=} x
* @param {?=} y
* @return {?}
*/
scrollTo(x = null, y = null) {
this.manualScroll$.next({ x, y });
}
/*
* Returns a stream of scroll events
*
* @returns {Observable<any>}
*/
/**
* @return {?}
*/
onScroll() {
return this.scroll$.pipe(share());
}
/*
* @private
* @returns Observable<NbScrollPosition>.
*/
/**
* @return {?}
*/
onManualScroll() {
return this.manualScroll$.pipe(share());
}
/*
* @private
* @returns {Subject<any>}
*/
/**
* @return {?}
*/
onGetPosition() {
return this.scrollPositionReq$;
}
/*
* @private
* @param {any} event
*/
/**
* @param {?} event
* @return {?}
*/
fireScrollChange(event) {
this.scroll$.next(event);
}
}
NbLayoutScrollService.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* Simple helper service to return Layout dimensions
* Depending of current Layout scroll mode (default or `withScroll` when scroll is moved to an element
* inside of the layout) corresponding dimensions will be returns - of `documentElement` in first case and
* `.scrollable-container` in the second.
*/
class NbLayoutRulerService {
constructor() {
this.contentDimensionsReq$ = new Subject();
}
/*
* Content dimensions
* @returns {Observable<NbLayoutDimensions>}
*/
/**
* @return {?}
*/
getDimensions() {
return Observable.create((observer) => {
/** @type {?} */
const listener = new Subject();
listener.subscribe(observer);
this.contentDimensionsReq$.next({ listener });
return () => listener.complete();
});
}
/*
* @private
* @returns {Subject<any>}
*/
/**
* @return {?}
*/
onGetDimensions() {
return this.contentDimensionsReq$;
}
}
NbLayoutRulerService.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NbSharedModule {
}
NbSharedModule.decorators = [
{ type: NgModule, args: [{
exports: [
CommonModule,
// TODO: probably we don't need FormsModule in SharedModule
FormsModule,
RouterModule,
],
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* Overrides angular cdk focus trap to keep restore functionality inside trap.
* */
class NbFocusTrap extends FocusTrap {
/**
* @param {?} element
* @param {?} checker
* @param {?} ngZone
* @param {?} document
* @param {?} deferAnchors
*/
constructor(element, checker, ngZone, document, deferAnchors) {
super(element, checker, ngZone, document, deferAnchors);
this.element = element;
this.checker = checker;
this.ngZone = ngZone;
this.document = document;
this.savePreviouslyFocusedElement();
}
/**
* @return {?}
*/
restoreFocus() {
this.previouslyFocusedElement.focus();
this.destroy();
}
/**
* @return {?}
*/
blurPreviouslyFocusedElement() {
this.previouslyFocusedElement.blur();
}
/**
* @protected
* @return {?}
*/
savePreviouslyFocusedElement() {
this.previouslyFocusedElement = (/** @type {?} */ (this.document.activeElement));
}
}
class NbFocusTrapFactoryService extends FocusTrapFactory {
/**
* @param {?} checker
* @param {?} ngZone
* @param {?} document
*/
constructor(checker, ngZone, document) {
super(checker, ngZone, document);
this.checker = checker;
this.ngZone = ngZone;
this.document = document;
}
/**
* @param {?} element
* @param {?=} deferCaptureElements
* @return {?}
*/
create(element, deferCaptureElements) {
return new NbFocusTrap(element, this.checker, this.ngZone, this.document, deferCaptureElements);
}
}
NbFocusTrapFactoryService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbFocusTrapFactoryService.ctorParameters = () => [
{ type: InteractivityChecker },
{ type: NgZone },
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NbA11yModule {
/**
* @return {?}
*/
static forRoot() {
return (/** @type {?} */ ({
ngModule: NbA11yModule,
providers: [NbFocusTrapFactoryService],
}));
}
}
NbA11yModule.decorators = [
{ type: NgModule, args: [{},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NbPortalDirective extends CdkPortal {
}
NbPortalDirective.decorators = [
{ type: Directive, args: [{ selector: '[nbPortal]' },] }
];
class NbPortalOutletDirective extends CdkPortalOutlet {
}
NbPortalOutletDirective.decorators = [
{ type: Directive, args: [{ selector: '[nbPortalOutlet]' },] }
];
/**
* @template T
*/
class NbComponentPortal extends ComponentPortal {
/**
* @param {?} component
* @param {?=} vcr
* @param {?=} injector
* @param {?=} cfr
*/
constructor(component, vcr, injector, cfr) {
super(component, vcr, injector);
this.cfr = cfr;
}
}
/*
* TODO remove after @angular/cdk@7.0.0 relased
* */
class NbDomPortalOutlet extends DomPortalOutlet {
/**
* @param {?} outletElement
* @param {?} componentFactoryResolver
* @param {?} appRef
* @param {?} defaultInjector
*/
constructor(outletElement, componentFactoryResolver, appRef, defaultInjector) {
super(outletElement, componentFactoryResolver, appRef, defaultInjector);
this.outletElement = outletElement;
this.componentFactoryResolver = componentFactoryResolver;
this.appRef = appRef;
this.defaultInjector = defaultInjector;
}
/*
* Attach the given ComponentPortal to DOM element using the ComponentFactoryResolver.
* @param portal Portal to be attached
* @returns Reference to the created component.
*/
/**
* @template T
* @param {?} portal
* @return {?}
*/
attachComponentPortal(portal) {
/** @type {?} */
const resolver = portal.cfr || this.componentFactoryResolver;
/** @type {?} */
const componentFactory = resolver.resolveComponentFactory(portal.component);
/** @type {?} */
let componentRef;
// If the portal specifies a ViewContainerRef, we will use that as the attachment point
// for the component (in terms of Angular's component tree, not rendering).
// When the ViewContainerRef is missing, we use the factory to create the component directly
// and then manually attach the view to the application.
if (portal.viewContainerRef) {
componentRef = portal.viewContainerRef.createComponent(componentFactory, portal.viewContainerRef.length, portal.injector || portal.viewContainerRef.parentInjector);
this.setDisposeFn(() => componentRef.destroy());
}
else {
componentRef = componentFactory.create(portal.injector || this.defaultInjector);
this.appRef.attachView(componentRef.hostView);
this.setDisposeFn(() => {
this.appRef.detachView(componentRef.hostView);
componentRef.destroy();
});
}
// At this point the component has been instantiated, so we move it to the location in the DOM
// where we want it to be rendered.
this.outletElement.appendChild(this.getComponentRootNode(componentRef));
return componentRef;
}
/* Gets the root HTMLElement for an instantiated component. */
/**
* @private
* @param {?} componentRef
* @return {?}
*/
getComponentRootNode(componentRef) {
return (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView))).rootNodes[0]));
}
}
class NbOverlay extends Overlay {
/**
* @param {?} scrollStrategies
* @param {?} overlayContainer
* @param {?} componentFactoryResolver
* @param {?} positionBuilder
* @param {?} keyboardDispatcher
* @param {?} injector
* @param {?} ngZone
* @param {?} document
* @param {?} directionality
*/
constructor(scrollStrategies, overlayContainer, componentFactoryResolver, positionBuilder, keyboardDispatcher, injector, ngZone, document, directionality) {
super(scrollStrategies, overlayContainer, componentFactoryResolver, positionBuilder, keyboardDispatcher, injector, ngZone, document, directionality);
this.scrollStrategies = scrollStrategies;
this.overlayContainer = overlayContainer;
this.componentFactoryResolver = componentFactoryResolver;
this.positionBuilder = positionBuilder;
this.keyboardDispatcher = keyboardDispatcher;
this.injector = injector;
this.ngZone = ngZone;
this.document = document;
this.directionality = directionality;
}
/*
* Creates an overlay.
* @param config Configuration applied to the overlay.
* @returns Reference to the created overlay.
*/
/**
* @param {?=} config
* @return {?}
*/
create(config) {
/** @type {?} */
const host = this.createHostElement();
/** @type {?} */
const pane = this.createPaneElement(host);
/** @type {?} */
const portalOutlet = this.createPortalOutlet(pane);
/** @type {?} */
const overlayConfig = new OverlayConfig(config);
overlayConfig.direction = overlayConfig.direction || this.directionality.value;
return new OverlayRef(portalOutlet, host, pane, overlayConfig, this.ngZone, this.keyboardDispatcher, this.document);
}
/*
* Creates the DOM element for an overlay and appends it to the overlay container.
* @returns Newly-created pane element
*/
/**
* @protected
* @param {?} host
* @return {?}
*/
createPaneElement(host) {
/** @type {?} */
const pane = this.document.createElement('div');
pane.id = `cdk-overlay-${NbOverlay.nextUniqueId++}`;
pane.classList.add('cdk-overlay-pane');
host.appendChild(pane);
return pane;
}
/*
* Creates the host element that wraps around an overlay
* and can be used for advanced positioning.
* @returns Newly-create host element.
*/
/**
* @protected
* @return {?}
*/
createHostElement() {
/** @type {?} */
const host = this.document.createElement('div');
this.overlayContainer.getContainerElement().appendChild(host);
return host;
}
/*
* Create a DomPortalOutlet into which the overlay content can be loaded.
* @param pane The DOM element to turn into a portal outlet.
* @returns A portal outlet for the given DOM element.
*/
/**
* @protected
* @param {?} pane
* @return {?}
*/
createPortalOutlet(pane) {
// We have to resolve the ApplicationRef later in order to allow people
// to use overlay-based providers during app initialization.
if (!this.appRef) {
this.appRef = this.injector.get(ApplicationRef);
}
return new NbDomPortalOutlet(pane, this.componentFactoryResolver, this.appRef, this.injector);
}
}
NbOverlay.nextUniqueId = 0;
NbOverlay.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbOverlay.ctorParameters = () => [
{ type: ScrollStrategyOptions },
{ type: OverlayContainer },
{ type: ComponentFactoryResolver },
{ type: OverlayPositionBuilder },
{ type: OverlayKeyboardDispatcher },
{ type: Injector },
{ type: NgZone },
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] },
{ type: Directionality }
];
class NbPlatform extends Platform {
}
NbPlatform.decorators = [
{ type: Injectable }
];
class NbOverlayPositionBuilder extends OverlayPositionBuilder {
}
NbOverlayPositionBuilder.decorators = [
{ type: Injectable }
];
/**
* @template T
*/
class NbTemplatePortal extends TemplatePortal {
/**
* @param {?} template
* @param {?=} viewContainerRef
* @param {?=} context
*/
constructor(template, viewContainerRef, context) {
super(template, viewContainerRef, context);
}
}
class NbOverlayContainer extends OverlayContainer {
}
/** @nocollapse */ NbOverlayContainer.ngInjectableDef = defineInjectable({ factory: function NbOverlayContainer_Factory() { return new NbOverlayContainer(inject(DOCUMENT)); }, token: NbOverlayContainer, providedIn: "root" });
class NbFlexibleConnectedPositionStrategy extends FlexibleConnectedPositionStrategy {
}
class NbPortalInjector extends PortalInjector {
}
/** @type {?} */
const CDK_MODULES = [OverlayModule, PortalModule];
/*
* This module helps us to keep all angular/cdk deps inside our cdk module via providing aliases.
* Approach will help us move cdk in separate npm package and refactor nebular/theme code.
* */
class NbCdkMappingModule {
/**
* @return {?}
*/
static forRoot() {
return (/** @type {?} */ ({
ngModule: NbCdkMappingModule,
providers: [
NbOverlay,
NbPlatform,
NbOverlayPositionBuilder,
],
}));
}
}
NbCdkMappingModule.decorators = [
{ type: NgModule, args: [{
imports: [...CDK_MODULES],
exports: [
...CDK_MODULES,
NbPortalDirective,
NbPortalOutletDirective,
],
declarations: [NbPortalDirective, NbPortalOutletDirective],
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class NbViewportRulerAdapter extends ViewportRuler {
/**
* @param {?} platform
* @param {?} ngZone
* @param {?} ruler
* @param {?} scroll
*/
constructor(platform, ngZone, ruler, scroll) {
super(platform, ngZone);
this.ruler = ruler;
this.scroll = scroll;
}
/**
* @return {?}
*/
getViewportSize() {
/** @type {?} */
let res;
/*
* getDimensions call is really synchronous operation.
* And we have to conform with the interface of the original service.
* */
this.ruler.getDimensions()
.pipe(map(dimensions => ({ width: dimensions.clientWidth, height: dimensions.clientHeight })))
.subscribe(rect => res = rect);
return res;
}
/**
* @return {?}
*/
getViewportScrollPosition() {
/** @type {?} */
let res;
/*
* getPosition call is really synchronous operation.
* And we have to conform with the interface of the original service.
* */
this.scroll.getPosition()
.pipe(map((position) => ({ top: position.y, left: position.x })))
.subscribe(position => res = position);
return res;
}
}
NbViewportRulerAdapter.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbViewportRulerAdapter.ctorParameters = () => [
{ type: NbPlatform },
{ type: NgZone },
{ type: NbLayoutRulerService },
{ type: NbLayoutScrollService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const NbGlobalLogicalPosition = {
TOP_START: 'top-start',
TOP_END: 'top-end',
BOTTOM_START: 'bottom-start',
BOTTOM_END: 'bottom-end',
};
/** @enum {string} */
const NbGlobalPhysicalPosition = {
TOP_RIGHT: 'top-right',
TOP_LEFT: 'top-left',
BOTTOM_RIGHT: 'bottom-right',
BOTTOM_LEFT: 'bottom-left',
};
class NbPositionHelper {
/**
* @param {?} layoutDirection
*/
constructor(layoutDirection) {
this.layoutDirection = layoutDirection;
}
/**
* @param {?} position
* @return {?}
*/
toLogicalPosition(position) {
if (Object.values(NbGlobalLogicalPosition).includes(position)) {
return (/** @type {?} */ (position));
}
if (this.layoutDirection.isLtr()) {
return this.toLogicalPositionWhenLtr((/** @type {?} */ (position)));
}
else {
return this.toLogicalPositionWhenRtl((/** @type {?} */ (position)));
}
}
/**
* @param {?} position
* @return {?}
*/
toPhysicalPosition(position) {
if (Object.values(NbGlobalPhysicalPosition).includes(position)) {
return (/** @type {?} */ (position));
}
if (this.layoutDirection.isLtr()) {
return this.toPhysicalPositionWhenLtr((/** @type {?} */ (position)));
}
else {
return this.toPhysicalPositionWhenRtl((/** @type {?} */ (position)));
}
}
/**
* @param {?} position
* @return {?}
*/
isTopPosition(position) {
/** @type {?} */
const logicalPosition = this.toLogicalPosition(position);
return logicalPosition === NbGlobalLogicalPosition.TOP_END
|| logicalPosition === NbGlobalLogicalPosition.TOP_START;
}
/**
* @param {?} position
* @return {?}
*/
isRightPosition(position) {
/** @type {?} */
const physicalPosition = this.toPhysicalPosition(position);
return physicalPosition === NbGlobalPhysicalPosition.TOP_RIGHT
|| physicalPosition === NbGlobalPhysicalPosition.BOTTOM_RIGHT;
}
/**
* @protected
* @param {?} position
* @return {?}
*/
toLogicalPositionWhenLtr(position) {
switch (position) {
case NbGlobalPhysicalPosition.TOP_RIGHT:
return NbGlobalLogicalPosition.TOP_END;
case NbGlobalPhysicalPosition.TOP_LEFT:
return NbGlobalLogicalPosition.TOP_START;
case NbGlobalPhysicalPosition.BOTTOM_RIGHT:
return NbGlobalLogicalPosition.BOTTOM_END;
case NbGlobalPhysicalPosition.BOTTOM_LEFT:
return NbGlobalLogicalPosition.BOTTOM_START;
}
}
/**
* @protected
* @param {?} position
* @return {?}
*/
toLogicalPositionWhenRtl(position) {
switch (position) {
case NbGlobalPhysicalPosition.TOP_RIGHT:
return NbGlobalLogicalPosition.TOP_START;
case NbGlobalPhysicalPosition.TOP_LEFT:
return NbGlobalLogicalPosition.TOP_END;
case NbGlobalPhysicalPosition.BOTTOM_RIGHT:
return NbGlobalLogicalPosition.BOTTOM_START;
case NbGlobalPhysicalPosition.BOTTOM_LEFT:
return NbGlobalLogicalPosition.BOTTOM_END;
}
}
/**
* @protected
* @param {?} position
* @return {?}
*/
toPhysicalPositionWhenLtr(position) {
switch (position) {
case NbGlobalLogicalPosition.TOP_START:
return NbGlobalPhysicalPosition.TOP_LEFT;
case NbGlobalLogicalPosition.TOP_END:
return NbGlobalPhysicalPosition.TOP_RIGHT;
case NbGlobalLogicalPosition.BOTTOM_START:
return NbGlobalPhysicalPosition.BOTTOM_LEFT;
case NbGlobalLogicalPosition.BOTTOM_END:
return NbGlobalPhysicalPosition.BOTTOM_RIGHT;
}
}
/**
* @protected
* @param {?} position
* @return {?}
*/
toPhysicalPositionWhenRtl(position) {
switch (position) {
case NbGlobalLogicalPosition.TOP_START:
return NbGlobalPhysicalPosition.TOP_RIGHT;
case NbGlobalLogicalPosition.TOP_END:
return NbGlobalPhysicalPosition.TOP_LEFT;
case NbGlobalLogicalPosition.BOTTOM_START:
return NbGlobalPhysicalPosition.BOTTOM_RIGHT;
case NbGlobalLogicalPosition.BOTTOM_END:
return NbGlobalPhysicalPosition.BOTTOM_LEFT;
}
}
}
NbPositionHelper.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NbPositionHelper.ctorParameters = () => [
{ type: NbLayoutDirectionService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const NbAdjustment = {
NOOP: 'noop',
CLOCKWISE: 'clockwise',
COUNTERCLOCKWISE: 'counterclockwise',
VERTICAL: 'vertical',
HORIZONTAL: 'horizontal',
};
/** @enum {string} */
const NbPosition = {
TOP: 'top',
BOTTOM: 'bottom',
LEFT: 'left',
RIGHT: 'right',
START: 'start',
END: 'end',
};
/** @type {?} */
const POSITIONS = {
/**
* @param {?} offset
* @return {?}
*/
[NbPosition.RIGHT](offset) {
return { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: offset };
},
/**
* @param {?} offset
* @return {?}
*/
[NbPosition.BOTTOM](offset) {
return { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: offset };
},
/**
* @param {?} offset
* @return {?}
*/
[NbPosition.LEFT](offset) {
return { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -offset };
},
/**
* @param {?} offset
* @return {?}
*/
[NbPosition.TOP](offset) {
return { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -offset };
},
};
/** @type {?} */
const COUNTER_CLOCKWISE_POSITIONS = [NbPosition.TOP, NbPosition.LEFT, NbPosition.BOTTOM, NbPosition.RIGHT];
/** @type {?} */
const NOOP_POSITIONS = [NbPosition.TOP, NbPosition.BOTTOM, NbPosition.LEFT, NbPosition.RIGHT];
/** @type {?} */
const CLOCKWISE_POSITIONS = [NbPosition.TOP, NbPosition.RIGHT, NbPosition.BOTTOM, NbPosition.LEFT];
/** @type {?} */
const VERTICAL_POSITIONS = [NbPosition.BOTTOM, NbPosition.TOP];
/** @type {?} */
const HORIZONTAL_POSITIONS = [NbPosition.START, NbPosition.END];
/**
* @param {?} p1
* @param {?} p2
* @return {?}
*/
function comparePositions(p1, p2) {
return p1.originX === p2.originX
&& p1.originY === p2.originY
&& p1.overlayX === p2.overlayX
&& p1.overlayY === p2.overlayY;
}
/*
* The main idea of the adjustable connected strategy is to provide predefined set of positions for your overlay.
* You have to provide adjustment and appropriate strategy will be chosen in runtime.
* */
class NbAdjustableConnectedPositionStrategy extends NbFlexibleConnectedPositionStrategy {
constructor() {
super(...arguments);
this._offset = 15;
this.positionChange = this.positionChanges.pipe(map((positionChange) => positionChange.connectionPair), map((connectionPair) => {
return this.appliedP