@webilix/ngx-helper-m3
Version:
Helper library for Angular and Material 3
694 lines (675 loc) • 193 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, makeEnvironmentProviders, Injector, Input, HostBinding, Component, Pipe, Injectable, Optional, Inject, EventEmitter, Output, inject, createComponent, HostListener, Directive } from '@angular/core';
import { NgComponentOutlet, NgClass, DecimalPipe } from '@angular/common';
import * as i1$1 from '@angular/material/button';
import { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';
import { MatDivider } from '@angular/material/divider';
import * as i3$1 from '@angular/material/icon';
import { MatIcon, MatIconModule } from '@angular/material/icon';
import * as i2 from '@angular/material/menu';
import { MatMenuModule } from '@angular/material/menu';
import { Helper } from '@webilix/helper-library';
import { JalaliDateTime } from '@webilix/jalali-date-time';
import * as i1 from '@angular/router';
import * as i3 from '@angular/cdk/clipboard';
import { ClipboardModule } from '@angular/cdk/clipboard';
import * as i2$1 from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import * as i1$2 from '@angular/material/bottom-sheet';
import { MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';
import * as i1$3 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
import { Map, View, Feature } from 'ol';
import { Point, LineString } from 'ol/geom';
import interactionDoubleClickZoom from 'ol/interaction/DoubleClickZoom';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import OSM from 'ol/source/OSM';
import VectorSource from 'ol/source/Vector';
import * as i1$4 from '@angular/common/http';
import { HttpHeaders, HttpEventType } from '@angular/common/http';
import * as i1$5 from 'ng2-pdf-viewer';
import { PdfViewerModule } from 'ng2-pdf-viewer';
import * as i1$6 from '@angular/platform-browser';
import * as i1$7 from '@angular/cdk/drag-drop';
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
const NGX_HELPER_CONFIG = new InjectionToken('NGX-HELPER-CONFIG');
const provideNgxHelperConfig = (config) => {
const providers = [{ provide: NGX_HELPER_CONFIG, useValue: config }];
return makeEnvironmentProviders(providers);
};
const NGX_HELPER_BOX_DATA = new InjectionToken('NGX-HELPER-BOX-DATA');
class NgxHelperBoxComponent {
className = 'ngx-helper-m3-box';
paddingCSS;
component;
data;
padding = '1rem';
hideShadow = false;
injector;
ngOnInit() {
this.setInjector();
}
ngOnChanges(changes) {
this.setInjector();
}
setInjector() {
this.paddingCSS = this.padding;
this.className = `ngx-helper-m3-box${this.hideShadow ? ' hide-shadow' : ''}`;
if (!this.component)
return;
this.injector = Injector.create({
providers: [{ provide: NGX_HELPER_BOX_DATA, useValue: this.data }],
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NgxHelperBoxComponent, isStandalone: true, selector: "ngx-helper-box", inputs: { component: "component", data: "data", padding: "padding", hideShadow: "hideShadow" }, host: { properties: { "className": "this.className", "style.padding": "this.paddingCSS" } }, usesOnChanges: true, ngImport: i0, template: "@if (component) {\n<span *ngComponentOutlet=\"component; injector: injector\"></span>\n} @else {\n<ng-content></ng-content>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperBoxComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-helper-box', imports: [NgComponentOutlet], template: "@if (component) {\n<span *ngComponentOutlet=\"component; injector: injector\"></span>\n} @else {\n<ng-content></ng-content>\n}\n" }]
}], propDecorators: { className: [{
type: HostBinding,
args: ['className']
}], paddingCSS: [{
type: HostBinding,
args: ['style.padding']
}], component: [{
type: Input,
args: [{ required: false }]
}], data: [{
type: Input,
args: [{ required: false }]
}], padding: [{
type: Input,
args: [{ required: false }]
}], hideShadow: [{
type: Input,
args: [{ required: false }]
}] } });
class NgxHelperBankCardPipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
return '';
switch (options?.view) {
case 'BANK':
return Helper.BANK.findCard(value)?.title || '';
default:
return Helper.STRING.getBankCardView(value, options?.join || '-');
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperBankCardPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperBankCardPipe, isStandalone: true, name: "ngxHelperBankCard" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperBankCardPipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperBankCard' }]
}] });
class NgxHelperDatePipe {
transform(value, options) {
if (value === undefined || value === null || (!Helper.IS.date(value) && !Helper.IS.number(value)))
return '';
const date = typeof value === 'number' ? new Date(value) : value;
const jalali = JalaliDateTime();
const timezone = options?.timezone && jalali.timezones().includes(options?.timezone) ? options?.timezone : 'Asia/Tehran';
switch (options?.format || 'DATE') {
case 'FULL':
return jalali.toFullText(date, { format: 'W، d N Y H:I', timezone });
case 'SHORT':
return jalali.toFullText(date, { format: 'Y/M/D', timezone });
case 'DATE':
return jalali.toFullText(date, { format: 'W، d N Y', timezone });
case 'TIME':
return jalali.toFullText(date, { format: 'H:I', timezone });
case 'WEEK':
const { from, to } = jalali.periodWeek(1, date, timezone);
return Helper.DATE.jalaliPeriod(from, to, timezone);
case 'MONTH':
return jalali.toFullText(date, { format: 'N Y', timezone });
case 'YEAR':
return jalali.toFullText(date, { format: 'Y', timezone });
default:
return jalali.toFullText(date, { format: options?.format, timezone });
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperDatePipe, isStandalone: true, name: "ngxHelperDate" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperDatePipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperDate' }]
}] });
class NgxHelperDurationPipe {
transform(value, options) {
if (value === undefined || value === null)
return '';
let seconds = 0;
if (Helper.IS.number(value))
seconds = Math.abs(value);
else if (Helper.IS.date(value))
seconds = Math.floor(Math.abs(new Date().getTime() - value.getTime()) / 1000);
else if (Helper.IS.object(value)) {
const from = 'from' in value ? value.from : new Date();
const to = 'to' in value ? value.to : new Date();
seconds = Math.floor(Math.abs(from.getTime() - to.getTime()) / 1000);
}
const days = Math.floor(seconds / (24 * 60 * 60));
seconds -= days * (24 * 60 * 60);
const hours = Math.floor(seconds / (60 * 60));
seconds -= hours * (60 * 60);
const minutes = Math.floor(seconds / 60);
seconds -= minutes * 60;
const hasDays = days !== 0;
const time = [hours, minutes, seconds].map((v) => v.toString().padStart(2, '0')).join(':');
switch (options?.format || 'TEXT') {
case 'TEXT':
const hasTime = !!hours || !!minutes || !!seconds;
const day = hasDays
? Helper.NUMBER.format(days, 'EN') + (!!options?.english ? (days === 1 ? ' day' : ' days') : ' روز')
: '';
const join = hasDays && hasTime ? (!!options?.english ? ', ' : ' و ') : '';
return (day + join + (!hasDays || hasTime ? time : '')).trim();
case 'FULL':
return (hasDays ? '(' + Helper.NUMBER.format(days, 'EN') + ') ' : '') + time;
case 'DAY':
return Helper.NUMBER.format(days + (hours !== 0 || minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
case 'HOUR':
return Helper.NUMBER.format(days * 24 + hours + (minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
case 'MINUTE':
return Helper.NUMBER.format(days * 24 * 60 + hours * 60 + minutes, !!options?.english ? 'EN' : 'FA');
case 'SECOND':
return Helper.NUMBER.format(days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds, !!options?.english ? 'EN' : 'FA');
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperDurationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperDurationPipe, isStandalone: true, name: "ngxHelperDuration" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperDurationPipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperDuration' }]
}] });
class NgxHelperFileSizePipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.number(value))
return '';
return Helper.NUMBER.toFileSize(value, !!options?.english ? 'EN' : 'FA');
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperFileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperFileSizePipe, isStandalone: true, name: "ngxHelperFileSize" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperFileSizePipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperFileSize' }]
}] });
class NgxHelperMobilePipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
return '';
return Helper.STRING.getMobileView(value, options?.join || '-');
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperMobilePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperMobilePipe, isStandalone: true, name: "ngxHelperMobile" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperMobilePipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperMobile' }]
}] });
class NgxHelperNumberPipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.number(value))
return '';
value = options?.fractionDigits ? +value.toFixed(options?.fractionDigits) : value;
return Helper.NUMBER.format(value, options?.english ? 'EN' : 'FA');
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperNumberPipe, isStandalone: true, name: "ngxHelperNumber" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperNumberPipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperNumber' }]
}] });
class NgxHelperPeriodPipe {
transform(value, options) {
if (value === undefined || value === null)
return '';
const from = Helper.IS.date(value) ? value : 'from' in value ? value.from : new Date();
const to = Helper.IS.date(value) ? new Date() : 'to' in value ? value.to : new Date();
return Helper.DATE.jalaliPeriod(from, to, options?.timezone || '');
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPeriodPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPeriodPipe, isStandalone: true, name: "ngxHelperPeriod" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPeriodPipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperPeriod' }]
}] });
class NgxHelperPricePipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
return '';
const getPrice = (...titles) => {
if (value === undefined || value === null)
return '';
const price = Helper.NUMBER.format(+value.toFixed(2), !!options?.english ? 'EN' : 'FA');
const unit = titles[options?.short ? 0 : 1][options?.english ? 0 : 1];
const currency = options?.currency ? ' ' + options?.currency : '';
return `${price} ${unit}${currency}`;
};
if (value < 1000)
return getPrice(['', ''], ['', '']);
value /= 1000;
if (value < 1000)
return getPrice(['T', 'ه'], ['Thousand', 'هزار']);
value /= 1000;
if (value < 1000)
return getPrice(['M', 'م'], ['Million', 'میلیون']);
value /= 1000;
return getPrice(['B', 'د'], ['Billion', 'میلیارد']);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPricePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPricePipe, isStandalone: true, name: "ngxHelperPrice" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPricePipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperPrice' }]
}] });
class NgxHelperVolumePipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
return '';
const getVolume = (...titles) => {
if (value === undefined || value === null)
return '';
const volume = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
const shortIndex = options?.short ? 0 : 1;
const titleIndex = options?.english ? 0 : 1;
return `${volume} ${titles[shortIndex][titleIndex]}`;
};
if (value === 0)
return getVolume(['', ''], ['', '']);
if (value < 1000)
return getVolume(['ML', 'م'], ['Milliliter', 'میلی لیتر']);
value /= 1000;
return getVolume(['L', 'ل'], ['Liter', 'لیتر']);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperVolumePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperVolumePipe, isStandalone: true, name: "ngxHelperVolume" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperVolumePipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperVolume' }]
}] });
class NgxHelperWeightPipe {
transform(value, options) {
if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
return '';
const getWeight = (...titles) => {
if (value === undefined || value === null)
return '';
const weight = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
const shortIndex = options?.short ? 0 : 1;
const titleIndex = options?.english ? 0 : 1;
return `${weight} ${titles[shortIndex][titleIndex]}`;
};
if (value === 0)
return getWeight(['', ''], ['', '']);
if (value < 1000)
return getWeight(['G', 'گ'], ['Gram', 'گرم']);
value /= 1000;
if (value < 1000)
return getWeight(['K', 'ک'], ['Kilogram', 'کیلو']);
value /= 1000;
if (value < 1000)
return getWeight(['T', 'ت'], ['Tonne', 'تن']);
value /= 1000;
if (value < 1000)
return getWeight(['KT', 'ه'], ['Kilotonne', 'هزار تن']);
value /= 1000;
return getWeight(['MT', 'م'], ['Milliontonne', 'میلیون تن']);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperWeightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperWeightPipe, isStandalone: true, name: "ngxHelperWeight" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperWeightPipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperWeight' }]
}] });
class NgxHelperValuePipe {
transform(value, options) {
const emptyText = options?.emptyText || '';
if (value === undefined || Helper.IS.empty(value))
return emptyText;
switch (value.type) {
case 'BANK-CARD':
return new NgxHelperBankCardPipe().transform(value.value, value) || emptyText;
case 'DATE':
return new NgxHelperDatePipe().transform(value.value, value) || emptyText;
case 'DURATION':
return new NgxHelperDurationPipe().transform(value.value, value) || emptyText;
case 'FILE-SIZE':
return new NgxHelperFileSizePipe().transform(value.value, value) || emptyText;
case 'MOBILE':
return new NgxHelperMobilePipe().transform(value.value, value) || emptyText;
case 'NUMBER':
return new NgxHelperNumberPipe().transform(value.value, value) || emptyText;
case 'PERIOD':
return new NgxHelperPeriodPipe().transform(value.value, value) || emptyText;
case 'PRICE':
return new NgxHelperPricePipe().transform(value.value, value) || emptyText;
case 'STRING':
return Helper.IS.string(value.value) ? value.value : emptyText;
case 'VOLUME':
return new NgxHelperVolumePipe().transform(value.value, value) || emptyText;
case 'WEIGHT':
return new NgxHelperWeightPipe().transform(value.value, value) || emptyText;
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperValuePipe, isStandalone: true, name: "ngxHelperValue" });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperValuePipe, decorators: [{
type: Pipe,
args: [{ name: 'ngxHelperValue' }]
}] });
class ComponentService {
getComponentConfig(config) {
const getStickyView = (config) => {
return {
desktopView: typeof config === 'string' ? config : config.desktopView,
mobileView: typeof config === 'string' ? config : config.mobileView,
};
};
return {
mobileWidth: config?.mobileWidth || 600,
pageGroupSidebarWidth: config?.pageGroupSidebarWidth || '200px',
stickyView: config?.stickyView
? {
top: config.stickyView.top ? getStickyView(config.stickyView.top) : undefined,
bottom: config.stickyView.bottom ? getStickyView(config.stickyView.bottom) : undefined,
}
: undefined,
};
}
isRTL(value) {
switch (value.type) {
case 'BANK-CARD':
case 'MOBILE':
case 'NUMBER':
return true;
case 'DURATION':
return value.format === 'FULL';
}
return false;
}
getValueData(values) {
const pipeTransform = new NgxHelperValuePipe().transform;
const ltrValues = ['BANK-CARD', 'MOBILE', 'NUMBER'];
return values.map((item) => {
const value = item.value;
return value === undefined
? { title: item.title, value: '' }
: typeof value === 'string'
? { title: item.title, value: value.trim(), color: item.color }
: {
title: item.title,
value: pipeTransform(value),
color: item.color,
action: item.action,
copyToClipboard: item.copyToClipboard,
ltr: this.isRTL(value),
english: 'english' in value && !!value.english,
};
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: ComponentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: ComponentService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: ComponentService, decorators: [{
type: Injectable
}] });
class NgxHelperCardComponent {
componentService;
config;
className = 'ngx-helper-m3-card';
title;
subTitle;
icon;
actions = [];
option;
padding = '1rem';
backgroundColor;
hasShadow = false;
isMobile = false;
buttons = [];
componentConfig;
optionId;
optionTitle;
optionItems = [];
constructor(componentService, config) {
this.componentService = componentService;
this.config = config;
}
ngOnInit() {
this.componentConfig = this.componentService.getComponentConfig(this.config);
this.onResize();
}
ngOnChanges(changes) {
this.className = `ngx-helper-m3-card${this.hasShadow ? ' has-shadow' : ''}`;
this.buttons = this.actions.map((action) => {
return 'buttons' in action ? { type: 'MENU', ...action } : { type: 'BUTTON', ...action };
});
this.optionId = undefined;
this.optionItems = [];
if (this.option) {
this.option.items.forEach((item) => {
if (item === 'DIVIDER') {
if (this.optionItems.length !== 0 && this.optionItems[this.optionItems.length - 1] !== 'DIVIDER')
this.optionItems.push('DIVIDER');
}
else
this.optionItems.push(item);
});
while (this.optionItems[this.optionItems.length - 1] === 'DIVIDER')
this.optionItems.splice(this.optionItems.length - 1);
const ids = this.option.items.map((item) => (item === 'DIVIDER' ? '' : item.id));
this.optionId = this.option.id && ids.includes(this.option.id) ? this.option.id : undefined;
this.setOption(this.optionId || '', true);
}
}
onResize() {
this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
}
setOption(id, firstCheck) {
if (!this.option || this.optionItems.length === 0)
return;
const ids = this.optionItems.filter((item) => item !== 'DIVIDER').map((item) => item.id);
this.optionId = id && ids.includes(id) ? id : ids[0];
this.optionTitle = this.optionItems
.filter((item) => item !== 'DIVIDER')
.find((item) => item.id === this.optionId)?.title;
if (!firstCheck)
this.option.action(this.optionId);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperCardComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NgxHelperCardComponent, isStandalone: true, selector: "ngx-helper-card", inputs: { title: "title", subTitle: "subTitle", icon: "icon", actions: "actions", option: "option", padding: "padding", backgroundColor: "backgroundColor", hasShadow: "hasShadow" }, host: { listeners: { "window:resize": "onResize()" }, properties: { "className": "this.className" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "<div class=\"card-header\" [class.has-sub-title]=\"subTitle\">\n <!-- ICON -->\n @if (icon) { <mat-icon>{{ icon }}</mat-icon> }\n\n <!-- TITLE -->\n <div class=\"content\">\n <div class=\"title\">{{ title }}</div>\n <!-- SUB TITLE -->\n @if (subTitle) {\n <div class=\"sub-title\">{{ subTitle }}</div>\n }\n </div>\n\n <!-- BUTTONS -->\n @if (buttons.length > 0) {\n <div class=\"buttons\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n @for (item of buttons; track $index) {\n <!-- TYPE -->\n @switch (item.type) {\n\n <!-- BUTTON -->\n @case('BUTTON') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" (click)=\"item.action()\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n }\n\n <!-- MENU -->\n @case('MENU') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" [matMenuTriggerFor]=\"actionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n <mat-menu #actionMenu=\"matMenu\" class=\"ngx-helper-card-action-menu\" [xPosition]=\"'before'\">\n @for (menu of item.buttons; track $index) {\n <!-- DIVIDER -->\n @if (menu === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" (click)=\"menu.action()\" [style.color]=\"menu.color\">\n <div class=\"title\">{{ menu.title }}</div>\n <mat-icon [style.color]=\"menu.color\">{{ menu.icon }}</mat-icon>\n </button>\n } }\n </mat-menu>\n } } }\n </div>\n }\n\n <!-- OPTION -->\n @if (option && optionItems.length > 0) {\n <div class=\"option\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n <button mat-button type=\"button\" [matMenuTriggerFor]=\"optionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ optionTitle }}</div>\n }\n <mat-icon [class.mobile-view]=\"isMobile\">{{ option.icon }}</mat-icon>\n </button>\n <mat-menu #optionMenu=\"matMenu\" class=\"ngx-helper-card-action-option\" [xPosition]=\"'before'\">\n @for (item of optionItems; track $index) {\n <!-- DIVIDER -->\n @if (item === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" [disabled]=\"optionId === item.id\" (click)=\"setOption(item.id)\">\n <div class=\"title\">{{ item.title }}</div>\n <mat-icon [style.opacity]=\"optionId === item.id ? 1 : 0\">done_all</mat-icon>\n </button>\n } }\n </mat-menu>\n </div>\n }\n</div>\n\n<div class=\"card-content\" [style.padding]=\"padding\" [style.background-color]=\"backgroundColor\">\n <ng-content></ng-content>\n</div>\n", styles: ["::ng-deep .ngx-helper-card-action-menu button mat-icon{font-size:115%;margin:0 0 0 .75rem!important}::ng-deep .ngx-helper-card-action-menu button .title{font-size:90%!important}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-menu .mat-divider{margin:0;border-top-color:var(--outline-variant)}::ng-deep .ngx-helper-card-action-option button{flex-direction:row-reverse}::ng-deep .ngx-helper-card-action-option button mat-icon{font-size:115%;margin:0 .75rem 0 0!important}::ng-deep .ngx-helper-card-action-option button .title{flex:1;font-size:90%!important}::ng-deep .ngx-helper-card-action-option .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-option .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-option .mat-divider{margin:0;border-top-color:var(--outline-variant)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.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: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperCardComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-helper-card', host: { '(window:resize)': 'onResize()' }, imports: [NgClass, MatButton, MatDivider, MatIcon, MatMenuModule], providers: [ComponentService], template: "<div class=\"card-header\" [class.has-sub-title]=\"subTitle\">\n <!-- ICON -->\n @if (icon) { <mat-icon>{{ icon }}</mat-icon> }\n\n <!-- TITLE -->\n <div class=\"content\">\n <div class=\"title\">{{ title }}</div>\n <!-- SUB TITLE -->\n @if (subTitle) {\n <div class=\"sub-title\">{{ subTitle }}</div>\n }\n </div>\n\n <!-- BUTTONS -->\n @if (buttons.length > 0) {\n <div class=\"buttons\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n @for (item of buttons; track $index) {\n <!-- TYPE -->\n @switch (item.type) {\n\n <!-- BUTTON -->\n @case('BUTTON') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" (click)=\"item.action()\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n }\n\n <!-- MENU -->\n @case('MENU') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" [matMenuTriggerFor]=\"actionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n <mat-menu #actionMenu=\"matMenu\" class=\"ngx-helper-card-action-menu\" [xPosition]=\"'before'\">\n @for (menu of item.buttons; track $index) {\n <!-- DIVIDER -->\n @if (menu === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" (click)=\"menu.action()\" [style.color]=\"menu.color\">\n <div class=\"title\">{{ menu.title }}</div>\n <mat-icon [style.color]=\"menu.color\">{{ menu.icon }}</mat-icon>\n </button>\n } }\n </mat-menu>\n } } }\n </div>\n }\n\n <!-- OPTION -->\n @if (option && optionItems.length > 0) {\n <div class=\"option\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n <button mat-button type=\"button\" [matMenuTriggerFor]=\"optionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ optionTitle }}</div>\n }\n <mat-icon [class.mobile-view]=\"isMobile\">{{ option.icon }}</mat-icon>\n </button>\n <mat-menu #optionMenu=\"matMenu\" class=\"ngx-helper-card-action-option\" [xPosition]=\"'before'\">\n @for (item of optionItems; track $index) {\n <!-- DIVIDER -->\n @if (item === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" [disabled]=\"optionId === item.id\" (click)=\"setOption(item.id)\">\n <div class=\"title\">{{ item.title }}</div>\n <mat-icon [style.opacity]=\"optionId === item.id ? 1 : 0\">done_all</mat-icon>\n </button>\n } }\n </mat-menu>\n </div>\n }\n</div>\n\n<div class=\"card-content\" [style.padding]=\"padding\" [style.background-color]=\"backgroundColor\">\n <ng-content></ng-content>\n</div>\n", styles: ["::ng-deep .ngx-helper-card-action-menu button mat-icon{font-size:115%;margin:0 0 0 .75rem!important}::ng-deep .ngx-helper-card-action-menu button .title{font-size:90%!important}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-menu .mat-divider{margin:0;border-top-color:var(--outline-variant)}::ng-deep .ngx-helper-card-action-option button{flex-direction:row-reverse}::ng-deep .ngx-helper-card-action-option button mat-icon{font-size:115%;margin:0 .75rem 0 0!important}::ng-deep .ngx-helper-card-action-option button .title{flex:1;font-size:90%!important}::ng-deep .ngx-helper-card-action-option .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-option .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-option .mat-divider{margin:0;border-top-color:var(--outline-variant)}\n"] }]
}], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [NGX_HELPER_CONFIG]
}] }], propDecorators: { className: [{
type: HostBinding,
args: ['className']
}], title: [{
type: Input,
args: [{ required: true }]
}], subTitle: [{
type: Input,
args: [{ required: false }]
}], icon: [{
type: Input,
args: [{ required: false }]
}], actions: [{
type: Input,
args: [{ required: false }]
}], option: [{
type: Input,
args: [{ required: false }]
}], padding: [{
type: Input,
args: [{ required: false }]
}], backgroundColor: [{
type: Input,
args: [{ required: false }]
}], hasShadow: [{
type: Input,
args: [{ required: false }]
}] } });
class NgxHelperLoaderComponent {
loaderSize;
loaderColor;
mode = 'SPINNER';
size;
color;
padding;
margin;
ngOnInit() {
this.init();
}
ngOnChanges(changes) {
this.init();
}
init() {
this.loaderSize = `${this.size || 25}px`;
this.loaderColor = this.color || `var(--secondary)`;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.1", type: NgxHelperLoaderComponent, isStandalone: true, selector: "ngx-helper-loader", inputs: { mode: "mode", size: "size", color: "color", padding: "padding", margin: "margin" }, host: { properties: { "style.--loader-size": "this.loaderSize", "style.--loader-color": "this.loaderColor" } }, usesOnChanges: true, ngImport: i0, template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\" [style.margin]=\"margin || '0px'\"></div>\n</div>\n", styles: [".spinner{--size: calc(var(--loader-size) / 7);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:radial-gradient(farthest-side,var(--loader-color) 94%,rgba(0,0,0,0)) top/var(--size) var(--size) no-repeat,conic-gradient(rgba(0,0,0,0) 30%,var(--loader-color));mask:radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size)),#000 0);animation:spinner 1s infinite linear}@keyframes spinner{to{transform:rotate(1turn)}}.dots-spinner{--dot: no-repeat radial-gradient(farthest-side, var(--loader-color) 92%, #0000);--size: calc(var(--loader-size) / 4);width:var(--loader-size);aspect-ratio:1;background:var(--dot) top,var(--dot) left,var(--dot) right,var(--dot) bottom;background-size:var(--size) var(--size);animation:dots-spinner 1s infinite}@keyframes dots-spinner{to{transform:rotate(.5turn)}}.wheel-spinner{--size: calc(var(--loader-size) / 9);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:var(--loader-color);mask:repeating-conic-gradient(rgba(0,0,0,0) 0deg,#000 1deg 70deg,rgba(0,0,0,0) 71deg 90deg),radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size) - 1px),#000 calc(100% - var(--size)));-webkit-mask-composite:destination-in;mask-composite:intersect;animation:wheel-spinner 1s infinite}@keyframes wheel-spinner{to{transform:rotate(.5turn)}}\n"] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperLoaderComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-helper-loader', imports: [], template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\" [style.margin]=\"margin || '0px'\"></div>\n</div>\n", styles: [".spinner{--size: calc(var(--loader-size) / 7);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:radial-gradient(farthest-side,var(--loader-color) 94%,rgba(0,0,0,0)) top/var(--size) var(--size) no-repeat,conic-gradient(rgba(0,0,0,0) 30%,var(--loader-color));mask:radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size)),#000 0);animation:spinner 1s infinite linear}@keyframes spinner{to{transform:rotate(1turn)}}.dots-spinner{--dot: no-repeat radial-gradient(farthest-side, var(--loader-color) 92%, #0000);--size: calc(var(--loader-size) / 4);width:var(--loader-size);aspect-ratio:1;background:var(--dot) top,var(--dot) left,var(--dot) right,var(--dot) bottom;background-size:var(--size) var(--size);animation:dots-spinner 1s infinite}@keyframes dots-spinner{to{transform:rotate(.5turn)}}.wheel-spinner{--size: calc(var(--loader-size) / 9);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:var(--loader-color);mask:repeating-conic-gradient(rgba(0,0,0,0) 0deg,#000 1deg 70deg,rgba(0,0,0,0) 71deg 90deg),radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size) - 1px),#000 calc(100% - var(--size)));-webkit-mask-composite:destination-in;mask-composite:intersect;animation:wheel-spinner 1s infinite}@keyframes wheel-spinner{to{transform:rotate(.5turn)}}\n"] }]
}], propDecorators: { loaderSize: [{
type: HostBinding,
args: ['style.--loader-size']
}], loaderColor: [{
type: HostBinding,
args: ['style.--loader-color']
}], mode: [{
type: Input,
args: [{ required: false }]
}], size: [{
type: Input,
args: [{ required: false }]
}], color: [{
type: Input,
args: [{ required: false }]
}], padding: [{
type: Input,
args: [{ required: false }]
}], margin: [{
type: Input,
args: [{ required: false }]
}] } });
const NGX_HELPER_PAGE_GROUP_ITEM = new InjectionToken('NGX-HELPER-PAGE-GROUP-ITEM');
const NGX_HELPER_PAGE_GROUP_DATA = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA');
const NGX_HELPER_PAGE_GROUP_DATA_CHANGE = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA-CHANGE');
class NgxHelperPageGroupComponent {
activatedRoute;
router;
componentService;
config;
className = 'ngx-helper-m3-page-group';
display = 'none';
pageGroup;
pageId;
data;
pageChanged = new EventEmitter();
dataChanged = new EventEmitter();
isMobile = false;
pages = [];
injector;
sidebarWidth;
componentConfig;
constructor(activatedRoute, router, componentService, config) {
this.activatedRoute = activatedRoute;
this.router = router;
this.componentService = componentService;
this.config = config;
}
ngOnInit() {
this.pages = Object.keys(this.pageGroup.pages);
this.display = this.pages.length === 0 ? 'none' : 'flex';
if (this.pages.length === 0)
return;
this.componentConfig = this.componentService.getComponentConfig(this.config);
this.sidebarWidth = this.pageGroup.sidebarWidth || this.componentConfig.pageGroupSidebarWidth;
if (!this.pageGroup.pages[this.pageId])
this.pageId = this.pages[0];
const queryParams = { ...this.activatedRoute.snapshot.queryParams };
if (!!this.pageGroup.route && Helper.IS.string(queryParams['ngx-helper-page-group'])) {
const id = queryParams['ngx-helper-page-group'];
if (this.pageId !== id && this.pages.includes(id)) {
this.pageId = id;
this.triggerPageChanged();
}
}
this.onResize();
this.setInjector();
}
ngOnChanges(changes) {
this.setInjector();
}
onResize() {
this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
this.className = `ngx-helper-m3-page-group${this.isMobile ? ' mobile-view' : ''}`;
}
setInjector() {
if (this.pages.length === 0)
return;
const item = {
index: this.pages.findIndex((page) => page === this.pageId),
id: this.pageId,
title: this.pageGroup.pages[this.pageId].title,
icon: this.pageGroup.pages[this.pageId].icon,
};
this.injector = Injector.create({
providers: [
{ provide: NGX_HELPER_PAGE_GROUP_ITEM, useValue: item },
{ provide: NGX_HELPER_PAGE_GROUP_DATA, useValue: this.data },
{ provide: NGX_HELPER_PAGE_GROUP_DATA_CHANGE, useValue: (data) => this.dataChanged.next(data) },
],
});
}
setPage(id) {
if (this.pages.length === 0 || this.pageId == id)
return;
const page = this.pageGroup.pages[id];
const index = this.pages.findIndex((p) => p === id);
if (!page || index === -1)
return;
this.pageId = id;
this.triggerPageChanged();
this.setInjector();
if (this.pageGroup.route) {
const queryParams = { ...this.activatedRoute.snapshot.queryParams };
queryParams['ngx-helper-page-group'] = this.pageId;
this.router.navigate(this.pageGroup.route, { queryParams });
}
}
triggerPageChanged() {
const item = {
index: this.pages.findIndex((page) => page === this.pageId),
id: this.pageId,
title: this.pageGroup.pages[this.pageId].title,
icon: this.pageGroup.pages[this.pageId].icon,
};
this.pageChanged.next(item);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NgxHelperPageGroupComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: NgxHelperPageGroupComponent, isStandalone: true, selector: "ngx-helper-page-group", inputs: { pageGroup: "pageGroup", pageId: "pageId", data: "data" }, outputs: { pageChanged: "pageChanged", dataChanged: "dataChanged" }, host: { listeners: { "window:resize": "onResize()" }, properties: { "className": "this.className", "style.display": "this.display" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@if (pages.length > 0) {\n<!-- DESKTOP VIEW -->\n@if (!isMobile) {\n<div\n class=\"page-group-aside\"\n [style.width]=\"sidebarWidth\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.desktopView || undefined\"\n>\n @for (item of pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageId === item\"\n [style.cursor]=\"pageId === item ? 'default' : 'pointer'\"\n (click)=\"setPage(item)\"\n >\n <!-- ICON -->\n <mat-icon>{{ pageGroup.pages[item].icon }}</mat-icon>\n <div class=\"title\">{{ pageGroup.pages[item].title }}</div>\n <!-- CURRENT PAGE -->\n @if (pageId === item) { <mat-icon>keyboard_double_arrow_left</mat-icon> }\n </div>\n }\n</div>\n}\n\n<!-- MOBILE VIEW -->\n@if (isMobile) {\n\n<!-- MOBILE LIST VIEW -->\n@if (pageGroup.showMenu === false || (pages.length <= 5 && !pageGroup.showMenu)) {\n<div\n class=\"page-group-nav\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.mobileView || undefined\"\n>\n @for (item of pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageId === item\"\n [style.cursor]=\"pageId === item ? 'default' : 'pointer'\"\n (click)=\"setPage(item)\"\n >\n <mat-icon>{{ pageGroup.pages[item].icon }}</mat-icon>\n @if (pageId === item) {\n <div class=\"title\">{{ pageGroup.pages[item].title }}</div>\n }\n </div>\n }\n</div>\n}\n\n<!-- MOBILE MENU VIEW -->\n@else {\n<div\n class=\"page-group-menu\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.mobileView || undefined\"\n>\n <mat-icon class=\"page\">{{ pageGroup.pages[pageId].icon }}</mat-icon>\n <div class=\"title\">{{ pageGroup.pages[pageId].title }}</div>\n <button mat-button type=\"button\" [matMenuTriggerFor]=\"pageMenu\" class=\"menu\">\n