@praxisui/dynamic-fields 3.0.0-beta.2 → 3.0.0-beta.3
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.
|
@@ -869,6 +869,11 @@ class SimpleBaseInputComponent {
|
|
|
869
869
|
const componentState = this.componentState();
|
|
870
870
|
const ngControl = this.getNgControl();
|
|
871
871
|
const parentInvalid = !!ngControl?.invalid;
|
|
872
|
+
const parentTouched = !!ngControl?.touched;
|
|
873
|
+
const parentDirty = !!ngControl?.dirty;
|
|
874
|
+
const controlState = this.control();
|
|
875
|
+
const controlTouched = !!controlState.touched;
|
|
876
|
+
const controlDirty = !!controlState.dirty;
|
|
872
877
|
const errors = ngControl?.errors ?? this.control().errors;
|
|
873
878
|
const meta = this.metadata();
|
|
874
879
|
const trig = meta?.validators?.validationTrigger;
|
|
@@ -883,13 +888,19 @@ class SimpleBaseInputComponent {
|
|
|
883
888
|
case 'immediate':
|
|
884
889
|
return true;
|
|
885
890
|
case 'blur':
|
|
886
|
-
return componentState.touched;
|
|
891
|
+
return componentState.touched || parentTouched || controlTouched;
|
|
887
892
|
case 'submit':
|
|
888
893
|
// Praxis onSubmit marca todos como touched; usamos esse sinal
|
|
889
|
-
return componentState.touched;
|
|
894
|
+
return componentState.touched || parentTouched || controlTouched;
|
|
890
895
|
case 'change':
|
|
891
896
|
default:
|
|
892
|
-
return (componentState.dirty
|
|
897
|
+
return (componentState.dirty
|
|
898
|
+
|| componentState.touched
|
|
899
|
+
|| parentDirty
|
|
900
|
+
|| parentTouched
|
|
901
|
+
|| controlDirty
|
|
902
|
+
|| controlTouched)
|
|
903
|
+
&& this.errorDisplayReady();
|
|
893
904
|
}
|
|
894
905
|
}, ...(ngDevMode ? [{ debugName: "hasValidationError" }] : []));
|
|
895
906
|
/** CSS classes básicas do componente */
|
|
@@ -1492,10 +1503,12 @@ class SimpleBaseInputComponent {
|
|
|
1492
1503
|
// =============================================================================
|
|
1493
1504
|
setupFormControlIntegration() {
|
|
1494
1505
|
const control = this.control();
|
|
1506
|
+
this.syncComponentStateFromControl(control);
|
|
1495
1507
|
control.valueChanges
|
|
1496
1508
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1497
1509
|
.subscribe((value) => {
|
|
1498
1510
|
this.fieldState.update((state) => ({ ...state, value }));
|
|
1511
|
+
this.syncComponentStateFromControl(control);
|
|
1499
1512
|
});
|
|
1500
1513
|
control.statusChanges
|
|
1501
1514
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
@@ -1505,6 +1518,7 @@ class SimpleBaseInputComponent {
|
|
|
1505
1518
|
valid: status === 'VALID',
|
|
1506
1519
|
errors: control.errors,
|
|
1507
1520
|
}));
|
|
1521
|
+
this.syncComponentStateFromControl(control);
|
|
1508
1522
|
this.refreshErrorTooltip();
|
|
1509
1523
|
});
|
|
1510
1524
|
// Sincronizar erros/estado do controle pai apenas quando usando controle interno
|
|
@@ -1520,35 +1534,51 @@ class SimpleBaseInputComponent {
|
|
|
1520
1534
|
errors: errs,
|
|
1521
1535
|
valid: !errs,
|
|
1522
1536
|
}));
|
|
1537
|
+
this.syncComponentStateFromControl(control);
|
|
1523
1538
|
this.refreshErrorTooltip();
|
|
1524
1539
|
this.cdr.markForCheck();
|
|
1525
1540
|
});
|
|
1526
1541
|
}
|
|
1527
1542
|
}
|
|
1543
|
+
syncComponentStateFromControl(control) {
|
|
1544
|
+
this.componentState.update((state) => ({
|
|
1545
|
+
...state,
|
|
1546
|
+
touched: !!control.touched,
|
|
1547
|
+
dirty: !!control.dirty,
|
|
1548
|
+
disabled: !!control.disabled,
|
|
1549
|
+
}));
|
|
1550
|
+
}
|
|
1528
1551
|
// Atualiza tooltip/atributos de erro quando erros mudam e quando inline errors estiverem desabilitados
|
|
1529
1552
|
refreshErrorTooltip() {
|
|
1530
1553
|
if (!this.nativeElement)
|
|
1531
1554
|
return;
|
|
1532
|
-
// Só aplica tooltip nativo quando errorPosition === 'tooltip' e não houver MatTooltip no template
|
|
1533
|
-
// Força avaliação de tooltipPosition para evitar aviso de membro não utilizado
|
|
1534
|
-
void this.tooltipPosition();
|
|
1535
|
-
if (!this.tooltipEnabled()) {
|
|
1536
|
-
this.nativeElement.removeAttribute('title');
|
|
1537
|
-
this.nativeElement.removeAttribute('aria-invalid');
|
|
1538
|
-
return;
|
|
1539
|
-
}
|
|
1540
1555
|
const hasErrors = !!(this.getNgControl()?.errors ?? this.control().errors);
|
|
1541
1556
|
if (hasErrors) {
|
|
1542
|
-
const msg = this.errorMessage();
|
|
1543
|
-
if (msg)
|
|
1544
|
-
this.nativeElement.setAttribute('title', msg);
|
|
1545
1557
|
this.nativeElement.setAttribute('aria-invalid', 'true');
|
|
1558
|
+
if (this.tooltipEnabled()) {
|
|
1559
|
+
// Força avaliação de tooltipPosition para evitar aviso de membro não utilizado
|
|
1560
|
+
void this.tooltipPosition();
|
|
1561
|
+
const msg = this.errorMessage();
|
|
1562
|
+
if (msg) {
|
|
1563
|
+
this.nativeElement.setAttribute('title', msg);
|
|
1564
|
+
}
|
|
1565
|
+
else {
|
|
1566
|
+
this.nativeElement.removeAttribute('title');
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
this.nativeElement.removeAttribute('title');
|
|
1571
|
+
}
|
|
1546
1572
|
}
|
|
1547
1573
|
else {
|
|
1548
1574
|
this.nativeElement.removeAttribute('title');
|
|
1549
1575
|
this.nativeElement.removeAttribute('aria-invalid');
|
|
1550
1576
|
}
|
|
1551
1577
|
}
|
|
1578
|
+
ariaInvalidAttribute() {
|
|
1579
|
+
const hasErrors = !!(this.getNgControl()?.errors ?? this.control().errors);
|
|
1580
|
+
return hasErrors ? 'true' : null;
|
|
1581
|
+
}
|
|
1552
1582
|
tDynamicFields(keySuffix, fallback, params) {
|
|
1553
1583
|
return this.i18n.t(`praxis.dynamicFields.${keySuffix}`, params, fallback, 'dynamicFields');
|
|
1554
1584
|
}
|
|
@@ -7725,6 +7755,7 @@ class TextInputComponent extends SimpleBaseInputComponent {
|
|
|
7725
7755
|
[minlength]="metadata()?.minLength || null"
|
|
7726
7756
|
[attr.aria-label]="!label && placeholder ? placeholder : null"
|
|
7727
7757
|
[attr.aria-required]="metadata()?.required ? 'true' : 'false'"
|
|
7758
|
+
[attr.aria-invalid]="ariaInvalidAttribute()"
|
|
7728
7759
|
[matTooltip]="tooltipEnabled() ? errorMessage() : null"
|
|
7729
7760
|
[matTooltipDisabled]="!(tooltipEnabled() && !!errorMessage())"
|
|
7730
7761
|
[matTooltipPosition]="tooltipPosition()"
|
|
@@ -7816,6 +7847,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
7816
7847
|
[minlength]="metadata()?.minLength || null"
|
|
7817
7848
|
[attr.aria-label]="!label && placeholder ? placeholder : null"
|
|
7818
7849
|
[attr.aria-required]="metadata()?.required ? 'true' : 'false'"
|
|
7850
|
+
[attr.aria-invalid]="ariaInvalidAttribute()"
|
|
7819
7851
|
[matTooltip]="tooltipEnabled() ? errorMessage() : null"
|
|
7820
7852
|
[matTooltipDisabled]="!(tooltipEnabled() && !!errorMessage())"
|
|
7821
7853
|
[matTooltipPosition]="tooltipPosition()"
|
|
@@ -47981,7 +48013,13 @@ const DYNAMIC_FIELD_ERROR_STATE_RECIPE = {
|
|
|
47981
48013
|
state: 'error',
|
|
47982
48014
|
label: 'Error',
|
|
47983
48015
|
supported: true,
|
|
47984
|
-
metadataPatch: {
|
|
48016
|
+
metadataPatch: {
|
|
48017
|
+
required: true,
|
|
48018
|
+
validators: {
|
|
48019
|
+
requiredMessage: 'Governed sample error state for playground preview.',
|
|
48020
|
+
validationTrigger: 'immediate',
|
|
48021
|
+
},
|
|
48022
|
+
},
|
|
47985
48023
|
errorMessage: 'Governed sample error state for playground preview.',
|
|
47986
48024
|
};
|
|
47987
48025
|
const DYNAMIC_FIELD_BASE_STATE_RECIPES = [
|