@nebular/theme
Version:
@nebular/theme
1,509 lines (1,481 loc) • 865 kB
JavaScript
import { Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactoryResolver, ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, Host, HostBinding, HostListener, Inject, Injectable, InjectionToken, Injector, Input, IterableDiffers, LOCALE_ID, NgModule, NgZone, Optional, Output, PLATFORM_ID, Renderer2, SimpleChange, TemplateRef, Type, ViewChild, ViewChildren, ViewContainerRef, forwardRef, isDevMode, ɵɵdefineInjectable, ɵɵinject } from '@angular/core';
import * as i0 from '@angular/core';
import { CommonModule, DOCUMENT, DatePipe, FormStyle, FormatWidth, Location, TranslationWidth, getLocaleDayNames, getLocaleFirstDayOfWeek, getLocaleMonthNames, getLocaleTimeFormat, isPlatformBrowser } from '@angular/common';
import { BehaviorSubject, EMPTY, Observable, ReplaySubject, Subject, combineLatest, forkJoin, from, fromEvent, interval, merge, of, timer } from 'rxjs';
import { debounceTime, delay, distinctUntilChanged, filter, finalize, map, pairwise, refCount, repeat, share, skip, startWith, switchMap, take, takeUntil, takeWhile, tap } from 'rxjs/operators';
import { FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { ActivatedRoute, NavigationEnd, Router, RouterModule } from '@angular/router';
import { ActiveDescendantKeyManager, FocusKeyManager, FocusMonitor, FocusTrap, FocusTrapFactory, InteractivityChecker } from '@angular/cdk/a11y';
import { CdkPortal, CdkPortalOutlet, ComponentPortal, PortalInjector, PortalModule, TemplatePortal } from '@angular/cdk/portal';
import { BlockScrollStrategy, FlexibleConnectedPositionStrategy, GlobalPositionStrategy, Overlay, OverlayContainer, OverlayModule, OverlayPositionBuilder, ScrollDispatcher, ScrollStrategyOptions, ViewportRuler } from '@angular/cdk/overlay';
import { Platform } from '@angular/cdk/platform';
import * as i1 from '@angular/cdk/platform';
import { DomSanitizer } from '@angular/platform-browser';
import { animate, state, style, transition, trigger } from '@angular/animations';
import 'intersection-observer';
import { BidiModule, Directionality } from '@angular/cdk/bidi';
import { CdkCell, CdkCellDef, CdkCellOutlet, CdkColumnDef, CdkFooterCell, CdkFooterCellDef, CdkFooterRow, CdkFooterRowDef, CdkHeaderCell, CdkHeaderCellDef, CdkHeaderRow, CdkHeaderRowDef, CdkRow, CdkRowDef, CdkTable, CdkTableModule, DataRowOutlet, DataSource, FooterRowOutlet, HeaderRowOutlet, NoDataRowOutlet, _COALESCED_STYLE_SCHEDULER, _CoalescedStyleScheduler } from '@angular/cdk/table';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { _DisposeViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY } from '@angular/cdk/collections';
import { BACKSPACE, DELETE, ENTER, ESCAPE, SPACE } from '@angular/cdk/keycodes';
import * as _angular_cdk_keycodes from '@angular/cdk/keycodes';
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
const NB_THEME_OPTIONS = new InjectionToken('Nebular Theme Options');
const NB_MEDIA_BREAKPOINTS = new InjectionToken('Nebular Media Breakpoints');
const NB_BUILT_IN_JS_THEMES = new InjectionToken('Nebular Built-in JS Themes');
const NB_JS_THEMES = new InjectionToken('Nebular JS Themes');
/**
* We're providing browser apis with tokens to improve testing capabilities.
* */
const NB_WINDOW = new InjectionToken('Window');
const NB_DOCUMENT = new InjectionToken('Document');
const palette = {
primary: '#3366ff',
success: '#00d68f',
info: '#0095ff',
warning: '#ffaa00',
danger: '#ff3d71',
};
const DEFAULT_THEME = {
name: 'default',
variables: {
fontMain: 'Open Sans, sans-serif',
fontSecondary: 'Raleway, sans-serif',
bg: '#ffffff',
bg2: '#f7f9fc',
bg3: '#edf1f7',
bg4: '#e4e9f2',
border: '#ffffff',
border2: '#f7f9fc',
border3: '#edf1f7',
border4: '#e4e9f2',
border5: '#c5cee0',
fg: '#8f9bb3',
fgHeading: '#1a2138',
fgText: '#1a2138',
fgHighlight: palette.primary,
layoutBg: '#f7f9fc',
separator: '#edf1f7',
primary: palette.primary,
success: palette.success,
info: palette.info,
warning: palette.warning,
danger: palette.danger,
primaryLight: '#598bff',
successLight: '#2ce69b',
infoLight: '#42aaff',
warningLight: '#ffc94d',
dangerLight: '#ff708d',
},
};
const palette$1 = {
primary: '#a16eff',
success: '#00d68f',
info: '#0095ff',
warning: '#ffaa00',
danger: '#ff3d71',
};
const COSMIC_THEME = {
name: 'cosmic',
variables: {
fontMain: 'Open Sans, sans-serif',
fontSecondary: 'Raleway, sans-serif',
bg: '#323259',
bg2: '#252547',
bg3: '#1b1b38',
bg4: '#13132b',
border: '#323259',
border2: '#252547',
border3: '#1b1b38',
border4: '#13132b',
border5: '#13132b',
fg: '#b4b4db',
fgHeading: '#ffffff',
fgText: '#ffffff',
fgHighlight: palette$1.primary,
layoutBg: '#151a30',
separator: '#151a30',
primary: palette$1.primary,
success: palette$1.success,
info: palette$1.info,
warning: palette$1.warning,
danger: palette$1.danger,
primaryLight: '#b18aff',
successLight: '#2ce69b',
infoLight: '#42aaff',
warningLight: '#ffc94d',
dangerLight: '#ff708d',
},
};
const palette$2 = {
primary: '#73a1ff',
success: '#5dcfe3',
info: '#ba7fec',
warning: '#ffa36b',
danger: '#ff6b83',
};
const CORPORATE_THEME = {
name: 'corporate',
base: 'default',
variables: {
fontMain: 'Open Sans, sans-serif',
fontSecondary: 'Raleway, sans-serif',
bg: '#ffffff',
bg2: '#f7f9fc',
bg3: '#edf1f7',
bg4: '#e4e9f2',
border: '#ffffff',
border2: '#f7f9fc',
border3: '#edf1f7',
border4: '#e4e9f2',
border5: '#c5cee0',
fg: '#8f9bb3',
fgHeading: '#1a2138',
fgText: '#1a2138',
fgHighlight: palette$2.primary,
layoutBg: '#f7f9fc',
separator: '#edf1f7',
primary: palette$2.primary,
success: palette$2.success,
info: palette$2.info,
warning: palette$2.warning,
danger: palette$2.danger,
primaryLight: '#598bff',
successLight: '#2ce69b',
infoLight: '#42aaff',
warningLight: '#ffc94d',
dangerLight: '#ff708d',
},
};
const palette$3 = {
primary: '#3366ff',
success: '#00d68f',
info: '#0095ff',
warning: '#ffaa00',
danger: '#ff3d71',
};
const DARK_THEME = {
name: 'dark',
variables: {
fontMain: 'Open Sans, sans-serif',
fontSecondary: 'Raleway, sans-serif',
bg: '#222b45',
bg2: '#1a2138',
bg3: '#151a30',
bg4: '#101426',
border: '#222b45',
border2: '#1a2138',
border3: '#151a30',
border4: '#101426',
border5: '#101426',
fg: '#8f9bb3',
fgHeading: '#ffffff',
fgText: '#ffffff',
fgHighlight: palette$3.primary,
layoutBg: '#1b1b38',
separator: '#1b1b38',
primary: palette$3.primary,
success: palette$3.success,
info: palette$3.info,
warning: palette$3.warning,
danger: palette$3.danger,
primaryLight: '#598bff',
successLight: '#2ce69b',
infoLight: '#42aaff',
warningLight: '#ffc94d',
dangerLight: '#ff708d',
},
};
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
const BUILT_IN_THEMES = [
DEFAULT_THEME,
COSMIC_THEME,
CORPORATE_THEME,
DARK_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 {
constructor(builtInThemes, newThemes = []) {
this.themes = {};
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
*/
register(config, themeName, baseTheme) {
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
*/
has(themeName) {
return !!this.themes[themeName];
}
/**
* Return a theme
* @param themeName
* @returns NbJSThemeOptions
*/
get(themeName) {
if (!this.themes[themeName]) {
throw Error(`NbThemeConfig: no theme '${themeName}' found registered.`);
}
return JSON.parse(JSON.stringify(this.themes[themeName]));
}
combineByNames(newThemes, oldThemes) {
if (newThemes) {
const mergedThemes = [];
newThemes.forEach((theme) => {
const sameOld = oldThemes.find((tm) => tm.name === theme.name)
|| {};
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;
}
isObject(item) {
return item && typeof item === 'object' && !Array.isArray(item);
}
// TODO: move to helpers
mergeDeep(target, ...sources) {
if (!sources.length) {
return target;
}
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 }
];
NbJSThemesRegistry.ctorParameters = () => [
{ type: Array, decorators: [{ type: Inject, args: [NB_BUILT_IN_JS_THEMES,] }] },
{ type: Array, decorators: [{ type: Inject, args: [NB_JS_THEMES,] }] }
];
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
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 {
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}}
*/
getByWidth(width) {
const unknown = { name: 'unknown', width: width };
const breakpoints = this.getBreakpoints();
return breakpoints
.find((point, index) => {
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
*/
getByName(name) {
const unknown = { name: 'unknown', width: NaN };
const breakpoints = this.getBreakpoints();
return breakpoints.find((point) => name === point.name) || unknown;
}
/**
* Returns a list of configured breakpoints for the theme
* @returns NbMediaBreakpoint[]
*/
getBreakpoints() {
return this.breakpoints;
}
/**
* Returns a map of configured breakpoints for the theme
* @returns {[p: string]: number}
*/
getBreakpointsMap() {
return this.breakpointsMap;
}
}
NbMediaBreakpointsService.decorators = [
{ type: Injectable }
];
NbMediaBreakpointsService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_MEDIA_BREAKPOINTS,] }] }
];
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
/**
* Main Nebular service. Includes various helper methods.
*/
class NbThemeService {
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
*/
changeTheme(name) {
this.themeChanges$.next({ name, previous: this.currentTheme });
this.currentTheme = name;
}
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>}
*/
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]>}
*/
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>}
*/
onThemeChange() {
return this.themeChanges$.pipe(share());
}
/**
* Append a class to nb-layout
* @param {string} className
*/
appendLayoutClass(className) {
this.appendLayoutClass$.next(className);
}
/**
* Triggered when a new class is added to nb-layout through `appendLayoutClass` method
* @returns {Observable<any>}
*/
onAppendLayoutClass() {
return this.appendLayoutClass$.pipe(share());
}
/**
* Removes a class from nb-layout
* @param {string} className
*/
removeLayoutClass(className) {
this.removeLayoutClass$.next(className);
}
/**
* Triggered when a class is removed from nb-layout through `removeLayoutClass` method
* @returns {Observable<any>}
*/
onRemoveLayoutClass() {
return this.removeLayoutClass$.pipe(share());
}
}
NbThemeService.decorators = [
{ type: Injectable }
];
NbThemeService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_THEME_OPTIONS,] }] },
{ type: NbMediaBreakpointsService },
{ type: NbJSThemesRegistry }
];
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
/**
* Service to control the global page spinner.
*/
class NbSpinnerService {
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>
*/
registerLoader(method) {
this.loaders.push(method);
}
/**
* Clears the list of loader
*/
clear() {
this.loaders = [];
}
/**
* Start the loader process, show spinnder and execute loaders
*/
load() {
this.showSpinner();
this.executeAll();
}
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?
showSpinner() {
const el = this.getSpinnerElement();
if (el) {
el.style['display'] = 'block';
}
}
hideSpinner() {
const el = this.getSpinnerElement();
if (el) {
el.style['display'] = 'none';
}
}
getSpinnerElement() {
return this.document.getElementById(this.selector);
}
}
NbSpinnerService.decorators = [
{ type: Injectable }
];
NbSpinnerService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }
];
/**
* Layout direction.
* */
var NbLayoutDirection;
(function (NbLayoutDirection) {
NbLayoutDirection["LTR"] = "ltr";
NbLayoutDirection["RTL"] = "rtl";
})(NbLayoutDirection || (NbLayoutDirection = {}));
/**
* Layout direction setting injection token.
* */
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 {
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.
* */
isLtr() {
return this.direction === NbLayoutDirection.LTR;
}
/**
* Returns true if layout direction set to right to left.
* @returns boolean.
* */
isRtl() {
return this.direction === NbLayoutDirection.RTL;
}
/**
* Returns current layout direction.
* @returns NbLayoutDirection.
* */
getDirection() {
return this.direction;
}
/**
* Sets layout direction
* @param {NbLayoutDirection} direction
*/
setDirection(direction) {
this.direction = direction;
this.$directionChange.next(direction);
}
/**
* Triggered when direction was changed.
* @returns Observable<NbLayoutDirection>.
*/
onDirectionChange() {
return this.$directionChange.pipe(share());
}
}
NbLayoutDirectionService.decorators = [
{ type: Injectable }
];
NbLayoutDirectionService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NB_LAYOUT_DIRECTION,] }] }
];
/**
* 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();
this.scrollable$ = new Subject();
}
/**
* Returns scroll position
*
* @returns {Observable<NbScrollPosition>}
*/
getPosition() {
return Observable.create((observer) => {
const listener = new Subject();
listener.subscribe(observer);
this.scrollPositionReq$.next({ listener });
return () => listener.complete();
});
}
/**
* Sets scroll position
*
* @param {number} x
* @param {number} y
*/
scrollTo(x = null, y = null) {
this.manualScroll$.next({ x, y });
}
/**
* Returns a stream of scroll events
*
* @returns {Observable<any>}
*/
onScroll() {
return this.scroll$.pipe(share());
}
/**
* @private
* @returns Observable<NbScrollPosition>.
*/
onManualScroll() {
return this.manualScroll$.pipe(share());
}
/**
* @private
* @returns {Subject<any>}
*/
onGetPosition() {
return this.scrollPositionReq$;
}
onScrollableChange() {
return this.scrollable$.pipe(share());
}
/**
* @private
* @param {any} event
*/
fireScrollChange(event) {
this.scroll$.next(event);
}
scrollable(scrollable) {
this.scrollable$.next(scrollable);
}
}
NbLayoutScrollService.decorators = [
{ type: Injectable }
];
/**
* 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>}
*/
getDimensions() {
return Observable.create((observer) => {
const listener = new Subject();
listener.subscribe(observer);
this.contentDimensionsReq$.next({ listener });
return () => listener.complete();
});
}
/**
* @private
* @returns {Subject<any>}
*/
onGetDimensions() {
return this.contentDimensionsReq$;
}
}
NbLayoutRulerService.decorators = [
{ type: Injectable }
];
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
class NbSharedModule {
}
NbSharedModule.decorators = [
{ type: NgModule, args: [{
exports: [
CommonModule,
// TODO: probably we don't need FormsModule in SharedModule
FormsModule,
RouterModule,
],
},] }
];
/**
* Overrides angular cdk focus trap to keep restore functionality inside trap.
* */
class NbFocusTrap extends FocusTrap {
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();
}
restoreFocus() {
this.previouslyFocusedElement.focus();
this.destroy();
}
blurPreviouslyFocusedElement() {
this.previouslyFocusedElement.blur();
}
savePreviouslyFocusedElement() {
this.previouslyFocusedElement = this.document.activeElement;
}
}
class NbFocusTrapFactoryService extends FocusTrapFactory {
constructor(checker, ngZone, document) {
super(checker, ngZone, document);
this.checker = checker;
this.ngZone = ngZone;
this.document = document;
}
create(element, deferCaptureElements) {
return new NbFocusTrap(element, this.checker, this.ngZone, this.document, deferCaptureElements);
}
}
NbFocusTrapFactoryService.decorators = [
{ type: Injectable }
];
NbFocusTrapFactoryService.ctorParameters = () => [
{ type: InteractivityChecker },
{ type: NgZone },
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }
];
class NbFocusKeyManager extends FocusKeyManager {
}
class NbFocusKeyManagerFactoryService {
create(items) {
return new NbFocusKeyManager(items);
}
}
class NbActiveDescendantKeyManager extends ActiveDescendantKeyManager {
}
class NbActiveDescendantKeyManagerFactoryService {
create(items) {
return new NbActiveDescendantKeyManager(items);
}
}
var NbKeyManagerActiveItemMode;
(function (NbKeyManagerActiveItemMode) {
NbKeyManagerActiveItemMode[NbKeyManagerActiveItemMode["RESET_ACTIVE"] = -1] = "RESET_ACTIVE";
NbKeyManagerActiveItemMode[NbKeyManagerActiveItemMode["FIRST_ACTIVE"] = 0] = "FIRST_ACTIVE";
})(NbKeyManagerActiveItemMode || (NbKeyManagerActiveItemMode = {}));
class NbFocusMonitor extends FocusMonitor {
}
NbFocusMonitor.decorators = [
{ type: Injectable }
];
class NbA11yModule {
static forRoot() {
return {
ngModule: NbA11yModule,
providers: [
NbFocusTrapFactoryService,
NbFocusKeyManagerFactoryService,
NbActiveDescendantKeyManagerFactoryService,
{ provide: NbFocusMonitor, useClass: FocusMonitor },
],
};
}
}
NbA11yModule.decorators = [
{ type: NgModule, args: [{},] }
];
class NbPortalDirective extends CdkPortal {
}
NbPortalDirective.decorators = [
{ type: Directive, args: [{ selector: '[nbPortal]' },] }
];
class NbPortalOutletDirective extends CdkPortalOutlet {
}
NbPortalOutletDirective.decorators = [
{ type: Directive, args: [{ selector: '[nbPortalOutlet]' },] }
];
class NbComponentPortal extends ComponentPortal {
}
class NbOverlay extends Overlay {
}
NbOverlay.decorators = [
{ type: Injectable }
];
class NbOverlayPositionBuilder extends OverlayPositionBuilder {
}
NbOverlayPositionBuilder.decorators = [
{ type: Injectable }
];
class NbTemplatePortal extends TemplatePortal {
constructor(template, viewContainerRef, context) {
super(template, viewContainerRef, context);
}
}
class NbOverlayContainer extends OverlayContainer {
}
NbOverlayContainer.decorators = [
{ type: Injectable }
];
class NbFlexibleConnectedPositionStrategy extends FlexibleConnectedPositionStrategy {
}
class NbPortalInjector extends PortalInjector {
}
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 {
static forRoot() {
return {
ngModule: NbCdkMappingModule,
providers: [
NbOverlay,
NbOverlayPositionBuilder,
],
};
}
}
NbCdkMappingModule.decorators = [
{ type: NgModule, args: [{
imports: [...CDK_MODULES],
exports: [
...CDK_MODULES,
NbPortalDirective,
NbPortalOutletDirective,
],
declarations: [NbPortalDirective, NbPortalOutletDirective],
},] }
];
class NbPlatform extends Platform {
}
NbPlatform.ɵprov = ɵɵdefineInjectable({ factory: function NbPlatform_Factory() { return new Platform(ɵɵinject(PLATFORM_ID)); }, token: NbPlatform, providedIn: "root" });
NbPlatform.decorators = [
{ type: Injectable, args: [{
providedIn: 'root',
useClass: Platform,
},] }
];
/**
* Provides nb-layout as overlay container.
* Container has to be cleared when layout destroys.
* Another way previous version of the container will be used
* but it isn't inserted in DOM and exists in memory only.
* This case important only if you switch between multiple layouts.
* */
class NbOverlayContainerAdapter extends NbOverlayContainer {
setContainer(container) {
this.container = container;
}
clearContainer() {
this.container = null;
this._containerElement = null;
}
_createContainer() {
const container = this._document.createElement('div');
container.classList.add('cdk-overlay-container');
this.container.appendChild(container);
this._containerElement = container;
}
}
NbOverlayContainerAdapter.decorators = [
{ type: Injectable }
];
class NbViewportRulerAdapter extends ViewportRuler {
constructor(platform, ngZone, ruler, scroll, document) {
super(platform, ngZone, document);
this.ruler = ruler;
this.scroll = scroll;
}
getViewportSize() {
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;
}
getViewportScrollPosition() {
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 }
];
NbViewportRulerAdapter.ctorParameters = () => [
{ type: NbPlatform },
{ type: NgZone },
{ type: NbLayoutRulerService },
{ type: NbLayoutScrollService },
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }
];
var NbGlobalLogicalPosition;
(function (NbGlobalLogicalPosition) {
NbGlobalLogicalPosition["TOP_START"] = "top-start";
NbGlobalLogicalPosition["TOP_END"] = "top-end";
NbGlobalLogicalPosition["BOTTOM_START"] = "bottom-start";
NbGlobalLogicalPosition["BOTTOM_END"] = "bottom-end";
})(NbGlobalLogicalPosition || (NbGlobalLogicalPosition = {}));
var NbGlobalPhysicalPosition;
(function (NbGlobalPhysicalPosition) {
NbGlobalPhysicalPosition["TOP_RIGHT"] = "top-right";
NbGlobalPhysicalPosition["TOP_LEFT"] = "top-left";
NbGlobalPhysicalPosition["BOTTOM_RIGHT"] = "bottom-right";
NbGlobalPhysicalPosition["BOTTOM_LEFT"] = "bottom-left";
})(NbGlobalPhysicalPosition || (NbGlobalPhysicalPosition = {}));
class NbPositionHelper {
constructor(layoutDirection) {
this.layoutDirection = layoutDirection;
}
toLogicalPosition(position) {
if (Object.values(NbGlobalLogicalPosition).includes(position)) {
return position;
}
if (this.layoutDirection.isLtr()) {
return this.toLogicalPositionWhenLtr(position);
}
else {
return this.toLogicalPositionWhenRtl(position);
}
}
toPhysicalPosition(position) {
if (Object.values(NbGlobalPhysicalPosition).includes(position)) {
return position;
}
if (this.layoutDirection.isLtr()) {
return this.toPhysicalPositionWhenLtr(position);
}
else {
return this.toPhysicalPositionWhenRtl(position);
}
}
isTopPosition(position) {
const logicalPosition = this.toLogicalPosition(position);
return logicalPosition === NbGlobalLogicalPosition.TOP_END
|| logicalPosition === NbGlobalLogicalPosition.TOP_START;
}
isRightPosition(position) {
const physicalPosition = this.toPhysicalPosition(position);
return physicalPosition === NbGlobalPhysicalPosition.TOP_RIGHT
|| physicalPosition === NbGlobalPhysicalPosition.BOTTOM_RIGHT;
}
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;
}
}
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;
}
}
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;
}
}
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 }
];
NbPositionHelper.ctorParameters = () => [
{ type: NbLayoutDirectionService }
];
var NbAdjustment;
(function (NbAdjustment) {
NbAdjustment["NOOP"] = "noop";
NbAdjustment["CLOCKWISE"] = "clockwise";
NbAdjustment["COUNTERCLOCKWISE"] = "counterclockwise";
NbAdjustment["VERTICAL"] = "vertical";
NbAdjustment["HORIZONTAL"] = "horizontal";
})(NbAdjustment || (NbAdjustment = {}));
var NbPosition;
(function (NbPosition) {
NbPosition["TOP"] = "top";
NbPosition["BOTTOM"] = "bottom";
NbPosition["LEFT"] = "left";
NbPosition["RIGHT"] = "right";
NbPosition["START"] = "start";
NbPosition["END"] = "end";
NbPosition["TOP_END"] = "top-end";
NbPosition["TOP_START"] = "top-start";
NbPosition["BOTTOM_END"] = "bottom-end";
NbPosition["BOTTOM_START"] = "bottom-start";
NbPosition["END_TOP"] = "end-top";
NbPosition["END_BOTTOM"] = "end-bottom";
NbPosition["START_TOP"] = "start-top";
NbPosition["START_BOTTOM"] = "start-bottom";
})(NbPosition || (NbPosition = {}));
const POSITIONS = {
[NbPosition.RIGHT](offset) {
return { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: offset };
},
[NbPosition.BOTTOM](offset) {
return { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: offset };
},
[NbPosition.LEFT](offset) {
return { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -offset };
},
[NbPosition.TOP](offset) {
return { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -offset };
},
[NbPosition.START](offset) {
return this[NbPosition.LEFT](offset);
},
[NbPosition.END](offset) {
return this[NbPosition.RIGHT](offset);
},
[NbPosition.END_TOP](offset) {
return { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom', offsetX: offset };
},
[NbPosition.END_BOTTOM](offset) {
return { originX: 'end', originY: 'top', overlayX: 'start', overlayY: 'top', offsetX: offset };
},
[NbPosition.BOTTOM_START](offset) {
return { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: offset };
},
[NbPosition.BOTTOM_END](offset) {
return { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: offset };
},
[NbPosition.START_TOP](offset) {
return { originX: 'start', originY: 'bottom', overlayX: 'end', overlayY: 'bottom', offsetX: -offset };
},
[NbPosition.START_BOTTOM](offset) {
return { originX: 'start', originY: 'top', overlayX: 'end', overlayY: 'top', offsetX: -offset };
},
[NbPosition.TOP_START](offset) {
return { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -offset };
},
[NbPosition.TOP_END](offset) {
return { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -offset };
},
};
const COUNTER_CLOCKWISE_POSITIONS = [
NbPosition.TOP,
NbPosition.TOP_END,
NbPosition.TOP_START,
NbPosition.START,
NbPosition.START_TOP,
NbPosition.START_BOTTOM,
NbPosition.BOTTOM,
NbPosition.BOTTOM_START,
NbPosition.BOTTOM_END,
NbPosition.END,
NbPosition.END_BOTTOM,
NbPosition.END_TOP,
];
const CLOCKWISE_POSITIONS = [
NbPosition.TOP,
NbPosition.TOP_START,
NbPosition.TOP_END,
NbPosition.END,
NbPosition.END_TOP,
NbPosition.END_BOTTOM,
NbPosition.BOTTOM,
NbPosition.BOTTOM_END,
NbPosition.BOTTOM_START,
NbPosition.START,
NbPosition.START_BOTTOM,
NbPosition.START_TOP,
];
const VERTICAL_POSITIONS = [NbPosition.BOTTOM, NbPosition.TOP];
const HORIZONTAL_POSITIONS = [NbPosition.START, NbPosition.END];
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.appliedPositions.find(({ connectedPosition }) => {
return comparePositions(connectedPosition, connectionPair);
}).key;
}));
}
attach(overlayRef) {
/**
* We have to apply positions before attach because super.attach() validates positions and crashes app
* if no positions provided.
* */
this.applyPositions();
super.attach(overlayRef);
}
apply() {
this.applyPositions();
super.apply();
}
position(position) {
this._position = position;
return this;
}
adjustment(adjustment) {
this._adjustment = adjustment;
return this;
}
offset(offset) {
this._offset = offset;
return this;
}
applyPositions() {
const positions = this.createPositions();
this.persistChosenPositions(positions);
this.withPositions(this.appliedPositions.map(({ connectedPosition }) => connectedPosition));
}
createPositions() {
switch (this._adjustment) {
case NbAdjustment.NOOP:
return [this._position];
case NbAdjustment.CLOCKWISE:
return this.reorderPreferredPositions(CLOCKWISE_POSITIONS);
case NbAdjustment.COUNTERCLOCKWISE:
return this.reorderPreferredPositions(COUNTER_CLOCKWISE_POSITIONS);
case NbAdjustment.HORIZONTAL:
return this.reorderPreferredPositions(HORIZONTAL_POSITIONS);
case NbAdjustment.VERTICAL:
return this.reorderPreferredPositions(VERTICAL_POSITIONS);
}
}
persistChosenPositions(positions) {
this.appliedPositions = positions.map(position => ({
key: position,
connectedPosition: POSITIONS[position](this._offset),
}));
}
reorderPreferredPositions(positions) {
// Physical positions should be mapped to logical as adjustments use logical positions.
const startPositionIndex = positions.indexOf(this.mapToLogicalPosition(this._position));
const firstPart = positions.slice(startPositionIndex);
const secondPart = positions.slice(0, startPositionIndex);
return firstPart.concat(secondPart);
}
mapToLogicalPosition(position) {
if (position === NbPosition.LEFT) {
return NbPosition.START;
}
if (position === NbPosition.RIGHT) {
return NbPosition.END;
}
return position;
}
}
class NbGlobalPositionStrategy extends GlobalPositionStrategy {
position(position) {
switch (position) {
case NbGlobalLogicalPosition.TOP_START:
return this.top().left();
case NbGlobalLogicalPosition.TOP_END:
return this.top().right();
case NbGlobalLogicalPosition.BOTTOM_START:
return this.bottom().left();
case NbGlobalLogicalPosition.BOTTOM_END:
return this.bottom().right();
}
}
}
class NbPositionBuilderService {
constructor(document, viewportRuler, platform, positionBuilder, overlayContainer) {
this.document = document;
this.viewportRuler = viewportRuler;
this.platform = platform;
this.positionBuilder = positionBuilder;
this.overlayContainer = overlayContainer;
}
global() {
return new NbGlobalPositionStrategy();
}
connectedTo(elementRef) {
return new NbAdjustableConnectedPositionStrategy(elementRef, this.viewportRuler, this.document, this.platform, this.overlayContainer)
.withFlexibleDimensions(false)
.withPush(false);
}
}
NbPositionBuilderService.decorators = [
{ type: Injectable }
];
NbPositionBuilderService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] },
{ type: NbViewportRulerAdapter },
{ type: NbPlatform },
{ type: NbOverlayPositionBuilder },
{ type: NbOverlayContainerAdapter }
];
class NbPositionedContainerComponent {
get top() {
return this.position === NbPosition.TOP;
}
get topStart() {
return this.position === NbPosition.TOP_START;
}
get topEnd() {
return this.position === NbPosition.TOP_END;
}
get right() {
return this.position === NbPosition.RIGHT || this.position === NbPosition.END;
}
get endTop() {
return this.position === NbPosition.END_TOP;
}
get endBottom() {
return this.position === NbPosition.END_BOTTOM;
}
get bottom() {
return this.position === NbPosition.BOTTOM;
}
get bottomStart() {
return this.position === NbPosition.BOTTOM_START;
}
get bottomEnd() {
return this.position === NbPosition.BOTTOM_END;
}
get left() {
return this.position === NbPosition.LEFT || this.position === NbPosition.START;
}
get startTop() {
return this.position === NbPosition.START_TOP;
}
get startBottom() {
return this.position === NbPosition.START_BOTTOM;
}
}
NbPositionedContainerComponent.decorators = [
{ type: Component, args: [{
template: ''
},] }
];
NbPositionedContainerComponent.propDecorators = {
position: [{ type: Input }],
top: [{ type: HostBinding, args: ['class.nb-overlay-top',] }],
topStart: [{ type: HostBinding, args: ['class.nb-overlay-top-start',] }],
topEnd: [{ type: HostBinding, args: ['class.nb-overlay-top-end',] }],
right: [{ type: HostBinding, args: ['class.nb-overlay-right',] }],
endTop: [{ type: HostBinding, args: ['class.nb-overlay-end-top',] }],
endBottom: [{ type: HostBinding, args: ['class.nb-overlay-end-bottom',] }],
bottom: [{ type: HostBinding, args: ['class.nb-overlay-bottom',] }],
bottomStart: [{ type: HostBinding, args: ['class.nb-overlay-bottom-start',] }],
bottomEnd: [{ type: HostBinding, args: ['class.nb-overlay-bottom-end',] }],
left: [{ type: HostBinding, args: ['class.nb-overlay-left',] }],
startTop: [{ type: HostBinding, args: ['class.nb-overlay-start-top',] }],
startBottom: [{ type: HostBinding, args: ['class.nb-overlay-start-bottom',] }]
};
class NbOverlayContainerComponent {
constructor(vcr, injector, changeDetectorRef) {
this.vcr = vcr;
this.injector = injector;
this.changeDetectorRef = changeDetectorRef;
this.isAttached = false;
}
get isStringContent() {
return !!this.content;
}
attachComponentPortal(portal, context) {
portal.injector = this.createChildInjector(portal.componentFactoryResolver);
const componentRef = this.portalOutlet.attachComponentPortal(portal);
if (context) {
Object.assign(componentRef.instance, context);
}
componentRef.changeDetectorRef.markForCheck();
componentRef.changeDetectorRef.detectChanges();
this.isAttached = true;
return componentRef;
}
attachTemplatePortal(portal) {
const templateRef = this.portalOutlet.attachTemplatePortal(portal);
templateRef.detectChanges();
this.isAttached = true;
return templateRef;
}
attachStringContent(content) {
this.content = content;
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
this.isAttached = true;
}
detach() {
if (this.portalOutlet.hasAttached()) {
this.portalOutlet.detach();
}
this.attachStringContent(null);
this.isAttached = false;
}
createChildInjector(cfr) {
return new NbPortalInjector(this.injector, new WeakMap([
[ComponentFactoryResolver, cfr],
]));
}
}
NbOverlayContainerComponent.decorators = [
{ type: Component, args: [{
selector: 'nb-overlay-container',
template: `
<div *ngIf="isStringContent" class="primitive-overlay">{{ content }}</div>
<ng-template nbPortalOutlet></ng-template>
`
},] }
];
NbOverlayContainerComponent.ctorParameters = () => [
{ type: ViewContainerRef },
{ type: Injector },
{ type: ChangeDetectorRef }
];
NbOverlayContainerComponent.propDecorators = {
portalOutlet: [{ type: ViewChild, args: [NbPortalOutletDirective, { static: true },] }]
};
function patch(container, containerContext) {
Object.assign(container.instance, containerContext);
container.changeDetectorRef.detectChanges();
return container;
}
function createContainer(ref, container, context, componentFactoryResolver) {
const containerRef = ref.attach(new NbComponentPortal(container, null, null, componentFactoryResolver));
patch(containerRef, context);
return containerRef;
}
class NbOverlayService {
constructor(overlay, layoutDirection) {
this.overlay = overlay;
this.layoutDirection = layoutDirection;
}
get scrollStrategies() {
return this.overlay.scrollStrategies;
}
create(config) {
const overlayRef = this.overlay.create(config);
this.layoutDirection.onDirectionChange()
.subscribe(dir => overlayRef.setDirection(dir));
return overlayRef;
}
}
NbOverlayService.decorators = [
{ type: Injectable }
];
NbOverlayService.ctorParameters = () => [
{ type: NbOverlay },
{ type: NbLayoutDirectionService }
];
class NbScrollDispatcherAdapter extends ScrollDispatcher {
constructor(ngZone, platform, scrollService, document) {
super(ngZone, platform, document);
this.scrollService = scrollService;
}
scrolled(auditTimeInMs) {
return this.scrollService.onScroll();
}
}
NbScrollDispatcherAdapter.decorators = [
{ type: Injectable }
];
NbScrollDispatcherAdapter.ctorParameters = () => [
{ type: NgZone },
{ type: NbPlatform },
{ type: NbLayoutScrollService },
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }
];
/**
* Overrides default block scroll strategy because default strategy blocks scrolling on the body only.
* But Nebular has i