matcha-components 20.90.0 → 20.91.0

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.
@@ -2277,13 +2277,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImpor
2277
2277
  }] } });
2278
2278
 
2279
2279
  class MatchaLabelComponent {
2280
- constructor(elementRef) {
2280
+ constructor(elementRef, cdr) {
2281
2281
  this.elementRef = elementRef;
2282
+ this.cdr = cdr;
2282
2283
  this.color = 'blue-grey';
2283
2284
  this.isRequired = false;
2284
2285
  }
2285
2286
  ngAfterViewInit() {
2286
- this.checkIfRequired();
2287
+ // Usar setTimeout para evitar ExpressionChangedAfterItHasBeenCheckedError
2288
+ setTimeout(() => {
2289
+ this.checkIfRequired();
2290
+ this.cdr.detectChanges();
2291
+ });
2287
2292
  }
2288
2293
  checkIfRequired() {
2289
2294
  // Busca o form-field pai
@@ -2295,13 +2300,13 @@ class MatchaLabelComponent {
2295
2300
  this.isRequired = !!inputElement;
2296
2301
  }
2297
2302
  }
2298
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: MatchaLabelComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
2303
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: MatchaLabelComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2299
2304
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.0", type: MatchaLabelComponent, isStandalone: false, selector: "matcha-label", inputs: { color: "color" }, ngImport: i0, template: "<label\n class=\"d-flex d-flex-align-center position-relative text-nowrap px-4 fs-12 lh-18 fw-700 color-{{color}}\"\n style=\"transform: translateY(-8px);\">\n <ng-content></ng-content>\n <span *ngIf=\"isRequired\">&nbsp;*</span>\n <!-- <span class=\"pl-4 fs-10 fw-400 lh-16 matcha-color-placeholder\">(Opcional)</span> -->\n</label>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
2300
2305
  }
2301
2306
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: MatchaLabelComponent, decorators: [{
2302
2307
  type: Component,
2303
2308
  args: [{ selector: 'matcha-label', standalone: false, template: "<label\n class=\"d-flex d-flex-align-center position-relative text-nowrap px-4 fs-12 lh-18 fw-700 color-{{color}}\"\n style=\"transform: translateY(-8px);\">\n <ng-content></ng-content>\n <span *ngIf=\"isRequired\">&nbsp;*</span>\n <!-- <span class=\"pl-4 fs-10 fw-400 lh-16 matcha-color-placeholder\">(Opcional)</span> -->\n</label>\n" }]
2304
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { color: [{
2309
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { color: [{
2305
2310
  type: Input
2306
2311
  }] } });
2307
2312
 
@@ -4822,6 +4827,7 @@ const initialConfig = {
4822
4827
  leadZero: false,
4823
4828
  keepCharacterPositions: false,
4824
4829
  triggerOnMaskChange: false,
4830
+ currencyMode: false,
4825
4831
  inputTransformFn: (value) => value,
4826
4832
  outputTransformFn: (value) => value,
4827
4833
  maskFilled: new EventEmitter(),
@@ -4911,6 +4917,7 @@ class MatchaMaskApplierService {
4911
4917
  this.keepCharacterPositions = this._config.keepCharacterPositions;
4912
4918
  this.instantPrefix = this._config.instantPrefix;
4913
4919
  this.triggerOnMaskChange = this._config.triggerOnMaskChange;
4920
+ this.currencyMode = this._config.currencyMode;
4914
4921
  this._shift = new Set();
4915
4922
  this.plusOnePosition = false;
4916
4923
  this.maskExpression = '';
@@ -5108,6 +5115,42 @@ class MatchaMaskApplierService {
5108
5115
  decimalMarker = this.decimalMarker.find((dm) => dm !== this.thousandSeparator);
5109
5116
  }
5110
5117
  }
5118
+ // Modo moeda: dígitos entram pela direita (ex: 1 → 0,01, 12 → 0,12, 123 → 1,23)
5119
+ if (this.currencyMode && precision > 0) {
5120
+ // Extrair apenas dígitos e sinal negativo
5121
+ const hasMinus = processedValue.startsWith("-" /* MaskExpression.MINUS */) ||
5122
+ (this.allowNegativeNumbers && processedValue.includes("-" /* MaskExpression.MINUS */));
5123
+ const digitsOnly = processedValue.replace(/[^\d]/g, '');
5124
+ if (digitsOnly.length === 0) {
5125
+ result = "" /* MaskExpression.EMPTY_STRING */;
5126
+ }
5127
+ else {
5128
+ // Remover zeros à esquerda desnecessários
5129
+ const cleanDigits = digitsOnly.replace(/^0+/, '') || '0';
5130
+ let formattedValue;
5131
+ if (cleanDigits.length <= precision) {
5132
+ // Menos ou igual dígitos que a precisão: 0,XX
5133
+ const paddedDecimal = cleanDigits.padStart(precision, '0');
5134
+ formattedValue = '0' + decimalMarker + paddedDecimal;
5135
+ }
5136
+ else {
5137
+ // Mais dígitos que a precisão: separar inteiro e decimal
5138
+ const integerPart = cleanDigits.slice(0, -precision);
5139
+ const decimalPart = cleanDigits.slice(-precision);
5140
+ // Aplicar separador de milhares na parte inteira
5141
+ let formattedInteger = integerPart;
5142
+ const rgx = /(\d+)(\d{3})/;
5143
+ while (this.thousandSeparator && rgx.test(formattedInteger)) {
5144
+ formattedInteger = formattedInteger.replace(rgx, '$1' + this.thousandSeparator + '$2');
5145
+ }
5146
+ formattedValue = formattedInteger + decimalMarker + decimalPart;
5147
+ }
5148
+ result = (hasMinus ? "-" /* MaskExpression.MINUS */ : '') + formattedValue;
5149
+ }
5150
+ // Mover o cursor para o final
5151
+ cb(result.length, result.length);
5152
+ return `${this.prefix}${result}${this.suffix}`;
5153
+ }
5111
5154
  if (backspaced) {
5112
5155
  const { decimalMarkerIndex, nonZeroIndex } = this._findFirstNonZeroAndDecimalIndex(processedValue, decimalMarker);
5113
5156
  const zeroIndexMinus = processedValue[0] === "-" /* MaskExpression.MINUS */;
@@ -5694,9 +5737,33 @@ class MatchaMaskService extends MatchaMaskApplierService {
5694
5737
  applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false,
5695
5738
  // eslint-disable-next-line @typescript-eslint/no-empty-function
5696
5739
  cb = () => { }) {
5740
+ // Converter automaticamente número, boolean ou object para string (retrocompatível)
5741
+ // Isso previne o erro "indexOf is not a function" quando números são passados
5742
+ let processedInputValue;
5743
+ if (inputValue === null || inputValue === undefined) {
5744
+ processedInputValue = '';
5745
+ }
5746
+ else if (typeof inputValue === 'number') {
5747
+ processedInputValue = String(inputValue);
5748
+ }
5749
+ else if (typeof inputValue === 'boolean') {
5750
+ processedInputValue = inputValue ? 'true' : 'false';
5751
+ }
5752
+ else if (typeof inputValue === 'object') {
5753
+ // Para objetos, tentar converter para string (JSON.stringify ou toString)
5754
+ try {
5755
+ processedInputValue = JSON.stringify(inputValue);
5756
+ }
5757
+ catch {
5758
+ processedInputValue = String(inputValue);
5759
+ }
5760
+ }
5761
+ else {
5762
+ processedInputValue = String(inputValue);
5763
+ }
5697
5764
  // If no mask expression, return the input value or the actual value
5698
5765
  if (!maskExpression) {
5699
- return inputValue !== this.actualValue ? this.actualValue : inputValue;
5766
+ return processedInputValue !== this.actualValue ? this.actualValue : processedInputValue;
5700
5767
  }
5701
5768
  // Show mask in input if required
5702
5769
  this.maskIsShown = this.showMaskTyped
@@ -5704,27 +5771,27 @@ class MatchaMaskService extends MatchaMaskApplierService {
5704
5771
  : "" /* MaskExpression.EMPTY_STRING */;
5705
5772
  // Handle specific mask expressions
5706
5773
  if (this.maskExpression === "IP" /* MaskExpression.IP */ && this.showMaskTyped) {
5707
- this.maskIsShown = this.showMaskInInput(inputValue || "#" /* MaskExpression.HASH */);
5774
+ this.maskIsShown = this.showMaskInInput(processedInputValue || "#" /* MaskExpression.HASH */);
5708
5775
  }
5709
5776
  if (this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */ && this.showMaskTyped) {
5710
- this.maskIsShown = this.showMaskInInput(inputValue || "#" /* MaskExpression.HASH */);
5777
+ this.maskIsShown = this.showMaskInInput(processedInputValue || "#" /* MaskExpression.HASH */);
5711
5778
  }
5712
5779
  // Handle empty input value with mask typed
5713
- if (!inputValue && this.showMaskTyped) {
5780
+ if (!processedInputValue && this.showMaskTyped) {
5714
5781
  this.formControlResult(this.prefix);
5715
5782
  return `${this.prefix}${this.maskIsShown}${this.suffix}`;
5716
5783
  }
5717
- const getSymbol = !!inputValue && typeof this.selStart === 'number'
5718
- ? (inputValue[this.selStart] ?? "" /* MaskExpression.EMPTY_STRING */)
5784
+ const getSymbol = !!processedInputValue && typeof this.selStart === 'number'
5785
+ ? (processedInputValue[this.selStart] ?? "" /* MaskExpression.EMPTY_STRING */)
5719
5786
  : "" /* MaskExpression.EMPTY_STRING */;
5720
5787
  let newInputValue = '';
5721
5788
  let newPosition = position;
5722
5789
  // Handle hidden input or input with asterisk symbol
5723
5790
  if ((this.hiddenInput ||
5724
- (inputValue && inputValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) >= 0)) &&
5791
+ (processedInputValue && processedInputValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) >= 0)) &&
5725
5792
  !this.writingValue) {
5726
- let actualResult = inputValue && inputValue.length === 1
5727
- ? inputValue.split("" /* MaskExpression.EMPTY_STRING */)
5793
+ let actualResult = processedInputValue && processedInputValue.length === 1
5794
+ ? processedInputValue.split("" /* MaskExpression.EMPTY_STRING */)
5728
5795
  : this.actualValue.split("" /* MaskExpression.EMPTY_STRING */);
5729
5796
  // Handle backspace
5730
5797
  if (backspaced) {
@@ -5735,7 +5802,7 @@ class MatchaMaskService extends MatchaMaskApplierService {
5735
5802
  // Remove mask if showMaskTyped is true
5736
5803
  if (this.showMaskTyped) {
5737
5804
  // eslint-disable-next-line no-param-reassign
5738
- inputValue = this.removeMask(inputValue);
5805
+ processedInputValue = this.removeMask(processedInputValue);
5739
5806
  actualResult = this.removeMask(actualResult.join('')).split("" /* MaskExpression.EMPTY_STRING */);
5740
5807
  }
5741
5808
  // Handle selection start and end
@@ -5744,18 +5811,18 @@ class MatchaMaskService extends MatchaMaskApplierService {
5744
5811
  this.selEnd = Number(this.selEnd);
5745
5812
  }
5746
5813
  else {
5747
- if (inputValue !== "" /* MaskExpression.EMPTY_STRING */ && actualResult.length) {
5814
+ if (processedInputValue !== "" /* MaskExpression.EMPTY_STRING */ && actualResult.length) {
5748
5815
  if (typeof this.selStart === 'number' && typeof this.selEnd === 'number') {
5749
- if (inputValue.length > actualResult.length) {
5816
+ if (processedInputValue.length > actualResult.length) {
5750
5817
  actualResult.splice(this.selStart, 0, getSymbol);
5751
5818
  }
5752
- else if (inputValue.length < actualResult.length) {
5753
- if (actualResult.length - inputValue.length === 1) {
5819
+ else if (processedInputValue.length < actualResult.length) {
5820
+ if (actualResult.length - processedInputValue.length === 1) {
5754
5821
  if (backspaced) {
5755
5822
  actualResult.splice(this.selStart - 1, 1);
5756
5823
  }
5757
5824
  else {
5758
- actualResult.splice(inputValue.length - 1, 1);
5825
+ actualResult.splice(processedInputValue.length - 1, 1);
5759
5826
  }
5760
5827
  }
5761
5828
  else {
@@ -5770,27 +5837,27 @@ class MatchaMaskService extends MatchaMaskApplierService {
5770
5837
  }
5771
5838
  // Remove mask if showMaskTyped is true and hiddenInput is false
5772
5839
  if (this.showMaskTyped && !this.hiddenInput) {
5773
- newInputValue = this.removeMask(inputValue);
5840
+ newInputValue = this.removeMask(processedInputValue);
5774
5841
  }
5775
5842
  // Handle actual value length
5776
5843
  if (this.actualValue.length) {
5777
- if (actualResult.length < inputValue.length) {
5844
+ if (actualResult.length < processedInputValue.length) {
5778
5845
  newInputValue = this.shiftTypedSymbols(actualResult.join("" /* MaskExpression.EMPTY_STRING */));
5779
5846
  }
5780
- else if (actualResult.length === inputValue.length) {
5847
+ else if (actualResult.length === processedInputValue.length) {
5781
5848
  newInputValue = actualResult.join("" /* MaskExpression.EMPTY_STRING */);
5782
5849
  }
5783
5850
  else {
5784
- newInputValue = inputValue;
5851
+ newInputValue = processedInputValue;
5785
5852
  }
5786
5853
  }
5787
5854
  else {
5788
- newInputValue = inputValue;
5855
+ newInputValue = processedInputValue;
5789
5856
  }
5790
5857
  }
5791
5858
  // Handle just pasted input
5792
5859
  if (justPasted && (this.hiddenInput || !this.hiddenInput)) {
5793
- newInputValue = inputValue;
5860
+ newInputValue = processedInputValue;
5794
5861
  }
5795
5862
  // Handle backspace with special characters
5796
5863
  if (backspaced &&
@@ -5817,11 +5884,11 @@ class MatchaMaskService extends MatchaMaskApplierService {
5817
5884
  }
5818
5885
  // Handle mask changed
5819
5886
  if (this.maskChanged) {
5820
- newInputValue = inputValue;
5887
+ newInputValue = processedInputValue;
5821
5888
  }
5822
5889
  else {
5823
5890
  newInputValue =
5824
- Boolean(newInputValue) && newInputValue.length ? newInputValue : inputValue;
5891
+ Boolean(newInputValue) && newInputValue.length ? newInputValue : processedInputValue;
5825
5892
  }
5826
5893
  // Handle showMaskTyped and keepCharacterPositions
5827
5894
  if (this.showMaskTyped &&
@@ -6316,23 +6383,24 @@ class MatchaMaskCompatibleDirective {
6316
6383
  this._suffix = '';
6317
6384
  this.thousandSeparator = ' ';
6318
6385
  this.decimalMarker = '.';
6319
- this.dropSpecialCharacters = null;
6320
- this.hiddenInput = null;
6321
- this.showMaskTyped = null;
6386
+ this._dropSpecialCharacters = null;
6387
+ this._hiddenInput = null;
6388
+ this._showMaskTyped = null;
6322
6389
  this.placeHolderCharacter = null;
6323
6390
  this.shownMaskExpression = null;
6324
- this.clearIfNotMatch = null;
6325
- this.validation = null;
6391
+ this._clearIfNotMatch = null;
6392
+ this._validation = null;
6326
6393
  this.separatorLimit = '';
6327
- this.allowNegativeNumbers = null;
6328
- this.leadZeroDateTime = null;
6329
- this.leadZero = null;
6330
- this.triggerOnMaskChange = null;
6331
- this.apm = null;
6394
+ this._allowNegativeNumbers = null;
6395
+ this._leadZeroDateTime = null;
6396
+ this._leadZero = null;
6397
+ this._triggerOnMaskChange = null;
6398
+ this._apm = null;
6332
6399
  this.inputTransformFn = null;
6333
6400
  this.outputTransformFn = null;
6334
- this.keepCharacterPositions = null;
6335
- this.instantPrefix = null;
6401
+ this._keepCharacterPositions = null;
6402
+ this._instantPrefix = null;
6403
+ this._currencyMode = null;
6336
6404
  this.maskFilled = new EventEmitter();
6337
6405
  this._maskValue = '';
6338
6406
  this._inputValue = '';
@@ -6366,8 +6434,112 @@ class MatchaMaskCompatibleDirective {
6366
6434
  get suffixAttr() {
6367
6435
  return this._suffix || null;
6368
6436
  }
6437
+ set dropSpecialCharacters(value) {
6438
+ // Converter string "true" ou "false" para boolean (retrocompatível)
6439
+ if (value === 'true' || value === true) {
6440
+ this._dropSpecialCharacters = true;
6441
+ }
6442
+ else if (value === 'false' || value === false) {
6443
+ this._dropSpecialCharacters = false;
6444
+ }
6445
+ else if (Array.isArray(value) || value === null) {
6446
+ this._dropSpecialCharacters = value;
6447
+ }
6448
+ else {
6449
+ // Para qualquer outro valor string, tratar como false
6450
+ this._dropSpecialCharacters = false;
6451
+ }
6452
+ }
6453
+ get dropSpecialCharacters() {
6454
+ return this._dropSpecialCharacters;
6455
+ }
6456
+ // Helper function para converter string para boolean (retrocompatível)
6457
+ convertToBoolean(value) {
6458
+ if (value === null || value === undefined) {
6459
+ return null;
6460
+ }
6461
+ if (typeof value === 'boolean') {
6462
+ return value;
6463
+ }
6464
+ if (typeof value === 'string') {
6465
+ return value.toLowerCase() === 'true';
6466
+ }
6467
+ return false;
6468
+ }
6469
+ set hiddenInput(value) {
6470
+ this._hiddenInput = this.convertToBoolean(value);
6471
+ }
6472
+ get hiddenInput() {
6473
+ return this._hiddenInput;
6474
+ }
6475
+ set showMaskTyped(value) {
6476
+ this._showMaskTyped = this.convertToBoolean(value);
6477
+ }
6478
+ get showMaskTyped() {
6479
+ return this._showMaskTyped;
6480
+ }
6481
+ set clearIfNotMatch(value) {
6482
+ this._clearIfNotMatch = this.convertToBoolean(value);
6483
+ }
6484
+ get clearIfNotMatch() {
6485
+ return this._clearIfNotMatch;
6486
+ }
6487
+ set validation(value) {
6488
+ this._validation = this.convertToBoolean(value);
6489
+ }
6490
+ get validation() {
6491
+ return this._validation;
6492
+ }
6493
+ set allowNegativeNumbers(value) {
6494
+ this._allowNegativeNumbers = this.convertToBoolean(value);
6495
+ }
6496
+ get allowNegativeNumbers() {
6497
+ return this._allowNegativeNumbers;
6498
+ }
6499
+ set leadZeroDateTime(value) {
6500
+ this._leadZeroDateTime = this.convertToBoolean(value);
6501
+ }
6502
+ get leadZeroDateTime() {
6503
+ return this._leadZeroDateTime;
6504
+ }
6505
+ set leadZero(value) {
6506
+ this._leadZero = this.convertToBoolean(value);
6507
+ }
6508
+ get leadZero() {
6509
+ return this._leadZero;
6510
+ }
6511
+ set triggerOnMaskChange(value) {
6512
+ this._triggerOnMaskChange = this.convertToBoolean(value);
6513
+ }
6514
+ get triggerOnMaskChange() {
6515
+ return this._triggerOnMaskChange;
6516
+ }
6517
+ set apm(value) {
6518
+ this._apm = this.convertToBoolean(value);
6519
+ }
6520
+ get apm() {
6521
+ return this._apm;
6522
+ }
6523
+ set keepCharacterPositions(value) {
6524
+ this._keepCharacterPositions = this.convertToBoolean(value);
6525
+ }
6526
+ get keepCharacterPositions() {
6527
+ return this._keepCharacterPositions;
6528
+ }
6529
+ set instantPrefix(value) {
6530
+ this._instantPrefix = this.convertToBoolean(value);
6531
+ }
6532
+ get instantPrefix() {
6533
+ return this._instantPrefix;
6534
+ }
6535
+ set currencyMode(value) {
6536
+ this._currencyMode = this.convertToBoolean(value);
6537
+ }
6538
+ get currencyMode() {
6539
+ return this._currencyMode;
6540
+ }
6369
6541
  ngOnChanges(changes) {
6370
- const { mask, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, leadZero, triggerOnMaskChange, apm, inputTransformFn, outputTransformFn, keepCharacterPositions, instantPrefix, } = changes;
6542
+ const { mask, specialCharacters, patterns, prefix, suffix, thousandSeparator, decimalMarker, dropSpecialCharacters, hiddenInput, showMaskTyped, placeHolderCharacter, shownMaskExpression, clearIfNotMatch, validation, separatorLimit, allowNegativeNumbers, leadZeroDateTime, leadZero, triggerOnMaskChange, apm, inputTransformFn, outputTransformFn, keepCharacterPositions, instantPrefix, currencyMode, } = changes;
6371
6543
  if (mask) {
6372
6544
  this._mask = mask.currentValue ?? '';
6373
6545
  this._maskValue = this._mask ?? '';
@@ -6394,13 +6566,25 @@ class MatchaMaskCompatibleDirective {
6394
6566
  this._maskService.decimalMarker = decimalMarker.currentValue ?? '.';
6395
6567
  }
6396
6568
  if (dropSpecialCharacters) {
6397
- this._maskService.dropSpecialCharacters = dropSpecialCharacters.currentValue;
6569
+ // O setter já faz a conversão automática de string para boolean
6570
+ const value = this.dropSpecialCharacters;
6571
+ if (value !== null) {
6572
+ this._maskService.dropSpecialCharacters = value;
6573
+ }
6398
6574
  }
6399
6575
  if (hiddenInput) {
6400
- this._maskService.hiddenInput = hiddenInput.currentValue;
6576
+ // O setter já faz a conversão automática de string para boolean
6577
+ const value = this.hiddenInput;
6578
+ if (value !== null) {
6579
+ this._maskService.hiddenInput = value;
6580
+ }
6401
6581
  }
6402
6582
  if (showMaskTyped) {
6403
- this._maskService.showMaskTyped = showMaskTyped.currentValue;
6583
+ // O setter já faz a conversão automática de string para boolean
6584
+ const value = this.showMaskTyped;
6585
+ if (value !== null) {
6586
+ this._maskService.showMaskTyped = value;
6587
+ }
6404
6588
  }
6405
6589
  if (placeHolderCharacter) {
6406
6590
  this._maskService.placeHolderCharacter = placeHolderCharacter.currentValue;
@@ -6409,28 +6593,56 @@ class MatchaMaskCompatibleDirective {
6409
6593
  this._maskService.shownMaskExpression = shownMaskExpression.currentValue;
6410
6594
  }
6411
6595
  if (clearIfNotMatch) {
6412
- this._maskService.clearIfNotMatch = clearIfNotMatch.currentValue;
6596
+ // O setter já faz a conversão automática de string para boolean
6597
+ const value = this.clearIfNotMatch;
6598
+ if (value !== null) {
6599
+ this._maskService.clearIfNotMatch = value;
6600
+ }
6413
6601
  }
6414
6602
  if (validation) {
6415
- this._maskService.validation = validation.currentValue;
6603
+ // O setter já faz a conversão automática de string para boolean
6604
+ const value = this.validation;
6605
+ if (value !== null) {
6606
+ this._maskService.validation = value;
6607
+ }
6416
6608
  }
6417
6609
  if (separatorLimit) {
6418
6610
  this._maskService.separatorLimit = separatorLimit.currentValue ?? '';
6419
6611
  }
6420
6612
  if (allowNegativeNumbers) {
6421
- this._maskService.allowNegativeNumbers = allowNegativeNumbers.currentValue;
6613
+ // O setter já faz a conversão automática de string para boolean
6614
+ const value = this.allowNegativeNumbers;
6615
+ if (value !== null) {
6616
+ this._maskService.allowNegativeNumbers = value;
6617
+ }
6422
6618
  }
6423
6619
  if (leadZeroDateTime) {
6424
- this._maskService.leadZeroDateTime = leadZeroDateTime.currentValue;
6620
+ // O setter já faz a conversão automática de string para boolean
6621
+ const value = this.leadZeroDateTime;
6622
+ if (value !== null) {
6623
+ this._maskService.leadZeroDateTime = value;
6624
+ }
6425
6625
  }
6426
6626
  if (leadZero) {
6427
- this._maskService.leadZero = leadZero.currentValue;
6627
+ // O setter já faz a conversão automática de string para boolean
6628
+ const value = this.leadZero;
6629
+ if (value !== null) {
6630
+ this._maskService.leadZero = value;
6631
+ }
6428
6632
  }
6429
6633
  if (triggerOnMaskChange) {
6430
- this._maskService.triggerOnMaskChange = triggerOnMaskChange.currentValue;
6634
+ // O setter já faz a conversão automática de string para boolean
6635
+ const value = this.triggerOnMaskChange;
6636
+ if (value !== null) {
6637
+ this._maskService.triggerOnMaskChange = value;
6638
+ }
6431
6639
  }
6432
6640
  if (apm) {
6433
- this._maskService.apm = apm.currentValue;
6641
+ // O setter já faz a conversão automática de string para boolean
6642
+ const value = this.apm;
6643
+ if (value !== null) {
6644
+ this._maskService.apm = value;
6645
+ }
6434
6646
  }
6435
6647
  if (inputTransformFn) {
6436
6648
  this._maskService.inputTransformFn = inputTransformFn.currentValue;
@@ -6439,10 +6651,25 @@ class MatchaMaskCompatibleDirective {
6439
6651
  this._maskService.outputTransformFn = outputTransformFn.currentValue;
6440
6652
  }
6441
6653
  if (keepCharacterPositions) {
6442
- this._maskService.keepCharacterPositions = keepCharacterPositions.currentValue;
6654
+ // O setter já faz a conversão automática de string para boolean
6655
+ const value = this.keepCharacterPositions;
6656
+ if (value !== null) {
6657
+ this._maskService.keepCharacterPositions = value;
6658
+ }
6443
6659
  }
6444
6660
  if (instantPrefix) {
6445
- this._maskService.instantPrefix = instantPrefix.currentValue;
6661
+ // O setter já faz a conversão automática de string para boolean
6662
+ const value = this.instantPrefix;
6663
+ if (value !== null) {
6664
+ this._maskService.instantPrefix = value;
6665
+ }
6666
+ }
6667
+ if (currencyMode) {
6668
+ // O setter já faz a conversão automática de string para boolean
6669
+ const value = this.currencyMode;
6670
+ if (value !== null) {
6671
+ this._maskService.currencyMode = value;
6672
+ }
6446
6673
  }
6447
6674
  }
6448
6675
  onPaste() {
@@ -6456,21 +6683,26 @@ class MatchaMaskCompatibleDirective {
6456
6683
  if (this._maskService.writingValue) {
6457
6684
  return;
6458
6685
  }
6459
- this._inputValue = value;
6686
+ // Converter automaticamente número para string (retrocompatível)
6687
+ const stringValue = typeof value === 'number' ? value.toString() : (value || '');
6688
+ this._inputValue = stringValue;
6460
6689
  // Aplicar máscara se definida
6461
6690
  if (this._mask && this._mask.trim() !== '') {
6462
- const maskedValue = this._maskService.applyMask(value, this._mask);
6463
- if (maskedValue !== value) {
6691
+ const maskedValue = this._maskService.applyMask(stringValue, this._mask);
6692
+ if (maskedValue !== stringValue) {
6464
6693
  this._maskService.writingValue = true;
6465
6694
  this._maskService.onChange(maskedValue);
6466
- this._maskService.writingValue = false;
6695
+ // Usar setTimeout para garantir que writingValue permaneça true durante o ciclo
6696
+ setTimeout(() => {
6697
+ this._maskService.writingValue = false;
6698
+ }, 0);
6467
6699
  }
6468
6700
  else {
6469
- this._maskService.onChange(value);
6701
+ this._maskService.onChange(stringValue);
6470
6702
  }
6471
6703
  }
6472
6704
  else {
6473
- this._maskService.onChange(value);
6705
+ this._maskService.onChange(stringValue);
6474
6706
  }
6475
6707
  }
6476
6708
  onInput(event) {
@@ -6511,17 +6743,65 @@ class MatchaMaskCompatibleDirective {
6511
6743
  // Implementar lógica de teclado se necessário
6512
6744
  }
6513
6745
  writeValue(value) {
6746
+ // Se já estamos escrevendo, não processar novamente (prevenir loop infinito)
6747
+ if (this._maskService.writingValue) {
6748
+ return;
6749
+ }
6514
6750
  this._maskService.writingValue = true;
6515
- this._inputValue = value;
6751
+ // Converter automaticamente número para string (retrocompatível)
6752
+ // Isso previne o erro "indexOf is not a function" quando números são passados
6753
+ let inputValue;
6754
+ if (value === null || value === undefined) {
6755
+ inputValue = '';
6756
+ }
6757
+ else if (typeof value === 'number') {
6758
+ inputValue = value.toString();
6759
+ }
6760
+ else {
6761
+ inputValue = String(value);
6762
+ }
6763
+ // Se a máscara usa separator e o valor tem ponto decimal, converter para vírgula
6764
+ // Isso é útil quando valores numéricos vêm do backend (ex: 10.5 -> 10,50)
6765
+ if (this._mask && this._mask.trim().startsWith('separator.') && inputValue.includes('.')) {
6766
+ // Converter ponto para vírgula se o decimalMarker é vírgula
6767
+ const decimalMarker = this._maskService.decimalMarker;
6768
+ if (decimalMarker === ',' || (Array.isArray(decimalMarker) && decimalMarker.includes(','))) {
6769
+ inputValue = inputValue.replace('.', ',');
6770
+ }
6771
+ }
6772
+ this._inputValue = inputValue;
6516
6773
  // Aplicar máscara se definida
6517
6774
  if (this._mask && this._mask.trim() !== '') {
6518
- const maskedValue = this._maskService.applyMask(value, this._mask);
6519
- this._maskService.onChange(maskedValue);
6775
+ const maskedValue = this._maskService.applyMask(inputValue, this._mask);
6776
+ // Só atualizar se o valor mascarado for diferente do valor atual
6777
+ // Isso previne loops quando o valor já está correto
6778
+ const currentValue = this._maskService.currentValue || '';
6779
+ if (maskedValue !== currentValue) {
6780
+ // Usar setTimeout para garantir que writingValue permaneça true durante o ciclo
6781
+ // Isso previne que onModelChange processe durante writeValue
6782
+ setTimeout(() => {
6783
+ this._maskService.onChange(maskedValue);
6784
+ this._maskService.writingValue = false;
6785
+ }, 0);
6786
+ }
6787
+ else {
6788
+ // Se o valor já está correto, não precisa atualizar
6789
+ this._maskService.writingValue = false;
6790
+ }
6520
6791
  }
6521
6792
  else {
6522
- this._maskService.onChange(value);
6793
+ // Sem máscara, apenas atualizar o valor
6794
+ const currentValue = this._maskService.currentValue || '';
6795
+ if (inputValue !== currentValue) {
6796
+ setTimeout(() => {
6797
+ this._maskService.onChange(inputValue);
6798
+ this._maskService.writingValue = false;
6799
+ }, 0);
6800
+ }
6801
+ else {
6802
+ this._maskService.writingValue = false;
6803
+ }
6523
6804
  }
6524
- this._maskService.writingValue = false;
6525
6805
  }
6526
6806
  registerOnChange(fn) {
6527
6807
  this.onChange = fn;
@@ -6538,7 +6818,7 @@ class MatchaMaskCompatibleDirective {
6538
6818
  return null;
6539
6819
  }
6540
6820
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: MatchaMaskCompatibleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
6541
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.0", type: MatchaMaskCompatibleDirective, isStandalone: false, selector: "input[matchaMask], textarea[matchaMask]", inputs: { mask: ["matchaMask", "mask"], specialCharacters: "specialCharacters", patterns: "patterns", prefix: "prefix", suffix: "suffix", thousandSeparator: "thousandSeparator", decimalMarker: "decimalMarker", dropSpecialCharacters: "dropSpecialCharacters", hiddenInput: "hiddenInput", showMaskTyped: "showMaskTyped", placeHolderCharacter: "placeHolderCharacter", shownMaskExpression: "shownMaskExpression", clearIfNotMatch: "clearIfNotMatch", validation: "validation", separatorLimit: "separatorLimit", allowNegativeNumbers: "allowNegativeNumbers", leadZeroDateTime: "leadZeroDateTime", leadZero: "leadZero", triggerOnMaskChange: "triggerOnMaskChange", apm: "apm", inputTransformFn: "inputTransformFn", outputTransformFn: "outputTransformFn", keepCharacterPositions: "keepCharacterPositions", instantPrefix: "instantPrefix" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste($event)", "focus": "onFocus($event)", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "compositionstart": "onCompositionStart($event)", "compositionend": "onCompositionEnd($event)", "blur": "onBlur($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" }, properties: { "attr.data-matcha-mask": "this.maskAttr", "attr.data-prefix": "this.prefixAttr", "attr.data-suffix": "this.suffixAttr" } }, providers: [
6821
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.0", type: MatchaMaskCompatibleDirective, isStandalone: false, selector: "input[matchaMask], textarea[matchaMask]", inputs: { mask: ["matchaMask", "mask"], specialCharacters: "specialCharacters", patterns: "patterns", prefix: "prefix", suffix: "suffix", thousandSeparator: "thousandSeparator", decimalMarker: "decimalMarker", dropSpecialCharacters: "dropSpecialCharacters", hiddenInput: "hiddenInput", showMaskTyped: "showMaskTyped", placeHolderCharacter: "placeHolderCharacter", shownMaskExpression: "shownMaskExpression", clearIfNotMatch: "clearIfNotMatch", validation: "validation", separatorLimit: "separatorLimit", allowNegativeNumbers: "allowNegativeNumbers", leadZeroDateTime: "leadZeroDateTime", leadZero: "leadZero", triggerOnMaskChange: "triggerOnMaskChange", apm: "apm", inputTransformFn: "inputTransformFn", outputTransformFn: "outputTransformFn", keepCharacterPositions: "keepCharacterPositions", instantPrefix: "instantPrefix", currencyMode: "currencyMode" }, outputs: { maskFilled: "maskFilled" }, host: { listeners: { "paste": "onPaste($event)", "focus": "onFocus($event)", "ngModelChange": "onModelChange($event)", "input": "onInput($event)", "compositionstart": "onCompositionStart($event)", "compositionend": "onCompositionEnd($event)", "blur": "onBlur($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" }, properties: { "attr.data-matcha-mask": "this.maskAttr", "attr.data-prefix": "this.prefixAttr", "attr.data-suffix": "this.suffixAttr" } }, providers: [
6542
6822
  {
6543
6823
  provide: NG_VALUE_ACCESSOR,
6544
6824
  useExisting: forwardRef(() => MatchaMaskCompatibleDirective),
@@ -6630,6 +6910,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImpor
6630
6910
  type: Input
6631
6911
  }], instantPrefix: [{
6632
6912
  type: Input
6913
+ }], currencyMode: [{
6914
+ type: Input
6633
6915
  }], maskFilled: [{
6634
6916
  type: Output
6635
6917
  }], onPaste: [{
@@ -6854,7 +7136,7 @@ class MatchaInputPhoneComponent {
6854
7136
  this.removeClickListener();
6855
7137
  }
6856
7138
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: MatchaInputPhoneComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6857
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.0", type: MatchaInputPhoneComponent, isStandalone: false, selector: "matcha-input-phone", inputs: { fallbackMask: "fallbackMask", value: "value" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "inputSelector", first: true, predicate: ["inputSelector"], descendants: true }, { propertyName: "phoneRef", first: true, predicate: ["phoneRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n<div class=\"flex-row position-relative px-16 gap-8\" #inputSelector>\n <div class=\"min-h-24 radius-8 cursor-pointer d-flex gap-8 flex-align-center fs-16\" (click)=\"toggleDropdown()\">\n <div class=\"d-flex-row flex-align-center\">\n <img alt=\"\" [src]=\"'https://flagcdn.com/16x12/'+ selectedCountry?.iso2?.toLowerCase() + '.png'\"\n height=\"16\">\n </div>\n <span class=\"w-16 fs-16\"\n [ngClass]=\"isOpen ? 'i-matcha-action_arrow_up': 'i-matcha-action_arrow_down'\"></span>\n\n </div>\n <input *ngIf=\"isInitialized\" #phoneRef type=\"text\" placeholder=\"{{ typeMask }}\"\n [(ngModel)]=\"inputValueModel\"\n pattern=\"[0-9]*\" (keyup)=\"onInput($event)\" [matchaMask]=\"typeMask\">\n\n <ng-container *ngIf=\"isOpen\">\n <div class=\"position-absolute z-index-10\">\n <div class=\"grid-1 gap-16 radius-8 z-index-10 p-8 w-300 position-absolute background-surface elevation-z-1\"\n style=\"top: calc(100% + 10px); overflow: hidden; height: 300px; overflow-y: auto;\">\n\n <label *ngFor=\"let country of allCountries; let i = index\"\n class=\"fs-16 lh-18 cursor-pointer d-flex-align-center p-8 ts-300-l\"\n [ngClass]=\"labelHover === i+'bg' ? 'background-bg' : 'background-surface'\"\n (mouseover)=\"labelHover = i+'bg'\" (mouseout)=\"labelHover = i+'su'\"\n (click)=\"selectCountry(country)\">\n <img alt=\"\" class=\"mr-8\"\n [src]=\"'https://flagcdn.com/16x12/'+ country?.iso2?.toLowerCase() + '.png'\" height=\"16\">\n {{country.name}}\n </label>\n </div>\n </div>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: MatchaMaskCompatibleDirective, selector: "input[matchaMask], textarea[matchaMask]", inputs: ["matchaMask", "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: ["matchaMask"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
7139
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.0", type: MatchaInputPhoneComponent, isStandalone: false, selector: "matcha-input-phone", inputs: { fallbackMask: "fallbackMask", value: "value" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "inputSelector", first: true, predicate: ["inputSelector"], descendants: true }, { propertyName: "phoneRef", first: true, predicate: ["phoneRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\n<div class=\"flex-row position-relative px-16 gap-8\" #inputSelector>\n <div class=\"min-h-24 radius-8 cursor-pointer d-flex gap-8 flex-align-center fs-16\" (click)=\"toggleDropdown()\">\n <div class=\"d-flex-row flex-align-center\">\n <img alt=\"\" [src]=\"'https://flagcdn.com/16x12/'+ selectedCountry?.iso2?.toLowerCase() + '.png'\"\n height=\"16\">\n </div>\n <span class=\"w-16 fs-16\"\n [ngClass]=\"isOpen ? 'i-matcha-action_arrow_up': 'i-matcha-action_arrow_down'\"></span>\n\n </div>\n <input *ngIf=\"isInitialized\" #phoneRef type=\"text\" placeholder=\"{{ typeMask }}\"\n [(ngModel)]=\"inputValueModel\"\n pattern=\"[0-9]*\" (keyup)=\"onInput($event)\" [matchaMask]=\"typeMask\">\n\n <ng-container *ngIf=\"isOpen\">\n <div class=\"position-absolute z-index-10\">\n <div class=\"grid-1 gap-16 radius-8 z-index-10 p-8 w-300 position-absolute background-surface elevation-z-1\"\n style=\"top: calc(100% + 10px); overflow: hidden; height: 300px; overflow-y: auto;\">\n\n <label *ngFor=\"let country of allCountries; let i = index\"\n class=\"fs-16 lh-18 cursor-pointer d-flex-align-center p-8 ts-300-l\"\n [ngClass]=\"labelHover === i+'bg' ? 'background-bg' : 'background-surface'\"\n (mouseover)=\"labelHover = i+'bg'\" (mouseout)=\"labelHover = i+'su'\"\n (click)=\"selectCountry(country)\">\n <img alt=\"\" class=\"mr-8\"\n [src]=\"'https://flagcdn.com/16x12/'+ country?.iso2?.toLowerCase() + '.png'\" height=\"16\">\n {{country.name}}\n </label>\n </div>\n </div>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: MatchaMaskCompatibleDirective, selector: "input[matchaMask], textarea[matchaMask]", inputs: ["matchaMask", "specialCharacters", "patterns", "prefix", "suffix", "thousandSeparator", "decimalMarker", "dropSpecialCharacters", "hiddenInput", "showMaskTyped", "placeHolderCharacter", "shownMaskExpression", "clearIfNotMatch", "validation", "separatorLimit", "allowNegativeNumbers", "leadZeroDateTime", "leadZero", "triggerOnMaskChange", "apm", "inputTransformFn", "outputTransformFn", "keepCharacterPositions", "instantPrefix", "currencyMode"], outputs: ["maskFilled"], exportAs: ["matchaMask"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
6858
7140
  }
6859
7141
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: MatchaInputPhoneComponent, decorators: [{
6860
7142
  type: Component,