UNPKG

@rosen-group/ngx-onboarding

Version:

Onboarding module for Angular applications

933 lines 54.1 kB
import { timer, interval } from 'rxjs';
import * as i0 from '@angular/core';
import { Inject, Injectable, EventEmitter, Pipe, ViewEncapsulation, Component, ViewChild, Input, NgModule } from '@angular/core';
import { DOCUMENT, NgStyle, NgClass, UpperCasePipe } from '@angular/common';
import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
import { MatIcon } from '@angular/material/icon';
import { MatIconButton, MatButton } from '@angular/material/button';
import { MatBadge } from '@angular/material/badge';
import * as i2 from '@angular/platform-browser';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';

/**
 * Wrapper for native implementations of querySelector from window.document
 */
class BrowserDOMSelectorService {
    constructor(doc) {
        this.doc = doc;
    }
    /** see https://developer.mozilla.org/de/docs/Web/API/Document/querySelectorAll */
    querySelectorAll(cssQuery) {
        return this.doc.querySelectorAll(cssQuery);
    }
    /** see https://developer.mozilla.org/de/docs/Web/API/Document/querySelector */
    querySelector(cssQuery) {
        return this.doc.querySelector(cssQuery);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BrowserDOMSelectorService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BrowserDOMSelectorService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: BrowserDOMSelectorService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }] });

/**
 * Container to pass visible onboarding elements from onboarding service
 * to onboarding component (which can be grouped by their "group" field).
 *
 * Current group of elements can be accessed via currentItems(). Next group can be accessed via nextItems().
 *
 * Container does not have immediate access to grouping keys since elements are stored in jagged array.
 */
class OnboardingItemContainer {
    constructor() {
        this.items = [];
        this.totalCount = 0;
        this.currentGroupIndex = 0;
    }
    get isEmpty() {
        return !this.items || this.totalCount === 0;
    }
    /**
     * Check if there is another group of visible onboarding items
     */
    get hasNext() {
        return this.items && this.currentGroupIndex < (this.items.length - 1);
    }
    /**
     * Return current group of visible onboarding items
     */
    get currentItem() {
        if (this.items && this.currentGroupIndex < this.items.length) {
            return this.items[this.currentGroupIndex];
        }
        return null;
    }
    /**
     * Return list of All visible onboarding items (regardless of grouping)
     */
    get allItems() {
        return this.items.slice();
    }
    /**
     * Return count of all items (regardless of grouping)
     */
    get totalLength() {
        return this.totalCount;
    }
    /**
     * Return next group of visible onboarding items
     */
    nextItem() {
        if (this.hasNext) {
            this.currentGroupIndex++;
            return this.currentItem;
        }
        return null;
    }
    /**
     * Add new group of items
     */
    add(items) {
        if (items) {
            this.items.push(...items);
            this.totalCount += items.length;
        }
    }
    /**
     * Clear items from container
     */
    clear() {
        this.items = [];
        this.totalCount = 0;
        this.currentGroupIndex = 0;
    }
}

/**
 * contains static helper methods for [[HTMLELement]]
 */
class OnboardingHtmlElementHelper {
    static isVisible(htmlElement) {
        if (!htmlElement || typeof getComputedStyle !== 'function') {
            return false;
        }
        const style = getComputedStyle(htmlElement);
        if (!htmlElement.offsetParent && style.position !== 'fixed') {
            return false;
        }
        return !(style.opacity === '0' || style.display === 'none' || style.visibility === 'hidden' || style.visibility === 'collapse');
    }
    /**
     * true if element is visible in view (not scrolled out) or false if not
     */
    static isNotScrolledOut(htmlElement) {
        if (!htmlElement || !htmlElement.offsetParent) {
            return false;
        }
        const parent = htmlElement.offsetParent;
        const parentTop = parent.scrollTop;
        const parentBottom = parentTop + parent.offsetHeight;
        const elementTop = htmlElement.offsetTop;
        const elementBottom = elementTop + htmlElement.offsetHeight;
        return parentTop < elementTop && parentBottom > elementBottom;
    }
    /**
     * true if element and all parents are visible in view (not scrolled out) or false if not
     */
    static isVisibleInViewWithParents(htmlElement) {
        do {
            if (htmlElement && htmlElement.tagName && htmlElement.tagName.toLowerCase() === 'body') {
                return true;
            }
            if (!OnboardingHtmlElementHelper.isVisible(htmlElement)) {
                return false;
            }
            if (htmlElement.scrollTop > 0) {
                if (!OnboardingHtmlElementHelper.isNotScrolledOut(htmlElement)) {
                    return false;
                }
            }
        } while (htmlElement = htmlElement.offsetParent);
        return true;
    }
    /**
     * returns the position of element in document
     */
    static getPosition(htmlElement) {
        const rect = htmlElement.getBoundingClientRect();
        if (typeof DOMRect !== 'undefined' && rect instanceof DOMRect) {
            return {
                fixed: OnboardingHtmlElementHelper.isFixed(htmlElement),
                x: rect.x,
                y: rect.y,
                width: rect.width,
                height: rect.height
            };
        }
        return {
            fixed: OnboardingHtmlElementHelper.isFixed(htmlElement),
            x: rect.left,
            y: rect.top,
            width: rect.width,
            height: rect.height
        };
    }
    static isFixed(htmlElement) {
        if (!htmlElement || typeof getComputedStyle !== 'function') {
            return false;
        }
        const style = getComputedStyle(htmlElement);
        if (style.position === 'fixed') {
            return true;
        }
        return OnboardingHtmlElementHelper.isFixed(htmlElement.offsetParent);
    }
}

/**
 * Base class for storing the onboarding item enabled status. Can be overridden with own implementations
 * if you don't want to store the settings in the local storage
 */
class EnabledStatusBaseService {
}

var OnboardingButtonsPosition;
(function (OnboardingButtonsPosition) {
    OnboardingButtonsPosition[OnboardingButtonsPosition["BottomRight"] = 0] = "BottomRight";
    OnboardingButtonsPosition[OnboardingButtonsPosition["Bottom"] = 1] = "Bottom";
    OnboardingButtonsPosition[OnboardingButtonsPosition["BottomLeft"] = 2] = "BottomLeft";
    OnboardingButtonsPosition[OnboardingButtonsPosition["Left"] = 3] = "Left";
    OnboardingButtonsPosition[OnboardingButtonsPosition["TopLeft"] = 4] = "TopLeft";
    OnboardingButtonsPosition[OnboardingButtonsPosition["Top"] = 5] = "Top";
    OnboardingButtonsPosition[OnboardingButtonsPosition["TopRight"] = 6] = "TopRight";
    OnboardingButtonsPosition[OnboardingButtonsPosition["Right"] = 7] = "Right";
})(OnboardingButtonsPosition || (OnboardingButtonsPosition = {}));

/**
 * Base class for storing the onboarding item seen status. Can be overridden with own implementations
 * if you don't want to store the settings in the local storage
 */
class SeenSelectorsBaseService {
}

const addSeenSelectorDebounceTime = 1000;
const enabledChangedDebounceTime = 1000;
const refreshTime = 2000;
/**
 * The OnboardingService manages the configuration and the status of the onboarding component.
 *
 * The OnboardingComponent listens to the visibleItemsChanged event and retrieves new onboarding items from the visibleItems object.
 */
class OnboardingService {
    constructor(browserDomSelectorService, loadAndSaveSeenSelectorsService, loadAndSaveEnabledStatusService, errorHandler, zone) {
        this.browserDomSelectorService = browserDomSelectorService;
        this.loadAndSaveSeenSelectorsService = loadAndSaveSeenSelectorsService;
        this.loadAndSaveEnabledStatusService = loadAndSaveEnabledStatusService;
        this.errorHandler = errorHandler;
        this.zone = zone;
        /**
         * Container with currently visible onboarding items (grouped).
         * OnboardingComponent must iterate through these groups.
         *
         * called by OnboardingComponent
         */
        this.visibleItems = new OnboardingItemContainer();
        /**
         * called by OnboardingComponent
         */
        this.visibleItemsChanged = new EventEmitter();
        this.defaultConfiguration = {
            iconConfiguration: {
                matIconName: 'contact_support',
                matBadgeColor: 'accent',
                matBadgePosition: 'below after',
                matBadgeSize: 'medium'
            },
            textConfiguration: {
                regularFontFamily: 'Roboto, "Segoe UI", Helvetica, Arial, sans-serif;',
                scriptFontFamily: '"Gochi Hand", Georgia, "Segoe Script",  "Comic Sans MS", serif'
            },
            buttonsConfiguration: {
                position: OnboardingButtonsPosition.BottomRight,
                horizontalDistanceToBorderInPx: 50,
                verticalDistanceToBorderInPx: 40
            }
        };
        this.configuration = this.defaultConfiguration;
        /* this is the default setting. can be changed by configure()*/
        this.init();
    }
    /**
     * returns the count of the registered items
     */
    get registeredItemsCount() {
        return this.items.length;
    }
    /**
     * Configures the onboarding icons and fonts.
     *
     * If you want to change the default settings, then call this in your module where you import this
     * service as provider and set global defaults like icon properties
     */
    configure(configuration) {
        if (typeof configuration === 'undefined') {
            throw new Error('Configuration must not be undefined or null');
        }
        // new merge default configuration with user configuration
        const mergedConfig = {
            iconConfiguration: Object.assign({}, this.defaultConfiguration.iconConfiguration),
            textConfiguration: Object.assign({}, this.defaultConfiguration.textConfiguration),
            buttonsConfiguration: Object.assign({}, this.defaultConfiguration.buttonsConfiguration)
        };
        if (configuration.iconConfiguration) {
            Object.assign(mergedConfig.iconConfiguration, configuration.iconConfiguration);
            // icon shape configurations are mutually exclusive so a special checks are needed for that
            if (!configuration.iconConfiguration.matIconName &&
                (configuration.iconConfiguration.fontSet || configuration.iconConfiguration.svgIcon)) {
                mergedConfig.iconConfiguration.matIconName = undefined; // if the user wants fontSet than we have to disable matIconName
            }
        }
        if (configuration.textConfiguration) {
            Object.assign(mergedConfig.textConfiguration, configuration.textConfiguration);
        }
        if (configuration.buttonsConfiguration) {
            Object.assign(mergedConfig.buttonsConfiguration, configuration.buttonsConfiguration);
        }
        this.configuration = mergedConfig;
    }
    /** used internal only to retrieve to configuration from configure()*/
    getConfiguration() {
        return this.configuration;
    }
    /**
     * registers [[OnboardingItem]]s in items, returns the method to unregister items (e.g. in ngOnDestroy)
     */
    register(items) {
        this.items.push(...items);
        return () => {
            // this.items = filter(this.items, thisItem => !some(items, item => thisItem.selector === item.selector));
            this.items = this.items.filter(thisItem => !items.some(item => thisItem.selector === item.selector));
        };
    }
    /**
     * Check which onboarding items are visible. Emit visibleItemsChanged event.
     * called by OnboardingComponent
     */
    check() {
        try {
            if (this.isEnabled() && this.visibleItems && this.visibleItems.totalLength > 0) {
                return;
            }
            const matches = [];
            const notSeenItems = this.getNotSeenItems();
            if (notSeenItems) {
                notSeenItems.forEach(item => {
                    const elements = Array.from(this.browserDomSelectorService.querySelectorAll(item.selector));
                    if (elements && elements.length > 0) {
                        let element = elements.find((e) => OnboardingHtmlElementHelper.isVisibleInViewWithParents(e));
                        if (element) {
                            if (item.toParent && element.offsetParent) {
                                element = element.offsetParent;
                            }
                            if (element) {
                                matches.push({
                                    item: item,
                                    element: element
                                });
                            }
                        }
                    }
                });
            }
            this.visibleItems.clear();
            this.visibleItems.add(matches);
            this.visibleItemsChanged.emit();
        }
        catch (error) {
            this.errorHandler.handleError(error);
        }
    }
    /**
     * Mark all visible items as SEEN, remove them from visible list and emit change event.
     * called by OnboardingComponent
     */
    hide() {
        this.visibleItems.allItems.forEach(i => {
            this.addToSeenSelectors(i.item.selector);
        });
        this.visibleItems.clear();
        this.visibleItemsChanged.emit();
    }
    /**
     * called by OnboardingComponent
     *
     * Disables the onboarding
     */
    disable() {
        this.hide();
        this.enabled = false;
        this.visibleItemsChanged.emit();
        this.enabledChanged();
    }
    /**
     * called by OnboardingComponent
     *
     * Enables the onboarding
     */
    enable() {
        this.enabled = true;
        this.visibleItems.clear();
        this.check();
        this.enabledChanged();
    }
    /**
     * called by OnboardingComponent
     */
    isEnabled() {
        return this.enabled;
    }
    /**
     * called by OnboardingComponent
     */
    clearSeenSelectors() {
        this.seenSelectors = [];
        this.seenSelectorsChanged();
    }
    init() {
        this.items = [];
        this.seenSelectors = [];
        this.visibleItems.clear();
        this.loadSeenSelectors();
        this.loadEnabledStatus();
        this.startRefreshTimer();
    }
    addToSeenSelectors(selector) {
        this.seenSelectors.push(selector);
        this.seenSelectorsChanged();
    }
    seenSelectorsChanged() {
        if (this.addSeenSelectorDebounceSubscription) {
            this.addSeenSelectorDebounceSubscription.unsubscribe();
        }
        const source = timer(addSeenSelectorDebounceTime);
        this.addSeenSelectorDebounceSubscription = source.subscribe(() => {
            this.saveSeenSelectors();
        });
    }
    enabledChanged() {
        if (this.enabledChangedDebounceSubscription) {
            this.enabledChangedDebounceSubscription.unsubscribe();
        }
        const source = timer(enabledChangedDebounceTime);
        this.enabledChangedDebounceSubscription = source.subscribe(() => {
            this.saveEnabledStatus();
        });
    }
    getNotSeenItems() {
        return this.items.filter(i => !this.seenSelectors.some(seen => seen === i.selector));
    }
    startRefreshTimer() {
        if (this.refreshSubscription) {
            this.refreshSubscription.unsubscribe();
        }
        const source = interval(refreshTime);
        this.zone.runOutsideAngular(() => {
            this.refreshSubscription = source.subscribe(() => {
                this.zone.run(() => {
                    this.check();
                });
            });
        });
    }
    loadSeenSelectors() {
        this.loadAndSaveSeenSelectorsService.load().subscribe(seenSelectors => {
            this.seenSelectors = seenSelectors;
        });
    }
    saveSeenSelectors() {
        this.loadAndSaveSeenSelectorsService.save(this.seenSelectors);
    }
    loadEnabledStatus() {
        this.loadAndSaveEnabledStatusService.load().subscribe(enabled => {
            this.enabled = enabled;
        });
    }
    saveEnabledStatus() {
        this.loadAndSaveEnabledStatusService.save(this.enabled);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingService, deps: [{ token: BrowserDOMSelectorService }, { token: SeenSelectorsBaseService }, { token: EnabledStatusBaseService }, { token: i0.ErrorHandler }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingService, providedIn: 'root' /* makes sure that service stays a single instance among seperate modules */ }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root' /* makes sure that service stays a single instance among seperate modules */
                }]
        }], ctorParameters: () => [{ type: BrowserDOMSelectorService }, { type: SeenSelectorsBaseService }, { type: EnabledStatusBaseService }, { type: i0.ErrorHandler }, { type: i0.NgZone }] });

/**
 * Base interface for translatorservice (used for core ngx-onboarding labels)
 */
class TranslatorBaseService {
}

/**
 * Pipe for internal usage to translate the text on the onboarding component like disable, enable
 */
class PrimitiveTranslatePipe {
    constructor(translateService) {
        this.translateService = translateService;
    }
    transform(query, ...args) {
        return this.translateService.instant(query);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: PrimitiveTranslatePipe, deps: [{ token: TranslatorBaseService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.11", ngImport: i0, type: PrimitiveTranslatePipe, isStandalone: true, name: "translate" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: PrimitiveTranslatePipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'translate'
                }]
        }], ctorParameters: () => [{ type: TranslatorBaseService }] });

/**
 * onboarding button including context menu
 */
class OnboardingButtonComponent {
    constructor(onboardingService) {
        this.onboardingService = onboardingService;
        const config = onboardingService.getConfiguration();
        if (config) {
            this.iconConfig = config.iconConfiguration;
        }
    }
    /**
     * if true, the count is visible
     * is true, if the onboarding service is disabled and at least one onboarding item is visible
     */
    get showOnboardingItemCount() {
        return !this.onboardingService.isEnabled() &&
            this.onboardingService.visibleItems &&
            this.onboardingService.visibleItems.totalLength > 0;
    }
    /**
     * gets the visible item count
     */
    get onboardingItemCount() {
        return this.onboardingService.visibleItems.totalLength;
    }
    /**
     * used by template
     * enables the onboarding service
     */
    enableOnboarding() {
        this.onboardingService.enable();
    }
    /**
     * disables the onboarding service
     */
    disableOnboarding() {
        this.onboardingService.disable();
    }
    /**
     * resets the onboarding service
     * removes all selectors from seen selectors
     */
    clearOnboarding() {
        this.onboardingService.clearSeenSelectors();
    }
    /**
     * is true, if the onboarding service is enabled
     */
    isOnboardingEnabled() {
        return this.onboardingService.isEnabled();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingButtonComponent, deps: [{ token: OnboardingService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: OnboardingButtonComponent, isStandalone: true, selector: "rosen-onboarding-button", ngImport: i0, template: "<div class=\"onboarding-button-container\">\n    <mat-menu #onboardingMenu=\"matMenu\">\n        @if (!isOnboardingEnabled()) {\n            <button mat-menu-item (click)=\"enableOnboarding()\"\n                    class=\"onboarding-menu-button\">\n                <mat-icon>add_alert</mat-icon>\n                {{ 'ONBOARDING_ENABLE'|translate }}\n            </button>\n        }\n        @if (isOnboardingEnabled()) {\n            <button mat-menu-item (click)=\"disableOnboarding()\"\n                    class=\"onboarding-menu-button\">\n                <mat-icon>notifications_off</mat-icon>\n                {{ 'ONBOARDING_DISABLE'|translate }}\n            </button>\n        }\n        <button mat-menu-item (click)=\"clearOnboarding()\" class=\"onboarding-menu-button\">\n            <mat-icon>undo</mat-icon>\n            {{ 'ONBOARDING_CLEAR'|translate }}\n        </button>\n    </mat-menu>\n    @if (iconConfig) {\n        <button mat-icon-button [matMenuTriggerFor]=\"onboardingMenu\" class=\"onboarding-button\"\n                [title]=\"'ONBOARDING'|translate\">\n            @if (iconConfig.matIconName && !iconConfig.svgIcon && !iconConfig.fontSet) {\n                <mat-icon [matBadgeHidden]=\"isOnboardingEnabled()\"\n                          [matBadge]=\"onboardingItemCount\"\n                          [matBadgeOverlap]=\"true\">{{ iconConfig.matIconName }}\n                </mat-icon>\n            }\n            @if (iconConfig.svgIcon || iconConfig.fontSet) {\n                <mat-icon [svgIcon]=\"iconConfig.svgIcon\"\n                          [fontSet]=\"iconConfig.fontSet\" [fontIcon]=\"iconConfig.fontIcon\"\n                          [matBadgeHidden]=\"isOnboardingEnabled()\"\n                          [matBadge]=\"onboardingItemCount\"\n                          [matBadgeOverlap]=\"true\">\n                </mat-icon>\n            }\n        </button>\n    }\n</div>\n", styles: [".onboarding-button-container{position:relative;text-align:center}\n"], dependencies: [{ kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "pipe", type: PrimitiveTranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingButtonComponent, decorators: [{
            type: Component,
            args: [{ selector: 'rosen-onboarding-button', imports: [
                        MatMenu,
                        MatMenuItem,
                        MatIcon,
                        MatIconButton,
                        MatMenuTrigger,
                        PrimitiveTranslatePipe,
                        MatBadge
                    ], encapsulation: ViewEncapsulation.None, template: "<div class=\"onboarding-button-container\">\n    <mat-menu #onboardingMenu=\"matMenu\">\n        @if (!isOnboardingEnabled()) {\n            <button mat-menu-item (click)=\"enableOnboarding()\"\n                    class=\"onboarding-menu-button\">\n                <mat-icon>add_alert</mat-icon>\n                {{ 'ONBOARDING_ENABLE'|translate }}\n            </button>\n        }\n        @if (isOnboardingEnabled()) {\n            <button mat-menu-item (click)=\"disableOnboarding()\"\n                    class=\"onboarding-menu-button\">\n                <mat-icon>notifications_off</mat-icon>\n                {{ 'ONBOARDING_DISABLE'|translate }}\n            </button>\n        }\n        <button mat-menu-item (click)=\"clearOnboarding()\" class=\"onboarding-menu-button\">\n            <mat-icon>undo</mat-icon>\n            {{ 'ONBOARDING_CLEAR'|translate }}\n        </button>\n    </mat-menu>\n    @if (iconConfig) {\n        <button mat-icon-button [matMenuTriggerFor]=\"onboardingMenu\" class=\"onboarding-button\"\n                [title]=\"'ONBOARDING'|translate\">\n            @if (iconConfig.matIconName && !iconConfig.svgIcon && !iconConfig.fontSet) {\n                <mat-icon [matBadgeHidden]=\"isOnboardingEnabled()\"\n                          [matBadge]=\"onboardingItemCount\"\n                          [matBadgeOverlap]=\"true\">{{ iconConfig.matIconName }}\n                </mat-icon>\n            }\n            @if (iconConfig.svgIcon || iconConfig.fontSet) {\n                <mat-icon [svgIcon]=\"iconConfig.svgIcon\"\n                          [fontSet]=\"iconConfig.fontSet\" [fontIcon]=\"iconConfig.fontIcon\"\n                          [matBadgeHidden]=\"isOnboardingEnabled()\"\n                          [matBadge]=\"onboardingItemCount\"\n                          [matBadgeOverlap]=\"true\">\n                </mat-icon>\n            }\n        </button>\n    }\n</div>\n", styles: [".onboarding-button-container{position:relative;text-align:center}\n"] }]
        }], ctorParameters: () => [{ type: OnboardingService }] });

class OnboardingItem {
    constructor() {
        this.disableSpotlight = false;
        this.disableBackground = false;
        this.transparentSpotlight = false;
        this.toParent = false;
    }
}

class VisibleOnboardingItem {
    constructor(item, element) {
        this.item = item;
        this.element = element;
    }
}

/**
 * return the global native browser window object
 */
function _window() {
    return window;
}
/**
 * Abstraction of the window reference
 */
class WindowRef {
    get nativeWindow() {
        return _window();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: WindowRef, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: WindowRef, providedIn: 'root' /* makes sure that service stays a single instance among seperate modules */ }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: WindowRef, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' /* makes sure that service stays a single instance among seperate modules */ }]
        }] });

const topPadding = 25;
const rightPadding = 25;
const leftPadding = 25;
/**
 * used by onboarding component
 * shows the headline and detail text of the OnboardingItem
 * calculates the positions of the item
 */
class OnboardingItemComponent {
    constructor(translatorService, windowRef) {
        this.translatorService = translatorService;
        this.windowRef = windowRef;
    }
    /**
     * calculates the position of the OnboardingItemComponent
     */
    getStyle() {
        const pos = OnboardingHtmlElementHelper.getPosition(this.item.element);
        let transform = 'none';
        switch (this.item.item.position) {
            case 'top':
                pos.x += this.item.element.offsetWidth / 2;
                if (pos.x < this.getContainerWidth() / 2) {
                    pos.x = this.getContainerWidth() / 2;
                }
                else if (pos.x > this.getWindowScreenWidth() - this.getContainerWidth()) {
                    pos.x = this.getWindowScreenWidth() - this.getContainerWidth();
                }
                pos.y -= topPadding;
                transform = 'translate(-50%,-100%)';
                break;
            case 'right':
                pos.x += Math.min(this.item.element.offsetWidth + rightPadding, this.getWindowScreenWidth() - this.getContainerWidth() / 2);
                pos.y += this.item.element.offsetHeight / 2;
                if (pos.y < 0) {
                    pos.y = 0;
                }
                else if (pos.y > this.getWindowScreenHeight() - this.getContainerHeight() / 2) {
                    pos.y = this.getWindowScreenHeight() - this.getContainerHeight() / 2;
                }
                transform = 'translateY(-50%)';
                break;
            case 'left':
                pos.x -= leftPadding;
                pos.y += this.item.element.offsetHeight / 2;
                if (pos.y < 0) {
                    pos.y = 0;
                }
                else if (pos.y > this.getWindowScreenHeight() - this.getContainerHeight() / 2) {
                    pos.y = this.getWindowScreenHeight() - this.getContainerHeight() / 2;
                }
                transform = 'translate(-100%,-50%)';
                break;
            case 'topleft':
                pos.x -= leftPadding;
                pos.y -= topPadding;
                if (pos.y < 0) {
                    pos.y = 0;
                }
                else if (pos.y > this.getWindowScreenHeight() - this.getContainerHeight() / 2) {
                    pos.y = this.getWindowScreenHeight() - this.getContainerHeight() / 2;
                }
                transform = 'translate(-100%,-100%)';
                break;
            case 'bottom':
            default:
                pos.x += this.item.element.offsetWidth / 2;
                if (pos.x < this.getContainerWidth() / 2) {
                    pos.x = this.getContainerWidth() / 2;
                }
                else if (pos.x > this.getWindowScreenWidth() - this.getContainerWidth()) {
                    pos.x = this.getWindowScreenWidth() - this.getContainerWidth();
                }
                pos.y += this.item.element.offsetHeight;
                transform = 'translate(-50%,25%)';
                break;
        }
        return {
            left: pos.x + 'px',
            transform: transform,
            top: pos.y + 'px'
        };
    }
    getHeadline() {
        const description = this.item.item.descriptions?.find(d => d.language === this.translatorService.currentLang);
        return description ? description.headline : this.item.item.headline;
    }
    getDetails() {
        const description = this.item.item.descriptions?.find(d => d.language === this.translatorService.currentLang);
        return description ? description.details : this.item.item.details;
    }
    getTextAlignClass() {
        if ((this.item.item.textAlign == null) || this.item.item.textAlign === 'center') {
            return ''; // ==> center
        }
        return `align-${this.item.item.textAlign}`;
    }
    getContainerWidth() {
        return this.container.nativeElement.offsetWidth;
    }
    getContainerHeight() {
        return this.container.nativeElement.offsetHeight;
    }
    getWindowScreenWidth() {
        return this.windowRef.nativeWindow ? this.windowRef.nativeWindow.screen.width : 1024;
    }
    getWindowScreenHeight() {
        return this.windowRef.nativeWindow ? this.windowRef.nativeWindow.screen.height : 768;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingItemComponent, deps: [{ token: TranslatorBaseService }, { token: WindowRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: OnboardingItemComponent, isStandalone: true, selector: "rosen-onboarding-item", inputs: { item: "item" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }], ngImport: i0, template: "<div #container class=\"onboarding-item\" [ngStyle]=\"getStyle()\">\n    <div class=\"onboarding-item-header text-color animated script-font fade-in-left\" [ngClass]=\"getTextAlignClass()\">\n        {{getHeadline()}}\n    </div>\n    <div class=\"onboarding-item-details text-color animated regular-font fade-in-right\" [ngClass]=\"getTextAlignClass()\">\n        {{getDetails()}}\n    </div>\n</div>\n", styles: [".onboarding-item{position:absolute}.onboarding-item .text-color{color:#fff}.onboarding-item .onboarding-item-header{font-size:24px;text-align:center}.onboarding-item .onboarding-item-details{font-size:14px;text-align:center}.onboarding-item .align-left{text-align:left}.onboarding-item .align-right{text-align:right}.onboarding-item .animated{animation-duration:1s}.onboarding-item .fade-in-right{animation-name:fadeInRight}.onboarding-item .fade-in-left{animation-name:fadeInLeft}.onboarding-item .fade-in-top{animation-name:fadeInTop}.onboarding-item .fade-in-bottom{animation-name:fadeInBottoim}@keyframes fadeInRight{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}@keyframes fadeInLeft{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}@keyframes fadeInTop{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInBottom{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingItemComponent, decorators: [{
            type: Component,
            args: [{ selector: 'rosen-onboarding-item', imports: [
                        NgStyle,
                        NgClass
                    ], encapsulation: ViewEncapsulation.None, template: "<div #container class=\"onboarding-item\" [ngStyle]=\"getStyle()\">\n    <div class=\"onboarding-item-header text-color animated script-font fade-in-left\" [ngClass]=\"getTextAlignClass()\">\n        {{getHeadline()}}\n    </div>\n    <div class=\"onboarding-item-details text-color animated regular-font fade-in-right\" [ngClass]=\"getTextAlignClass()\">\n        {{getDetails()}}\n    </div>\n</div>\n", styles: [".onboarding-item{position:absolute}.onboarding-item .text-color{color:#fff}.onboarding-item .onboarding-item-header{font-size:24px;text-align:center}.onboarding-item .onboarding-item-details{font-size:14px;text-align:center}.onboarding-item .align-left{text-align:left}.onboarding-item .align-right{text-align:right}.onboarding-item .animated{animation-duration:1s}.onboarding-item .fade-in-right{animation-name:fadeInRight}.onboarding-item .fade-in-left{animation-name:fadeInLeft}.onboarding-item .fade-in-top{animation-name:fadeInTop}.onboarding-item .fade-in-bottom{animation-name:fadeInBottoim}@keyframes fadeInRight{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}@keyframes fadeInLeft{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}@keyframes fadeInTop{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes fadeInBottom{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
        }], ctorParameters: () => [{ type: TranslatorBaseService }, { type: WindowRef }], propDecorators: { item: [{
                type: Input
            }], container: [{
                type: ViewChild,
                args: ['container', { static: true }]
            }] } });

/**
 * Main component of the onboarding module.
 * Handles the visualization of the onboarding items
 */
class OnboardingComponent {
    constructor(onboardingService, domSanitizer) {
        this.onboardingService = onboardingService;
        this.domSanitizer = domSanitizer;
        this.visibleItem = null;
        const config = onboardingService.getConfiguration();
        this.textConfig = config.textConfiguration;
        this.buttonConfig = config.buttonsConfiguration;
        if (config.iconConfiguration) { // we expect the config to be present always but just in case
            this.matIconName = config.iconConfiguration.matIconName;
            this.fontSet = config.iconConfiguration.fontSet;
            this.fontIcon = config.iconConfiguration.fontIcon;
            this.svgIcon = config.iconConfiguration.svgIcon;
        }
    }
    ngOnInit() {
        // Dynamic generated css is needed because these options have be configurable
        let dynCss = ``;
        // for this component
        dynCss += `<style type="text/css">`;
        dynCss += `.onboarding-component-container .script-font { font-family: ${this.textConfig.scriptFontFamily}}`;
        dynCss += `.onboarding-component-container .regular-font { font-family: ${this.textConfig.regularFontFamily}}`;
        dynCss += `</style>`;
        this.dynamicCss = this.domSanitizer.bypassSecurityTrustHtml(dynCss);
    }
    ngAfterViewInit() {
        this.visibleItemsChangedSubscription = this.onboardingService.visibleItemsChanged.subscribe(() => {
            this.visibleItem = this.onboardingService.visibleItems.currentItem;
            this.hasNext = this.onboardingService.visibleItems.hasNext;
            if (this.visibleItem) {
                this.showItem(this.visibleItem);
            }
        });
    }
    ngOnDestroy() {
        if (this.visibleItemsChangedSubscription) {
            this.visibleItemsChangedSubscription.unsubscribe();
        }
        this.onboardingService.hide(); // hide ALL items
    }
    /**
     * gets the fixed position of the html element
     * used by template to set the position of the spotlight
     */
    getPositionStyle(ele) {
        const pos = OnboardingHtmlElementHelper.getPosition(ele);
        const style = {
            position: 'fixed',
            left: pos.x + 'px',
            top: pos.y + 'px',
            width: pos.width + 'px',
            height: pos.height + 'px'
        };
        if (pos.fixed) {
            style.background = 'transparent';
        }
        return style;
    }
    isSpotlightTransparent(item) {
        return item.transparentSpotlight;
    }
    /**
     * used by turn off button in template
     */
    disable() {
        if (this.visibleItem) {
            this.hideItem(this.visibleItem); // hide old item
        }
        this.onboardingService.disable();
    }
    /**
     * hide current group (show next one if one is available
     */
    hide() {
        if (this.onboardingService.visibleItems && this.hasNext) {
            // hide current and show next item
            this.hideItem(this.visibleItem); // hide OLD items
            this.visibleItem = this.onboardingService.visibleItems.nextItem();
            this.hasNext = this.onboardingService.visibleItems.hasNext; // show NEW ones
            this.showItem(this.visibleItem);
        }
        else {
            this.hideItem(this.visibleItem);
            this.onboardingService.hide(); // mark all items as seen...
            this.visibleItem = null;
            this.hasNext = false;
        }
    }
    buttonsPositionStyle() {
        switch (this.buttonConfig.position) {
            case OnboardingButtonsPosition.Bottom:
                return {
                    bottom: this.buttonConfig.verticalDistanceToBorderInPx + 'px',
                    left: '50%',
                    transform: 'translateX(-50%)',
                };
            case OnboardingButtonsPosition.BottomLeft:
                return {
                    bottom: this.buttonConfig.verticalDistanceToBorderInPx + 'px',
                    left: this.buttonConfig.horizontalDistanceToBorderInPx + 'px',
                };
            case OnboardingButtonsPosition.Left:
                return {
                    top: '50%',
                    transform: 'translateY(-50%)',
                    left: this.buttonConfig.horizontalDistanceToBorderInPx + 'px'
                };
            case OnboardingButtonsPosition.TopLeft:
                return {
                    top: this.buttonConfig.verticalDistanceToBorderInPx + 'px',
                    left: this.buttonConfig.horizontalDistanceToBorderInPx + 'px'
                };
            case OnboardingButtonsPosition.Top:
                return {
                    top: this.buttonConfig.verticalDistanceToBorderInPx + 'px',
                    left: '50%',
                    transform: 'translateX(-50%)',
                };
            case OnboardingButtonsPosition.TopRight:
                return {
                    top: this.buttonConfig.verticalDistanceToBorderInPx + 'px',
                    right: this.buttonConfig.horizontalDistanceToBorderInPx + 'px'
                };
            case OnboardingButtonsPosition.Right:
                return {
                    top: '50%',
                    transform: 'translateY(-50%)',
                    right: this.buttonConfig.horizontalDistanceToBorderInPx + 'px'
                };
            case OnboardingButtonsPosition.BottomRight:
            default:
                return {
                    bottom: this.buttonConfig.verticalDistanceToBorderInPx + 'px',
                    right: this.buttonConfig.horizontalDistanceToBorderInPx + 'px'
                };
        }
    }
    /**
     * Show onboarding item
     */
    showItem(i) {
        if (this.onboardingService.isEnabled()) {
            i.element.classList.add('onboarding-highlighted');
            if (!i.element.style.position || i.element.style.position === 'static') {
                i.element.classList.add('onboarding-highlighted-on-static');
            }
        }
    }
    /**
     * Hide SINGLE element without change notification
     */
    hideItem(i) {
        i.element.classList.remove('onboarding-highlighted');
        i.element.classList.remove('onboarding-highlighted-on-static');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingComponent, deps: [{ token: OnboardingService }, { token: i2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: OnboardingComponent, isStandalone: true, selector: "rosen-onboarding", ngImport: i0, template: "<span [innerHtml]=\"dynamicCss\"></span>\n\n@if (onboardingService.isEnabled() && visibleItem) {\n    <div class=\"onboarding-component-container\">\n        @if (onboardingService.isEnabled() && visibleItem) {\n            <div class=\"onboarding-header script-font\">\n                @if (matIconName && !svgIcon && !fontSet) {\n                    <mat-icon>{{ matIconName }}</mat-icon>\n                }\n                @if (svgIcon || fontSet) {\n                    <mat-icon [svgIcon]=\"svgIcon\" [fontSet]=\"fontSet\" [fontIcon]=\"fontIcon\"></mat-icon>\n                }\n                {{ 'ONBOARDING' | translate | uppercase }}\n            </div>\n        }\n        <div class=\"onboarding-shadow\"\n             [ngStyle]=\"getPositionStyle(visibleItem.element)\"></div>\n        <div class=\"onboarding-spotlight\"\n             [class.onboarding-spotlight-transparent]=\"isSpotlightTransparent(visibleItem.item)\"\n             [ngStyle]=\"getPositionStyle(visibleItem.element)\"></div>\n        <div class=\"onboarding-items\">\n            @for (currentItem of onboardingService.visibleItems.allItems; track currentItem) {\n                <div>\n                    @if (currentItem === visibleItem) {\n                        <rosen-onboarding-item [item]=\"currentItem\"></rosen-onboarding-item>\n                    }\n                </div>\n            }\n        </div>\n        <div class=\"onboarding-overlay\" (click)=\"hide()\"></div>\n        <div class=\"onboarding-buttons\" [ngStyle]=\"buttonsPositionStyle()\">\n            <button mat-flat-button color=\"warn\" (click)=\"disable()\">\n                <span>{{ 'ONBOARDING_DO_NOT_SHOW_AGAIN_MSG' | translate }}</span>\n            </button>\n            <button mat-flat-button color=\"primary\" (click)=\"hide()\">\n                @if (!hasNext) {\n                    <span>{{ 'ONBOARDING_GOT_IT_MSG' | translate }}</span>\n                }\n                @if (hasNext) {\n                    <span>{{ 'ONBOARDING_NEXT_MSG' | translate }}</span>\n                }\n            </button>\n        </div>\n    </div>\n}\n", styles: [".onboarding-component-container .mat-icon{font-size:32px;width:32px!important;height:32px!important;line-height:32px!important}.onboarding-component-container .onboarding-shadow{box-shadow:0 0 0 10000px #000000b3;z-index:9999994}.onboarding-component-container .onboarding-spotlight{box-shadow:0 0 8px 8px #fff;background:#fff;z-index:9999995}.onboarding-component-container .onboarding-spotlight-transparent{background:transparent}.onboarding-component-container .onboarding-items{position:fixed;inset:0;z-index:9999997}.onboarding-component-container .onboarding-overlay{position:fixed;inset:0;z-index:9999998}.onboarding-component-container .onboarding-buttons{position:fixed;z-index:9999999;clear:both}.onboarding-component-container .onboarding-buttons>button{float:right}.onboarding-component-container .onboarding-buttons button[color=primary]{margin-right:8px}.onboarding-component-container .onboarding-header{position:fixed;inset:4px 0 0 4px;z-index:9999998;font-size:24px;color:#d9d9d9}.onboarding-component-container .onboarding-header>span{font-size:24px}.onboarding-highlighted,.onboarding-highlighted *{z-index:9999996!important}.onboarding-highlighted *.glyphicon,.onboarding-highlighted a,a.onboarding-highlighted{color:#444!important}.onboarding-highlighted-on-static{position:relative}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: OnboardingItemComponent, selector: "rosen-onboarding-item", inputs: ["item"] }, { kind: "component", type: MatButton, selector: "    button[matButton], a[matButton], button[mat-button], button[mat-raised-button],    button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button],    a[mat-flat-button], a[mat-stroked-button]  ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: PrimitiveTranslatePipe, name: "translate" }, { kind: "pipe", type: UpperCasePipe, name: "uppercase" }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingComponent, decorators: [{
            type: Component,
            args: [{ selector: 'rosen-onboarding', imports: [
                        PrimitiveTranslatePipe,
                        NgStyle,
                        OnboardingItemComponent,
                        MatButton,
                        MatIcon,
                        UpperCasePipe
                    ], encapsulation: ViewEncapsulation.None, template: "<span [innerHtml]=\"dynamicCss\"></span>\n\n@if (onboardingService.isEnabled() && visibleItem) {\n    <div class=\"onboarding-component-container\">\n        @if (onboardingService.isEnabled() && visibleItem) {\n            <div class=\"onboarding-header script-font\">\n                @if (matIconName && !svgIcon && !fontSet) {\n                    <mat-icon>{{ matIconName }}</mat-icon>\n                }\n                @if (svgIcon || fontSet) {\n                    <mat-icon [svgIcon]=\"svgIcon\" [fontSet]=\"fontSet\" [fontIcon]=\"fontIcon\"></mat-icon>\n                }\n                {{ 'ONBOARDING' | translate | uppercase }}\n            </div>\n        }\n        <div class=\"onboarding-shadow\"\n             [ngStyle]=\"getPositionStyle(visibleItem.element)\"></div>\n        <div class=\"onboarding-spotlight\"\n             [class.onboarding-spotlight-transparent]=\"isSpotlightTransparent(visibleItem.item)\"\n             [ngStyle]=\"getPositionStyle(visibleItem.element)\"></div>\n        <div class=\"onboarding-items\">\n            @for (currentItem of onboardingService.visibleItems.allItems; track currentItem) {\n                <div>\n                    @if (currentItem === visibleItem) {\n                        <rosen-onboarding-item [item]=\"currentItem\"></rosen-onboarding-item>\n                    }\n                </div>\n            }\n        </div>\n        <div class=\"onboarding-overlay\" (click)=\"hide()\"></div>\n        <div class=\"onboarding-buttons\" [ngStyle]=\"buttonsPositionStyle()\">\n            <button mat-flat-button color=\"warn\" (click)=\"disable()\">\n                <span>{{ 'ONBOARDING_DO_NOT_SHOW_AGAIN_MSG' | translate }}</span>\n            </button>\n            <button mat-flat-button color=\"primary\" (click)=\"hide()\">\n                @if (!hasNext) {\n                    <span>{{ 'ONBOARDING_GOT_IT_MSG' | translate }}</span>\n                }\n                @if (hasNext) {\n                    <span>{{ 'ONBOARDING_NEXT_MSG' | translate }}</span>\n                }\n            </button>\n        </div>\n    </div>\n}\n", styles: [".onboarding-component-container .mat-icon{font-size:32px;width:32px!important;height:32px!important;line-height:32px!important}.onboarding-component-container .onboarding-shadow{box-shadow:0 0 0 10000px #000000b3;z-index:9999994}.onboarding-component-container .onboarding-spotlight{box-shadow:0 0 8px 8px #fff;background:#fff;z-index:9999995}.onboarding-component-container .onboarding-spotlight-transparent{background:transparent}.onboarding-component-container .onboarding-items{position:fixed;inset:0;z-index:9999997}.onboarding-component-container .onboarding-overlay{position:fixed;inset:0;z-index:9999998}.onboarding-component-container .onboarding-buttons{position:fixed;z-index:9999999;clear:both}.onboarding-component-container .onboarding-buttons>button{float:right}.onboarding-component-container .onboarding-buttons button[color=primary]{margin-right:8px}.onboarding-component-container .onboarding-header{position:fixed;inset:4px 0 0 4px;z-index:9999998;font-size:24px;color:#d9d9d9}.onboarding-component-container .onboarding-header>span{font-size:24px}.onboarding-highlighted,.onboarding-highlighted *{z-index:9999996!important}.onboarding-highlighted *.glyphicon,.onboarding-highlighted a,a.onboarding-highlighted{color:#444!important}.onboarding-highlighted-on-static{position:relative}\n"] }]
        }], ctorParameters: () => [{ type: OnboardingService }, { type: i2.DomSanitizer }] });

/**
 * Module for ngx-onboarding.
 * Import this into your "main" module e.g. AppModule
 */
class OnboardingModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.11", ngImport: i0, type: OnboardingModule }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingModule, providers: [
            provideHttpClient(withInterceptorsFromDi())
        ] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: OnboardingModule, decorators: [{
            type: NgModule,
            args: [{
                    providers: [
                        provideHttpClient(withInterceptorsFromDi())
                    ]
                }]
        }] });

/*
 * Public API Surface of ngx-onboarding
 */

/**
 * Generated bundle index. Do not edit.
 */

export { EnabledStatusBaseService, OnboardingButtonComponent, OnboardingButtonsPosition, OnboardingComponent, OnboardingItem, OnboardingModule, OnboardingService, SeenSelectorsBaseService, TranslatorBaseService };
//# sourceMappingURL=rosen-group-ngx-onboarding.mjs.map