@rosen-group/ngx-onboarding
Version:
Onboarding module for Angular applications
933 lines • 54.1 kB
JavaScript
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