@webilix/ngx-form-m3 0.0.23 → 0.0.25

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.
@@ -11,13 +11,13 @@ import * as i2$1 from '@angular/material/input';
11
11
  import { MatInputModule } from '@angular/material/input';
12
12
  import { Helper } from '@webilix/helper-library';
13
13
  import * as i1$1 from '@angular/platform-browser';
14
+ import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
15
+ import { JalaliDateTime } from '@webilix/jalali-date-time';
14
16
  import { NgComponentOutlet, NgClass, DecimalPipe } from '@angular/common';
15
17
  import * as i1$2 from '@webilix/ngx-helper-m3';
16
18
  import { NgxHelperDatePipe, NgxHelperFileSizePipe } from '@webilix/ngx-helper-m3';
17
19
  import * as i1$3 from '@webilix/ngx-calendar-m3';
18
- import { JalaliDateTime } from '@webilix/jalali-date-time';
19
20
  import * as i3 from '@angular/cdk/bidi';
20
- import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
21
21
  import * as i3$1 from '@angular/material/menu';
22
22
  import { MatMenuModule } from '@angular/material/menu';
23
23
  import * as i3$2 from '@angular/material/select';
@@ -196,6 +196,10 @@ class InputErrorPipe {
196
196
  return `انتخاب حداقل ${Helper.NUMBER.format(value)} گزینه الزامی است.`;
197
197
  case 'maxcount':
198
198
  return `امکان انتخاب بیشتر از ${Helper.NUMBER.format(value)} گزینه وجود ندارد.`;
199
+ case 'bank-card':
200
+ return `شماره کارت بانکی صحیح مشخص نشده است.`;
201
+ case 'bank-sheba':
202
+ return `شماره شبا صحیح مشخص نشده است.`;
199
203
  case 'pattern':
200
204
  switch (type) {
201
205
  case 'EMAIL':
@@ -216,6 +220,10 @@ class InputErrorPipe {
216
220
  break;
217
221
  case 'mask':
218
222
  switch (type) {
223
+ case 'BANK-CARD':
224
+ return 'شماره کارت بانکی دارای ۱۶ رقم است.';
225
+ case 'BANK-SHEBA':
226
+ return 'شماره شبا دارای ۲۴ رقم است.';
219
227
  case 'MOBILE':
220
228
  return 'شماره موبایل دارای ۱۱ رقم است.';
221
229
  }
@@ -310,6 +318,220 @@ class InputAutoCompleteMethods extends InputMethods {
310
318
  }
311
319
  }
312
320
 
321
+ class InputBankCardComponent {
322
+ formControl = inject(INPUT_CONTROL);
323
+ input = inject(INPUT_TYPE);
324
+ config = inject(INPUT_CONFIG);
325
+ values;
326
+ isButtonDisabled;
327
+ bank = '';
328
+ inputTransformFn = (value) => Helper.STRING.changeNumbers(value.toString(), 'EN');
329
+ ngOnInit() {
330
+ this.setBank(this.input.value || '');
331
+ }
332
+ setBank(card) {
333
+ card = card.replace(/-/g, '').substring(0, 6);
334
+ const bank = Helper.BANK.findCard(card);
335
+ this.bank = bank?.title || '';
336
+ }
337
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: InputBankCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
338
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: InputBankCardComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-bank-card" } }, providers: [provideNgxMask()], ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\">\n <mat-label>{{ input.title || '\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0628\u0627\u0646\u06A9\u06CC' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <div class=\"ngx-helper-form-m3-bank-card-input\">\n <!-- BANK NAME -->\n @if (!input.hideBank && bank !== '') {\n <div class=\"bank\">{{ bank }}</div>\n }\n\n <input\n matInput\n type=\"text\"\n inputmode=\"numeric\"\n [name]=\"input.name\"\n [formControl]=\"formControl\"\n class=\"ngx-form-m3-en\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [mask]=\"'0000-0000-0000-0000'\"\n [inputTransformFn]=\"inputTransformFn\"\n (input)=\"setBank(bankCardInput.value)\"\n #bankCardInput\n />\n </div>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { 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"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: NgxMaskDirective, selector: "input[mask], textarea[mask]", inputs: ["mask", "specialCharacters", "patterns", "prefix", "suffix", "thousandSeparator", "decimalMarker", "dropSpecialCharacters", "hiddenInput", "showMaskTyped", "placeHolderCharacter", "shownMaskExpression", "clearIfNotMatch", "validation", "separatorLimit", "allowNegativeNumbers", "leadZeroDateTime", "leadZero", "triggerOnMaskChange", "apm", "inputTransformFn", "outputTransformFn", "keepCharacterPositions", "instantPrefix"], outputs: ["maskFilled"], exportAs: ["mask", "ngxMask"] }, { kind: "directive", type: AutoCompleteDirective, selector: "input[type=\"text\"]" }, { kind: "directive", type: AutoFocusDirective, selector: "[AutoFocusDirective]", inputs: ["AutoFocusDirective"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
339
+ }
340
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: InputBankCardComponent, decorators: [{
341
+ type: Component,
342
+ args: [{ host: { selector: 'input-bank-card' }, imports: [
343
+ ReactiveFormsModule,
344
+ MatFormField,
345
+ MatIcon,
346
+ MatIconButton,
347
+ MatInputModule,
348
+ NgxMaskDirective,
349
+ AutoCompleteDirective,
350
+ AutoFocusDirective,
351
+ InputErrorPipe,
352
+ MultiLinePipe,
353
+ ], providers: [provideNgxMask()], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\">\n <mat-label>{{ input.title || '\u0634\u0645\u0627\u0631\u0647 \u06A9\u0627\u0631\u062A \u0628\u0627\u0646\u06A9\u06CC' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <div class=\"ngx-helper-form-m3-bank-card-input\">\n <!-- BANK NAME -->\n @if (!input.hideBank && bank !== '') {\n <div class=\"bank\">{{ bank }}</div>\n }\n\n <input\n matInput\n type=\"text\"\n inputmode=\"numeric\"\n [name]=\"input.name\"\n [formControl]=\"formControl\"\n class=\"ngx-form-m3-en\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [mask]=\"'0000-0000-0000-0000'\"\n [inputTransformFn]=\"inputTransformFn\"\n (input)=\"setBank(bankCardInput.value)\"\n #bankCardInput\n />\n </div>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n" }]
354
+ }], propDecorators: { values: [{
355
+ type: Input,
356
+ args: [{ required: true }]
357
+ }], isButtonDisabled: [{
358
+ type: Input,
359
+ args: [{ required: true }]
360
+ }] } });
361
+
362
+ const BankCardValidator = () => {
363
+ return (formControl) => {
364
+ const value = formControl.value;
365
+ if (Helper.IS.empty(value) || !Helper.IS.string(value) || value.length !== 16)
366
+ return null;
367
+ return !Helper.IS.STRING.bankCard(value) ? { 'bank-card': true } : null;
368
+ };
369
+ };
370
+
371
+ const BankShebaValidator = () => {
372
+ return (formControl) => {
373
+ const value = formControl.value;
374
+ if (Helper.IS.empty(value) || !Helper.IS.string(value) || value.length !== 24)
375
+ return null;
376
+ return !Helper.IS.STRING.bankSheba(`IR${value}`) ? { 'bank-sheba': true } : null;
377
+ };
378
+ };
379
+
380
+ const MaxCountValidator = (max) => {
381
+ return (formControl) => {
382
+ const value = Array.isArray(formControl.value) ? formControl.value : [];
383
+ return value.length > max ? { maxcount: max } : null;
384
+ };
385
+ };
386
+
387
+ const MinCountValidator = (min) => {
388
+ return (formControl) => {
389
+ const value = Array.isArray(formControl.value) ? formControl.value : [];
390
+ return value.length === 0 ? { required: true } : value.length < min ? { mincount: min } : null;
391
+ };
392
+ };
393
+
394
+ const MaxDateValidator = (max) => {
395
+ const jalali = JalaliDateTime();
396
+ return (formControl) => {
397
+ const value = formControl.value;
398
+ if (Helper.IS.empty(value) || !Helper.IS.date(value))
399
+ return null;
400
+ const maximum = jalali.periodDay(1, max === 'NOW' ? new Date() : max).to;
401
+ return value.getTime() > maximum.getTime() ? { maxdate: jalali.toFullText(maximum, { format: 'Y/M/D' }) } : null;
402
+ };
403
+ };
404
+
405
+ const MinDateValidator = (min) => {
406
+ const jalali = JalaliDateTime();
407
+ return (formControl) => {
408
+ const value = formControl.value;
409
+ if (Helper.IS.empty(value) || !Helper.IS.date(value))
410
+ return null;
411
+ const minimum = jalali.periodDay(1, min === 'NOW' ? new Date() : min).from;
412
+ return value.getTime() < minimum.getTime() ? { mindate: jalali.toFullText(minimum, { format: 'Y/M/D' }) } : null;
413
+ };
414
+ };
415
+
416
+ const MaxMomentValidator = (max) => {
417
+ const jalali = JalaliDateTime();
418
+ const formatDate = (date) => jalali.toString(date, { format: 'Y-M-D H:I' });
419
+ return (formControl) => {
420
+ const value = formControl.value;
421
+ if (Helper.IS.empty(value) || !Helper.IS.date(value))
422
+ return null;
423
+ const maximum = max === 'NOW' ? new Date() : max;
424
+ return formatDate(value) > formatDate(maximum)
425
+ ? { maxmoment: jalali.toFullText(maximum, { format: 'H:I Y/M/D' }) }
426
+ : null;
427
+ };
428
+ };
429
+
430
+ const MinMomentValidator = (min) => {
431
+ const jalali = JalaliDateTime();
432
+ const formatDate = (date) => jalali.toString(date, { format: 'Y-M-D H:I' });
433
+ return (formControl) => {
434
+ const value = formControl.value;
435
+ if (Helper.IS.empty(value) || !Helper.IS.date(value))
436
+ return null;
437
+ const minimum = min === 'NOW' ? new Date() : min;
438
+ return formatDate(value) < formatDate(minimum)
439
+ ? { minmoment: jalali.toFullText(minimum, { format: 'H:I Y/M/D' }) }
440
+ : null;
441
+ };
442
+ };
443
+
444
+ const MaxNumberValidator = (maximum) => {
445
+ return (formControl) => {
446
+ const value = Helper.IS.string(formControl.value) ? +formControl.value.replace(/,/g, '') : formControl.value;
447
+ if (Helper.IS.empty(value) || !Helper.IS.number(value))
448
+ return null;
449
+ return value <= maximum ? null : { maximum };
450
+ };
451
+ };
452
+
453
+ const MinNumberValidator = (minimum) => {
454
+ return (formControl) => {
455
+ const value = Helper.IS.string(formControl.value) ? +formControl.value.replace(/,/g, '') : formControl.value;
456
+ if (Helper.IS.empty(value) || !Helper.IS.number(value))
457
+ return null;
458
+ return value >= minimum ? null : { minimum };
459
+ };
460
+ };
461
+
462
+ const MultiplyOfNumberValidator = (multiplyOf) => {
463
+ return (formControl) => {
464
+ const value = Helper.IS.string(formControl.value) ? +formControl.value.replace(/,/g, '') : formControl.value;
465
+ if (Helper.IS.empty(value) || !Helper.IS.number(value))
466
+ return null;
467
+ return value % multiplyOf === 0 ? null : { multiplyOf };
468
+ };
469
+ };
470
+
471
+ const LengthValidator = (length) => {
472
+ return (formControl) => {
473
+ const value = formControl.value;
474
+ if (Helper.IS.empty(value) || !Helper.IS.string(value))
475
+ return null;
476
+ return value.length !== length ? { length } : null;
477
+ };
478
+ };
479
+
480
+ class InputBankCardMethods extends InputMethods {
481
+ control(input, validators) {
482
+ validators.push(BankCardValidator());
483
+ const value = input.value && Helper.IS.STRING.bankCard(input.value) ? input.value : null;
484
+ return new FormControl(value, validators);
485
+ }
486
+ value(value, input) {
487
+ return Helper.IS.STRING.bankCard(value) ? value : null;
488
+ }
489
+ }
490
+
491
+ class InputBankShebaComponent {
492
+ formControl = inject(INPUT_CONTROL);
493
+ input = inject(INPUT_TYPE);
494
+ config = inject(INPUT_CONFIG);
495
+ values;
496
+ isButtonDisabled;
497
+ bank = '';
498
+ inputTransformFn = (value) => Helper.STRING.changeNumbers(value.toString(), 'EN');
499
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: InputBankShebaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
500
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: InputBankShebaComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-bank-sheba" } }, providers: [provideNgxMask()], ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\">\n <mat-label>{{ input.title || '\u0634\u0645\u0627\u0631\u0647 \u0634\u0628\u0627' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span class=\"ngx-form-m3-en\">IR</span>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <input\n matInput\n type=\"text\"\n inputmode=\"numeric\"\n [name]=\"input.name\"\n [formControl]=\"formControl\"\n class=\"ngx-form-m3-en\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [mask]=\"'000000000000000000000000'\"\n [inputTransformFn]=\"inputTransformFn\"\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { 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"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: NgxMaskDirective, selector: "input[mask], textarea[mask]", inputs: ["mask", "specialCharacters", "patterns", "prefix", "suffix", "thousandSeparator", "decimalMarker", "dropSpecialCharacters", "hiddenInput", "showMaskTyped", "placeHolderCharacter", "shownMaskExpression", "clearIfNotMatch", "validation", "separatorLimit", "allowNegativeNumbers", "leadZeroDateTime", "leadZero", "triggerOnMaskChange", "apm", "inputTransformFn", "outputTransformFn", "keepCharacterPositions", "instantPrefix"], outputs: ["maskFilled"], exportAs: ["mask", "ngxMask"] }, { kind: "directive", type: AutoCompleteDirective, selector: "input[type=\"text\"]" }, { kind: "directive", type: AutoFocusDirective, selector: "[AutoFocusDirective]", inputs: ["AutoFocusDirective"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
501
+ }
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: InputBankShebaComponent, decorators: [{
503
+ type: Component,
504
+ args: [{ host: { selector: 'input-bank-sheba' }, imports: [
505
+ ReactiveFormsModule,
506
+ MatFormField,
507
+ MatIcon,
508
+ MatIconButton,
509
+ MatInputModule,
510
+ NgxMaskDirective,
511
+ AutoCompleteDirective,
512
+ AutoFocusDirective,
513
+ InputErrorPipe,
514
+ MultiLinePipe,
515
+ ], providers: [provideNgxMask()], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\">\n <mat-label>{{ input.title || '\u0634\u0645\u0627\u0631\u0647 \u0634\u0628\u0627' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- SUFFIX -->\n <span matTextSuffix class=\"ngx-form-m3-input-suffix\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span class=\"ngx-form-m3-en\">IR</span>\n </span>\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <input\n matInput\n type=\"text\"\n inputmode=\"numeric\"\n [name]=\"input.name\"\n [formControl]=\"formControl\"\n class=\"ngx-form-m3-en\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [mask]=\"'000000000000000000000000'\"\n [inputTransformFn]=\"inputTransformFn\"\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n" }]
516
+ }], propDecorators: { values: [{
517
+ type: Input,
518
+ args: [{ required: true }]
519
+ }], isButtonDisabled: [{
520
+ type: Input,
521
+ args: [{ required: true }]
522
+ }] } });
523
+
524
+ class InputBankShebaMethods extends InputMethods {
525
+ control(input, validators) {
526
+ validators.push(BankShebaValidator());
527
+ const value = input.value && Helper.IS.STRING.bankSheba(input.value) ? input.value.substring(2) : null;
528
+ return new FormControl(value, validators);
529
+ }
530
+ value(value, input) {
531
+ return Helper.IS.STRING.bankSheba(`IR${value}`) ? `IR${value}` : null;
532
+ }
533
+ }
534
+
313
535
  class InputCheckboxComponent {
314
536
  formControl = inject(INPUT_CONTROL);
315
537
  input = inject(INPUT_TYPE);
@@ -528,106 +750,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
528
750
  args: [{ required: true }]
529
751
  }] } });
530
752
 
531
- const MaxCountValidator = (max) => {
532
- return (formControl) => {
533
- const value = Array.isArray(formControl.value) ? formControl.value : [];
534
- return value.length > max ? { maxcount: max } : null;
535
- };
536
- };
537
-
538
- const MinCountValidator = (min) => {
539
- return (formControl) => {
540
- const value = Array.isArray(formControl.value) ? formControl.value : [];
541
- return value.length === 0 ? { required: true } : value.length < min ? { mincount: min } : null;
542
- };
543
- };
544
-
545
- const MaxDateValidator = (max) => {
546
- const jalali = JalaliDateTime();
547
- return (formControl) => {
548
- const value = formControl.value;
549
- if (Helper.IS.empty(value) || !Helper.IS.date(value))
550
- return null;
551
- const maximum = jalali.periodDay(1, max === 'NOW' ? new Date() : max).to;
552
- return value.getTime() > maximum.getTime() ? { maxdate: jalali.toFullText(maximum, { format: 'Y/M/D' }) } : null;
553
- };
554
- };
555
-
556
- const MinDateValidator = (min) => {
557
- const jalali = JalaliDateTime();
558
- return (formControl) => {
559
- const value = formControl.value;
560
- if (Helper.IS.empty(value) || !Helper.IS.date(value))
561
- return null;
562
- const minimum = jalali.periodDay(1, min === 'NOW' ? new Date() : min).from;
563
- return value.getTime() < minimum.getTime() ? { mindate: jalali.toFullText(minimum, { format: 'Y/M/D' }) } : null;
564
- };
565
- };
566
-
567
- const MaxMomentValidator = (max) => {
568
- const jalali = JalaliDateTime();
569
- const formatDate = (date) => jalali.toString(date, { format: 'Y-M-D H:I' });
570
- return (formControl) => {
571
- const value = formControl.value;
572
- if (Helper.IS.empty(value) || !Helper.IS.date(value))
573
- return null;
574
- const maximum = max === 'NOW' ? new Date() : max;
575
- return formatDate(value) > formatDate(maximum)
576
- ? { maxmoment: jalali.toFullText(maximum, { format: 'H:I Y/M/D' }) }
577
- : null;
578
- };
579
- };
580
-
581
- const MinMomentValidator = (min) => {
582
- const jalali = JalaliDateTime();
583
- const formatDate = (date) => jalali.toString(date, { format: 'Y-M-D H:I' });
584
- return (formControl) => {
585
- const value = formControl.value;
586
- if (Helper.IS.empty(value) || !Helper.IS.date(value))
587
- return null;
588
- const minimum = min === 'NOW' ? new Date() : min;
589
- return formatDate(value) < formatDate(minimum)
590
- ? { minmoment: jalali.toFullText(minimum, { format: 'H:I Y/M/D' }) }
591
- : null;
592
- };
593
- };
594
-
595
- const MaxNumberValidator = (maximum) => {
596
- return (formControl) => {
597
- const value = Helper.IS.string(formControl.value) ? +formControl.value.replace(/,/g, '') : formControl.value;
598
- if (Helper.IS.empty(value) || !Helper.IS.number(value))
599
- return null;
600
- return value <= maximum ? null : { maximum };
601
- };
602
- };
603
-
604
- const MinNumberValidator = (minimum) => {
605
- return (formControl) => {
606
- const value = Helper.IS.string(formControl.value) ? +formControl.value.replace(/,/g, '') : formControl.value;
607
- if (Helper.IS.empty(value) || !Helper.IS.number(value))
608
- return null;
609
- return value >= minimum ? null : { minimum };
610
- };
611
- };
612
-
613
- const MultiplyOfNumberValidator = (multiplyOf) => {
614
- return (formControl) => {
615
- const value = Helper.IS.string(formControl.value) ? +formControl.value.replace(/,/g, '') : formControl.value;
616
- if (Helper.IS.empty(value) || !Helper.IS.number(value))
617
- return null;
618
- return value % multiplyOf === 0 ? null : { multiplyOf };
619
- };
620
- };
621
-
622
- const LengthValidator = (length) => {
623
- return (formControl) => {
624
- const value = formControl.value;
625
- if (Helper.IS.empty(value) || !Helper.IS.string(value))
626
- return null;
627
- return value.length !== length ? { length } : null;
628
- };
629
- };
630
-
631
753
  class InputDateMethods extends InputMethods {
632
754
  control(input, validators) {
633
755
  if (input.minDate)
@@ -1166,6 +1288,75 @@ class InputPasswordMethods extends InputMethods {
1166
1288
  }
1167
1289
  }
1168
1290
 
1291
+ class InputPriceComponent {
1292
+ formControl = inject(INPUT_CONTROL);
1293
+ input = inject(INPUT_TYPE);
1294
+ config = inject(INPUT_CONFIG);
1295
+ values;
1296
+ isButtonDisabled;
1297
+ maxLength = 15;
1298
+ hintText;
1299
+ isFocused = false;
1300
+ inputTransformFn = (value) => Helper.STRING.changeNumbers(value.toString(), 'EN');
1301
+ ngOnInit() {
1302
+ if (!this.input.fractionDigits && this.input.maximum)
1303
+ this.maxLength = Helper.NUMBER.format(this.input.maximum, 'EN').length;
1304
+ this.updateHint();
1305
+ }
1306
+ setValue(input) {
1307
+ const value = input.length === 0 ? null : +input.replace(/,/gi, '');
1308
+ this.formControl.setValue(Helper.IS.number(value) ? value : null);
1309
+ this.formControl.markAllAsTouched();
1310
+ }
1311
+ updateHint() {
1312
+ const value = this.formControl.value;
1313
+ this.hintText =
1314
+ this.input.hideText || !Helper.IS.number(value)
1315
+ ? undefined
1316
+ : Helper.NUMBER.getTitle(Math.abs(value)) + (this.input.currency ? ` ${this.input.currency}` : '');
1317
+ }
1318
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: InputPriceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1319
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: InputPriceComponent, isStandalone: true, selector: "ng-component", inputs: { values: "values", isButtonDisabled: "isButtonDisabled" }, host: { attributes: { "selector": "input-price" } }, providers: [provideNgxMask()], ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\">\n <mat-label>{{ input.title || '\u0642\u06CC\u0645\u062A' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint|| (isFocused && hintText)) { <mat-hint>{{ isFocused && hintText ? hintText : input.hint }}</mat-hint> }\n\n <!-- CURRENCY -->\n @if (input.currency) {\n <span matTextSuffix class=\"ngx-form-m3-input-suffix\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>{{ input.currency }}</span>\n </span>\n }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <input\n matInput\n type=\"text\"\n inputmode=\"numeric\"\n class=\"ngx-form-m3-en\"\n [ngModel]=\"formControl.value?.toString() || ''\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [mask]=\"\n input.fractionDigits === true\n ? 'separator.3'\n : !!input.fractionDigits && input.fractionDigits > 0\n ? 'separator.' + input.fractionDigits.toString()\n : 'separator.0'\n \"\n thousandSeparator=\",\"\n decimalMarker=\".\"\n [allowNegativeNumbers]=\"false\"\n [inputTransformFn]=\"inputTransformFn\"\n [maxlength]=\"maxLength\"\n (input)=\"setValue(numberInput.value); updateHint()\"\n [disabled]=\"formControl.disabled\"\n (focus)=\"isFocused = true; updateHint()\"\n (blur)=\"isFocused = false\"\n #numberInput\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [".ngx-form-m3-input-suffix{padding-right:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { 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"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: NgxMaskDirective, selector: "input[mask], textarea[mask]", inputs: ["mask", "specialCharacters", "patterns", "prefix", "suffix", "thousandSeparator", "decimalMarker", "dropSpecialCharacters", "hiddenInput", "showMaskTyped", "placeHolderCharacter", "shownMaskExpression", "clearIfNotMatch", "validation", "separatorLimit", "allowNegativeNumbers", "leadZeroDateTime", "leadZero", "triggerOnMaskChange", "apm", "inputTransformFn", "outputTransformFn", "keepCharacterPositions", "instantPrefix"], outputs: ["maskFilled"], exportAs: ["mask", "ngxMask"] }, { kind: "directive", type: AutoCompleteDirective, selector: "input[type=\"text\"]" }, { kind: "directive", type: AutoFocusDirective, selector: "[AutoFocusDirective]", inputs: ["AutoFocusDirective"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
1320
+ }
1321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: InputPriceComponent, decorators: [{
1322
+ type: Component,
1323
+ args: [{ host: { selector: 'input-price' }, imports: [
1324
+ FormsModule,
1325
+ ReactiveFormsModule,
1326
+ MatFormField,
1327
+ MatIcon,
1328
+ MatIconButton,
1329
+ MatInputModule,
1330
+ NgxMaskDirective,
1331
+ AutoCompleteDirective,
1332
+ AutoFocusDirective,
1333
+ InputErrorPipe,
1334
+ MultiLinePipe,
1335
+ ], providers: [provideNgxMask()], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\">\n <mat-label>{{ input.title || '\u0642\u06CC\u0645\u062A' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint|| (isFocused && hintText)) { <mat-hint>{{ isFocused && hintText ? hintText : input.hint }}</mat-hint> }\n\n <!-- CURRENCY -->\n @if (input.currency) {\n <span matTextSuffix class=\"ngx-form-m3-input-suffix\" [class.ngx-form-m3-disabled-input]=\"formControl.disabled\">\n <span>{{ input.currency }}</span>\n </span>\n }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <!-- INPUT -->\n <input matInput type=\"text\" [name]=\"input.name\" [formControl]=\"formControl\" [style.display]=\"'none !important'\" />\n <input\n matInput\n type=\"text\"\n inputmode=\"numeric\"\n class=\"ngx-form-m3-en\"\n [ngModel]=\"formControl.value?.toString() || ''\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [mask]=\"\n input.fractionDigits === true\n ? 'separator.3'\n : !!input.fractionDigits && input.fractionDigits > 0\n ? 'separator.' + input.fractionDigits.toString()\n : 'separator.0'\n \"\n thousandSeparator=\",\"\n decimalMarker=\".\"\n [allowNegativeNumbers]=\"false\"\n [inputTransformFn]=\"inputTransformFn\"\n [maxlength]=\"maxLength\"\n (input)=\"setValue(numberInput.value); updateHint()\"\n [disabled]=\"formControl.disabled\"\n (focus)=\"isFocused = true; updateHint()\"\n (blur)=\"isFocused = false\"\n #numberInput\n />\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [".ngx-form-m3-input-suffix{padding-right:.5rem}\n"] }]
1336
+ }], propDecorators: { values: [{
1337
+ type: Input,
1338
+ args: [{ required: true }]
1339
+ }], isButtonDisabled: [{
1340
+ type: Input,
1341
+ args: [{ required: true }]
1342
+ }] } });
1343
+
1344
+ class InputPriceMethods extends InputMethods {
1345
+ control(input, validators) {
1346
+ if (input.minimum)
1347
+ validators.push(MinNumberValidator(input.minimum));
1348
+ if (input.maximum)
1349
+ validators.push(MaxNumberValidator(input.maximum));
1350
+ if (input.multiplyOf)
1351
+ validators.push(MultiplyOfNumberValidator(input.multiplyOf));
1352
+ const value = input.value !== undefined && Helper.IS.number(input.value) ? input.value : null;
1353
+ return new FormControl(value, validators);
1354
+ }
1355
+ value(value, input) {
1356
+ return Helper.IS.number(value) ? value : null;
1357
+ }
1358
+ }
1359
+
1169
1360
  class InputSelectComponent {
1170
1361
  formControl = inject(INPUT_CONTROL);
1171
1362
  input = inject(INPUT_TYPE);
@@ -1401,6 +1592,8 @@ const InputInfo = {
1401
1592
  methods: new InputAutoCompleteMethods(),
1402
1593
  component: InputAutoCompleteComponent,
1403
1594
  },
1595
+ 'BANK-CARD': { title: 'شماره کارت بانکی', methods: new InputBankCardMethods(), component: InputBankCardComponent },
1596
+ 'BANK-SHEBA': { title: 'شماره شبا', methods: new InputBankShebaMethods(), component: InputBankShebaComponent },
1404
1597
  CHECKBOX: { title: 'یک انتخابی', methods: new InputCheckboxMethods(), component: InputCheckboxComponent },
1405
1598
  COLOR: { title: 'رنگ', methods: new InputColorMethods(), component: InputColorComponent },
1406
1599
  COMPONENT: { title: 'کامپوننت', methods: new InputComponentMethods(), component: InputComponentComponent },
@@ -1416,6 +1609,7 @@ const InputInfo = {
1416
1609
  NAME: { title: 'نام و نام خانوادگی', methods: new InputNameMethods(), component: InputNameComponent },
1417
1610
  NUMBER: { title: 'مقدار عددی', methods: new InputNumberMethods(), component: InputNumberComponent },
1418
1611
  PASSWORD: { title: 'کلمه عبور', methods: new InputPasswordMethods(), component: InputPasswordComponent },
1612
+ PRICE: { title: 'قیمت', methods: new InputPriceMethods(), component: InputPriceComponent },
1419
1613
  SELECT: { title: 'لیست کشویی', methods: new InputSelectMethods(), component: InputSelectComponent },
1420
1614
  TEXT: { title: 'متن یک خطی', methods: new InputTextMethods(), component: InputTextComponent },
1421
1615
  TEXTAREA: { title: 'متن چند خطی', methods: new InputTextareaMethods(), component: InputTextareaComponent },