UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

1,625 lines (1,606 loc) 1.51 MB
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