@webilix/ngx-helper-m3 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, makeEnvironmentProviders, Injector, Component, HostBinding, Input, Injectable, Optional, Inject, EventEmitter, Output, inject, Directive, Pipe } from '@angular/core';
2
+ import { InjectionToken, makeEnvironmentProviders, Injector, Component, HostBinding, Input, Pipe, Injectable, Optional, Inject, EventEmitter, Output, inject, Directive, createComponent } from '@angular/core';
3
3
  import { NgComponentOutlet, NgClass } from '@angular/common';
4
4
  import * as i1$2 from '@angular/material/button';
5
5
  import { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';
@@ -9,15 +9,18 @@ import { MatIcon, MatIconModule } from '@angular/material/icon';
9
9
  import * as i2 from '@angular/material/menu';
10
10
  import { MatMenuModule } from '@angular/material/menu';
11
11
  import { Helper } from '@webilix/helper-library';
12
+ import { JalaliDateTime } from '@webilix/jalali-date-time';
12
13
  import * as i1 from '@angular/router';
13
14
  import * as i3 from '@angular/cdk/clipboard';
14
15
  import { ClipboardModule } from '@angular/cdk/clipboard';
15
- import { JalaliDateTime } from '@webilix/jalali-date-time';
16
16
  import * as i1$1 from '@angular/platform-browser';
17
17
  import * as i2$1 from '@angular/material/dialog';
18
18
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
19
19
  import * as i1$3 from '@angular/material/bottom-sheet';
20
20
  import { MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';
21
+ import * as i1$4 from '@angular/common/http';
22
+ import { HttpHeaders, HttpEventType } from '@angular/common/http';
23
+ import { trigger, transition, style, animate } from '@angular/animations';
21
24
 
22
25
  const NGX_HELPER_CONFIG = new InjectionToken('NGX-HELPER-CONFIG');
23
26
  const provideNgxHelperConfig = (config) => {
@@ -76,139 +79,451 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
76
79
  args: [{ required: false }]
77
80
  }] } });
78
81
 
79
- class ComponentService {
80
- getComponentConfig(config) {
81
- const getStickyView = (config) => {
82
- return {
83
- desktopView: typeof config === 'string' ? config : config.desktopView,
84
- mobileView: typeof config === 'string' ? config : config.mobileView,
85
- };
86
- };
87
- return {
88
- mobileWidth: config?.mobileWidth || 600,
89
- pageGroupSidebarWidth: config?.pageGroupSidebarWidth || '200px',
90
- stickyView: config?.stickyView
91
- ? {
92
- top: config.stickyView.top ? getStickyView(config.stickyView.top) : undefined,
93
- bottom: config.stickyView.bottom ? getStickyView(config.stickyView.bottom) : undefined,
94
- }
95
- : undefined,
96
- };
82
+ class NgxHelperBankCardPipe {
83
+ transform(value, options) {
84
+ if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
85
+ return '';
86
+ switch (options?.view) {
87
+ case 'BANK':
88
+ return Helper.BANK.findCard(value)?.title || '';
89
+ default:
90
+ return Helper.STRING.getBankCardView(value, options?.join || '-');
91
+ }
97
92
  }
98
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
99
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService });
93
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
94
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, isStandalone: true, name: "ngxHelperBankCard" });
100
95
  }
101
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, decorators: [{
102
- type: Injectable
96
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, decorators: [{
97
+ type: Pipe,
98
+ args: [{ name: 'ngxHelperBankCard' }]
103
99
  }] });
104
100
 
105
- class NgxHelperCardComponent {
106
- componentService;
107
- config;
108
- className = 'ngx-helper-m3-card';
109
- title;
110
- subTitle;
111
- icon;
112
- actions = [];
113
- padding = '1rem';
114
- backgroundColor;
115
- hasShadow = false;
116
- isMobile = false;
117
- buttons = [];
118
- componentConfig;
119
- constructor(componentService, config) {
120
- this.componentService = componentService;
121
- this.config = config;
101
+ class NgxHelperDatePipe {
102
+ transform(value, options) {
103
+ if (value === undefined || value === null || (!Helper.IS.date(value) && !Helper.IS.number(value)))
104
+ return '';
105
+ const date = typeof value === 'number' ? new Date(value) : value;
106
+ const jalali = JalaliDateTime();
107
+ const timezone = options?.timezone && jalali.timezones().includes(options?.timezone) ? options?.timezone : 'Asia/Tehran';
108
+ switch (options?.format || 'DATE') {
109
+ case 'FULL':
110
+ return jalali.toFullText(date, { format: 'W، d N Y H:I', timezone });
111
+ case 'SHORT':
112
+ return jalali.toFullText(date, { format: 'Y/M/D', timezone });
113
+ case 'DATE':
114
+ return jalali.toFullText(date, { format: 'W، d N Y', timezone });
115
+ case 'TIME':
116
+ return jalali.toFullText(date, { format: 'H:I', timezone });
117
+ case 'WEEK':
118
+ const { from, to } = jalali.periodWeek(1, date, timezone);
119
+ return Helper.DATE.jalaliPeriod(from, to, timezone);
120
+ case 'MONTH':
121
+ return jalali.toFullText(date, { format: 'N Y', timezone });
122
+ case 'YEAR':
123
+ return jalali.toFullText(date, { format: 'Y', timezone });
124
+ default:
125
+ return jalali.toFullText(date, { format: options?.format, timezone });
126
+ }
122
127
  }
123
- ngOnInit() {
124
- this.componentConfig = this.componentService.getComponentConfig(this.config);
125
- this.onResize();
128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
129
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, isStandalone: true, name: "ngxHelperDate" });
130
+ }
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, decorators: [{
132
+ type: Pipe,
133
+ args: [{ name: 'ngxHelperDate' }]
134
+ }] });
135
+
136
+ class NgxHelperDurationPipe {
137
+ transform(value, options) {
138
+ if (value === undefined || value === null)
139
+ return '';
140
+ let seconds = 0;
141
+ if (Helper.IS.number(value))
142
+ seconds = Math.abs(value);
143
+ else if (Helper.IS.date(value))
144
+ seconds = Math.floor(Math.abs(new Date().getTime() - value.getTime()) / 1000);
145
+ else if (Helper.IS.object(value)) {
146
+ const from = 'from' in value ? value.from : new Date();
147
+ const to = 'to' in value ? value.to : new Date();
148
+ seconds = Math.floor(Math.abs(from.getTime() - to.getTime()) / 1000);
149
+ }
150
+ const days = Math.floor(seconds / (24 * 60 * 60));
151
+ seconds -= days * (24 * 60 * 60);
152
+ const hours = Math.floor(seconds / (60 * 60));
153
+ seconds -= hours * (60 * 60);
154
+ const minutes = Math.floor(seconds / 60);
155
+ seconds -= minutes * 60;
156
+ const hasDays = days !== 0;
157
+ const time = [hours, minutes, seconds].map((v) => v.toString().padStart(2, '0')).join(':');
158
+ switch (options?.format || 'TEXT') {
159
+ case 'TEXT':
160
+ const hasTime = !!hours || !!minutes || !!seconds;
161
+ const day = hasDays
162
+ ? Helper.NUMBER.format(days, 'EN') + (!!options?.english ? (days === 1 ? ' day' : ' days') : ' روز')
163
+ : '';
164
+ const join = hasDays && hasTime ? (!!options?.english ? ', ' : ' و ') : '';
165
+ return (day + join + (!hasDays || hasTime ? time : '')).trim();
166
+ case 'FULL':
167
+ return (hasDays ? Helper.NUMBER.format(days, 'EN') + ':' : '') + time;
168
+ case 'DAY':
169
+ return Helper.NUMBER.format(days + (hours !== 0 || minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
170
+ case 'HOUR':
171
+ return Helper.NUMBER.format(days * 24 + hours + (minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
172
+ case 'MINUTE':
173
+ return Helper.NUMBER.format(days * 24 * 60 + hours * 60 + minutes, !!options?.english ? 'EN' : 'FA');
174
+ case 'SECOND':
175
+ return Helper.NUMBER.format(days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds, !!options?.english ? 'EN' : 'FA');
176
+ }
126
177
  }
127
- ngOnChanges(changes) {
128
- this.className = `ngx-helper-m3-card${this.hasShadow ? ' has-shadow' : ''}`;
129
- this.buttons = this.actions.map((action) => {
130
- return 'buttons' in action ? { type: 'MENU', ...action } : { type: 'BUTTON', ...action };
131
- });
178
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
179
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, isStandalone: true, name: "ngxHelperDuration" });
180
+ }
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, decorators: [{
182
+ type: Pipe,
183
+ args: [{ name: 'ngxHelperDuration' }]
184
+ }] });
185
+
186
+ class NgxHelperFileSizePipe {
187
+ transform(value, options) {
188
+ if (value === undefined || value === null || !Helper.IS.number(value))
189
+ return '';
190
+ return Helper.NUMBER.toFileSize(value, !!options?.english ? 'EN' : 'FA');
132
191
  }
133
- onResize() {
134
- this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
192
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
193
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, isStandalone: true, name: "ngxHelperFileSize" });
194
+ }
195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, decorators: [{
196
+ type: Pipe,
197
+ args: [{ name: 'ngxHelperFileSize' }]
198
+ }] });
199
+
200
+ class NgxHelperMobilePipe {
201
+ transform(value, options) {
202
+ if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
203
+ return '';
204
+ return Helper.STRING.getMobileView(value, options?.join || '-');
135
205
  }
136
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
137
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperCardComponent, isStandalone: true, selector: "ngx-helper-card", inputs: { title: "title", subTitle: "subTitle", icon: "icon", actions: "actions", padding: "padding", backgroundColor: "backgroundColor", hasShadow: "hasShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, 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\">\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</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)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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"] }] });
206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
207
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, isStandalone: true, name: "ngxHelperMobile" });
138
208
  }
139
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, decorators: [{
140
- type: Component,
141
- args: [{ selector: 'ngx-helper-card', host: { '(window:resize)': 'onResize($event)' }, 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\">\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</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)}\n"] }]
142
- }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
143
- type: Optional
144
- }, {
145
- type: Inject,
146
- args: [NGX_HELPER_CONFIG]
147
- }] }], propDecorators: { className: [{
148
- type: HostBinding,
149
- args: ['className']
150
- }], title: [{
151
- type: Input,
152
- args: [{ required: true }]
153
- }], subTitle: [{
154
- type: Input,
155
- args: [{ required: false }]
156
- }], icon: [{
157
- type: Input,
158
- args: [{ required: false }]
159
- }], actions: [{
160
- type: Input,
161
- args: [{ required: false }]
162
- }], padding: [{
163
- type: Input,
164
- args: [{ required: false }]
165
- }], backgroundColor: [{
166
- type: Input,
167
- args: [{ required: false }]
168
- }], hasShadow: [{
169
- type: Input,
170
- args: [{ required: false }]
171
- }] } });
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, decorators: [{
210
+ type: Pipe,
211
+ args: [{ name: 'ngxHelperMobile' }]
212
+ }] });
172
213
 
173
- class NgxHelperLoaderComponent {
174
- loaderSize;
175
- loaderColor;
176
- mode;
177
- size;
178
- color;
179
- padding;
180
- ngOnChanges(changes) {
181
- this.loaderSize = `${this.size || 25}px`;
182
- this.loaderColor = this.color || `var(--secondary)`;
214
+ class NgxHelperNumberPipe {
215
+ transform(value, options) {
216
+ if (value === undefined || value === null || !Helper.IS.number(value))
217
+ return '';
218
+ value = options?.fractionDigits ? +value.toFixed(options?.fractionDigits) : value;
219
+ return Helper.NUMBER.format(value, options?.english ? 'EN' : 'FA');
183
220
  }
184
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
185
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperLoaderComponent, isStandalone: true, selector: "ngx-helper-loader", inputs: { mode: "mode", size: "size", color: "color", padding: "padding" }, 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()\"></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"] });
221
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
222
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, isStandalone: true, name: "ngxHelperNumber" });
186
223
  }
187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, decorators: [{
188
- type: Component,
189
- args: [{ selector: 'ngx-helper-loader', imports: [], template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\"></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"] }]
190
- }], propDecorators: { loaderSize: [{
191
- type: HostBinding,
192
- args: ['style.--loader-size']
193
- }], loaderColor: [{
194
- type: HostBinding,
195
- args: ['style.--loader-color']
196
- }], mode: [{
197
- type: Input,
198
- args: [{ required: true }]
199
- }], size: [{
200
- type: Input,
201
- args: [{ required: false }]
202
- }], color: [{
203
- type: Input,
204
- args: [{ required: false }]
205
- }], padding: [{
206
- type: Input,
207
- args: [{ required: false }]
208
- }] } });
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, decorators: [{
225
+ type: Pipe,
226
+ args: [{ name: 'ngxHelperNumber' }]
227
+ }] });
209
228
 
210
- const NGX_HELPER_PAGE_GROUP_ITEM = new InjectionToken('NGX-HELPER-PAGE-GROUP-ITEM');
211
- const NGX_HELPER_PAGE_GROUP_DATA = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA');
229
+ class NgxHelperPeriodPipe {
230
+ transform(value, options) {
231
+ if (value === undefined || value === null)
232
+ return '';
233
+ const from = Helper.IS.date(value) ? value : 'from' in value ? value.from : new Date();
234
+ const to = Helper.IS.date(value) ? new Date() : 'to' in value ? value.to : new Date();
235
+ return Helper.DATE.jalaliPeriod(from, to, options?.timezone || '');
236
+ }
237
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
238
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, isStandalone: true, name: "ngxHelperPeriod" });
239
+ }
240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, decorators: [{
241
+ type: Pipe,
242
+ args: [{ name: 'ngxHelperPeriod' }]
243
+ }] });
244
+
245
+ class NgxHelperPricePipe {
246
+ transform(value, options) {
247
+ if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
248
+ return '';
249
+ const getPrice = (...titles) => {
250
+ if (value === undefined || value === null)
251
+ return '';
252
+ const price = Helper.NUMBER.format(+value.toFixed(2), !!options?.english ? 'EN' : 'FA');
253
+ const unit = titles[options?.short ? 0 : 1][options?.english ? 0 : 1];
254
+ const currency = options?.currency ? ' ' + options?.currency : '';
255
+ return `${price} ${unit}${currency}`;
256
+ };
257
+ if (value < 1000)
258
+ return getPrice(['', ''], ['', '']);
259
+ value /= 1000;
260
+ if (value < 1000)
261
+ return getPrice(['T', 'ه'], ['Thousand', 'هزار']);
262
+ value /= 1000;
263
+ if (value < 1000)
264
+ return getPrice(['M', 'م'], ['Million', 'میلیون']);
265
+ value /= 1000;
266
+ return getPrice(['B', 'د'], ['Billion', 'میلیارد']);
267
+ }
268
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
269
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, isStandalone: true, name: "ngxHelperPrice" });
270
+ }
271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, decorators: [{
272
+ type: Pipe,
273
+ args: [{ name: 'ngxHelperPrice' }]
274
+ }] });
275
+
276
+ class NgxHelperVolumePipe {
277
+ transform(value, options) {
278
+ if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
279
+ return '';
280
+ const getVolume = (...titles) => {
281
+ if (value === undefined || value === null)
282
+ return '';
283
+ const volume = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
284
+ const shortIndex = options?.short ? 0 : 1;
285
+ const titleIndex = options?.english ? 0 : 1;
286
+ return `${volume} ${titles[shortIndex][titleIndex]}`;
287
+ };
288
+ if (value === 0)
289
+ return getVolume(['', ''], ['', '']);
290
+ if (value < 1000)
291
+ return getVolume(['ML', 'م'], ['Milliliter', 'میلی لیتر']);
292
+ value /= 1000;
293
+ return getVolume(['L', 'ل'], ['Liter', 'لیتر']);
294
+ }
295
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
296
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, isStandalone: true, name: "ngxHelperVolume" });
297
+ }
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, decorators: [{
299
+ type: Pipe,
300
+ args: [{ name: 'ngxHelperVolume' }]
301
+ }] });
302
+
303
+ class NgxHelperWeightPipe {
304
+ transform(value, options) {
305
+ if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
306
+ return '';
307
+ const getWeight = (...titles) => {
308
+ if (value === undefined || value === null)
309
+ return '';
310
+ const weight = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
311
+ const shortIndex = options?.short ? 0 : 1;
312
+ const titleIndex = options?.english ? 0 : 1;
313
+ return `${weight} ${titles[shortIndex][titleIndex]}`;
314
+ };
315
+ if (value === 0)
316
+ return getWeight(['', ''], ['', '']);
317
+ if (value < 1000)
318
+ return getWeight(['G', 'گ'], ['Gram', 'گرم']);
319
+ value /= 1000;
320
+ if (value < 1000)
321
+ return getWeight(['K', 'ک'], ['Kilogram', 'کیلو']);
322
+ value /= 1000;
323
+ if (value < 1000)
324
+ return getWeight(['T', 'ت'], ['Tonne', 'تن']);
325
+ value /= 1000;
326
+ return getWeight(['KT', 'ه'], ['Kilotonne', 'هزار تن']);
327
+ }
328
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
329
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, isStandalone: true, name: "ngxHelperWeight" });
330
+ }
331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, decorators: [{
332
+ type: Pipe,
333
+ args: [{ name: 'ngxHelperWeight' }]
334
+ }] });
335
+
336
+ class NgxHelperValuePipe {
337
+ transform(value, options) {
338
+ const emptyText = options?.emptyText || '';
339
+ if (value === undefined || Helper.IS.empty(value))
340
+ return emptyText;
341
+ switch (value.type) {
342
+ case 'BANK-CARD':
343
+ return new NgxHelperBankCardPipe().transform(value.value, value) || emptyText;
344
+ case 'DATE':
345
+ return new NgxHelperDatePipe().transform(value.value, value) || emptyText;
346
+ case 'DURATION':
347
+ return new NgxHelperDurationPipe().transform(value.value, value) || emptyText;
348
+ case 'FILE-SIZE':
349
+ return new NgxHelperFileSizePipe().transform(value.value, value) || emptyText;
350
+ case 'MOBILE':
351
+ return new NgxHelperMobilePipe().transform(value.value, value) || emptyText;
352
+ case 'NUMBER':
353
+ return new NgxHelperNumberPipe().transform(value.value, value) || emptyText;
354
+ case 'PERIOD':
355
+ return new NgxHelperPeriodPipe().transform(value.value, value) || emptyText;
356
+ case 'PRICE':
357
+ return new NgxHelperPricePipe().transform(value.value, value) || emptyText;
358
+ case 'STRING':
359
+ return Helper.IS.string(value.value) ? value.value : emptyText;
360
+ case 'VOLUME':
361
+ return new NgxHelperVolumePipe().transform(value.value, value) || emptyText;
362
+ case 'WEIGHT':
363
+ return new NgxHelperWeightPipe().transform(value.value, value) || emptyText;
364
+ }
365
+ }
366
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
367
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, isStandalone: true, name: "ngxHelperValue" });
368
+ }
369
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, decorators: [{
370
+ type: Pipe,
371
+ args: [{ name: 'ngxHelperValue' }]
372
+ }] });
373
+
374
+ class ComponentService {
375
+ getComponentConfig(config) {
376
+ const getStickyView = (config) => {
377
+ return {
378
+ desktopView: typeof config === 'string' ? config : config.desktopView,
379
+ mobileView: typeof config === 'string' ? config : config.mobileView,
380
+ };
381
+ };
382
+ return {
383
+ mobileWidth: config?.mobileWidth || 600,
384
+ pageGroupSidebarWidth: config?.pageGroupSidebarWidth || '200px',
385
+ stickyView: config?.stickyView
386
+ ? {
387
+ top: config.stickyView.top ? getStickyView(config.stickyView.top) : undefined,
388
+ bottom: config.stickyView.bottom ? getStickyView(config.stickyView.bottom) : undefined,
389
+ }
390
+ : undefined,
391
+ };
392
+ }
393
+ getValueData(values) {
394
+ const pipeTransform = new NgxHelperValuePipe().transform;
395
+ const ltrValues = ['BANK-CARD', 'MOBILE', 'NUMBER'];
396
+ return values.map((item) => {
397
+ const value = item.value;
398
+ return value === undefined
399
+ ? { title: item.title, value: '' }
400
+ : typeof value === 'string'
401
+ ? { title: item.title, value: value.trim() }
402
+ : {
403
+ title: item.title,
404
+ value: pipeTransform(value),
405
+ color: item.color,
406
+ action: item.action,
407
+ copyToClipboard: item.copyToClipboard,
408
+ ltr: ltrValues.includes(value.type),
409
+ english: 'english' in value && !!value.english,
410
+ };
411
+ });
412
+ }
413
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
414
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService });
415
+ }
416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, decorators: [{
417
+ type: Injectable
418
+ }] });
419
+
420
+ class NgxHelperCardComponent {
421
+ componentService;
422
+ config;
423
+ className = 'ngx-helper-m3-card';
424
+ title;
425
+ subTitle;
426
+ icon;
427
+ actions = [];
428
+ padding = '1rem';
429
+ backgroundColor;
430
+ hasShadow = false;
431
+ isMobile = false;
432
+ buttons = [];
433
+ componentConfig;
434
+ constructor(componentService, config) {
435
+ this.componentService = componentService;
436
+ this.config = config;
437
+ }
438
+ ngOnInit() {
439
+ this.componentConfig = this.componentService.getComponentConfig(this.config);
440
+ this.onResize();
441
+ }
442
+ ngOnChanges(changes) {
443
+ this.className = `ngx-helper-m3-card${this.hasShadow ? ' has-shadow' : ''}`;
444
+ this.buttons = this.actions.map((action) => {
445
+ return 'buttons' in action ? { type: 'MENU', ...action } : { type: 'BUTTON', ...action };
446
+ });
447
+ }
448
+ onResize() {
449
+ this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
450
+ }
451
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperCardComponent, isStandalone: true, selector: "ngx-helper-card", inputs: { title: "title", subTitle: "subTitle", icon: "icon", actions: "actions", padding: "padding", backgroundColor: "backgroundColor", hasShadow: "hasShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, 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\">\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</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)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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"] }] });
453
+ }
454
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, decorators: [{
455
+ type: Component,
456
+ args: [{ selector: 'ngx-helper-card', host: { '(window:resize)': 'onResize($event)' }, 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\">\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</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)}\n"] }]
457
+ }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
458
+ type: Optional
459
+ }, {
460
+ type: Inject,
461
+ args: [NGX_HELPER_CONFIG]
462
+ }] }], propDecorators: { className: [{
463
+ type: HostBinding,
464
+ args: ['className']
465
+ }], title: [{
466
+ type: Input,
467
+ args: [{ required: true }]
468
+ }], subTitle: [{
469
+ type: Input,
470
+ args: [{ required: false }]
471
+ }], icon: [{
472
+ type: Input,
473
+ args: [{ required: false }]
474
+ }], actions: [{
475
+ type: Input,
476
+ args: [{ required: false }]
477
+ }], padding: [{
478
+ type: Input,
479
+ args: [{ required: false }]
480
+ }], backgroundColor: [{
481
+ type: Input,
482
+ args: [{ required: false }]
483
+ }], hasShadow: [{
484
+ type: Input,
485
+ args: [{ required: false }]
486
+ }] } });
487
+
488
+ class NgxHelperLoaderComponent {
489
+ loaderSize;
490
+ loaderColor;
491
+ mode;
492
+ size;
493
+ color;
494
+ padding;
495
+ ngOnChanges(changes) {
496
+ this.loaderSize = `${this.size || 25}px`;
497
+ this.loaderColor = this.color || `var(--secondary)`;
498
+ }
499
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
500
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperLoaderComponent, isStandalone: true, selector: "ngx-helper-loader", inputs: { mode: "mode", size: "size", color: "color", padding: "padding" }, 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()\"></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"] });
501
+ }
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, decorators: [{
503
+ type: Component,
504
+ args: [{ selector: 'ngx-helper-loader', imports: [], template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\"></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"] }]
505
+ }], propDecorators: { loaderSize: [{
506
+ type: HostBinding,
507
+ args: ['style.--loader-size']
508
+ }], loaderColor: [{
509
+ type: HostBinding,
510
+ args: ['style.--loader-color']
511
+ }], mode: [{
512
+ type: Input,
513
+ args: [{ required: true }]
514
+ }], size: [{
515
+ type: Input,
516
+ args: [{ required: false }]
517
+ }], color: [{
518
+ type: Input,
519
+ args: [{ required: false }]
520
+ }], padding: [{
521
+ type: Input,
522
+ args: [{ required: false }]
523
+ }] } });
524
+
525
+ const NGX_HELPER_PAGE_GROUP_ITEM = new InjectionToken('NGX-HELPER-PAGE-GROUP-ITEM');
526
+ const NGX_HELPER_PAGE_GROUP_DATA = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA');
212
527
  const NGX_HELPER_PAGE_GROUP_DATA_CHANGE = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA-CHANGE');
213
528
 
214
529
  class NgxHelperPageGroupComponent {
@@ -303,467 +618,173 @@ class NgxHelperPageGroupComponent {
303
618
  };
304
619
  this.pageChanged.next(item);
305
620
  }
306
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
307
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", 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($event)" }, 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<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<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <div\n class=\"header\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </div>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageId].component; injector: injector\"></span>\n</div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
308
- }
309
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, decorators: [{
310
- type: Component,
311
- args: [{ selector: 'ngx-helper-page-group', host: { '(window:resize)': 'onResize($event)' }, imports: [NgComponentOutlet, MatIcon], providers: [ComponentService], 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<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<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <div\n class=\"header\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </div>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageId].component; injector: injector\"></span>\n</div>\n}\n" }]
312
- }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: ComponentService }, { type: undefined, decorators: [{
313
- type: Optional
314
- }, {
315
- type: Inject,
316
- args: [NGX_HELPER_CONFIG]
317
- }] }], propDecorators: { className: [{
318
- type: HostBinding,
319
- args: ['className']
320
- }], display: [{
321
- type: HostBinding,
322
- args: ['style.display']
323
- }], pageGroup: [{
324
- type: Input,
325
- args: [{ required: true }]
326
- }], pageId: [{
327
- type: Input,
328
- args: [{ required: false }]
329
- }], data: [{
330
- type: Input,
331
- args: [{ required: false }]
332
- }], pageChanged: [{
333
- type: Output
334
- }], dataChanged: [{
335
- type: Output
336
- }] } });
337
-
338
- class NgxHelperSectionStickyDirective {
339
- elementRef;
340
- config;
341
- ngxHelperSectionSticky;
342
- ngxHelperSectionZIndex;
343
- componentService = inject(ComponentService);
344
- componentConfig;
345
- isMobile = false;
346
- constructor(elementRef, config) {
347
- this.elementRef = elementRef;
348
- this.config = config;
349
- }
350
- ngOnInit() {
351
- this.componentConfig = this.componentService.getComponentConfig(this.config);
352
- this.onResize();
353
- }
354
- onResize() {
355
- this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
356
- this.setPosition();
357
- }
358
- setPosition() {
359
- const element = this.elementRef.nativeElement;
360
- if (!element)
361
- return;
362
- switch (this.ngxHelperSectionSticky) {
363
- case 'TOP':
364
- const top = this.componentConfig.stickyView?.top;
365
- if (!top)
366
- return;
367
- element.style.position = 'sticky';
368
- element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
369
- element.style.top = this.isMobile ? top.mobileView : top.desktopView;
370
- break;
371
- case 'BOTTOM':
372
- const bottom = this.componentConfig.stickyView?.bottom;
373
- if (!bottom)
374
- return;
375
- element.style.position = 'sticky';
376
- element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
377
- element.style.bottom = this.isMobile ? bottom.mobileView : bottom.desktopView;
378
- break;
379
- }
380
- }
381
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, deps: [{ token: i0.ElementRef }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
382
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionStickyDirective, isStandalone: true, selector: "[ngxHelperSectionSticky]", inputs: { ngxHelperSectionSticky: "ngxHelperSectionSticky", ngxHelperSectionZIndex: "ngxHelperSectionZIndex" }, host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0 });
383
- }
384
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, decorators: [{
385
- type: Directive,
386
- args: [{
387
- selector: '[ngxHelperSectionSticky]',
388
- host: { '(window:resize)': 'onResize($event)' },
389
- }]
390
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
391
- type: Optional
392
- }, {
393
- type: Inject,
394
- args: [NGX_HELPER_CONFIG]
395
- }] }], propDecorators: { ngxHelperSectionSticky: [{
396
- type: Input,
397
- args: [{ required: true }]
398
- }], ngxHelperSectionZIndex: [{
399
- type: Input,
400
- args: [{ required: false }]
401
- }] } });
402
-
403
- class NgxHelperSectionComponent {
404
- componentService;
405
- config;
406
- gap;
407
- gapSize;
408
- componentConfig;
409
- isMobile = false;
410
- constructor(componentService, config) {
411
- this.componentService = componentService;
412
- this.config = config;
413
- }
414
- ngOnInit() {
415
- this.componentConfig = this.componentService.getComponentConfig(this.config);
416
- this.gap = this.gapSize || '1rem';
417
- this.onResize();
418
- }
419
- onResize() {
420
- this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
421
- }
422
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
423
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionComponent, isStandalone: true, selector: "ngx-helper-section", inputs: { gapSize: "gapSize" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "style.--section-gap": "this.gap" } }, providers: [ComponentService], ngImport: i0, template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] });
621
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
622
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", 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($event)" }, 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<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<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <div\n class=\"header\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </div>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageId].component; injector: injector\"></span>\n</div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
424
623
  }
425
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, decorators: [{
624
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, decorators: [{
426
625
  type: Component,
427
- args: [{ selector: 'ngx-helper-section', host: { '(window:resize)': 'onResize($event)' }, imports: [], providers: [ComponentService], template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] }]
428
- }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
626
+ args: [{ selector: 'ngx-helper-page-group', host: { '(window:resize)': 'onResize($event)' }, imports: [NgComponentOutlet, MatIcon], providers: [ComponentService], 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<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<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <div\n class=\"header\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </div>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageId].component; injector: injector\"></span>\n</div>\n}\n" }]
627
+ }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: ComponentService }, { type: undefined, decorators: [{
429
628
  type: Optional
430
629
  }, {
431
630
  type: Inject,
432
631
  args: [NGX_HELPER_CONFIG]
433
- }] }], propDecorators: { gap: [{
434
- type: HostBinding,
435
- args: ['style.--section-gap']
436
- }], gapSize: [{
437
- type: Input,
438
- args: [{ required: false }]
439
- }] } });
440
-
441
- class NgxHelperSectionColumnComponent {
442
- flexStyle = '1';
443
- widthStyle = '*';
444
- flex;
445
- width;
446
- sticky;
447
- ngOnChanges(changes) {
448
- this.flexStyle = this.width ? 'unset' : this.flex?.toString() || '1';
449
- this.widthStyle = this.width || '*';
450
- }
451
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
452
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionColumnComponent, isStandalone: true, selector: "ngx-helper-section-column", inputs: { flex: "flex", width: "width", sticky: "sticky" }, host: { properties: { "style.flex": "this.flexStyle", "style.width": "this.widthStyle" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [""] });
453
- }
454
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, decorators: [{
455
- type: Component,
456
- args: [{ selector: 'ngx-helper-section-column', imports: [], template: "<ng-content></ng-content>\n" }]
457
- }], propDecorators: { flexStyle: [{
632
+ }] }], propDecorators: { className: [{
458
633
  type: HostBinding,
459
- args: ['style.flex']
460
- }], widthStyle: [{
634
+ args: ['className']
635
+ }], display: [{
461
636
  type: HostBinding,
462
- args: ['style.width']
463
- }], flex: [{
637
+ args: ['style.display']
638
+ }], pageGroup: [{
464
639
  type: Input,
465
- args: [{ required: false }]
466
- }], width: [{
640
+ args: [{ required: true }]
641
+ }], pageId: [{
467
642
  type: Input,
468
643
  args: [{ required: false }]
469
- }], sticky: [{
644
+ }], data: [{
470
645
  type: Input,
471
646
  args: [{ required: false }]
647
+ }], pageChanged: [{
648
+ type: Output
649
+ }], dataChanged: [{
650
+ type: Output
472
651
  }] } });
473
652
 
474
- const ltrValues = ['BANK-CARD', 'MOBILE', 'NUMBER'];
475
-
476
- class NgxHelperBankCardPipe {
477
- transform(value, options) {
478
- if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
479
- return '';
480
- switch (options?.view) {
481
- case 'BANK':
482
- return Helper.BANK.findCard(value)?.title || '';
483
- default:
484
- return Helper.STRING.getBankCardView(value, options?.join || '-');
485
- }
486
- }
487
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
488
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, isStandalone: true, name: "ngxHelperBankCard" });
489
- }
490
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, decorators: [{
491
- type: Pipe,
492
- args: [{ name: 'ngxHelperBankCard' }]
493
- }] });
494
-
495
- class NgxHelperDatePipe {
496
- transform(value, options) {
497
- if (value === undefined || value === null || (!Helper.IS.date(value) && !Helper.IS.number(value)))
498
- return '';
499
- const date = typeof value === 'number' ? new Date(value) : value;
500
- const jalali = JalaliDateTime();
501
- const timezone = options?.timezone && jalali.timezones().includes(options?.timezone) ? options?.timezone : 'Asia/Tehran';
502
- switch (options?.format || 'DATE') {
503
- case 'FULL':
504
- return jalali.toFullText(date, { format: 'W، d N Y H:I', timezone });
505
- case 'SHORT':
506
- return jalali.toFullText(date, { format: 'Y/M/D', timezone });
507
- case 'DATE':
508
- return jalali.toFullText(date, { format: 'W، d N Y', timezone });
509
- case 'TIME':
510
- return jalali.toFullText(date, { format: 'H:I', timezone });
511
- case 'WEEK':
512
- const { from, to } = jalali.periodWeek(1, date, timezone);
513
- return Helper.DATE.jalaliPeriod(from, to, timezone);
514
- case 'MONTH':
515
- return jalali.toFullText(date, { format: 'N Y', timezone });
516
- case 'YEAR':
517
- return jalali.toFullText(date, { format: 'Y', timezone });
518
- default:
519
- return jalali.toFullText(date, { format: options?.format, timezone });
520
- }
521
- }
522
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
523
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, isStandalone: true, name: "ngxHelperDate" });
524
- }
525
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, decorators: [{
526
- type: Pipe,
527
- args: [{ name: 'ngxHelperDate' }]
528
- }] });
529
-
530
- class NgxHelperDurationPipe {
531
- transform(value, options) {
532
- if (value === undefined || value === null)
533
- return '';
534
- let seconds = 0;
535
- if (Helper.IS.number(value))
536
- seconds = Math.abs(value);
537
- else if (Helper.IS.date(value))
538
- seconds = Math.floor(Math.abs(new Date().getTime() - value.getTime()) / 1000);
539
- else if (Helper.IS.object(value)) {
540
- const from = 'from' in value ? value.from : new Date();
541
- const to = 'to' in value ? value.to : new Date();
542
- seconds = Math.floor(Math.abs(from.getTime() - to.getTime()) / 1000);
543
- }
544
- const days = Math.floor(seconds / (24 * 60 * 60));
545
- seconds -= days * (24 * 60 * 60);
546
- const hours = Math.floor(seconds / (60 * 60));
547
- seconds -= hours * (60 * 60);
548
- const minutes = Math.floor(seconds / 60);
549
- seconds -= minutes * 60;
550
- const hasDays = days !== 0;
551
- const time = [hours, minutes, seconds].map((v) => v.toString().padStart(2, '0')).join(':');
552
- switch (options?.format || 'TEXT') {
553
- case 'TEXT':
554
- const hasTime = !!hours || !!minutes || !!seconds;
555
- const day = hasDays
556
- ? Helper.NUMBER.format(days, 'EN') + (!!options?.english ? (days === 1 ? ' day' : ' days') : ' روز')
557
- : '';
558
- const join = hasDays && hasTime ? (!!options?.english ? ', ' : ' و ') : '';
559
- return (day + join + (!hasDays || hasTime ? time : '')).trim();
560
- case 'FULL':
561
- return (hasDays ? Helper.NUMBER.format(days, 'EN') + ':' : '') + time;
562
- case 'DAY':
563
- return Helper.NUMBER.format(days + (hours !== 0 || minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
564
- case 'HOUR':
565
- return Helper.NUMBER.format(days * 24 + hours + (minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
566
- case 'MINUTE':
567
- return Helper.NUMBER.format(days * 24 * 60 + hours * 60 + minutes, !!options?.english ? 'EN' : 'FA');
568
- case 'SECOND':
569
- return Helper.NUMBER.format(days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds, !!options?.english ? 'EN' : 'FA');
570
- }
571
- }
572
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
573
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, isStandalone: true, name: "ngxHelperDuration" });
574
- }
575
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, decorators: [{
576
- type: Pipe,
577
- args: [{ name: 'ngxHelperDuration' }]
578
- }] });
579
-
580
- class NgxHelperFileSizePipe {
581
- transform(value, options) {
582
- if (value === undefined || value === null || !Helper.IS.number(value))
583
- return '';
584
- return Helper.NUMBER.toFileSize(value, !!options?.english ? 'EN' : 'FA');
585
- }
586
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
587
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, isStandalone: true, name: "ngxHelperFileSize" });
588
- }
589
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, decorators: [{
590
- type: Pipe,
591
- args: [{ name: 'ngxHelperFileSize' }]
592
- }] });
593
-
594
- class NgxHelperMobilePipe {
595
- transform(value, options) {
596
- if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
597
- return '';
598
- return Helper.STRING.getMobileView(value, options?.join || '-');
653
+ class NgxHelperSectionStickyDirective {
654
+ elementRef;
655
+ config;
656
+ ngxHelperSectionSticky;
657
+ ngxHelperSectionZIndex;
658
+ componentService = inject(ComponentService);
659
+ componentConfig;
660
+ isMobile = false;
661
+ constructor(elementRef, config) {
662
+ this.elementRef = elementRef;
663
+ this.config = config;
599
664
  }
600
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
601
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, isStandalone: true, name: "ngxHelperMobile" });
602
- }
603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, decorators: [{
604
- type: Pipe,
605
- args: [{ name: 'ngxHelperMobile' }]
606
- }] });
607
-
608
- class NgxHelperNumberPipe {
609
- transform(value, options) {
610
- if (value === undefined || value === null || !Helper.IS.number(value))
611
- return '';
612
- value = options?.fractionDigits ? +value.toFixed(options?.fractionDigits) : value;
613
- return Helper.NUMBER.format(value, options?.english ? 'EN' : 'FA');
665
+ ngOnInit() {
666
+ this.componentConfig = this.componentService.getComponentConfig(this.config);
667
+ this.onResize();
614
668
  }
615
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
616
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, isStandalone: true, name: "ngxHelperNumber" });
617
- }
618
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, decorators: [{
619
- type: Pipe,
620
- args: [{ name: 'ngxHelperNumber' }]
621
- }] });
622
-
623
- class NgxHelperPeriodPipe {
624
- transform(value, options) {
625
- if (value === undefined || value === null)
626
- return '';
627
- const from = Helper.IS.date(value) ? value : 'from' in value ? value.from : new Date();
628
- const to = Helper.IS.date(value) ? new Date() : 'to' in value ? value.to : new Date();
629
- return Helper.DATE.jalaliPeriod(from, to, options?.timezone || '');
669
+ onResize() {
670
+ this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
671
+ this.setPosition();
630
672
  }
631
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
632
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, isStandalone: true, name: "ngxHelperPeriod" });
633
- }
634
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, decorators: [{
635
- type: Pipe,
636
- args: [{ name: 'ngxHelperPeriod' }]
637
- }] });
638
-
639
- class NgxHelperPricePipe {
640
- transform(value, options) {
641
- if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
642
- return '';
643
- const getPrice = (...titles) => {
644
- if (value === undefined || value === null)
645
- return '';
646
- const price = Helper.NUMBER.format(+value.toFixed(2), !!options?.english ? 'EN' : 'FA');
647
- const unit = titles[options?.short ? 0 : 1][options?.english ? 0 : 1];
648
- const currency = options?.currency ? ' ' + options?.currency : '';
649
- return `${price} ${unit}${currency}`;
650
- };
651
- if (value < 1000)
652
- return getPrice(['', ''], ['', '']);
653
- value /= 1000;
654
- if (value < 1000)
655
- return getPrice(['T', 'ه'], ['Thousand', 'هزار']);
656
- value /= 1000;
657
- if (value < 1000)
658
- return getPrice(['M', 'م'], ['Million', 'میلیون']);
659
- value /= 1000;
660
- return getPrice(['B', 'د'], ['Billion', 'میلیارد']);
673
+ setPosition() {
674
+ const element = this.elementRef.nativeElement;
675
+ if (!element)
676
+ return;
677
+ switch (this.ngxHelperSectionSticky) {
678
+ case 'TOP':
679
+ const top = this.componentConfig.stickyView?.top;
680
+ if (!top)
681
+ return;
682
+ element.style.position = 'sticky';
683
+ element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
684
+ element.style.top = this.isMobile ? top.mobileView : top.desktopView;
685
+ break;
686
+ case 'BOTTOM':
687
+ const bottom = this.componentConfig.stickyView?.bottom;
688
+ if (!bottom)
689
+ return;
690
+ element.style.position = 'sticky';
691
+ element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
692
+ element.style.bottom = this.isMobile ? bottom.mobileView : bottom.desktopView;
693
+ break;
694
+ }
661
695
  }
662
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
663
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, isStandalone: true, name: "ngxHelperPrice" });
696
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, deps: [{ token: i0.ElementRef }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
697
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionStickyDirective, isStandalone: true, selector: "[ngxHelperSectionSticky]", inputs: { ngxHelperSectionSticky: "ngxHelperSectionSticky", ngxHelperSectionZIndex: "ngxHelperSectionZIndex" }, host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0 });
664
698
  }
665
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, decorators: [{
666
- type: Pipe,
667
- args: [{ name: 'ngxHelperPrice' }]
668
- }] });
699
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, decorators: [{
700
+ type: Directive,
701
+ args: [{
702
+ selector: '[ngxHelperSectionSticky]',
703
+ host: { '(window:resize)': 'onResize($event)' },
704
+ }]
705
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
706
+ type: Optional
707
+ }, {
708
+ type: Inject,
709
+ args: [NGX_HELPER_CONFIG]
710
+ }] }], propDecorators: { ngxHelperSectionSticky: [{
711
+ type: Input,
712
+ args: [{ required: true }]
713
+ }], ngxHelperSectionZIndex: [{
714
+ type: Input,
715
+ args: [{ required: false }]
716
+ }] } });
669
717
 
670
- class NgxHelperVolumePipe {
671
- transform(value, options) {
672
- if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
673
- return '';
674
- const getVolume = (...titles) => {
675
- if (value === undefined || value === null)
676
- return '';
677
- const volume = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
678
- const shortIndex = options?.short ? 0 : 1;
679
- const titleIndex = options?.english ? 0 : 1;
680
- return `${volume} ${titles[shortIndex][titleIndex]}`;
681
- };
682
- if (value === 0)
683
- return getVolume(['', ''], ['', '']);
684
- if (value < 1000)
685
- return getVolume(['ML', 'م'], ['Milliliter', 'میلی لیتر']);
686
- value /= 1000;
687
- return getVolume(['L', 'ل'], ['Liter', 'لیتر']);
718
+ class NgxHelperSectionComponent {
719
+ componentService;
720
+ config;
721
+ gap;
722
+ gapSize;
723
+ componentConfig;
724
+ isMobile = false;
725
+ constructor(componentService, config) {
726
+ this.componentService = componentService;
727
+ this.config = config;
688
728
  }
689
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
690
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, isStandalone: true, name: "ngxHelperVolume" });
691
- }
692
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, decorators: [{
693
- type: Pipe,
694
- args: [{ name: 'ngxHelperVolume' }]
695
- }] });
696
-
697
- class NgxHelperWeightPipe {
698
- transform(value, options) {
699
- if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
700
- return '';
701
- const getWeight = (...titles) => {
702
- if (value === undefined || value === null)
703
- return '';
704
- const weight = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
705
- const shortIndex = options?.short ? 0 : 1;
706
- const titleIndex = options?.english ? 0 : 1;
707
- return `${weight} ${titles[shortIndex][titleIndex]}`;
708
- };
709
- if (value === 0)
710
- return getWeight(['', ''], ['', '']);
711
- if (value < 1000)
712
- return getWeight(['G', 'گ'], ['Gram', 'گرم']);
713
- value /= 1000;
714
- if (value < 1000)
715
- return getWeight(['K', 'ک'], ['Kilogram', 'کیلو']);
716
- value /= 1000;
717
- if (value < 1000)
718
- return getWeight(['T', 'ت'], ['Tonne', 'تن']);
719
- value /= 1000;
720
- return getWeight(['KT', 'ه'], ['Kilotonne', 'هزار تن']);
729
+ ngOnInit() {
730
+ this.componentConfig = this.componentService.getComponentConfig(this.config);
731
+ this.gap = this.gapSize || '1rem';
732
+ this.onResize();
721
733
  }
722
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
723
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, isStandalone: true, name: "ngxHelperWeight" });
734
+ onResize() {
735
+ this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
736
+ }
737
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
738
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionComponent, isStandalone: true, selector: "ngx-helper-section", inputs: { gapSize: "gapSize" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "style.--section-gap": "this.gap" } }, providers: [ComponentService], ngImport: i0, template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] });
724
739
  }
725
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, decorators: [{
726
- type: Pipe,
727
- args: [{ name: 'ngxHelperWeight' }]
728
- }] });
740
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, decorators: [{
741
+ type: Component,
742
+ args: [{ selector: 'ngx-helper-section', host: { '(window:resize)': 'onResize($event)' }, imports: [], providers: [ComponentService], template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] }]
743
+ }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
744
+ type: Optional
745
+ }, {
746
+ type: Inject,
747
+ args: [NGX_HELPER_CONFIG]
748
+ }] }], propDecorators: { gap: [{
749
+ type: HostBinding,
750
+ args: ['style.--section-gap']
751
+ }], gapSize: [{
752
+ type: Input,
753
+ args: [{ required: false }]
754
+ }] } });
729
755
 
730
- class NgxHelperValuePipe {
731
- transform(value, options) {
732
- const emptyText = options?.emptyText || '';
733
- if (value === undefined || Helper.IS.empty(value))
734
- return emptyText;
735
- switch (value.type) {
736
- case 'BANK-CARD':
737
- return new NgxHelperBankCardPipe().transform(value.value, value) || emptyText;
738
- case 'DATE':
739
- return new NgxHelperDatePipe().transform(value.value, value) || emptyText;
740
- case 'DURATION':
741
- return new NgxHelperDurationPipe().transform(value.value, value) || emptyText;
742
- case 'FILE-SIZE':
743
- return new NgxHelperFileSizePipe().transform(value.value, value) || emptyText;
744
- case 'MOBILE':
745
- return new NgxHelperMobilePipe().transform(value.value, value) || emptyText;
746
- case 'NUMBER':
747
- return new NgxHelperNumberPipe().transform(value.value, value) || emptyText;
748
- case 'PERIOD':
749
- return new NgxHelperPeriodPipe().transform(value.value, value) || emptyText;
750
- case 'PRICE':
751
- return new NgxHelperPricePipe().transform(value.value, value) || emptyText;
752
- case 'STRING':
753
- return Helper.IS.string(value.value) ? value.value : emptyText;
754
- case 'VOLUME':
755
- return new NgxHelperVolumePipe().transform(value.value, value) || emptyText;
756
- case 'WEIGHT':
757
- return new NgxHelperWeightPipe().transform(value.value, value) || emptyText;
758
- }
756
+ class NgxHelperSectionColumnComponent {
757
+ flexStyle = '1';
758
+ widthStyle = '*';
759
+ flex;
760
+ width;
761
+ sticky;
762
+ ngOnChanges(changes) {
763
+ this.flexStyle = this.width ? 'unset' : this.flex?.toString() || '1';
764
+ this.widthStyle = this.width || '*';
759
765
  }
760
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
761
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, isStandalone: true, name: "ngxHelperValue" });
766
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
767
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionColumnComponent, isStandalone: true, selector: "ngx-helper-section-column", inputs: { flex: "flex", width: "width", sticky: "sticky" }, host: { properties: { "style.flex": "this.flexStyle", "style.width": "this.widthStyle" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [""] });
762
768
  }
763
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, decorators: [{
764
- type: Pipe,
765
- args: [{ name: 'ngxHelperValue' }]
766
- }] });
769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, decorators: [{
770
+ type: Component,
771
+ args: [{ selector: 'ngx-helper-section-column', imports: [], template: "<ng-content></ng-content>\n" }]
772
+ }], propDecorators: { flexStyle: [{
773
+ type: HostBinding,
774
+ args: ['style.flex']
775
+ }], widthStyle: [{
776
+ type: HostBinding,
777
+ args: ['style.width']
778
+ }], flex: [{
779
+ type: Input,
780
+ args: [{ required: false }]
781
+ }], width: [{
782
+ type: Input,
783
+ args: [{ required: false }]
784
+ }], sticky: [{
785
+ type: Input,
786
+ args: [{ required: false }]
787
+ }] } });
767
788
 
768
789
  class NgxHelperValueBoxComponent {
769
790
  router;
@@ -782,7 +803,6 @@ class NgxHelperValueBoxComponent {
782
803
  copyIndex;
783
804
  copyTimeout;
784
805
  componentConfig;
785
- pipeTransform = new NgxHelperValuePipe().transform;
786
806
  constructor(router, componentService, config) {
787
807
  this.router = router;
788
808
  this.componentService = componentService;
@@ -795,21 +815,7 @@ class NgxHelperValueBoxComponent {
795
815
  ngOnChanges(changes) {
796
816
  this.boxGap = this.gapSize;
797
817
  this.className = `ngx-helper-m3-value-box${this.hideShadow ? ' hide-shadow' : ''}`;
798
- this.data = this.values.map((item) => {
799
- const value = item.value;
800
- return value === undefined
801
- ? { title: item.title, value: '' }
802
- : typeof value === 'string'
803
- ? { title: item.title, value: value.trim() }
804
- : {
805
- title: item.title,
806
- value: this.pipeTransform(value),
807
- action: item.action,
808
- copyToClipboard: item.copyToClipboard,
809
- ltr: ltrValues.includes(value.type),
810
- english: 'english' in value && !!value.english,
811
- };
812
- });
818
+ this.data = this.componentService.getValueData(this.values);
813
819
  }
814
820
  onResize() {
815
821
  if (this.values.length === 0)
@@ -843,11 +849,11 @@ class NgxHelperValueBoxComponent {
843
849
  }, 2000);
844
850
  }
845
851
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueBoxComponent, deps: [{ token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
846
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueBoxComponent, isStandalone: true, selector: "ngx-helper-value-box", inputs: { values: "values", column: "column", clearBox: "clearBox", emptyText: "emptyText", gapSize: "gapSize", hideShadow: "hideShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className", "style.grid-template-columns": "this.gridTemplateColumns", "style.--gap-size": "this.boxGap" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
852
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueBoxComponent, isStandalone: true, selector: "ngx-helper-value-box", inputs: { values: "values", column: "column", clearBox: "clearBox", emptyText: "emptyText", gapSize: "gapSize", hideShadow: "hideShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className", "style.grid-template-columns": "this.gridTemplateColumns", "style.--gap-size": "this.boxGap" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
847
853
  }
848
854
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueBoxComponent, decorators: [{
849
855
  type: Component,
850
- args: [{ selector: 'ngx-helper-value-box', host: { '(window:resize)': 'onResize($event)' }, imports: [ClipboardModule, MatIcon, MatIconButton], providers: [ComponentService], template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
856
+ args: [{ selector: 'ngx-helper-value-box', host: { '(window:resize)': 'onResize($event)' }, imports: [ClipboardModule, MatIcon, MatIconButton], providers: [ComponentService], template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
851
857
  }], ctorParameters: () => [{ type: i1.Router }, { type: ComponentService }, { type: undefined, decorators: [{
852
858
  type: Optional
853
859
  }, {
@@ -884,6 +890,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
884
890
 
885
891
  class NgxHelperValueListComponent {
886
892
  router;
893
+ componentService;
887
894
  className = 'ngx-helper-m3-value-list';
888
895
  values;
889
896
  titleWidth = '20%';
@@ -891,26 +898,12 @@ class NgxHelperValueListComponent {
891
898
  data = [];
892
899
  copyIndex;
893
900
  copyTimeout;
894
- pipeTransform = new NgxHelperValuePipe().transform;
895
- constructor(router) {
901
+ constructor(router, componentService) {
896
902
  this.router = router;
903
+ this.componentService = componentService;
897
904
  }
898
905
  ngOnChanges(changes) {
899
- this.data = this.values.map((item) => {
900
- const value = item.value;
901
- return value === undefined
902
- ? { title: item.title, value: '' }
903
- : typeof value === 'string'
904
- ? { title: item.title, value: value.trim() }
905
- : {
906
- title: item.title,
907
- value: this.pipeTransform(value),
908
- action: item.action,
909
- copyToClipboard: item.copyToClipboard,
910
- ltr: ltrValues.includes(value.type),
911
- english: 'english' in value && !!value.english,
912
- };
913
- });
906
+ this.data = this.componentService.getValueData(this.values);
914
907
  }
915
908
  onClick(action) {
916
909
  if (!action)
@@ -929,13 +922,13 @@ class NgxHelperValueListComponent {
929
922
  this.copyTimeout = undefined;
930
923
  }, 2000);
931
924
  }
932
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueListComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
933
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueListComponent, isStandalone: true, selector: "ngx-helper-value-list", inputs: { values: "values", titleWidth: "titleWidth", emptyText: "emptyText" }, host: { properties: { "className": "this.className" } }, usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon>open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
925
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueListComponent, deps: [{ token: i1.Router }, { token: ComponentService }], target: i0.ɵɵFactoryTarget.Component });
926
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueListComponent, isStandalone: true, selector: "ngx-helper-value-list", inputs: { values: "values", titleWidth: "titleWidth", emptyText: "emptyText" }, host: { properties: { "className": "this.className" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon [style.color]=\"item.color\">open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
934
927
  }
935
928
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueListComponent, decorators: [{
936
929
  type: Component,
937
- args: [{ selector: 'ngx-helper-value-list', imports: [ClipboardModule, MatIcon, MatIconButton], template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon>open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
938
- }], ctorParameters: () => [{ type: i1.Router }], propDecorators: { className: [{
930
+ args: [{ selector: 'ngx-helper-value-list', imports: [ClipboardModule, MatIcon, MatIconButton], providers: [ComponentService], template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon [style.color]=\"item.color\">open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
931
+ }], ctorParameters: () => [{ type: i1.Router }, { type: ComponentService }], propDecorators: { className: [{
939
932
  type: HostBinding,
940
933
  args: ['className']
941
934
  }], values: [{
@@ -1283,6 +1276,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
1283
1276
  args: [{ providedIn: 'root' }]
1284
1277
  }], ctorParameters: () => [{ type: i1$3.MatBottomSheet }, { type: i2$1.MatDialog }] });
1285
1278
 
1279
+ class UploadComponent {
1280
+ httpClient;
1281
+ className = 'ngx-helper-m3-http';
1282
+ host = true;
1283
+ bottom = '1rem';
1284
+ id;
1285
+ file;
1286
+ url;
1287
+ config;
1288
+ close;
1289
+ progress = 0;
1290
+ constructor(httpClient) {
1291
+ this.httpClient = httpClient;
1292
+ }
1293
+ ngAfterViewInit() {
1294
+ setTimeout(this.upload.bind(this), 0);
1295
+ }
1296
+ upload() {
1297
+ const formData = new FormData();
1298
+ formData.append('file', this.file);
1299
+ const body = this.config.body || {};
1300
+ Object.keys(body).forEach((k) => formData.append(k, body[k]));
1301
+ let headers = new HttpHeaders();
1302
+ const header = this.config.header || {};
1303
+ Object.keys(header).forEach((key) => (headers = headers.set(key, header[key])));
1304
+ let request;
1305
+ switch (this.config.method || 'POST') {
1306
+ case 'POST':
1307
+ request = this.httpClient.post(this.url, formData, { headers, reportProgress: true, observe: 'events' });
1308
+ break;
1309
+ case 'PUT':
1310
+ request = this.httpClient.put(this.url, formData, { headers, reportProgress: true, observe: 'events' });
1311
+ break;
1312
+ case 'PATCH':
1313
+ request = this.httpClient.patch(this.url, formData, { headers, reportProgress: true, observe: 'events' });
1314
+ break;
1315
+ }
1316
+ request.subscribe({
1317
+ next: (event) => {
1318
+ switch (event.type) {
1319
+ case HttpEventType.UploadProgress:
1320
+ if (!event.loaded || !event.total)
1321
+ return;
1322
+ const progress = (event.loaded / event.total) * 100;
1323
+ this.progress = progress > 100 ? 100 : +progress.toFixed(2);
1324
+ break;
1325
+ case HttpEventType.Response:
1326
+ this.progress = 100;
1327
+ this.close('RESPONSE', event.body, event.status);
1328
+ break;
1329
+ }
1330
+ },
1331
+ error: (error) => this.close('ERROR', error.error, error.status),
1332
+ });
1333
+ }
1334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: UploadComponent, deps: [{ token: i1$4.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
1335
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: UploadComponent, isStandalone: true, selector: "ng-component", host: { attributes: { "selector": "upload" }, properties: { "className": "this.className", "@host": "this.host", "style.bottom": "this.bottom" } }, ngImport: i0, template: "<div class=\"content\">\n <mat-icon>file_upload</mat-icon>\n <div class=\"file\">{{ file.name }}</div>\n</div>\n\n<div class=\"progress-container\">\n <div class=\"progress-value\" [style.width]=\"progress + '%'\"></div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], animations: [
1336
+ trigger('host', [
1337
+ transition(':enter', [
1338
+ style({ left: 'calc(-250px - 1rem)' }),
1339
+ animate('100ms ease-in-out', style({ left: '1rem' })),
1340
+ ]),
1341
+ ]),
1342
+ ] });
1343
+ }
1344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: UploadComponent, decorators: [{
1345
+ type: Component,
1346
+ args: [{ host: { selector: 'upload' }, imports: [MatIcon], animations: [
1347
+ trigger('host', [
1348
+ transition(':enter', [
1349
+ style({ left: 'calc(-250px - 1rem)' }),
1350
+ animate('100ms ease-in-out', style({ left: '1rem' })),
1351
+ ]),
1352
+ ]),
1353
+ ], template: "<div class=\"content\">\n <mat-icon>file_upload</mat-icon>\n <div class=\"file\">{{ file.name }}</div>\n</div>\n\n<div class=\"progress-container\">\n <div class=\"progress-value\" [style.width]=\"progress + '%'\"></div>\n</div>\n" }]
1354
+ }], ctorParameters: () => [{ type: i1$4.HttpClient }], propDecorators: { className: [{
1355
+ type: HostBinding,
1356
+ args: ['className']
1357
+ }], host: [{
1358
+ type: HostBinding,
1359
+ args: ['@host']
1360
+ }], bottom: [{
1361
+ type: HostBinding,
1362
+ args: ['style.bottom']
1363
+ }] } });
1364
+
1365
+ class NgxHelperHttpService {
1366
+ applicationRef;
1367
+ injector;
1368
+ components = [];
1369
+ constructor(applicationRef, injector) {
1370
+ this.applicationRef = applicationRef;
1371
+ this.injector = injector;
1372
+ }
1373
+ getId() {
1374
+ let id = undefined;
1375
+ while (!id || this.components.some((c) => c.id === id))
1376
+ id = Helper.STRING.getRandom(10);
1377
+ return id;
1378
+ }
1379
+ updatePositions() {
1380
+ this.components.forEach((c, index) => {
1381
+ c.componentRef.instance.bottom = `calc(${(index / 1.5).toFixed(1)}rem + calc(${index * 40}px + 1rem))`;
1382
+ });
1383
+ }
1384
+ upload(file, url, arg1, arg2, arg3) {
1385
+ const config = typeof arg3 === 'function' ? arg1 : {};
1386
+ const onSuccess = typeof arg3 === 'function' ? arg2 : arg1;
1387
+ const onError = typeof arg3 === 'function' ? arg3 : arg2;
1388
+ const componentRef = createComponent(UploadComponent, {
1389
+ environmentInjector: this.applicationRef.injector,
1390
+ elementInjector: this.injector,
1391
+ });
1392
+ const id = this.getId();
1393
+ componentRef.instance.id = id;
1394
+ componentRef.instance.file = file;
1395
+ componentRef.instance.url = url;
1396
+ componentRef.instance.config = config;
1397
+ componentRef.instance.close = (type, result, status) => {
1398
+ this.applicationRef.detachView(componentRef.hostView);
1399
+ document.body.removeChild(htmlElement);
1400
+ this.components = this.components.filter((c) => c.id !== componentRef.instance.id);
1401
+ this.updatePositions();
1402
+ switch (type) {
1403
+ case 'RESPONSE':
1404
+ onSuccess(result || undefined, status);
1405
+ break;
1406
+ case 'ERROR':
1407
+ onError(result || undefined, status);
1408
+ break;
1409
+ }
1410
+ };
1411
+ const htmlElement = componentRef.hostView.rootNodes[0];
1412
+ this.applicationRef.attachView(componentRef.hostView);
1413
+ document.body.appendChild(htmlElement);
1414
+ this.components.push({ id, componentRef });
1415
+ this.updatePositions();
1416
+ }
1417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperHttpService, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
1418
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperHttpService, providedIn: 'root' });
1419
+ }
1420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperHttpService, decorators: [{
1421
+ type: Injectable,
1422
+ args: [{ providedIn: 'root' }]
1423
+ }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.Injector }] });
1424
+
1286
1425
  /*
1287
1426
  * Public API Surface of ngx-helper-m3
1288
1427
  */
@@ -1291,5 +1430,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
1291
1430
  * Generated bundle index. Do not edit.
1292
1431
  */
1293
1432
 
1294
- export { NGX_HELPER_BOX_DATA, NGX_HELPER_CONFIG, NGX_HELPER_CONTAINER_CLOSE, NGX_HELPER_CONTAINER_DATA, NGX_HELPER_CONTAINER_TYPE, NGX_HELPER_PAGE_GROUP_DATA, NGX_HELPER_PAGE_GROUP_DATA_CHANGE, NGX_HELPER_PAGE_GROUP_ITEM, NgxHelperBankCardPipe, NgxHelperBoxComponent, NgxHelperCardComponent, NgxHelperConfirmService, NgxHelperContainerService, NgxHelperDatePipe, NgxHelperDurationPipe, NgxHelperFileSizePipe, NgxHelperLoaderComponent, NgxHelperMobilePipe, NgxHelperMultiLinePipe, NgxHelperNumberPipe, NgxHelperPageGroupComponent, NgxHelperPeriodPipe, NgxHelperPricePipe, NgxHelperSafePipe, NgxHelperSectionColumnComponent, NgxHelperSectionComponent, NgxHelperSectionStickyDirective, NgxHelperValueBoxComponent, NgxHelperValueListComponent, NgxHelperValuePipe, NgxHelperVolumePipe, NgxHelperWeightPipe, provideNgxHelperConfig };
1433
+ export { NGX_HELPER_BOX_DATA, NGX_HELPER_CONFIG, NGX_HELPER_CONTAINER_CLOSE, NGX_HELPER_CONTAINER_DATA, NGX_HELPER_CONTAINER_TYPE, NGX_HELPER_PAGE_GROUP_DATA, NGX_HELPER_PAGE_GROUP_DATA_CHANGE, NGX_HELPER_PAGE_GROUP_ITEM, NgxHelperBankCardPipe, NgxHelperBoxComponent, NgxHelperCardComponent, NgxHelperConfirmService, NgxHelperContainerService, NgxHelperDatePipe, NgxHelperDurationPipe, NgxHelperFileSizePipe, NgxHelperHttpService, NgxHelperLoaderComponent, NgxHelperMobilePipe, NgxHelperMultiLinePipe, NgxHelperNumberPipe, NgxHelperPageGroupComponent, NgxHelperPeriodPipe, NgxHelperPricePipe, NgxHelperSafePipe, NgxHelperSectionColumnComponent, NgxHelperSectionComponent, NgxHelperSectionStickyDirective, NgxHelperValueBoxComponent, NgxHelperValueListComponent, NgxHelperValuePipe, NgxHelperVolumePipe, NgxHelperWeightPipe, provideNgxHelperConfig };
1295
1434
  //# sourceMappingURL=webilix-ngx-helper-m3.mjs.map