ng-prime-tools 1.1.7 → 1.1.8
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.
|
@@ -1577,9 +1577,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1577
1577
|
|
|
1578
1578
|
class PTMultiSelectComponent {
|
|
1579
1579
|
constructor() {
|
|
1580
|
-
/**
|
|
1581
|
-
* Two-way standalone value.
|
|
1582
|
-
*/
|
|
1583
1580
|
this.value = [];
|
|
1584
1581
|
this.valueChange = new EventEmitter();
|
|
1585
1582
|
this.selectionChange = new EventEmitter();
|
|
@@ -1609,7 +1606,8 @@ class PTMultiSelectComponent {
|
|
|
1609
1606
|
return `pt-multiselect-${this.controlName}`;
|
|
1610
1607
|
}
|
|
1611
1608
|
get resolvedHidden() {
|
|
1612
|
-
|
|
1609
|
+
const hidden = this.formField?.hidden ?? this.config?.hidden;
|
|
1610
|
+
return this.resolveHiddenValue(hidden);
|
|
1613
1611
|
}
|
|
1614
1612
|
get resolvedLabel() {
|
|
1615
1613
|
return this.formField?.label || this.config?.label;
|
|
@@ -1626,10 +1624,10 @@ class PTMultiSelectComponent {
|
|
|
1626
1624
|
'Select options');
|
|
1627
1625
|
}
|
|
1628
1626
|
get resolvedOptionLabel() {
|
|
1629
|
-
return this.config?.optionLabel || 'label';
|
|
1627
|
+
return this.formField?.optionLabel || this.config?.optionLabel || 'label';
|
|
1630
1628
|
}
|
|
1631
1629
|
get resolvedOptionValue() {
|
|
1632
|
-
return this.config?.optionValue || 'value';
|
|
1630
|
+
return this.formField?.optionValue || this.config?.optionValue || 'value';
|
|
1633
1631
|
}
|
|
1634
1632
|
get resolvedRequired() {
|
|
1635
1633
|
return this.formField?.required ?? this.config?.required ?? false;
|
|
@@ -1641,19 +1639,45 @@ class PTMultiSelectComponent {
|
|
|
1641
1639
|
return this.formField?.errorText || this.config?.errorText;
|
|
1642
1640
|
}
|
|
1643
1641
|
get resolvedFilter() {
|
|
1644
|
-
return this.config?.filter === true;
|
|
1642
|
+
return this.formField?.filter === true || this.config?.filter === true;
|
|
1645
1643
|
}
|
|
1646
1644
|
get resolvedFilterBy() {
|
|
1647
|
-
return this.
|
|
1645
|
+
return (this.formField?.filterBy ||
|
|
1646
|
+
this.config?.filterBy ||
|
|
1647
|
+
this.resolvedOptionLabel);
|
|
1648
1648
|
}
|
|
1649
1649
|
get resolvedDisplay() {
|
|
1650
|
-
return this.config?.display || 'comma';
|
|
1650
|
+
return this.formField?.display || this.config?.display || 'comma';
|
|
1651
1651
|
}
|
|
1652
1652
|
get resolvedMaxSelectedLabels() {
|
|
1653
|
-
return this.config?.maxSelectedLabels ?? 3;
|
|
1653
|
+
return (this.formField?.maxSelectedLabels ?? this.config?.maxSelectedLabels ?? 3);
|
|
1654
1654
|
}
|
|
1655
1655
|
get resolvedSelectedItemsLabel() {
|
|
1656
|
-
return this.
|
|
1656
|
+
return (this.formField?.selectedItemsLabel ||
|
|
1657
|
+
this.config?.selectedItemsLabel ||
|
|
1658
|
+
'{0} items selected');
|
|
1659
|
+
}
|
|
1660
|
+
getErrorMessage() {
|
|
1661
|
+
const control = this.activeFormGroup.get(this.controlName);
|
|
1662
|
+
if (!control?.errors) {
|
|
1663
|
+
return '';
|
|
1664
|
+
}
|
|
1665
|
+
const errorKey = Object.keys(control.errors)[0];
|
|
1666
|
+
if (!errorKey) {
|
|
1667
|
+
return '';
|
|
1668
|
+
}
|
|
1669
|
+
const customMessage = this.formField?.validationMessages?.[errorKey];
|
|
1670
|
+
if (customMessage) {
|
|
1671
|
+
return customMessage;
|
|
1672
|
+
}
|
|
1673
|
+
if (this.resolvedErrorText) {
|
|
1674
|
+
return this.resolvedErrorText;
|
|
1675
|
+
}
|
|
1676
|
+
const label = this.resolvedLabel || this.controlName;
|
|
1677
|
+
if (control.hasError('required')) {
|
|
1678
|
+
return `${label} is required`;
|
|
1679
|
+
}
|
|
1680
|
+
return `${label} is invalid`;
|
|
1657
1681
|
}
|
|
1658
1682
|
setupControl(forceValueFromConfig) {
|
|
1659
1683
|
const name = this.controlName;
|
|
@@ -1662,23 +1686,35 @@ class PTMultiSelectComponent {
|
|
|
1662
1686
|
}
|
|
1663
1687
|
let control = this.activeFormGroup.get(name);
|
|
1664
1688
|
if (!control) {
|
|
1665
|
-
control = new FormControl(this.getInitialValue()
|
|
1689
|
+
control = new FormControl(this.getInitialValue(), {
|
|
1690
|
+
nonNullable: true,
|
|
1691
|
+
});
|
|
1666
1692
|
this.activeFormGroup.addControl(name, control);
|
|
1667
1693
|
}
|
|
1668
1694
|
else if (forceValueFromConfig) {
|
|
1669
|
-
control.setValue(this.getInitialValue(), {
|
|
1695
|
+
control.setValue(this.getInitialValue(), {
|
|
1696
|
+
emitEvent: false,
|
|
1697
|
+
});
|
|
1670
1698
|
}
|
|
1671
1699
|
else if (!this.formGroup && this.value !== undefined) {
|
|
1672
|
-
control.setValue(this.normalizeValue(this.value), {
|
|
1700
|
+
control.setValue(this.normalizeValue(this.value), {
|
|
1701
|
+
emitEvent: false,
|
|
1702
|
+
});
|
|
1673
1703
|
}
|
|
1674
1704
|
control.setValidators(this.getValidators());
|
|
1675
1705
|
if (this.resolvedDisabled) {
|
|
1676
|
-
control.disable({
|
|
1706
|
+
control.disable({
|
|
1707
|
+
emitEvent: false,
|
|
1708
|
+
});
|
|
1677
1709
|
}
|
|
1678
1710
|
else {
|
|
1679
|
-
control.enable({
|
|
1711
|
+
control.enable({
|
|
1712
|
+
emitEvent: false,
|
|
1713
|
+
});
|
|
1680
1714
|
}
|
|
1681
|
-
control.updateValueAndValidity({
|
|
1715
|
+
control.updateValueAndValidity({
|
|
1716
|
+
emitEvent: false,
|
|
1717
|
+
});
|
|
1682
1718
|
this.valueChangesSubscription?.unsubscribe();
|
|
1683
1719
|
this.valueChangesSubscription = control.valueChanges.subscribe((selectedValues) => {
|
|
1684
1720
|
const normalizedValues = this.normalizeValue(selectedValues);
|
|
@@ -1690,7 +1726,7 @@ class PTMultiSelectComponent {
|
|
|
1690
1726
|
if (this.formField?.value !== undefined) {
|
|
1691
1727
|
return this.normalizeValue(this.formField.value);
|
|
1692
1728
|
}
|
|
1693
|
-
if (
|
|
1729
|
+
if (Array.isArray(this.value)) {
|
|
1694
1730
|
return this.normalizeValue(this.value);
|
|
1695
1731
|
}
|
|
1696
1732
|
return this.normalizeValue(this.config?.value);
|
|
@@ -1700,39 +1736,42 @@ class PTMultiSelectComponent {
|
|
|
1700
1736
|
if (this.resolvedRequired) {
|
|
1701
1737
|
validators.push(Validators.required);
|
|
1702
1738
|
}
|
|
1739
|
+
if (Array.isArray(this.formField?.validators) &&
|
|
1740
|
+
this.formField.validators.length > 0) {
|
|
1741
|
+
validators.push(...this.formField.validators);
|
|
1742
|
+
}
|
|
1703
1743
|
return validators;
|
|
1704
1744
|
}
|
|
1705
|
-
/**
|
|
1706
|
-
* Le MultiSelect doit manipuler un tableau d'identifiants primitifs,
|
|
1707
|
-
* pas des objets complets, pour éviter les problèmes de référence.
|
|
1708
|
-
*/
|
|
1709
1745
|
normalizeValue(value) {
|
|
1710
|
-
if (!Array.isArray(value)) {
|
|
1746
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
1711
1747
|
return [];
|
|
1712
1748
|
}
|
|
1713
|
-
if (value.
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
return value;
|
|
1749
|
+
if (value.every((item) => typeof item === 'number' ||
|
|
1750
|
+
typeof item === 'string' ||
|
|
1751
|
+
typeof item === 'boolean')) {
|
|
1752
|
+
return [...value];
|
|
1718
1753
|
}
|
|
1754
|
+
const optionValue = this.resolvedOptionValue;
|
|
1719
1755
|
return value
|
|
1720
1756
|
.map((item) => {
|
|
1721
|
-
|
|
1722
|
-
|
|
1757
|
+
if (item === null || item === undefined) {
|
|
1758
|
+
return null;
|
|
1759
|
+
}
|
|
1760
|
+
if (typeof item !== 'object') {
|
|
1761
|
+
return item;
|
|
1762
|
+
}
|
|
1763
|
+
if (item[optionValue] !== undefined) {
|
|
1723
1764
|
return item[optionValue];
|
|
1724
1765
|
}
|
|
1725
|
-
return item
|
|
1766
|
+
return item.value ?? item.id ?? null;
|
|
1726
1767
|
})
|
|
1727
1768
|
.filter((item) => item !== null && item !== undefined);
|
|
1728
1769
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
return (this.resolvedErrorText ||
|
|
1733
|
-
`${this.resolvedLabel || this.controlName} is required`);
|
|
1770
|
+
resolveHiddenValue(hidden) {
|
|
1771
|
+
if (typeof hidden === 'function') {
|
|
1772
|
+
return Boolean(hidden(this.activeFormGroup.getRawValue()));
|
|
1734
1773
|
}
|
|
1735
|
-
return
|
|
1774
|
+
return Boolean(hidden);
|
|
1736
1775
|
}
|
|
1737
1776
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTMultiSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1738
1777
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTMultiSelectComponent, isStandalone: false, selector: "pt-multi-select", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n @if (resolvedLabel) {\n <label [for]=\"inputId\" class=\"field-label\">\n {{ resolvedLabel }}\n </label>\n }\n\n <p-multiSelect\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [display]=\"resolvedDisplay\"\n [maxSelectedLabels]=\"resolvedMaxSelectedLabels\"\n [selectedItemsLabel]=\"resolvedSelectedItemsLabel\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{ baseZIndex: 11000 }\"\n ></p-multiSelect>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-multiselect{width:100%}.form-field ::ng-deep .p-multiselect.ng-invalid.ng-touched,.form-field ::ng-deep .p-multiselect.ng-invalid.ng-dirty{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }] }); }
|
|
@@ -2357,56 +2396,109 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2357
2396
|
}]
|
|
2358
2397
|
}] });
|
|
2359
2398
|
|
|
2399
|
+
// projects/ng-prime-tools/src/lib/pt-check-box-input/pt-check-box-input.component.ts
|
|
2360
2400
|
class PTCheckBoxInputComponent {
|
|
2361
2401
|
ngOnInit() {
|
|
2362
2402
|
this.setupControl();
|
|
2363
2403
|
}
|
|
2404
|
+
ngOnChanges(changes) {
|
|
2405
|
+
if (changes['formGroup'] || changes['formField']) {
|
|
2406
|
+
this.setupControl();
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2364
2409
|
get inputId() {
|
|
2365
2410
|
return `pt-checkbox-${this.formField?.name || 'field'}`;
|
|
2366
2411
|
}
|
|
2412
|
+
get errorId() {
|
|
2413
|
+
return `pt-checkbox-error-${this.formField?.name || 'field'}`;
|
|
2414
|
+
}
|
|
2415
|
+
get isInvalid() {
|
|
2416
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
2417
|
+
return Boolean(control &&
|
|
2418
|
+
control.enabled &&
|
|
2419
|
+
control.invalid &&
|
|
2420
|
+
(control.touched || control.dirty));
|
|
2421
|
+
}
|
|
2422
|
+
getErrorMessage() {
|
|
2423
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
2424
|
+
if (!control?.errors) {
|
|
2425
|
+
return '';
|
|
2426
|
+
}
|
|
2427
|
+
const errorKey = this.resolveFirstErrorKey(control.errors);
|
|
2428
|
+
if (!errorKey) {
|
|
2429
|
+
return '';
|
|
2430
|
+
}
|
|
2431
|
+
const customMessage = this.formField.validationMessages?.[errorKey];
|
|
2432
|
+
if (customMessage) {
|
|
2433
|
+
return customMessage;
|
|
2434
|
+
}
|
|
2435
|
+
if (this.formField.errorText) {
|
|
2436
|
+
return this.formField.errorText;
|
|
2437
|
+
}
|
|
2438
|
+
const label = this.formField.label?.trim() || this.formField.name;
|
|
2439
|
+
switch (errorKey) {
|
|
2440
|
+
case 'required':
|
|
2441
|
+
return `${label} is required`;
|
|
2442
|
+
default:
|
|
2443
|
+
return `${label} is invalid`;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2367
2446
|
setupControl() {
|
|
2368
|
-
|
|
2447
|
+
const name = this.formField?.name;
|
|
2448
|
+
if (!name || !this.formGroup) {
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2451
|
+
let control = this.formGroup.get(name);
|
|
2369
2452
|
if (!control) {
|
|
2370
|
-
control = new FormControl(
|
|
2371
|
-
|
|
2453
|
+
control = new FormControl(this.resolveInitialValue(), {
|
|
2454
|
+
nonNullable: true,
|
|
2455
|
+
});
|
|
2456
|
+
this.formGroup.addControl(name, control);
|
|
2372
2457
|
}
|
|
2373
|
-
|
|
2374
|
-
control.setValidators(validators);
|
|
2458
|
+
control.setValidators(this.getValidators());
|
|
2375
2459
|
if (this.formField.disabled) {
|
|
2376
|
-
control.disable({
|
|
2460
|
+
control.disable({
|
|
2461
|
+
emitEvent: false,
|
|
2462
|
+
});
|
|
2377
2463
|
}
|
|
2378
2464
|
else {
|
|
2379
|
-
control.enable({
|
|
2465
|
+
control.enable({
|
|
2466
|
+
emitEvent: false,
|
|
2467
|
+
});
|
|
2380
2468
|
}
|
|
2381
|
-
control.updateValueAndValidity({
|
|
2469
|
+
control.updateValueAndValidity({
|
|
2470
|
+
emitEvent: false,
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
resolveInitialValue() {
|
|
2474
|
+
const value = this.formField.value;
|
|
2475
|
+
if (typeof value === 'boolean') {
|
|
2476
|
+
return value;
|
|
2477
|
+
}
|
|
2478
|
+
return false;
|
|
2382
2479
|
}
|
|
2383
2480
|
getValidators() {
|
|
2384
2481
|
const validators = [];
|
|
2385
2482
|
if (this.formField.required) {
|
|
2386
|
-
validators.push(
|
|
2483
|
+
validators.push(Validators.requiredTrue);
|
|
2484
|
+
}
|
|
2485
|
+
if (Array.isArray(this.formField.validators) &&
|
|
2486
|
+
this.formField.validators.length > 0) {
|
|
2487
|
+
validators.push(...this.formField.validators);
|
|
2387
2488
|
}
|
|
2388
2489
|
return validators;
|
|
2389
2490
|
}
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
: { requiredChoice: true };
|
|
2395
|
-
};
|
|
2396
|
-
}
|
|
2397
|
-
getErrorMessage() {
|
|
2398
|
-
const control = this.formGroup.get(this.formField.name);
|
|
2399
|
-
if (control?.errors?.['requiredChoice']) {
|
|
2400
|
-
return this.formField.errorText || `${this.formField.label} is required`;
|
|
2401
|
-
}
|
|
2402
|
-
return '';
|
|
2491
|
+
resolveFirstErrorKey(errors) {
|
|
2492
|
+
const priority = ['required'];
|
|
2493
|
+
return (priority.find((key) => errors[key] !== undefined) ||
|
|
2494
|
+
Object.keys(errors)[0]);
|
|
2403
2495
|
}
|
|
2404
2496
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTCheckBoxInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2405
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTCheckBoxInputComponent, isStandalone: false, selector: "pt-check-box-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "
|
|
2497
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTCheckBoxInputComponent, isStandalone: false, selector: "pt-check-box-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-check-box-input/pt-check-box-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n 'max-width': formField.width || '100%',\n }\"\n>\n <div class=\"checkbox-container\">\n <p-checkbox\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [binary]=\"true\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></p-checkbox>\n\n @if (formField.label) {\n <label class=\"checkbox-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n </div>\n\n @if (isInvalid) {\n <div class=\"error-container\" role=\"alert\" [id]=\"errorId\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"p-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{display:flex;flex-direction:column;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.checkbox-container{display:flex;align-items:center;gap:.5rem;width:100%;min-width:0}.checkbox-label{min-width:0;cursor:pointer;font-size:1rem;font-weight:600;overflow-wrap:anywhere}.required-indicator{margin-left:.2rem;color:#ef4444}.form-field-invalid ::ng-deep .p-checkbox-box{border-color:#ef4444!important}.error-container{display:flex;align-items:flex-start;gap:.35rem;width:100%;min-width:0;margin-top:.35rem;color:#ef4444}.error-container .pi{flex:0 0 auto;margin-top:.1rem;font-size:.8rem}.p-error{min-width:0;color:inherit;font-size:.8rem;overflow-wrap:anywhere}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
|
|
2406
2498
|
}
|
|
2407
2499
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTCheckBoxInputComponent, decorators: [{
|
|
2408
2500
|
type: Component,
|
|
2409
|
-
args: [{ selector: 'pt-check-box-input', standalone: false, template: "
|
|
2501
|
+
args: [{ selector: 'pt-check-box-input', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-check-box-input/pt-check-box-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n 'max-width': formField.width || '100%',\n }\"\n>\n <div class=\"checkbox-container\">\n <p-checkbox\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n [binary]=\"true\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></p-checkbox>\n\n @if (formField.label) {\n <label class=\"checkbox-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n </div>\n\n @if (isInvalid) {\n <div class=\"error-container\" role=\"alert\" [id]=\"errorId\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"p-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{display:flex;flex-direction:column;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.checkbox-container{display:flex;align-items:center;gap:.5rem;width:100%;min-width:0}.checkbox-label{min-width:0;cursor:pointer;font-size:1rem;font-weight:600;overflow-wrap:anywhere}.required-indicator{margin-left:.2rem;color:#ef4444}.form-field-invalid ::ng-deep .p-checkbox-box{border-color:#ef4444!important}.error-container{display:flex;align-items:flex-start;gap:.35rem;width:100%;min-width:0;margin-top:.35rem;color:#ef4444}.error-container .pi{flex:0 0 auto;margin-top:.1rem;font-size:.8rem}.p-error{min-width:0;color:inherit;font-size:.8rem;overflow-wrap:anywhere}\n"] }]
|
|
2410
2502
|
}], propDecorators: { formGroup: [{
|
|
2411
2503
|
type: Input
|
|
2412
2504
|
}], formField: [{
|
|
@@ -2541,12 +2633,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2541
2633
|
}]
|
|
2542
2634
|
}], ctorParameters: () => [] });
|
|
2543
2635
|
|
|
2636
|
+
// projects/ng-prime-tools/src/lib/pt-date-input/pt-date-input.component.ts
|
|
2544
2637
|
class PTDateInputComponent {
|
|
2545
2638
|
constructor(dateService) {
|
|
2546
2639
|
this.dateService = dateService;
|
|
2547
|
-
/**
|
|
2548
|
-
* Two-way standalone value.
|
|
2549
|
-
*/
|
|
2550
2640
|
this.value = null;
|
|
2551
2641
|
this.valueChange = new EventEmitter();
|
|
2552
2642
|
this.dateChange = new EventEmitter();
|
|
@@ -2579,8 +2669,15 @@ class PTDateInputComponent {
|
|
|
2579
2669
|
get inputId() {
|
|
2580
2670
|
return `pt-date-${this.controlName}`;
|
|
2581
2671
|
}
|
|
2672
|
+
get labelId() {
|
|
2673
|
+
return `pt-date-label-${this.controlName}`;
|
|
2674
|
+
}
|
|
2675
|
+
get errorId() {
|
|
2676
|
+
return `pt-date-error-${this.controlName}`;
|
|
2677
|
+
}
|
|
2582
2678
|
get resolvedHidden() {
|
|
2583
|
-
|
|
2679
|
+
const hidden = this.formField?.hidden ?? this.config?.hidden;
|
|
2680
|
+
return this.resolveHiddenValue(hidden);
|
|
2584
2681
|
}
|
|
2585
2682
|
get resolvedLabel() {
|
|
2586
2683
|
return this.formField?.label || this.config?.label;
|
|
@@ -2626,12 +2723,47 @@ class PTDateInputComponent {
|
|
|
2626
2723
|
get resolvedErrorText() {
|
|
2627
2724
|
return this.formField?.errorText || this.config?.errorText;
|
|
2628
2725
|
}
|
|
2726
|
+
get isInvalid() {
|
|
2727
|
+
const control = this.activeFormGroup.get(this.controlName);
|
|
2728
|
+
return Boolean(control &&
|
|
2729
|
+
control.enabled &&
|
|
2730
|
+
control.invalid &&
|
|
2731
|
+
(control.touched || control.dirty));
|
|
2732
|
+
}
|
|
2733
|
+
getErrorMessage() {
|
|
2734
|
+
const control = this.activeFormGroup.get(this.controlName);
|
|
2735
|
+
if (!control?.errors) {
|
|
2736
|
+
return '';
|
|
2737
|
+
}
|
|
2738
|
+
const errorKey = this.resolveFirstErrorKey(control.errors);
|
|
2739
|
+
if (!errorKey) {
|
|
2740
|
+
return '';
|
|
2741
|
+
}
|
|
2742
|
+
const customMessage = this.formField?.validationMessages?.[errorKey];
|
|
2743
|
+
if (customMessage) {
|
|
2744
|
+
return customMessage;
|
|
2745
|
+
}
|
|
2746
|
+
if (this.resolvedErrorText) {
|
|
2747
|
+
return this.resolvedErrorText;
|
|
2748
|
+
}
|
|
2749
|
+
const label = this.resolvedLabel || this.controlName;
|
|
2750
|
+
switch (errorKey) {
|
|
2751
|
+
case 'required':
|
|
2752
|
+
return `${label} is required`;
|
|
2753
|
+
case 'minDate':
|
|
2754
|
+
return `${label} must be on or after ${this.resolvedMinValue}`;
|
|
2755
|
+
case 'maxDate':
|
|
2756
|
+
return `${label} must be on or before ${this.resolvedMaxValue}`;
|
|
2757
|
+
default:
|
|
2758
|
+
return `${label} is invalid`;
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2629
2761
|
initializeComponent() {
|
|
2630
2762
|
this.defaultDateFormat = this.dateService.assignDefaultDateFormat(this.resolvedDateInputType, this.formField?.dateFormat || this.config?.dateFormat);
|
|
2631
|
-
this.
|
|
2763
|
+
this.defaultPlaceholder = getDefaultPlaceholder(this.resolvedDateInputType);
|
|
2632
2764
|
this.initializeDateLimits();
|
|
2633
2765
|
this.validateConfiguration();
|
|
2634
|
-
this.
|
|
2766
|
+
this.setupControl();
|
|
2635
2767
|
}
|
|
2636
2768
|
setupControl() {
|
|
2637
2769
|
const name = this.controlName;
|
|
@@ -2643,19 +2775,27 @@ class PTDateInputComponent {
|
|
|
2643
2775
|
control = new FormControl(this.getInitialValue());
|
|
2644
2776
|
this.activeFormGroup.addControl(name, control);
|
|
2645
2777
|
}
|
|
2646
|
-
if (!this.formGroup &&
|
|
2778
|
+
else if (!this.formGroup &&
|
|
2647
2779
|
this.value !== undefined &&
|
|
2648
2780
|
control.value !== this.value) {
|
|
2649
|
-
control.setValue(this.value, {
|
|
2781
|
+
control.setValue(this.value, {
|
|
2782
|
+
emitEvent: false,
|
|
2783
|
+
});
|
|
2650
2784
|
}
|
|
2651
2785
|
control.setValidators(this.getValidators());
|
|
2652
2786
|
if (this.resolvedDisabled) {
|
|
2653
|
-
control.disable({
|
|
2787
|
+
control.disable({
|
|
2788
|
+
emitEvent: false,
|
|
2789
|
+
});
|
|
2654
2790
|
}
|
|
2655
2791
|
else {
|
|
2656
|
-
control.enable({
|
|
2792
|
+
control.enable({
|
|
2793
|
+
emitEvent: false,
|
|
2794
|
+
});
|
|
2657
2795
|
}
|
|
2658
|
-
control.updateValueAndValidity({
|
|
2796
|
+
control.updateValueAndValidity({
|
|
2797
|
+
emitEvent: false,
|
|
2798
|
+
});
|
|
2659
2799
|
this.valueChangesSubscription?.unsubscribe();
|
|
2660
2800
|
this.valueChangesSubscription = control.valueChanges.subscribe((selectedValue) => {
|
|
2661
2801
|
this.valueChange.emit(selectedValue);
|
|
@@ -2686,10 +2826,9 @@ class PTDateInputComponent {
|
|
|
2686
2826
|
catch (error) {
|
|
2687
2827
|
if (error instanceof Error) {
|
|
2688
2828
|
console.error(error.message);
|
|
2829
|
+
return;
|
|
2689
2830
|
}
|
|
2690
|
-
|
|
2691
|
-
console.error('An unknown error occurred.');
|
|
2692
|
-
}
|
|
2831
|
+
console.error('An unknown error occurred.');
|
|
2693
2832
|
}
|
|
2694
2833
|
}
|
|
2695
2834
|
getValidators() {
|
|
@@ -2697,22 +2836,90 @@ class PTDateInputComponent {
|
|
|
2697
2836
|
if (this.resolvedRequired) {
|
|
2698
2837
|
validators.push(Validators.required);
|
|
2699
2838
|
}
|
|
2839
|
+
if (this.minDate) {
|
|
2840
|
+
validators.push(this.minDateValidator(this.minDate));
|
|
2841
|
+
}
|
|
2842
|
+
if (this.maxDate) {
|
|
2843
|
+
validators.push(this.maxDateValidator(this.maxDate));
|
|
2844
|
+
}
|
|
2845
|
+
if (Array.isArray(this.formField?.validators) &&
|
|
2846
|
+
this.formField.validators.length > 0) {
|
|
2847
|
+
validators.push(...this.formField.validators);
|
|
2848
|
+
}
|
|
2700
2849
|
return validators;
|
|
2701
2850
|
}
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2851
|
+
minDateValidator(minDate) {
|
|
2852
|
+
return (control) => {
|
|
2853
|
+
const dates = this.extractDates(control.value);
|
|
2854
|
+
if (dates.length === 0) {
|
|
2855
|
+
return null;
|
|
2856
|
+
}
|
|
2857
|
+
const hasInvalidDate = dates.some((date) => date.getTime() < minDate.getTime());
|
|
2858
|
+
return hasInvalidDate
|
|
2859
|
+
? {
|
|
2860
|
+
minDate: {
|
|
2861
|
+
requiredMinDate: minDate,
|
|
2862
|
+
actualValue: control.value,
|
|
2863
|
+
},
|
|
2864
|
+
}
|
|
2865
|
+
: null;
|
|
2866
|
+
};
|
|
2867
|
+
}
|
|
2868
|
+
maxDateValidator(maxDate) {
|
|
2869
|
+
return (control) => {
|
|
2870
|
+
const dates = this.extractDates(control.value);
|
|
2871
|
+
if (dates.length === 0) {
|
|
2872
|
+
return null;
|
|
2873
|
+
}
|
|
2874
|
+
const hasInvalidDate = dates.some((date) => date.getTime() > maxDate.getTime());
|
|
2875
|
+
return hasInvalidDate
|
|
2876
|
+
? {
|
|
2877
|
+
maxDate: {
|
|
2878
|
+
requiredMaxDate: maxDate,
|
|
2879
|
+
actualValue: control.value,
|
|
2880
|
+
},
|
|
2881
|
+
}
|
|
2882
|
+
: null;
|
|
2883
|
+
};
|
|
2884
|
+
}
|
|
2885
|
+
extractDates(value) {
|
|
2886
|
+
if (value === null || value === undefined || value === '') {
|
|
2887
|
+
return [];
|
|
2707
2888
|
}
|
|
2708
|
-
|
|
2889
|
+
const values = Array.isArray(value) ? value : [value];
|
|
2890
|
+
return values
|
|
2891
|
+
.map((item) => this.convertToDate(item))
|
|
2892
|
+
.filter((date) => date !== null);
|
|
2893
|
+
}
|
|
2894
|
+
convertToDate(value) {
|
|
2895
|
+
if (value === null || value === undefined || value === '') {
|
|
2896
|
+
return null;
|
|
2897
|
+
}
|
|
2898
|
+
if (value instanceof Date) {
|
|
2899
|
+
return Number.isNaN(value.getTime()) ? null : value;
|
|
2900
|
+
}
|
|
2901
|
+
const parsedDate = parseDate(value, this.resolvedDateFormat);
|
|
2902
|
+
return parsedDate && !Number.isNaN(parsedDate.getTime())
|
|
2903
|
+
? parsedDate
|
|
2904
|
+
: null;
|
|
2905
|
+
}
|
|
2906
|
+
resolveFirstErrorKey(errors) {
|
|
2907
|
+
const priority = ['required', 'minDate', 'maxDate'];
|
|
2908
|
+
const prioritizedError = priority.find((key) => errors[key] !== undefined);
|
|
2909
|
+
return prioritizedError || Object.keys(errors)[0];
|
|
2910
|
+
}
|
|
2911
|
+
resolveHiddenValue(hidden) {
|
|
2912
|
+
if (typeof hidden === 'function') {
|
|
2913
|
+
return Boolean(hidden(this.activeFormGroup.getRawValue()));
|
|
2914
|
+
}
|
|
2915
|
+
return Boolean(hidden);
|
|
2709
2916
|
}
|
|
2710
2917
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDateInputComponent, deps: [{ token: PTDateService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2711
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDateInputComponent, isStandalone: false, selector: "pt-date-input", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", dateChange: "dateChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n
|
|
2918
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDateInputComponent, isStandalone: false, selector: "pt-date-input", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", dateChange: "dateChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n class=\"form-field\"\n [formGroup]=\"activeFormGroup\"\n [ngClass]=\"{\n 'form-field-invalid':\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty),\n }\"\n [ngStyle]=\"{\n width: resolvedWidth,\n 'max-width': resolvedWidth,\n }\"\n >\n @if (resolvedLabel) {\n <label class=\"field-label\" [id]=\"labelId\" [for]=\"inputId\">\n {{ resolvedLabel }}\n\n @if (resolvedRequired) {\n <span class=\"required-indicator\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <p-datepicker\n class=\"date-input\"\n styleClass=\"date-input-control\"\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [placeholder]=\"resolvedPlaceholder\"\n [dateFormat]=\"resolvedDateFormat\"\n [showIcon]=\"resolvedShowIcon\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [showTime]=\"\n resolvedDateInputType === 'datetime' || resolvedDateInputType === 'time'\n \"\n [timeOnly]=\"resolvedDateInputType === 'time'\"\n [hourFormat]=\"resolvedHourFormat\"\n [selectionMode]=\"resolvedDateInputType === 'range' ? 'range' : 'single'\"\n [readonlyInput]=\"false\"\n [showButtonBar]=\"true\"\n [appendTo]=\"'body'\"\n [panelStyle]=\"{\n 'z-index': 99999,\n }\"\n [attr.aria-labelledby]=\"resolvedLabel ? labelId : null\"\n [attr.aria-describedby]=\"\n activeFormGroup.get(controlName)?.invalid\n ? controlName + '-error'\n : null\n \"\n [attr.aria-invalid]=\"\n activeFormGroup.get(controlName)?.invalid ? 'true' : 'false'\n \"\n ></p-datepicker>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\" role=\"alert\" [id]=\"controlName + '-error'\">\n <i class=\"pi pi-exclamation-circle\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem;overflow:visible}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-datepicker.ng-invalid.ng-touched .p-inputtext,.form-field ::ng-deep .p-datepicker.ng-invalid.ng-dirty .p-inputtext{border-color:#dc2626}.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-touched,.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-dirty{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo", "motionOptions"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }] }); }
|
|
2712
2919
|
}
|
|
2713
2920
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDateInputComponent, decorators: [{
|
|
2714
2921
|
type: Component,
|
|
2715
|
-
args: [{ selector: 'pt-date-input', standalone: false, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n
|
|
2922
|
+
args: [{ selector: 'pt-date-input', standalone: false, template: "@if (!resolvedHidden) {\n <div\n class=\"form-field\"\n [formGroup]=\"activeFormGroup\"\n [ngClass]=\"{\n 'form-field-invalid':\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty),\n }\"\n [ngStyle]=\"{\n width: resolvedWidth,\n 'max-width': resolvedWidth,\n }\"\n >\n @if (resolvedLabel) {\n <label class=\"field-label\" [id]=\"labelId\" [for]=\"inputId\">\n {{ resolvedLabel }}\n\n @if (resolvedRequired) {\n <span class=\"required-indicator\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <p-datepicker\n class=\"date-input\"\n styleClass=\"date-input-control\"\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [placeholder]=\"resolvedPlaceholder\"\n [dateFormat]=\"resolvedDateFormat\"\n [showIcon]=\"resolvedShowIcon\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [showTime]=\"\n resolvedDateInputType === 'datetime' || resolvedDateInputType === 'time'\n \"\n [timeOnly]=\"resolvedDateInputType === 'time'\"\n [hourFormat]=\"resolvedHourFormat\"\n [selectionMode]=\"resolvedDateInputType === 'range' ? 'range' : 'single'\"\n [readonlyInput]=\"false\"\n [showButtonBar]=\"true\"\n [appendTo]=\"'body'\"\n [panelStyle]=\"{\n 'z-index': 99999,\n }\"\n [attr.aria-labelledby]=\"resolvedLabel ? labelId : null\"\n [attr.aria-describedby]=\"\n activeFormGroup.get(controlName)?.invalid\n ? controlName + '-error'\n : null\n \"\n [attr.aria-invalid]=\"\n activeFormGroup.get(controlName)?.invalid ? 'true' : 'false'\n \"\n ></p-datepicker>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\" role=\"alert\" [id]=\"controlName + '-error'\">\n <i class=\"pi pi-exclamation-circle\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem;overflow:visible}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-datepicker.ng-invalid.ng-touched .p-inputtext,.form-field ::ng-deep .p-datepicker.ng-invalid.ng-dirty .p-inputtext{border-color:#dc2626}.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-touched,.form-field ::ng-deep .p-datepicker-input.ng-invalid.ng-dirty{border-color:#dc2626}\n"] }]
|
|
2716
2923
|
}], ctorParameters: () => [{ type: PTDateService }], propDecorators: { formGroup: [{
|
|
2717
2924
|
type: Input
|
|
2718
2925
|
}], formField: [{
|
|
@@ -2727,18 +2934,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2727
2934
|
type: Output
|
|
2728
2935
|
}] } });
|
|
2729
2936
|
|
|
2937
|
+
// projects/ng-prime-tools/src/lib/pt-number-input/pt-number-input.component.ts
|
|
2730
2938
|
class PTNumberInputComponent {
|
|
2731
2939
|
ngOnInit() {
|
|
2732
2940
|
this.setupControl();
|
|
2733
2941
|
}
|
|
2734
2942
|
ngOnChanges(changes) {
|
|
2735
|
-
if (changes['
|
|
2943
|
+
if (changes['formGroup'] || changes['formField']) {
|
|
2736
2944
|
this.setupControl();
|
|
2737
2945
|
}
|
|
2738
2946
|
}
|
|
2739
2947
|
get inputId() {
|
|
2740
2948
|
return `pt-number-${this.formField?.name || 'field'}`;
|
|
2741
2949
|
}
|
|
2950
|
+
get errorId() {
|
|
2951
|
+
return `pt-number-error-${this.formField?.name || 'field'}`;
|
|
2952
|
+
}
|
|
2953
|
+
get isInvalid() {
|
|
2954
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
2955
|
+
return Boolean(control &&
|
|
2956
|
+
control.enabled &&
|
|
2957
|
+
control.invalid &&
|
|
2958
|
+
(control.touched || control.dirty));
|
|
2959
|
+
}
|
|
2960
|
+
getErrorMessage() {
|
|
2961
|
+
const control = this.formGroup.get(this.formField.name);
|
|
2962
|
+
if (!control?.errors) {
|
|
2963
|
+
return '';
|
|
2964
|
+
}
|
|
2965
|
+
const errorKey = this.resolveFirstErrorKey(control.errors);
|
|
2966
|
+
if (!errorKey) {
|
|
2967
|
+
return '';
|
|
2968
|
+
}
|
|
2969
|
+
const customMessage = this.formField.validationMessages?.[errorKey];
|
|
2970
|
+
if (customMessage) {
|
|
2971
|
+
return customMessage;
|
|
2972
|
+
}
|
|
2973
|
+
if (this.formField.errorText) {
|
|
2974
|
+
return this.formField.errorText;
|
|
2975
|
+
}
|
|
2976
|
+
const label = this.formField.label?.trim() || this.formField.name;
|
|
2977
|
+
switch (errorKey) {
|
|
2978
|
+
case 'required':
|
|
2979
|
+
return `${label} is required`;
|
|
2980
|
+
case 'min': {
|
|
2981
|
+
const minValue = control.getError('min')?.min ?? this.formField.minValue;
|
|
2982
|
+
return `${label} must be at least ${minValue}`;
|
|
2983
|
+
}
|
|
2984
|
+
case 'max': {
|
|
2985
|
+
const maxValue = control.getError('max')?.max ?? this.formField.maxValue;
|
|
2986
|
+
return `${label} must be at most ${maxValue}`;
|
|
2987
|
+
}
|
|
2988
|
+
case 'pattern':
|
|
2989
|
+
return `${label} is invalid`;
|
|
2990
|
+
default:
|
|
2991
|
+
return `${label} is invalid`;
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2742
2994
|
setupControl() {
|
|
2743
2995
|
const name = this.formField?.name;
|
|
2744
2996
|
if (!name || !this.formGroup) {
|
|
@@ -2746,24 +2998,30 @@ class PTNumberInputComponent {
|
|
|
2746
2998
|
}
|
|
2747
2999
|
let control = this.formGroup.get(name);
|
|
2748
3000
|
if (!control) {
|
|
2749
|
-
control = new FormControl(this.formField
|
|
3001
|
+
control = new FormControl(this.formField.value ?? null);
|
|
2750
3002
|
this.formGroup.addControl(name, control);
|
|
2751
3003
|
}
|
|
2752
3004
|
control.setValidators(this.getValidators());
|
|
2753
|
-
if (this.formField
|
|
2754
|
-
control.disable({
|
|
3005
|
+
if (this.formField.disabled) {
|
|
3006
|
+
control.disable({
|
|
3007
|
+
emitEvent: false,
|
|
3008
|
+
});
|
|
2755
3009
|
}
|
|
2756
3010
|
else {
|
|
2757
|
-
control.enable({
|
|
3011
|
+
control.enable({
|
|
3012
|
+
emitEvent: false,
|
|
3013
|
+
});
|
|
2758
3014
|
}
|
|
2759
|
-
control.updateValueAndValidity({
|
|
3015
|
+
control.updateValueAndValidity({
|
|
3016
|
+
emitEvent: false,
|
|
3017
|
+
});
|
|
2760
3018
|
}
|
|
2761
3019
|
getValidators() {
|
|
2762
3020
|
const validators = [];
|
|
2763
|
-
if (this.formField
|
|
3021
|
+
if (this.formField.required) {
|
|
2764
3022
|
validators.push(Validators.required);
|
|
2765
3023
|
}
|
|
2766
|
-
if (this.formField
|
|
3024
|
+
if (this.formField.minValue !== undefined &&
|
|
2767
3025
|
this.formField.minValue !== null) {
|
|
2768
3026
|
const minValue = Number(this.formField.minValue);
|
|
2769
3027
|
if (!Number.isNaN(minValue)) {
|
|
@@ -2773,7 +3031,7 @@ class PTNumberInputComponent {
|
|
|
2773
3031
|
console.error(`Invalid minValue: ${this.formField.minValue} is not a number.`);
|
|
2774
3032
|
}
|
|
2775
3033
|
}
|
|
2776
|
-
if (this.formField
|
|
3034
|
+
if (this.formField.maxValue !== undefined &&
|
|
2777
3035
|
this.formField.maxValue !== null) {
|
|
2778
3036
|
const maxValue = Number(this.formField.maxValue);
|
|
2779
3037
|
if (!Number.isNaN(maxValue)) {
|
|
@@ -2783,47 +3041,41 @@ class PTNumberInputComponent {
|
|
|
2783
3041
|
console.error(`Invalid maxValue: ${this.formField.maxValue} is not a number.`);
|
|
2784
3042
|
}
|
|
2785
3043
|
}
|
|
2786
|
-
if (this.formField
|
|
3044
|
+
if (this.formField.inputValidation) {
|
|
2787
3045
|
validators.push(this.validateWithInputValidation(this.formField.inputValidation));
|
|
2788
3046
|
}
|
|
3047
|
+
else if (this.formField.pattern) {
|
|
3048
|
+
validators.push(Validators.pattern(this.formField.pattern));
|
|
3049
|
+
}
|
|
3050
|
+
if (Array.isArray(this.formField.validators) &&
|
|
3051
|
+
this.formField.validators.length > 0) {
|
|
3052
|
+
validators.push(...this.formField.validators);
|
|
3053
|
+
}
|
|
2789
3054
|
return validators;
|
|
2790
3055
|
}
|
|
2791
3056
|
validateWithInputValidation(inputValidation) {
|
|
2792
3057
|
return Validators.pattern(new RegExp(inputValidation));
|
|
2793
3058
|
}
|
|
2794
|
-
|
|
2795
|
-
const
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
}
|
|
2799
|
-
if (control?.hasError('min')) {
|
|
2800
|
-
return `${this.formField.label} must be at least ${this.formField.minValue}`;
|
|
2801
|
-
}
|
|
2802
|
-
if (control?.hasError('max')) {
|
|
2803
|
-
return `${this.formField.label} must be at most ${this.formField.maxValue}`;
|
|
2804
|
-
}
|
|
2805
|
-
if (control?.hasError('pattern')) {
|
|
2806
|
-
return `${this.formField.label} is invalid`;
|
|
2807
|
-
}
|
|
2808
|
-
return '';
|
|
3059
|
+
resolveFirstErrorKey(errors) {
|
|
3060
|
+
const priority = ['required', 'min', 'max', 'pattern'];
|
|
3061
|
+
return (priority.find((key) => errors[key] !== undefined) ||
|
|
3062
|
+
Object.keys(errors)[0]);
|
|
2809
3063
|
}
|
|
2810
3064
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTNumberInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2811
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTNumberInputComponent, isStandalone: false, selector: "pt-number-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "
|
|
3065
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTNumberInputComponent, isStandalone: false, selector: "pt-number-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-number-input/pt-number-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n 'max-width': formField.width || '100%',\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n <p-inputGroup class=\"number-input-group\">\n @if (!formField.iconPosition || formField.iconPosition === \"left\") {\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\" aria-hidden=\"true\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n\n <p-inputNumber\n class=\"number-input\"\n styleClass=\"number-input-control\"\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits ?? 0\"\n [maxFractionDigits]=\"formField.decimalDigits ?? 0\"\n [min]=\"\n formField.minValue !== undefined && formField.minValue !== null\n ? +formField.minValue\n : undefined\n \"\n [max]=\"\n formField.maxValue !== undefined && formField.maxValue !== null\n ? +formField.maxValue\n : undefined\n \"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></p-inputNumber>\n }\n\n @if (formField.iconPosition === \"right\") {\n <p-inputNumber\n class=\"number-input\"\n styleClass=\"number-input-control\"\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits ?? 0\"\n [maxFractionDigits]=\"formField.decimalDigits ?? 0\"\n [min]=\"\n formField.minValue !== undefined && formField.minValue !== null\n ? +formField.minValue\n : undefined\n \"\n [max]=\"\n formField.maxValue !== undefined && formField.maxValue !== null\n ? +formField.maxValue\n : undefined\n \"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></p-inputNumber>\n\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\" aria-hidden=\"true\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n\n @if (isInvalid) {\n <div class=\"error-container\" role=\"alert\" [id]=\"errorId\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{display:flex;flex-direction:column;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-size:1rem;font-weight:600}.required-indicator{margin-left:.2rem;color:#ef4444}.number-input-group{display:flex;width:100%;min-width:0;max-width:100%}:host ::ng-deep .number-input-group.p-inputgroup,:host ::ng-deep .number-input-group .p-inputgroup{display:flex;width:100%;min-width:0;max-width:100%}.number-input{display:block;flex:1 1 auto;width:100%;min-width:0;max-width:100%}:host ::ng-deep .number-input-control,:host ::ng-deep .number-input.p-inputnumber,:host ::ng-deep .number-input .p-inputnumber{flex:1 1 auto;width:100%;min-width:0;max-width:100%}:host ::ng-deep .number-input .p-inputnumber-input{width:100%;min-width:0}:host ::ng-deep .p-inputgroup-addon{flex:0 0 auto}.form-field-invalid ::ng-deep .p-inputnumber-input{border-color:#ef4444!important}.error-container{display:flex;align-items:flex-start;gap:.35rem;margin-top:.35rem;color:#ef4444}.error-container .pi{flex:0 0 auto;margin-top:.1rem;font-size:.8rem}.field-error{min-width:0;color:inherit;font-size:.8rem;overflow-wrap:anywhere}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$2.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "component", type: i4.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "component", type: i8$1.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }] }); }
|
|
2812
3066
|
}
|
|
2813
3067
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTNumberInputComponent, decorators: [{
|
|
2814
3068
|
type: Component,
|
|
2815
|
-
args: [{ selector: 'pt-number-input', standalone: false, template: "
|
|
3069
|
+
args: [{ selector: 'pt-number-input', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-number-input/pt-number-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n 'max-width': formField.width || '100%',\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n <p-inputGroup class=\"number-input-group\">\n @if (!formField.iconPosition || formField.iconPosition === \"left\") {\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\" aria-hidden=\"true\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n\n <p-inputNumber\n class=\"number-input\"\n styleClass=\"number-input-control\"\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits ?? 0\"\n [maxFractionDigits]=\"formField.decimalDigits ?? 0\"\n [min]=\"\n formField.minValue !== undefined && formField.minValue !== null\n ? +formField.minValue\n : undefined\n \"\n [max]=\"\n formField.maxValue !== undefined && formField.maxValue !== null\n ? +formField.maxValue\n : undefined\n \"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></p-inputNumber>\n }\n\n @if (formField.iconPosition === \"right\") {\n <p-inputNumber\n class=\"number-input\"\n styleClass=\"number-input-control\"\n [inputId]=\"inputId\"\n [name]=\"formField.name\"\n [formControlName]=\"formField.name\"\n mode=\"decimal\"\n [locale]=\"formField.numberFormat || undefined\"\n [useGrouping]=\"!!formField.numberFormat\"\n [minFractionDigits]=\"formField.decimalDigits ?? 0\"\n [maxFractionDigits]=\"formField.decimalDigits ?? 0\"\n [min]=\"\n formField.minValue !== undefined && formField.minValue !== null\n ? +formField.minValue\n : undefined\n \"\n [max]=\"\n formField.maxValue !== undefined && formField.maxValue !== null\n ? +formField.maxValue\n : undefined\n \"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></p-inputNumber>\n\n @if (formField.iconClass || formField.currency) {\n <p-inputGroupAddon>\n @if (formField.iconClass) {\n <i [ngClass]=\"formField.iconClass\" aria-hidden=\"true\"></i>\n }\n\n @if (!formField.iconClass && formField.currency) {\n <span>\n {{ formField.currency }}\n </span>\n }\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n\n @if (isInvalid) {\n <div class=\"error-container\" role=\"alert\" [id]=\"errorId\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{display:flex;flex-direction:column;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.field-label{display:block;margin-bottom:.5rem;font-size:1rem;font-weight:600}.required-indicator{margin-left:.2rem;color:#ef4444}.number-input-group{display:flex;width:100%;min-width:0;max-width:100%}:host ::ng-deep .number-input-group.p-inputgroup,:host ::ng-deep .number-input-group .p-inputgroup{display:flex;width:100%;min-width:0;max-width:100%}.number-input{display:block;flex:1 1 auto;width:100%;min-width:0;max-width:100%}:host ::ng-deep .number-input-control,:host ::ng-deep .number-input.p-inputnumber,:host ::ng-deep .number-input .p-inputnumber{flex:1 1 auto;width:100%;min-width:0;max-width:100%}:host ::ng-deep .number-input .p-inputnumber-input{width:100%;min-width:0}:host ::ng-deep .p-inputgroup-addon{flex:0 0 auto}.form-field-invalid ::ng-deep .p-inputnumber-input{border-color:#ef4444!important}.error-container{display:flex;align-items:flex-start;gap:.35rem;margin-top:.35rem;color:#ef4444}.error-container .pi{flex:0 0 auto;margin-top:.1rem;font-size:.8rem}.field-error{min-width:0;color:inherit;font-size:.8rem;overflow-wrap:anywhere}\n"] }]
|
|
2816
3070
|
}], propDecorators: { formGroup: [{
|
|
2817
3071
|
type: Input
|
|
2818
3072
|
}], formField: [{
|
|
2819
3073
|
type: Input
|
|
2820
3074
|
}] } });
|
|
2821
3075
|
|
|
3076
|
+
// projects/ng-prime-tools/src/lib/pt-switch-input/pt-switch-input.component.ts
|
|
2822
3077
|
class PTSwitchInputComponent {
|
|
2823
3078
|
constructor() {
|
|
2824
|
-
/**
|
|
2825
|
-
* Two-way standalone value.
|
|
2826
|
-
*/
|
|
2827
3079
|
this.value = null;
|
|
2828
3080
|
this.valueChange = new EventEmitter();
|
|
2829
3081
|
this.switchChange = new EventEmitter();
|
|
@@ -2856,7 +3108,8 @@ class PTSwitchInputComponent {
|
|
|
2856
3108
|
return `pt-switch-label-${this.controlName}`;
|
|
2857
3109
|
}
|
|
2858
3110
|
get resolvedHidden() {
|
|
2859
|
-
|
|
3111
|
+
const hidden = this.formField?.hidden ?? this.config?.hidden;
|
|
3112
|
+
return this.resolveHiddenValue(hidden);
|
|
2860
3113
|
}
|
|
2861
3114
|
get resolvedLabel() {
|
|
2862
3115
|
return this.formField?.label || this.config?.label;
|
|
@@ -2873,6 +3126,28 @@ class PTSwitchInputComponent {
|
|
|
2873
3126
|
get resolvedErrorText() {
|
|
2874
3127
|
return this.formField?.errorText || this.config?.errorText;
|
|
2875
3128
|
}
|
|
3129
|
+
getErrorMessage() {
|
|
3130
|
+
const control = this.activeFormGroup.get(this.controlName);
|
|
3131
|
+
if (!control?.errors) {
|
|
3132
|
+
return '';
|
|
3133
|
+
}
|
|
3134
|
+
const errorKey = Object.keys(control.errors)[0];
|
|
3135
|
+
if (!errorKey) {
|
|
3136
|
+
return '';
|
|
3137
|
+
}
|
|
3138
|
+
const customMessage = this.formField?.validationMessages?.[errorKey];
|
|
3139
|
+
if (customMessage) {
|
|
3140
|
+
return customMessage;
|
|
3141
|
+
}
|
|
3142
|
+
if (this.resolvedErrorText) {
|
|
3143
|
+
return this.resolvedErrorText;
|
|
3144
|
+
}
|
|
3145
|
+
const label = this.resolvedLabel || this.controlName;
|
|
3146
|
+
if (control.hasError('requiredChoice')) {
|
|
3147
|
+
return `${label} is required`;
|
|
3148
|
+
}
|
|
3149
|
+
return `${label} is invalid`;
|
|
3150
|
+
}
|
|
2876
3151
|
setupControl() {
|
|
2877
3152
|
const name = this.controlName;
|
|
2878
3153
|
if (!name) {
|
|
@@ -2886,16 +3161,24 @@ class PTSwitchInputComponent {
|
|
|
2886
3161
|
this.activeFormGroup.addControl(name, control);
|
|
2887
3162
|
}
|
|
2888
3163
|
else if (!this.formGroup && this.hasExplicitFieldValue(this.value)) {
|
|
2889
|
-
control.setValue(this.value, {
|
|
3164
|
+
control.setValue(this.value, {
|
|
3165
|
+
emitEvent: false,
|
|
3166
|
+
});
|
|
2890
3167
|
}
|
|
2891
3168
|
control.setValidators(this.getValidators());
|
|
2892
3169
|
if (this.resolvedDisabled) {
|
|
2893
|
-
control.disable({
|
|
3170
|
+
control.disable({
|
|
3171
|
+
emitEvent: false,
|
|
3172
|
+
});
|
|
2894
3173
|
}
|
|
2895
3174
|
else {
|
|
2896
|
-
control.enable({
|
|
3175
|
+
control.enable({
|
|
3176
|
+
emitEvent: false,
|
|
3177
|
+
});
|
|
2897
3178
|
}
|
|
2898
|
-
control.updateValueAndValidity({
|
|
3179
|
+
control.updateValueAndValidity({
|
|
3180
|
+
emitEvent: false,
|
|
3181
|
+
});
|
|
2899
3182
|
this.valueChangesSubscription?.unsubscribe();
|
|
2900
3183
|
this.valueChangesSubscription = control.valueChanges.subscribe((selectedValue) => {
|
|
2901
3184
|
this.valueChange.emit(selectedValue);
|
|
@@ -2919,22 +3202,26 @@ class PTSwitchInputComponent {
|
|
|
2919
3202
|
if (this.resolvedRequired) {
|
|
2920
3203
|
validators.push(this.requireChoiceValidator());
|
|
2921
3204
|
}
|
|
3205
|
+
if (Array.isArray(this.formField?.validators) &&
|
|
3206
|
+
this.formField.validators.length > 0) {
|
|
3207
|
+
validators.push(...this.formField.validators);
|
|
3208
|
+
}
|
|
2922
3209
|
return validators;
|
|
2923
3210
|
}
|
|
2924
3211
|
requireChoiceValidator() {
|
|
2925
3212
|
return (control) => {
|
|
2926
3213
|
return control.value !== null && control.value !== undefined
|
|
2927
3214
|
? null
|
|
2928
|
-
: {
|
|
3215
|
+
: {
|
|
3216
|
+
requiredChoice: true,
|
|
3217
|
+
};
|
|
2929
3218
|
};
|
|
2930
3219
|
}
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
return (this.resolvedErrorText ||
|
|
2935
|
-
`${this.resolvedLabel || this.controlName} is required`);
|
|
3220
|
+
resolveHiddenValue(hidden) {
|
|
3221
|
+
if (typeof hidden === 'function') {
|
|
3222
|
+
return Boolean(hidden(this.activeFormGroup.getRawValue()));
|
|
2936
3223
|
}
|
|
2937
|
-
return
|
|
3224
|
+
return Boolean(hidden);
|
|
2938
3225
|
}
|
|
2939
3226
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTSwitchInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2940
3227
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTSwitchInputComponent, isStandalone: false, selector: "pt-switch-input", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", switchChange: "switchChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n class=\"form-field\"\n [ngStyle]=\"{ width: resolvedWidth }\"\n >\n <div class=\"switch-container\">\n <p-toggleswitch\n [inputId]=\"inputId\"\n [formControlName]=\"controlName\"\n [ariaLabelledBy]=\"labelId\"\n ></p-toggleswitch>\n\n @if (resolvedLabel) {\n <label [id]=\"labelId\" [for]=\"inputId\" class=\"switch-label\">\n {{ resolvedLabel }}\n </label>\n }\n </div>\n\n @if (\n activeFormGroup.get(controlName)?.errors &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\">\n <small class=\"field-error\">{{ getErrorMessage() }}</small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{margin-bottom:1rem}.switch-container{display:flex;align-items:center;gap:.5rem;min-height:2.75rem}.switch-label{display:inline-flex;align-items:center;margin:0;padding:0;font-weight:600;font-size:1rem;line-height:1;cursor:pointer}.error-container{margin-top:.25rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-toggleswitch.ng-invalid.ng-touched .p-toggleswitch-slider,.form-field ::ng-deep .p-toggleswitch.ng-invalid.ng-dirty .p-toggleswitch-slider{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$3.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }] }); }
|
|
@@ -2956,6 +3243,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2956
3243
|
type: Output
|
|
2957
3244
|
}] } });
|
|
2958
3245
|
|
|
3246
|
+
// projects/ng-prime-tools/src/lib/pt-text-area-input/pt-text-area-input.component.ts
|
|
2959
3247
|
class PTTextAreaInputComponent {
|
|
2960
3248
|
constructor() {
|
|
2961
3249
|
this.characterCount = 0;
|
|
@@ -2965,14 +3253,63 @@ class PTTextAreaInputComponent {
|
|
|
2965
3253
|
this.updateCharacterCount();
|
|
2966
3254
|
}
|
|
2967
3255
|
ngOnChanges(changes) {
|
|
2968
|
-
if (changes['
|
|
3256
|
+
if (changes['formGroup'] || changes['formField']) {
|
|
2969
3257
|
this.setupControl();
|
|
2970
3258
|
this.updateCharacterCount();
|
|
2971
3259
|
}
|
|
2972
3260
|
}
|
|
3261
|
+
ngOnDestroy() {
|
|
3262
|
+
this.valueChangesSubscription?.unsubscribe();
|
|
3263
|
+
}
|
|
2973
3264
|
get inputId() {
|
|
2974
3265
|
return `pt-textarea-${this.formField?.name || 'field'}`;
|
|
2975
3266
|
}
|
|
3267
|
+
get errorId() {
|
|
3268
|
+
return `pt-textarea-error-${this.formField?.name || 'field'}`;
|
|
3269
|
+
}
|
|
3270
|
+
get isInvalid() {
|
|
3271
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
3272
|
+
return Boolean(control &&
|
|
3273
|
+
control.enabled &&
|
|
3274
|
+
control.invalid &&
|
|
3275
|
+
(control.touched || control.dirty));
|
|
3276
|
+
}
|
|
3277
|
+
getErrorMessage() {
|
|
3278
|
+
const control = this.formGroup.get(this.formField.name);
|
|
3279
|
+
if (!control?.errors) {
|
|
3280
|
+
return '';
|
|
3281
|
+
}
|
|
3282
|
+
const errorKey = this.resolveFirstErrorKey(control.errors);
|
|
3283
|
+
if (!errorKey) {
|
|
3284
|
+
return '';
|
|
3285
|
+
}
|
|
3286
|
+
const customMessage = this.formField.validationMessages?.[errorKey];
|
|
3287
|
+
if (customMessage) {
|
|
3288
|
+
return customMessage;
|
|
3289
|
+
}
|
|
3290
|
+
if (this.formField.errorText) {
|
|
3291
|
+
return this.formField.errorText;
|
|
3292
|
+
}
|
|
3293
|
+
const label = this.formField.label?.trim() || this.formField.name;
|
|
3294
|
+
switch (errorKey) {
|
|
3295
|
+
case 'required':
|
|
3296
|
+
return `${label} is required`;
|
|
3297
|
+
case 'minlength': {
|
|
3298
|
+
const requiredLength = control.getError('minlength')?.requiredLength ??
|
|
3299
|
+
this.formField.minLength;
|
|
3300
|
+
return `${label} must be at least ${requiredLength} characters long`;
|
|
3301
|
+
}
|
|
3302
|
+
case 'maxlength': {
|
|
3303
|
+
const requiredLength = control.getError('maxlength')?.requiredLength ??
|
|
3304
|
+
this.formField.maxLength;
|
|
3305
|
+
return `${label} must be at most ${requiredLength} characters long`;
|
|
3306
|
+
}
|
|
3307
|
+
case 'pattern':
|
|
3308
|
+
return `${label} is invalid`;
|
|
3309
|
+
default:
|
|
3310
|
+
return `${label} is invalid`;
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
2976
3313
|
setupControl() {
|
|
2977
3314
|
const name = this.formField?.name;
|
|
2978
3315
|
if (!name || !this.formGroup) {
|
|
@@ -2980,18 +3317,25 @@ class PTTextAreaInputComponent {
|
|
|
2980
3317
|
}
|
|
2981
3318
|
let control = this.formGroup.get(name);
|
|
2982
3319
|
if (!control) {
|
|
2983
|
-
control = new FormControl(this.formField
|
|
3320
|
+
control = new FormControl(this.formField.value ?? null);
|
|
2984
3321
|
this.formGroup.addControl(name, control);
|
|
2985
3322
|
}
|
|
2986
3323
|
control.setValidators(this.getValidators());
|
|
2987
|
-
if (this.formField
|
|
2988
|
-
control.disable({
|
|
3324
|
+
if (this.formField.disabled) {
|
|
3325
|
+
control.disable({
|
|
3326
|
+
emitEvent: false,
|
|
3327
|
+
});
|
|
2989
3328
|
}
|
|
2990
3329
|
else {
|
|
2991
|
-
control.enable({
|
|
3330
|
+
control.enable({
|
|
3331
|
+
emitEvent: false,
|
|
3332
|
+
});
|
|
2992
3333
|
}
|
|
2993
|
-
control.updateValueAndValidity({
|
|
2994
|
-
|
|
3334
|
+
control.updateValueAndValidity({
|
|
3335
|
+
emitEvent: false,
|
|
3336
|
+
});
|
|
3337
|
+
this.valueChangesSubscription?.unsubscribe();
|
|
3338
|
+
this.valueChangesSubscription = control.valueChanges.subscribe(() => {
|
|
2995
3339
|
this.updateCharacterCount();
|
|
2996
3340
|
});
|
|
2997
3341
|
}
|
|
@@ -3002,55 +3346,55 @@ class PTTextAreaInputComponent {
|
|
|
3002
3346
|
return;
|
|
3003
3347
|
}
|
|
3004
3348
|
const value = control.value;
|
|
3005
|
-
this.characterCount =
|
|
3349
|
+
this.characterCount =
|
|
3350
|
+
value === null || value === undefined ? 0 : String(value).length;
|
|
3006
3351
|
}
|
|
3007
3352
|
getValidators() {
|
|
3008
3353
|
const validators = [];
|
|
3009
|
-
if (this.formField
|
|
3354
|
+
if (this.formField.required) {
|
|
3010
3355
|
validators.push(Validators.required);
|
|
3011
3356
|
}
|
|
3012
|
-
if (this.formField
|
|
3357
|
+
if (this.formField.minLength !== undefined &&
|
|
3358
|
+
this.formField.minLength !== null) {
|
|
3013
3359
|
validators.push(Validators.minLength(this.formField.minLength));
|
|
3014
3360
|
}
|
|
3015
|
-
if (this.formField
|
|
3361
|
+
if (this.formField.maxLength !== undefined &&
|
|
3362
|
+
this.formField.maxLength !== null) {
|
|
3016
3363
|
validators.push(Validators.maxLength(this.formField.maxLength));
|
|
3017
3364
|
}
|
|
3018
|
-
if (this.formField
|
|
3365
|
+
if (this.formField.inputValidation) {
|
|
3019
3366
|
validators.push(this.validateWithInputValidation(this.formField.inputValidation));
|
|
3020
3367
|
}
|
|
3368
|
+
else if (this.formField.pattern) {
|
|
3369
|
+
validators.push(Validators.pattern(this.formField.pattern));
|
|
3370
|
+
}
|
|
3371
|
+
if (Array.isArray(this.formField.validators) &&
|
|
3372
|
+
this.formField.validators.length > 0) {
|
|
3373
|
+
validators.push(...this.formField.validators);
|
|
3374
|
+
}
|
|
3021
3375
|
return validators;
|
|
3022
3376
|
}
|
|
3023
3377
|
validateWithInputValidation(inputValidation) {
|
|
3024
3378
|
return Validators.pattern(new RegExp(inputValidation));
|
|
3025
3379
|
}
|
|
3026
|
-
|
|
3027
|
-
const
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
}
|
|
3031
|
-
if (control?.hasError('minlength')) {
|
|
3032
|
-
return `${this.formField.label} must be at least ${this.formField.minLength} characters long`;
|
|
3033
|
-
}
|
|
3034
|
-
if (control?.hasError('maxlength')) {
|
|
3035
|
-
return `${this.formField.label} must be at most ${this.formField.maxLength} characters long`;
|
|
3036
|
-
}
|
|
3037
|
-
if (control?.hasError('pattern')) {
|
|
3038
|
-
return `${this.formField.label} is invalid`;
|
|
3039
|
-
}
|
|
3040
|
-
return '';
|
|
3380
|
+
resolveFirstErrorKey(errors) {
|
|
3381
|
+
const priority = ['required', 'minlength', 'maxlength', 'pattern'];
|
|
3382
|
+
return (priority.find((key) => errors[key] !== undefined) ||
|
|
3383
|
+
Object.keys(errors)[0]);
|
|
3041
3384
|
}
|
|
3042
3385
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextAreaInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3043
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTTextAreaInputComponent, isStandalone: false, selector: "pt-text-area-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "
|
|
3386
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTTextAreaInputComponent, isStandalone: false, selector: "pt-text-area-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-text-area-input/pt-text-area-input.component.html -->\n\n<div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n }\"\n>\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <p-inputGroup class=\"textarea-input-group\">\n @if (!formField.iconPosition || formField.iconPosition === \"left\") {\n @if (formField.iconClass) {\n <p-inputGroupAddon>\n <i [ngClass]=\"formField.iconClass\"></i>\n </p-inputGroupAddon>\n }\n\n <textarea\n class=\"textarea-control\"\n [id]=\"inputId\"\n pTextarea\n [formControlName]=\"formField.name\"\n [rows]=\"formField.rows || 5\"\n [autoResize]=\"formField.autoResize || false\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></textarea>\n }\n\n @if (formField.iconPosition === \"right\") {\n <textarea\n class=\"textarea-control\"\n [id]=\"inputId\"\n pTextarea\n [formControlName]=\"formField.name\"\n [rows]=\"formField.rows || 5\"\n [autoResize]=\"formField.autoResize || false\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></textarea>\n\n @if (formField.iconClass) {\n <p-inputGroupAddon>\n <i [ngClass]=\"formField.iconClass\"></i>\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n\n <div class=\"form-info-row\">\n @if (isInvalid) {\n <small class=\"p-error\" role=\"alert\" [id]=\"errorId\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (!formField.disabled && formField.maxLength !== undefined) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}:host *,:host *:before,:host *:after{box-sizing:border-box}.form-field{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.form-field label{display:block;width:100%;margin-bottom:.5rem;font-size:1rem;font-weight:700}.textarea-input-group{display:flex;width:100%;min-width:0;max-width:100%}:host ::ng-deep .textarea-input-group.p-inputgroup,:host ::ng-deep .textarea-input-group .p-inputgroup{display:flex;width:100%;min-width:0;max-width:100%}.textarea-control{display:block;flex:1 1 auto;width:100%;min-width:0;max-width:100%;resize:vertical}:host ::ng-deep .textarea-control.p-textarea,:host ::ng-deep textarea.textarea-control{display:block;flex:1 1 auto;width:100%!important;min-width:0;max-width:100%}:host ::ng-deep .p-inputgroup textarea{flex:1 1 auto;width:100%!important;min-width:0}:host ::ng-deep .p-inputgroup-addon{flex:0 0 auto}.form-info-row{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;width:100%;min-width:0;margin-top:.5rem}.spacer{flex:1 1 auto;min-width:0}.character-counter{flex:0 0 auto;margin-left:auto;color:#888;font-size:.8rem;text-align:right;white-space:nowrap}.p-error{min-width:0;color:#f44336;font-size:.8rem;overflow-wrap:anywhere}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "component", type: i3$2.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "component", type: i4.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }] }); }
|
|
3044
3387
|
}
|
|
3045
3388
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextAreaInputComponent, decorators: [{
|
|
3046
3389
|
type: Component,
|
|
3047
|
-
args: [{ selector: 'pt-text-area-input', standalone: false, template: "
|
|
3390
|
+
args: [{ selector: 'pt-text-area-input', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-text-area-input/pt-text-area-input.component.html -->\n\n<div\n [formGroup]=\"formGroup\"\n class=\"form-field\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n }\"\n>\n @if (formField.label) {\n <label [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <p-inputGroup class=\"textarea-input-group\">\n @if (!formField.iconPosition || formField.iconPosition === \"left\") {\n @if (formField.iconClass) {\n <p-inputGroupAddon>\n <i [ngClass]=\"formField.iconClass\"></i>\n </p-inputGroupAddon>\n }\n\n <textarea\n class=\"textarea-control\"\n [id]=\"inputId\"\n pTextarea\n [formControlName]=\"formField.name\"\n [rows]=\"formField.rows || 5\"\n [autoResize]=\"formField.autoResize || false\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></textarea>\n }\n\n @if (formField.iconPosition === \"right\") {\n <textarea\n class=\"textarea-control\"\n [id]=\"inputId\"\n pTextarea\n [formControlName]=\"formField.name\"\n [rows]=\"formField.rows || 5\"\n [autoResize]=\"formField.autoResize || false\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [placeholder]=\"formField.placeholder || ''\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n ></textarea>\n\n @if (formField.iconClass) {\n <p-inputGroupAddon>\n <i [ngClass]=\"formField.iconClass\"></i>\n </p-inputGroupAddon>\n }\n }\n </p-inputGroup>\n\n <div class=\"form-info-row\">\n @if (isInvalid) {\n <small class=\"p-error\" role=\"alert\" [id]=\"errorId\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (!formField.disabled && formField.maxLength !== undefined) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}:host *,:host *:before,:host *:after{box-sizing:border-box}.form-field{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.form-field label{display:block;width:100%;margin-bottom:.5rem;font-size:1rem;font-weight:700}.textarea-input-group{display:flex;width:100%;min-width:0;max-width:100%}:host ::ng-deep .textarea-input-group.p-inputgroup,:host ::ng-deep .textarea-input-group .p-inputgroup{display:flex;width:100%;min-width:0;max-width:100%}.textarea-control{display:block;flex:1 1 auto;width:100%;min-width:0;max-width:100%;resize:vertical}:host ::ng-deep .textarea-control.p-textarea,:host ::ng-deep textarea.textarea-control{display:block;flex:1 1 auto;width:100%!important;min-width:0;max-width:100%}:host ::ng-deep .p-inputgroup textarea{flex:1 1 auto;width:100%!important;min-width:0}:host ::ng-deep .p-inputgroup-addon{flex:0 0 auto}.form-info-row{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem;width:100%;min-width:0;margin-top:.5rem}.spacer{flex:1 1 auto;min-width:0}.character-counter{flex:0 0 auto;margin-left:auto;color:#888;font-size:.8rem;text-align:right;white-space:nowrap}.p-error{min-width:0;color:#f44336;font-size:.8rem;overflow-wrap:anywhere}\n"] }]
|
|
3048
3391
|
}], propDecorators: { formGroup: [{
|
|
3049
3392
|
type: Input
|
|
3050
3393
|
}], formField: [{
|
|
3051
3394
|
type: Input
|
|
3052
3395
|
}] } });
|
|
3053
3396
|
|
|
3397
|
+
// projects/ng-prime-tools/src/lib/pt-text-input/pt-text-input.component.ts
|
|
3054
3398
|
class PTTextInputComponent {
|
|
3055
3399
|
constructor() {
|
|
3056
3400
|
this.characterCount = 0;
|
|
@@ -3059,38 +3403,27 @@ class PTTextInputComponent {
|
|
|
3059
3403
|
this.setupControl();
|
|
3060
3404
|
this.updateCharacterCount();
|
|
3061
3405
|
}
|
|
3406
|
+
ngOnChanges(changes) {
|
|
3407
|
+
if (changes['formGroup'] || changes['formField']) {
|
|
3408
|
+
this.setupControl();
|
|
3409
|
+
this.updateCharacterCount();
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3062
3412
|
ngOnDestroy() {
|
|
3063
3413
|
this.valueChangesSubscription?.unsubscribe();
|
|
3064
3414
|
}
|
|
3065
3415
|
get inputId() {
|
|
3066
3416
|
return `pt-input-${this.formField?.name || 'field'}`;
|
|
3067
3417
|
}
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
if (!control) {
|
|
3071
|
-
return;
|
|
3072
|
-
}
|
|
3073
|
-
control.setValidators(this.getValidators());
|
|
3074
|
-
this.valueChangesSubscription?.unsubscribe();
|
|
3075
|
-
if (this.formField.disabled) {
|
|
3076
|
-
control.disable({ emitEvent: false });
|
|
3077
|
-
}
|
|
3078
|
-
else {
|
|
3079
|
-
control.enable({ emitEvent: false });
|
|
3080
|
-
this.valueChangesSubscription = control.valueChanges.subscribe(() => {
|
|
3081
|
-
this.updateCharacterCount();
|
|
3082
|
-
});
|
|
3083
|
-
}
|
|
3084
|
-
control.updateValueAndValidity({ emitEvent: false });
|
|
3418
|
+
get errorId() {
|
|
3419
|
+
return `pt-input-error-${this.formField?.name || 'field'}`;
|
|
3085
3420
|
}
|
|
3086
|
-
|
|
3087
|
-
const control = this.formGroup
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
const value = control.value;
|
|
3093
|
-
this.characterCount = value != null ? String(value).length : 0;
|
|
3421
|
+
get isInvalid() {
|
|
3422
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
3423
|
+
return Boolean(control &&
|
|
3424
|
+
control.enabled &&
|
|
3425
|
+
control.invalid &&
|
|
3426
|
+
(control.touched || control.dirty));
|
|
3094
3427
|
}
|
|
3095
3428
|
getInputType() {
|
|
3096
3429
|
switch (this.formField.type) {
|
|
@@ -3113,15 +3446,100 @@ class PTTextInputComponent {
|
|
|
3113
3446
|
getPasswordFeedback() {
|
|
3114
3447
|
return this.formField.feedback ?? false;
|
|
3115
3448
|
}
|
|
3449
|
+
hasCharacterCounter() {
|
|
3450
|
+
return !this.formField.disabled && this.formField.maxLength !== undefined;
|
|
3451
|
+
}
|
|
3452
|
+
hasInfoRow() {
|
|
3453
|
+
return this.isInvalid || this.hasCharacterCounter();
|
|
3454
|
+
}
|
|
3455
|
+
getErrorMessage() {
|
|
3456
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
3457
|
+
if (!control?.errors) {
|
|
3458
|
+
return '';
|
|
3459
|
+
}
|
|
3460
|
+
const errorKey = this.resolveFirstErrorKey(control.errors);
|
|
3461
|
+
if (!errorKey) {
|
|
3462
|
+
return '';
|
|
3463
|
+
}
|
|
3464
|
+
const customMessage = this.formField.validationMessages?.[errorKey];
|
|
3465
|
+
if (customMessage) {
|
|
3466
|
+
return customMessage;
|
|
3467
|
+
}
|
|
3468
|
+
if (this.formField.errorText) {
|
|
3469
|
+
return this.formField.errorText;
|
|
3470
|
+
}
|
|
3471
|
+
const label = this.formField.label?.trim() || this.formField.name;
|
|
3472
|
+
switch (errorKey) {
|
|
3473
|
+
case 'required':
|
|
3474
|
+
return `${label} is required`;
|
|
3475
|
+
case 'email':
|
|
3476
|
+
return `${label} is not a valid email`;
|
|
3477
|
+
case 'minlength': {
|
|
3478
|
+
const requiredLength = control.getError('minlength')?.requiredLength ??
|
|
3479
|
+
this.formField.minLength;
|
|
3480
|
+
return `${label} must be at least ${requiredLength} characters`;
|
|
3481
|
+
}
|
|
3482
|
+
case 'maxlength': {
|
|
3483
|
+
const requiredLength = control.getError('maxlength')?.requiredLength ??
|
|
3484
|
+
this.formField.maxLength;
|
|
3485
|
+
return `${label} must be at most ${requiredLength} characters`;
|
|
3486
|
+
}
|
|
3487
|
+
case 'pattern':
|
|
3488
|
+
return `${label} is invalid`;
|
|
3489
|
+
default:
|
|
3490
|
+
return `${label} is invalid`;
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
setupControl() {
|
|
3494
|
+
const name = this.formField?.name;
|
|
3495
|
+
if (!name || !this.formGroup) {
|
|
3496
|
+
return;
|
|
3497
|
+
}
|
|
3498
|
+
let control = this.formGroup.get(name);
|
|
3499
|
+
if (!control) {
|
|
3500
|
+
control = new FormControl(this.formField.value ?? null);
|
|
3501
|
+
this.formGroup.addControl(name, control);
|
|
3502
|
+
}
|
|
3503
|
+
control.setValidators(this.getValidators());
|
|
3504
|
+
if (this.formField.disabled) {
|
|
3505
|
+
control.disable({
|
|
3506
|
+
emitEvent: false,
|
|
3507
|
+
});
|
|
3508
|
+
}
|
|
3509
|
+
else {
|
|
3510
|
+
control.enable({
|
|
3511
|
+
emitEvent: false,
|
|
3512
|
+
});
|
|
3513
|
+
}
|
|
3514
|
+
control.updateValueAndValidity({
|
|
3515
|
+
emitEvent: false,
|
|
3516
|
+
});
|
|
3517
|
+
this.valueChangesSubscription?.unsubscribe();
|
|
3518
|
+
this.valueChangesSubscription = control.valueChanges.subscribe(() => {
|
|
3519
|
+
this.updateCharacterCount();
|
|
3520
|
+
});
|
|
3521
|
+
}
|
|
3522
|
+
updateCharacterCount() {
|
|
3523
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
3524
|
+
if (!control) {
|
|
3525
|
+
this.characterCount = 0;
|
|
3526
|
+
return;
|
|
3527
|
+
}
|
|
3528
|
+
const value = control.value;
|
|
3529
|
+
this.characterCount =
|
|
3530
|
+
value === null || value === undefined ? 0 : String(value).length;
|
|
3531
|
+
}
|
|
3116
3532
|
getValidators() {
|
|
3117
3533
|
const validators = [];
|
|
3118
3534
|
if (this.formField.required) {
|
|
3119
3535
|
validators.push(Validators.required);
|
|
3120
3536
|
}
|
|
3121
|
-
if (this.formField.minLength !== undefined
|
|
3537
|
+
if (this.formField.minLength !== undefined &&
|
|
3538
|
+
this.formField.minLength !== null) {
|
|
3122
3539
|
validators.push(Validators.minLength(this.formField.minLength));
|
|
3123
3540
|
}
|
|
3124
|
-
if (this.formField.maxLength !== undefined
|
|
3541
|
+
if (this.formField.maxLength !== undefined &&
|
|
3542
|
+
this.formField.maxLength !== null) {
|
|
3125
3543
|
validators.push(Validators.maxLength(this.formField.maxLength));
|
|
3126
3544
|
}
|
|
3127
3545
|
if (this.formField.type === FormInputTypeEnum.EMAIL) {
|
|
@@ -3130,46 +3548,29 @@ class PTTextInputComponent {
|
|
|
3130
3548
|
if (this.formField.inputValidation) {
|
|
3131
3549
|
validators.push(this.validateWithInputValidation(this.formField.inputValidation));
|
|
3132
3550
|
}
|
|
3551
|
+
else if (this.formField.pattern) {
|
|
3552
|
+
validators.push(Validators.pattern(this.formField.pattern));
|
|
3553
|
+
}
|
|
3554
|
+
if (Array.isArray(this.formField.validators) &&
|
|
3555
|
+
this.formField.validators.length > 0) {
|
|
3556
|
+
validators.push(...this.formField.validators);
|
|
3557
|
+
}
|
|
3133
3558
|
return validators;
|
|
3134
3559
|
}
|
|
3135
3560
|
validateWithInputValidation(inputValidation) {
|
|
3136
3561
|
return Validators.pattern(new RegExp(inputValidation));
|
|
3137
3562
|
}
|
|
3138
|
-
|
|
3139
|
-
const
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
}
|
|
3143
|
-
if (control?.hasError('email')) {
|
|
3144
|
-
return `${this.formField.label} is not a valid email`;
|
|
3145
|
-
}
|
|
3146
|
-
if (control?.hasError('minlength')) {
|
|
3147
|
-
return `${this.formField.label} must be at least ${this.formField.minLength} characters`;
|
|
3148
|
-
}
|
|
3149
|
-
if (control?.hasError('maxlength')) {
|
|
3150
|
-
return `${this.formField.label} must be at most ${this.formField.maxLength} characters`;
|
|
3151
|
-
}
|
|
3152
|
-
if (control?.hasError('pattern')) {
|
|
3153
|
-
return `${this.formField.label} is invalid`;
|
|
3154
|
-
}
|
|
3155
|
-
return '';
|
|
3156
|
-
}
|
|
3157
|
-
hasError() {
|
|
3158
|
-
const control = this.formGroup.get(this.formField.name);
|
|
3159
|
-
return !!(control?.invalid && (control.touched || control.dirty));
|
|
3160
|
-
}
|
|
3161
|
-
hasCharacterCounter() {
|
|
3162
|
-
return !this.formField.disabled && this.formField.maxLength !== undefined;
|
|
3163
|
-
}
|
|
3164
|
-
hasInfoRow() {
|
|
3165
|
-
return this.hasError() || this.hasCharacterCounter();
|
|
3563
|
+
resolveFirstErrorKey(errors) {
|
|
3564
|
+
const priority = ['required', 'email', 'minlength', 'maxlength', 'pattern'];
|
|
3565
|
+
return (priority.find((key) => errors[key] !== undefined) ||
|
|
3566
|
+
Object.keys(errors)[0]);
|
|
3166
3567
|
}
|
|
3167
3568
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3168
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTTextInputComponent, isStandalone: false, selector: "pt-text-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "
|
|
3569
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTTextInputComponent, isStandalone: false, selector: "pt-text-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-text-input/pt-text-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n @if (formField.iconClass) {\n <p-iconField\n class=\"text-icon-field\"\n [iconPosition]=\"formField.iconPosition || 'left'\"\n >\n <p-inputIcon [styleClass]=\"formField.iconClass\"></p-inputIcon>\n\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n pInputText\n class=\"pt-text-input\"\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [ngStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n </p-iconField>\n } @else {\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n pInputText\n class=\"pt-text-input\"\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [ngStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n }\n\n @if (hasInfoRow()) {\n <div class=\"form-info-row\">\n @if (isInvalid) {\n <small class=\"field-error\" role=\"alert\" [id]=\"errorId\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (hasCharacterCounter()) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{width:100%;min-width:0}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.required-indicator{margin-left:.2rem;color:#dc2626}.text-icon-field{display:block;width:100%;min-width:0}.pt-text-input{width:100%;min-width:0;box-sizing:border-box}.form-info-row{display:flex;align-items:center;gap:.5rem;min-height:1.25rem;margin-top:.35rem}.spacer{flex:1 1 auto}.field-error{display:block;min-width:0;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2;overflow-wrap:anywhere}.character-counter{flex:0 0 auto;color:#64748b;font-size:.8rem;font-weight:500;white-space:nowrap}.form-field-invalid .pt-text-input{border-color:#dc2626}:host ::ng-deep .text-icon-field.p-iconfield,:host ::ng-deep .text-icon-field .p-iconfield{display:block;width:100%;min-width:0}:host ::ng-deep .pt-password-input{display:block;width:100%;min-width:0}:host ::ng-deep .pt-password-input.p-password,:host ::ng-deep .pt-password-input .p-password{display:block;width:100%;min-width:0}:host ::ng-deep .pt-password-input .p-password-input,:host ::ng-deep .pt-password-input input{width:100%;min-width:0;box-sizing:border-box}.form-field-invalid ::ng-deep .pt-password-input .p-password-input{border-color:#dc2626}:host ::ng-deep .pt-password-input .p-password-toggle-mask-icon,:host ::ng-deep .pt-password-input .p-password-toggle-mask{right:1rem}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: i10.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "component", type: i6$1.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }] }); }
|
|
3169
3570
|
}
|
|
3170
3571
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTTextInputComponent, decorators: [{
|
|
3171
3572
|
type: Component,
|
|
3172
|
-
args: [{ selector: 'pt-text-input', standalone: false, template: "
|
|
3573
|
+
args: [{ selector: 'pt-text-input', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-text-input/pt-text-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n @if (formField.iconClass) {\n <p-iconField\n class=\"text-icon-field\"\n [iconPosition]=\"formField.iconPosition || 'left'\"\n >\n <p-inputIcon [styleClass]=\"formField.iconClass\"></p-inputIcon>\n\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n pInputText\n class=\"pt-text-input\"\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [ngStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n </p-iconField>\n } @else {\n @if (isPasswordInput()) {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n } @else {\n <input\n pInputText\n class=\"pt-text-input\"\n [id]=\"inputId\"\n [attr.name]=\"formField.name\"\n [type]=\"getInputType()\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [attr.minlength]=\"formField.minLength\"\n [attr.maxlength]=\"formField.maxLength\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [ngStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n />\n }\n }\n\n @if (hasInfoRow()) {\n <div class=\"form-info-row\">\n @if (isInvalid) {\n <small class=\"field-error\" role=\"alert\" [id]=\"errorId\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (hasCharacterCounter()) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{width:100%;min-width:0}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.required-indicator{margin-left:.2rem;color:#dc2626}.text-icon-field{display:block;width:100%;min-width:0}.pt-text-input{width:100%;min-width:0;box-sizing:border-box}.form-info-row{display:flex;align-items:center;gap:.5rem;min-height:1.25rem;margin-top:.35rem}.spacer{flex:1 1 auto}.field-error{display:block;min-width:0;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2;overflow-wrap:anywhere}.character-counter{flex:0 0 auto;color:#64748b;font-size:.8rem;font-weight:500;white-space:nowrap}.form-field-invalid .pt-text-input{border-color:#dc2626}:host ::ng-deep .text-icon-field.p-iconfield,:host ::ng-deep .text-icon-field .p-iconfield{display:block;width:100%;min-width:0}:host ::ng-deep .pt-password-input{display:block;width:100%;min-width:0}:host ::ng-deep .pt-password-input.p-password,:host ::ng-deep .pt-password-input .p-password{display:block;width:100%;min-width:0}:host ::ng-deep .pt-password-input .p-password-input,:host ::ng-deep .pt-password-input input{width:100%;min-width:0;box-sizing:border-box}.form-field-invalid ::ng-deep .pt-password-input .p-password-input{border-color:#dc2626}:host ::ng-deep .pt-password-input .p-password-toggle-mask-icon,:host ::ng-deep .pt-password-input .p-password-toggle-mask{right:1rem}\n"] }]
|
|
3173
3574
|
}], propDecorators: { formGroup: [{
|
|
3174
3575
|
type: Input
|
|
3175
3576
|
}], formField: [{
|
|
@@ -3213,7 +3614,11 @@ class PTDropdownComponent {
|
|
|
3213
3614
|
return `pt-dropdown-label-${this.controlName}`;
|
|
3214
3615
|
}
|
|
3215
3616
|
get resolvedHidden() {
|
|
3216
|
-
|
|
3617
|
+
const hidden = this.formField?.hidden;
|
|
3618
|
+
if (typeof hidden === 'function') {
|
|
3619
|
+
return Boolean(hidden(this.activeFormGroup.getRawValue()));
|
|
3620
|
+
}
|
|
3621
|
+
return hidden ?? this.config?.hidden ?? false;
|
|
3217
3622
|
}
|
|
3218
3623
|
get resolvedLabel() {
|
|
3219
3624
|
return this.formField?.label || this.config?.label;
|
|
@@ -3425,11 +3830,11 @@ class PTDropdownComponent {
|
|
|
3425
3830
|
return 'left';
|
|
3426
3831
|
}
|
|
3427
3832
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3428
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDropdownComponent, isStandalone: false, selector: "pt-dropdown", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n
|
|
3833
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDropdownComponent, isStandalone: false, selector: "pt-dropdown", inputs: { formGroup: "formGroup", formField: "formField", config: "config", value: "value" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange" }, usesOnChanges: true, ngImport: i0, template: "@if (!resolvedHidden) {\n <div\n class=\"form-field\"\n [formGroup]=\"activeFormGroup\"\n [ngClass]=\"{\n 'form-field-invalid':\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty),\n }\"\n [ngStyle]=\"{\n width: resolvedWidth,\n 'max-width': resolvedWidth,\n }\"\n >\n @if (resolvedLabel) {\n <label class=\"field-label\" [id]=\"labelId\" [for]=\"inputId\">\n {{ resolvedLabel }}\n\n @if (resolvedRequired) {\n <span class=\"required-indicator\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <p-select\n class=\"dropdown-input\"\n styleClass=\"dropdown-input-control\"\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [optionDisabled]=\"resolvedOptionDisabled\"\n [dataKey]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{\n baseZIndex: 11000,\n }\"\n [ariaLabelledBy]=\"resolvedLabel ? labelId : undefined\"\n [attr.aria-describedby]=\"\n activeFormGroup.get(controlName)?.invalid\n ? controlName + '-error'\n : null\n \"\n [attr.aria-invalid]=\"\n activeFormGroup.get(controlName)?.invalid ? 'true' : 'false'\n \"\n >\n <ng-template pTemplate=\"selectedItem\" let-option>\n @if (option) {\n <div class=\"pt-dropdown-item\">\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n class=\"pt-dropdown-icon-image\"\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n alt=\"\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n class=\"pt-dropdown-icon-font\"\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n aria-hidden=\"true\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n } @else {\n <span class=\"pt-dropdown-placeholder\">\n {{ resolvedPlaceholder }}\n </span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-option>\n <div\n class=\"pt-dropdown-item\"\n [class.pt-dropdown-parent-option]=\"option?.isParent\"\n [class.pt-dropdown-child-option]=\"option?.isChild\"\n [class.pt-dropdown-disabled-option]=\"option?.[resolvedOptionDisabled]\"\n [ngStyle]=\"{\n 'padding-left': option?.indent || '0rem',\n }\"\n >\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n class=\"pt-dropdown-icon-image\"\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n alt=\"\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n class=\"pt-dropdown-icon-font\"\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n aria-hidden=\"true\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n </ng-template>\n </p-select>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\" role=\"alert\" [id]=\"controlName + '-error'\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{display:flex;flex-direction:column;margin-bottom:1rem;gap:.25rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.pt-dropdown-item{display:flex;align-items:center;gap:.55rem}.pt-dropdown-label{display:inline-block}.pt-dropdown-parent-option{font-weight:700}.pt-dropdown-child-option{font-weight:400}.pt-dropdown-disabled-option{opacity:.65;cursor:not-allowed}.pt-dropdown-icon-font{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;text-align:center}.pt-dropdown-icon-image{object-fit:cover}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-select.ng-invalid.ng-touched{border-color:#dc2626}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i1$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }] }); }
|
|
3429
3834
|
}
|
|
3430
3835
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDropdownComponent, decorators: [{
|
|
3431
3836
|
type: Component,
|
|
3432
|
-
args: [{ selector: 'pt-dropdown', standalone: false, template: "@if (!resolvedHidden) {\n <div\n [formGroup]=\"activeFormGroup\"\n
|
|
3837
|
+
args: [{ selector: 'pt-dropdown', standalone: false, template: "@if (!resolvedHidden) {\n <div\n class=\"form-field\"\n [formGroup]=\"activeFormGroup\"\n [ngClass]=\"{\n 'form-field-invalid':\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty),\n }\"\n [ngStyle]=\"{\n width: resolvedWidth,\n 'max-width': resolvedWidth,\n }\"\n >\n @if (resolvedLabel) {\n <label class=\"field-label\" [id]=\"labelId\" [for]=\"inputId\">\n {{ resolvedLabel }}\n\n @if (resolvedRequired) {\n <span class=\"required-indicator\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <p-select\n class=\"dropdown-input\"\n styleClass=\"dropdown-input-control\"\n [inputId]=\"inputId\"\n [name]=\"controlName\"\n [formControlName]=\"controlName\"\n [options]=\"resolvedOptions\"\n [placeholder]=\"resolvedPlaceholder\"\n [optionLabel]=\"resolvedOptionLabel\"\n [optionValue]=\"resolvedOptionValue\"\n [optionDisabled]=\"resolvedOptionDisabled\"\n [dataKey]=\"resolvedOptionValue\"\n [filter]=\"resolvedFilter\"\n [filterBy]=\"resolvedFilterBy\"\n [appendTo]=\"'body'\"\n [overlayOptions]=\"{\n baseZIndex: 11000,\n }\"\n [ariaLabelledBy]=\"resolvedLabel ? labelId : undefined\"\n [attr.aria-describedby]=\"\n activeFormGroup.get(controlName)?.invalid\n ? controlName + '-error'\n : null\n \"\n [attr.aria-invalid]=\"\n activeFormGroup.get(controlName)?.invalid ? 'true' : 'false'\n \"\n >\n <ng-template pTemplate=\"selectedItem\" let-option>\n @if (option) {\n <div class=\"pt-dropdown-item\">\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n class=\"pt-dropdown-icon-image\"\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n alt=\"\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n class=\"pt-dropdown-icon-font\"\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n aria-hidden=\"true\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n } @else {\n <span class=\"pt-dropdown-placeholder\">\n {{ resolvedPlaceholder }}\n </span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"item\" let-option>\n <div\n class=\"pt-dropdown-item\"\n [class.pt-dropdown-parent-option]=\"option?.isParent\"\n [class.pt-dropdown-child-option]=\"option?.isChild\"\n [class.pt-dropdown-disabled-option]=\"option?.[resolvedOptionDisabled]\"\n [ngStyle]=\"{\n 'padding-left': option?.indent || '0rem',\n }\"\n >\n @if (getResolvedIcon(option); as iconMeta) {\n @if (iconMeta.type === \"image\") {\n <img\n class=\"pt-dropdown-icon-image\"\n [src]=\"iconMeta.imageUrl\"\n [ngStyle]=\"iconMeta.imageStyle\"\n alt=\"\"\n />\n }\n\n @if (iconMeta.type === \"font\") {\n <i\n class=\"pt-dropdown-icon-font\"\n [ngClass]=\"iconMeta.fontIconClass\"\n [ngStyle]=\"iconMeta.fontIconStyle\"\n aria-hidden=\"true\"\n ></i>\n }\n }\n\n <span class=\"pt-dropdown-label\">\n {{ option[resolvedOptionLabel] }}\n </span>\n </div>\n </ng-template>\n </p-select>\n\n @if (\n activeFormGroup.get(controlName)?.invalid &&\n (activeFormGroup.get(controlName)?.touched ||\n activeFormGroup.get(controlName)?.dirty)\n ) {\n <div class=\"error-container\" role=\"alert\" [id]=\"controlName + '-error'\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n </div>\n}\n", styles: [".form-field{display:flex;flex-direction:column;margin-bottom:1rem;gap:.25rem}.field-label{display:block;margin-bottom:.5rem;font-weight:700;font-size:1rem}.pt-dropdown-item{display:flex;align-items:center;gap:.55rem}.pt-dropdown-label{display:inline-block}.pt-dropdown-parent-option{font-weight:700}.pt-dropdown-child-option{font-weight:400}.pt-dropdown-disabled-option{opacity:.65;cursor:not-allowed}.pt-dropdown-icon-font{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;text-align:center}.pt-dropdown-icon-image{object-fit:cover}.error-container{margin-top:.35rem}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.form-field ::ng-deep .p-select.ng-invalid.ng-touched{border-color:#dc2626}\n"] }]
|
|
3433
3838
|
}], propDecorators: { formGroup: [{
|
|
3434
3839
|
type: Input
|
|
3435
3840
|
}], formField: [{
|
|
@@ -3542,18 +3947,25 @@ class PTOtpInputComponent {
|
|
|
3542
3947
|
control.setValue(normalizedValue, { emitEvent: false });
|
|
3543
3948
|
}
|
|
3544
3949
|
}
|
|
3950
|
+
get labelId() {
|
|
3951
|
+
return `pt-otp-label-${this.formField?.name || 'field'}`;
|
|
3952
|
+
}
|
|
3953
|
+
get errorId() {
|
|
3954
|
+
return `pt-otp-error-${this.formField?.name || 'field'}`;
|
|
3955
|
+
}
|
|
3545
3956
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3546
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTOtpInputComponent, isStandalone: false, selector: "pt-otp-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "
|
|
3957
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTOtpInputComponent, isStandalone: false, selector: "pt-otp-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-otp-input/pt-otp-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': hasError(),\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [id]=\"labelId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n <div class=\"otp-input-wrapper\">\n <p-inputOtp\n [formControlName]=\"formField.name\"\n [length]=\"resolvedLength\"\n [integerOnly]=\"resolvedIntegerOnly\"\n [mask]=\"resolvedMask\"\n [readonly]=\"formField.disabled ?? false\"\n [attr.aria-labelledby]=\"formField.label ? labelId : null\"\n [attr.aria-describedby]=\"hasError() ? errorId : null\"\n [attr.aria-invalid]=\"hasError() ? 'true' : 'false'\"\n styleClass=\"pt-otp-input\"\n ></p-inputOtp>\n </div>\n\n @if (hasError()) {\n <div class=\"form-info-row\" role=\"alert\" [id]=\"errorId\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{width:100%;min-width:0}.field-label{display:block;margin-bottom:.85rem;color:#172554;font-size:1.1rem;font-weight:700;letter-spacing:.01em}.required-indicator{margin-left:.2rem;color:#ef4444}.otp-input-wrapper{display:flex;width:100%;min-width:0;justify-content:center}.form-info-row{display:flex;align-items:center;min-height:1.35rem;margin-top:.65rem;justify-content:center;gap:.35rem;color:#fca5a5}.form-info-row .pi{font-size:.8rem}.field-error{color:inherit;font-size:.82rem;font-weight:600;text-align:center}:host ::ng-deep .pt-otp-input{display:flex;width:100%;min-width:0;justify-content:center;gap:.7rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:3.7rem;height:4rem;border:2px solid rgba(255,255,255,.62);border-radius:.85rem;background:#fffffff0;box-shadow:0 6px 14px #0f172a29,inset 0 1px #ffffffe6;color:#172554;font-size:1.75rem;font-weight:800;text-align:center;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}:host ::ng-deep .pt-otp-input .p-inputotp-input:hover{border-color:#60a5fa;transform:translateY(-2px)}:host ::ng-deep .pt-otp-input .p-inputotp-input:focus{border-color:#2563eb;box-shadow:0 0 0 4px #2563eb33,0 8px 18px #0f172a33;outline:none}.form-field-invalid ::ng-deep .pt-otp-input .p-inputotp-input{border-color:#ef4444}@media(max-width:480px){:host ::ng-deep .pt-otp-input{gap:.42rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:2.85rem;height:3.3rem;font-size:1.4rem}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3$6.InputOtp, selector: "p-inputOtp, p-inputotp, p-input-otp", inputs: ["readonly", "tabindex", "length", "styleClass", "mask", "integerOnly", "autofocus", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
|
|
3547
3958
|
}
|
|
3548
3959
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTOtpInputComponent, decorators: [{
|
|
3549
3960
|
type: Component,
|
|
3550
|
-
args: [{ selector: 'pt-otp-input', standalone: false, template: "
|
|
3961
|
+
args: [{ selector: 'pt-otp-input', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-otp-input/pt-otp-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': hasError(),\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [id]=\"labelId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n <div class=\"otp-input-wrapper\">\n <p-inputOtp\n [formControlName]=\"formField.name\"\n [length]=\"resolvedLength\"\n [integerOnly]=\"resolvedIntegerOnly\"\n [mask]=\"resolvedMask\"\n [readonly]=\"formField.disabled ?? false\"\n [attr.aria-labelledby]=\"formField.label ? labelId : null\"\n [attr.aria-describedby]=\"hasError() ? errorId : null\"\n [attr.aria-invalid]=\"hasError() ? 'true' : 'false'\"\n styleClass=\"pt-otp-input\"\n ></p-inputOtp>\n </div>\n\n @if (hasError()) {\n <div class=\"form-info-row\" role=\"alert\" [id]=\"errorId\">\n <i class=\"pi pi-exclamation-circle\" aria-hidden=\"true\"></i>\n\n <small class=\"field-error\">\n {{ getErrorMessage() }}\n </small>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0}.form-field{width:100%;min-width:0}.field-label{display:block;margin-bottom:.85rem;color:#172554;font-size:1.1rem;font-weight:700;letter-spacing:.01em}.required-indicator{margin-left:.2rem;color:#ef4444}.otp-input-wrapper{display:flex;width:100%;min-width:0;justify-content:center}.form-info-row{display:flex;align-items:center;min-height:1.35rem;margin-top:.65rem;justify-content:center;gap:.35rem;color:#fca5a5}.form-info-row .pi{font-size:.8rem}.field-error{color:inherit;font-size:.82rem;font-weight:600;text-align:center}:host ::ng-deep .pt-otp-input{display:flex;width:100%;min-width:0;justify-content:center;gap:.7rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:3.7rem;height:4rem;border:2px solid rgba(255,255,255,.62);border-radius:.85rem;background:#fffffff0;box-shadow:0 6px 14px #0f172a29,inset 0 1px #ffffffe6;color:#172554;font-size:1.75rem;font-weight:800;text-align:center;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}:host ::ng-deep .pt-otp-input .p-inputotp-input:hover{border-color:#60a5fa;transform:translateY(-2px)}:host ::ng-deep .pt-otp-input .p-inputotp-input:focus{border-color:#2563eb;box-shadow:0 0 0 4px #2563eb33,0 8px 18px #0f172a33;outline:none}.form-field-invalid ::ng-deep .pt-otp-input .p-inputotp-input{border-color:#ef4444}@media(max-width:480px){:host ::ng-deep .pt-otp-input{gap:.42rem}:host ::ng-deep .pt-otp-input .p-inputotp-input{width:2.85rem;height:3.3rem;font-size:1.4rem}}\n"] }]
|
|
3551
3962
|
}], propDecorators: { formGroup: [{
|
|
3552
3963
|
type: Input
|
|
3553
3964
|
}], formField: [{
|
|
3554
3965
|
type: Input
|
|
3555
3966
|
}] } });
|
|
3556
3967
|
|
|
3968
|
+
// projects/ng-prime-tools/src/lib/pt-password-input/pt-password-input.component.ts
|
|
3557
3969
|
class PTPasswordInputComponent {
|
|
3558
3970
|
constructor() {
|
|
3559
3971
|
this.characterCount = 0;
|
|
@@ -3562,96 +3974,154 @@ class PTPasswordInputComponent {
|
|
|
3562
3974
|
this.setupControl();
|
|
3563
3975
|
this.updateCharacterCount();
|
|
3564
3976
|
}
|
|
3977
|
+
ngOnChanges(changes) {
|
|
3978
|
+
if (changes['formGroup'] || changes['formField']) {
|
|
3979
|
+
this.setupControl();
|
|
3980
|
+
this.updateCharacterCount();
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3565
3983
|
ngOnDestroy() {
|
|
3566
3984
|
this.valueChangesSubscription?.unsubscribe();
|
|
3567
3985
|
}
|
|
3568
3986
|
get inputId() {
|
|
3569
3987
|
return `pt-password-${this.formField?.name || 'field'}`;
|
|
3570
3988
|
}
|
|
3989
|
+
get errorId() {
|
|
3990
|
+
return `pt-password-error-${this.formField?.name || 'field'}`;
|
|
3991
|
+
}
|
|
3992
|
+
get isInvalid() {
|
|
3993
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
3994
|
+
return Boolean(control &&
|
|
3995
|
+
control.enabled &&
|
|
3996
|
+
control.invalid &&
|
|
3997
|
+
(control.touched || control.dirty));
|
|
3998
|
+
}
|
|
3999
|
+
getPasswordToggleMask() {
|
|
4000
|
+
return this.formField?.toggleMask ?? true;
|
|
4001
|
+
}
|
|
4002
|
+
getPasswordFeedback() {
|
|
4003
|
+
return this.formField?.feedback ?? false;
|
|
4004
|
+
}
|
|
4005
|
+
hasCharacterCounter() {
|
|
4006
|
+
return !this.formField?.disabled && this.formField?.maxLength !== undefined;
|
|
4007
|
+
}
|
|
4008
|
+
hasInfoRow() {
|
|
4009
|
+
return this.isInvalid || this.hasCharacterCounter();
|
|
4010
|
+
}
|
|
4011
|
+
getErrorMessage() {
|
|
4012
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
4013
|
+
if (!control?.errors) {
|
|
4014
|
+
return '';
|
|
4015
|
+
}
|
|
4016
|
+
const errorKey = this.resolveFirstErrorKey(control.errors);
|
|
4017
|
+
if (!errorKey) {
|
|
4018
|
+
return '';
|
|
4019
|
+
}
|
|
4020
|
+
const customMessage = this.formField.validationMessages?.[errorKey];
|
|
4021
|
+
if (customMessage) {
|
|
4022
|
+
return customMessage;
|
|
4023
|
+
}
|
|
4024
|
+
if (this.formField.errorText) {
|
|
4025
|
+
return this.formField.errorText;
|
|
4026
|
+
}
|
|
4027
|
+
const label = this.formField.label?.trim() || this.formField.name;
|
|
4028
|
+
switch (errorKey) {
|
|
4029
|
+
case 'required':
|
|
4030
|
+
return `${label} is required`;
|
|
4031
|
+
case 'minlength': {
|
|
4032
|
+
const requiredLength = control.getError('minlength')?.requiredLength ??
|
|
4033
|
+
this.formField.minLength;
|
|
4034
|
+
return `${label} must be at least ${requiredLength} characters`;
|
|
4035
|
+
}
|
|
4036
|
+
case 'maxlength': {
|
|
4037
|
+
const requiredLength = control.getError('maxlength')?.requiredLength ??
|
|
4038
|
+
this.formField.maxLength;
|
|
4039
|
+
return `${label} must be at most ${requiredLength} characters`;
|
|
4040
|
+
}
|
|
4041
|
+
case 'pattern':
|
|
4042
|
+
return `${label} is invalid`;
|
|
4043
|
+
default:
|
|
4044
|
+
return `${label} is invalid`;
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
3571
4047
|
setupControl() {
|
|
3572
|
-
const
|
|
3573
|
-
if (!
|
|
4048
|
+
const name = this.formField?.name;
|
|
4049
|
+
if (!name || !this.formGroup) {
|
|
3574
4050
|
return;
|
|
3575
4051
|
}
|
|
4052
|
+
let control = this.formGroup.get(name);
|
|
4053
|
+
if (!control) {
|
|
4054
|
+
control = new FormControl(this.formField.value ?? null);
|
|
4055
|
+
this.formGroup.addControl(name, control);
|
|
4056
|
+
}
|
|
3576
4057
|
control.setValidators(this.getValidators());
|
|
3577
|
-
this.valueChangesSubscription?.unsubscribe();
|
|
3578
4058
|
if (this.formField.disabled) {
|
|
3579
|
-
control.disable({
|
|
4059
|
+
control.disable({
|
|
4060
|
+
emitEvent: false,
|
|
4061
|
+
});
|
|
3580
4062
|
}
|
|
3581
4063
|
else {
|
|
3582
|
-
control.enable({
|
|
3583
|
-
|
|
3584
|
-
this.updateCharacterCount();
|
|
4064
|
+
control.enable({
|
|
4065
|
+
emitEvent: false,
|
|
3585
4066
|
});
|
|
3586
4067
|
}
|
|
3587
|
-
control.updateValueAndValidity({
|
|
4068
|
+
control.updateValueAndValidity({
|
|
4069
|
+
emitEvent: false,
|
|
4070
|
+
});
|
|
4071
|
+
this.valueChangesSubscription?.unsubscribe();
|
|
4072
|
+
this.valueChangesSubscription = control.valueChanges.subscribe(() => {
|
|
4073
|
+
this.updateCharacterCount();
|
|
4074
|
+
});
|
|
3588
4075
|
}
|
|
3589
4076
|
updateCharacterCount() {
|
|
3590
|
-
const control = this.formGroup
|
|
4077
|
+
const control = this.formGroup?.get(this.formField?.name);
|
|
3591
4078
|
if (!control) {
|
|
3592
4079
|
this.characterCount = 0;
|
|
3593
4080
|
return;
|
|
3594
4081
|
}
|
|
3595
4082
|
const value = control.value;
|
|
3596
|
-
this.characterCount =
|
|
3597
|
-
|
|
3598
|
-
getPasswordToggleMask() {
|
|
3599
|
-
return this.formField.toggleMask ?? true;
|
|
3600
|
-
}
|
|
3601
|
-
getPasswordFeedback() {
|
|
3602
|
-
return this.formField.feedback ?? false;
|
|
4083
|
+
this.characterCount =
|
|
4084
|
+
value === null || value === undefined ? 0 : String(value).length;
|
|
3603
4085
|
}
|
|
3604
4086
|
getValidators() {
|
|
3605
4087
|
const validators = [];
|
|
3606
4088
|
if (this.formField.required) {
|
|
3607
4089
|
validators.push(Validators.required);
|
|
3608
4090
|
}
|
|
3609
|
-
if (this.formField.minLength !== undefined
|
|
4091
|
+
if (this.formField.minLength !== undefined &&
|
|
4092
|
+
this.formField.minLength !== null) {
|
|
3610
4093
|
validators.push(Validators.minLength(this.formField.minLength));
|
|
3611
4094
|
}
|
|
3612
|
-
if (this.formField.maxLength !== undefined
|
|
4095
|
+
if (this.formField.maxLength !== undefined &&
|
|
4096
|
+
this.formField.maxLength !== null) {
|
|
3613
4097
|
validators.push(Validators.maxLength(this.formField.maxLength));
|
|
3614
4098
|
}
|
|
3615
4099
|
if (this.formField.inputValidation) {
|
|
3616
4100
|
validators.push(this.validateWithInputValidation(this.formField.inputValidation));
|
|
3617
4101
|
}
|
|
4102
|
+
else if (this.formField.pattern) {
|
|
4103
|
+
validators.push(Validators.pattern(this.formField.pattern));
|
|
4104
|
+
}
|
|
4105
|
+
if (Array.isArray(this.formField.validators) &&
|
|
4106
|
+
this.formField.validators.length > 0) {
|
|
4107
|
+
validators.push(...this.formField.validators);
|
|
4108
|
+
}
|
|
3618
4109
|
return validators;
|
|
3619
4110
|
}
|
|
3620
4111
|
validateWithInputValidation(inputValidation) {
|
|
3621
4112
|
return Validators.pattern(new RegExp(inputValidation));
|
|
3622
4113
|
}
|
|
3623
|
-
|
|
3624
|
-
const
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
}
|
|
3628
|
-
if (control?.hasError('minlength')) {
|
|
3629
|
-
return `${this.formField.label} must be at least ${this.formField.minLength} characters`;
|
|
3630
|
-
}
|
|
3631
|
-
if (control?.hasError('maxlength')) {
|
|
3632
|
-
return `${this.formField.label} must be at most ${this.formField.maxLength} characters`;
|
|
3633
|
-
}
|
|
3634
|
-
if (control?.hasError('pattern')) {
|
|
3635
|
-
return this.formField.errorText ?? `${this.formField.label} is invalid`;
|
|
3636
|
-
}
|
|
3637
|
-
return '';
|
|
3638
|
-
}
|
|
3639
|
-
hasError() {
|
|
3640
|
-
const control = this.formGroup.get(this.formField.name);
|
|
3641
|
-
return !!(control?.invalid && (control.touched || control.dirty));
|
|
3642
|
-
}
|
|
3643
|
-
hasCharacterCounter() {
|
|
3644
|
-
return !this.formField.disabled && this.formField.maxLength !== undefined;
|
|
3645
|
-
}
|
|
3646
|
-
hasInfoRow() {
|
|
3647
|
-
return this.hasError() || this.hasCharacterCounter();
|
|
4114
|
+
resolveFirstErrorKey(errors) {
|
|
4115
|
+
const priority = ['required', 'minlength', 'maxlength', 'pattern'];
|
|
4116
|
+
return (priority.find((key) => errors[key] !== undefined) ||
|
|
4117
|
+
Object.keys(errors)[0]);
|
|
3648
4118
|
}
|
|
3649
4119
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTPasswordInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3650
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTPasswordInputComponent, isStandalone: false, selector: "pt-password-input", inputs: { formGroup: "formGroup", formField: "formField" }, ngImport: i0, template: "
|
|
4120
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTPasswordInputComponent, isStandalone: false, selector: "pt-password-input", inputs: { formGroup: "formGroup", formField: "formField" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-password-input/pt-password-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n @if (formField.iconClass) {\n <p-iconField\n class=\"password-icon-field\"\n [iconPosition]=\"formField.iconPosition || 'left'\"\n >\n <p-inputIcon [styleClass]=\"formField.iconClass\"></p-inputIcon>\n\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n </p-iconField>\n } @else {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n }\n\n @if (hasInfoRow()) {\n <div class=\"form-info-row\">\n @if (isInvalid) {\n <small class=\"field-error\" role=\"alert\" [id]=\"errorId\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (hasCharacterCounter()) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.form-field{width:100%}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.form-info-row{display:flex;align-items:center;gap:.5rem;min-height:1.25rem;margin-top:.35rem}.spacer{flex:1 1 auto}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.character-counter{font-size:.8rem;font-weight:500;color:#64748b;white-space:nowrap}::ng-deep .pt-password-input{display:block!important;width:100%!important}::ng-deep .pt-password-input .p-password{display:block!important;width:100%!important}::ng-deep .pt-password-input .p-password-input{width:100%!important}::ng-deep .pt-password-input input{box-sizing:border-box;width:100%!important}::ng-deep .pt-password-input.ng-invalid.ng-touched input,::ng-deep .pt-password-input.ng-invalid.ng-dirty input,::ng-deep .pt-password-input input.ng-invalid.ng-touched,::ng-deep .pt-password-input input.ng-invalid.ng-dirty{border-color:#dc2626}::ng-deep .pt-password-input .p-password-toggle-mask-icon,::ng-deep .pt-password-input .p-password-toggle-mask{right:1rem}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i10.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: i11.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "component", type: i6$1.Password, selector: "p-password", inputs: ["ariaLabel", "ariaLabelledBy", "label", "promptLabel", "mediumRegex", "strongRegex", "weakLabel", "mediumLabel", "maxLength", "strongLabel", "inputId", "feedback", "toggleMask", "inputStyleClass", "styleClass", "inputStyle", "showTransitionOptions", "hideTransitionOptions", "autocomplete", "placeholder", "showClear", "autofocus", "tabindex", "appendTo", "motionOptions", "overlayOptions"], outputs: ["onFocus", "onBlur", "onClear"] }] }); }
|
|
3651
4121
|
}
|
|
3652
4122
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTPasswordInputComponent, decorators: [{
|
|
3653
4123
|
type: Component,
|
|
3654
|
-
args: [{ selector: 'pt-password-input', standalone: false, template: "
|
|
4124
|
+
args: [{ selector: 'pt-password-input', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-password-input/pt-password-input.component.html -->\n\n<div\n class=\"form-field\"\n [formGroup]=\"formGroup\"\n [ngClass]=\"{\n 'form-field-invalid': isInvalid,\n }\"\n [ngStyle]=\"{\n width: formField.width || '100%',\n height: formField.height || 'auto',\n margin: formField.margin || null,\n }\"\n>\n @if (formField.label) {\n <label class=\"field-label\" [for]=\"inputId\">\n {{ formField.label }}\n\n @if (formField.required) {\n <span class=\"required-indicator\" aria-hidden=\"true\"> * </span>\n }\n </label>\n }\n\n @if (formField.iconClass) {\n <p-iconField\n class=\"password-icon-field\"\n [iconPosition]=\"formField.iconPosition || 'left'\"\n >\n <p-inputIcon [styleClass]=\"formField.iconClass\"></p-inputIcon>\n\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n </p-iconField>\n } @else {\n <p-password\n [inputId]=\"inputId\"\n [formControlName]=\"formField.name\"\n [placeholder]=\"formField.placeholder ?? ''\"\n [toggleMask]=\"getPasswordToggleMask()\"\n [feedback]=\"getPasswordFeedback()\"\n [attr.name]=\"formField.name\"\n [attr.aria-invalid]=\"isInvalid ? 'true' : 'false'\"\n [attr.aria-describedby]=\"isInvalid ? errorId : null\"\n [inputStyle]=\"{\n width: '100%',\n height: formField.height || 'auto',\n }\"\n styleClass=\"pt-password-input\"\n ></p-password>\n }\n\n @if (hasInfoRow()) {\n <div class=\"form-info-row\">\n @if (isInvalid) {\n <small class=\"field-error\" role=\"alert\" [id]=\"errorId\">\n {{ getErrorMessage() }}\n </small>\n }\n\n <div class=\"spacer\"></div>\n\n @if (hasCharacterCounter()) {\n <div class=\"character-counter\">\n {{ characterCount }}/{{ formField.maxLength }} characters\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.form-field{width:100%}.field-label{display:block;margin-bottom:.5rem;font-weight:700}.form-info-row{display:flex;align-items:center;gap:.5rem;min-height:1.25rem;margin-top:.35rem}.spacer{flex:1 1 auto}.field-error{display:block;color:#dc2626;font-size:.8rem;font-weight:500;line-height:1.2}.character-counter{font-size:.8rem;font-weight:500;color:#64748b;white-space:nowrap}::ng-deep .pt-password-input{display:block!important;width:100%!important}::ng-deep .pt-password-input .p-password{display:block!important;width:100%!important}::ng-deep .pt-password-input .p-password-input{width:100%!important}::ng-deep .pt-password-input input{box-sizing:border-box;width:100%!important}::ng-deep .pt-password-input.ng-invalid.ng-touched input,::ng-deep .pt-password-input.ng-invalid.ng-dirty input,::ng-deep .pt-password-input input.ng-invalid.ng-touched,::ng-deep .pt-password-input input.ng-invalid.ng-dirty{border-color:#dc2626}::ng-deep .pt-password-input .p-password-toggle-mask-icon,::ng-deep .pt-password-input .p-password-toggle-mask{right:1rem}\n"] }]
|
|
3655
4125
|
}], propDecorators: { formGroup: [{
|
|
3656
4126
|
type: Input
|
|
3657
4127
|
}], formField: [{
|
|
@@ -3690,11 +4160,11 @@ class PTDynamicFormFieldComponent {
|
|
|
3690
4160
|
return field;
|
|
3691
4161
|
}
|
|
3692
4162
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3693
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDynamicFormFieldComponent, isStandalone: false, selector: "pt-dynamic-form-field", inputs: { field: "field", form: "form", inputWidth: "inputWidth" }, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-form-builder/pt-dynamic-form-field/pt-dynamic-form-field.component.html -->\n\n<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX\n ? field.width || inputWidth\n : 'auto',\n }\"\n>\n @switch (field.type) {\n <!-- TEXT -->\n @case (FormInputTypeEnum.TEXT) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- PASSWORD -->\n @case (FormInputTypeEnum.PASSWORD) {\n <pt-password-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-password-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- TEXTAREA -->\n @case (FormInputTypeEnum.TEXTAREA) {\n <pt-text-area-input\n [formGroup]=\"form\"\n [formField]=\"asTextAreaField(field)\"\n ></pt-text-area-input>\n }\n\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n\n <!-- OTP -->\n @case (FormInputTypeEnum.OTP) {\n <pt-otp-input\n [formGroup]=\"form\"\n [formField]=\"asOtpField(field)\"\n ></pt-otp-input>\n }\n\n <!-- CHECKBOX -->\n @case (FormInputTypeEnum.CHECKBOX) {\n <pt-check-box-input\n [formGroup]=\"form\"\n [formField]=\"asCheckboxField(field)\"\n ></pt-check-box-input>\n }\n\n <!-- SWITCH -->\n @case (FormInputTypeEnum.SWITCH) {\n <pt-switch-input\n [formGroup]=\"form\"\n [formField]=\"asSwitchField(field)\"\n ></pt-switch-input>\n }\n }\n</div>\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PTCheckBoxInputComponent, selector: "pt-check-box-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDateInputComponent, selector: "pt-date-input", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "dateChange"] }, { kind: "component", type: PTNumberInputComponent, selector: "pt-number-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTSwitchInputComponent, selector: "pt-switch-input", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "switchChange"] }, { kind: "component", type: PTTextAreaInputComponent, selector: "pt-text-area-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDropdownComponent, selector: "pt-dropdown", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "selectionChange"] }, { kind: "component", type: PTMultiSelectComponent, selector: "pt-multi-select", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "selectionChange"] }, { kind: "component", type: PTOtpInputComponent, selector: "pt-otp-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTPasswordInputComponent, selector: "pt-password-input", inputs: ["formGroup", "formField"] }] }); }
|
|
4163
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTDynamicFormFieldComponent, isStandalone: false, selector: "pt-dynamic-form-field", inputs: { field: "field", form: "form", inputWidth: "inputWidth" }, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/pt-form-builder/pt-dynamic-form-field/pt-dynamic-form-field.component.html -->\n\n<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX\n ? field.width || inputWidth\n : 'auto',\n }\"\n>\n @switch (field.type) {\n <!-- TEXT -->\n @case (FormInputTypeEnum.TEXT) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- PASSWORD -->\n @case (FormInputTypeEnum.PASSWORD) {\n <pt-password-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-password-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- TEXTAREA -->\n @case (FormInputTypeEnum.TEXTAREA) {\n <pt-text-area-input\n [formGroup]=\"form\"\n [formField]=\"asTextAreaField(field)\"\n ></pt-text-area-input>\n }\n\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n\n <!-- OTP -->\n @case (FormInputTypeEnum.OTP) {\n <pt-otp-input\n [formGroup]=\"form\"\n [formField]=\"asOtpField(field)\"\n ></pt-otp-input>\n }\n\n <!-- CHECKBOX -->\n @case (FormInputTypeEnum.CHECKBOX) {\n <pt-check-box-input\n [formGroup]=\"form\"\n [formField]=\"asCheckboxField(field)\"\n ></pt-check-box-input>\n }\n\n <!-- SWITCH -->\n @case (FormInputTypeEnum.SWITCH) {\n <pt-switch-input\n [formGroup]=\"form\"\n [formField]=\"asSwitchField(field)\"\n ></pt-switch-input>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0;max-width:100%}.form-field{display:block;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.form-field>pt-text-input,.form-field>pt-password-input,.form-field>pt-number-input,.form-field>pt-text-area-input,.form-field>pt-date-input,.form-field>pt-multi-select,.form-field>pt-dropdown,.form-field>pt-otp-input,.form-field>pt-switch-input{display:block;width:100%;min-width:0;max-width:100%}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: PTCheckBoxInputComponent, selector: "pt-check-box-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDateInputComponent, selector: "pt-date-input", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "dateChange"] }, { kind: "component", type: PTNumberInputComponent, selector: "pt-number-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTSwitchInputComponent, selector: "pt-switch-input", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "switchChange"] }, { kind: "component", type: PTTextAreaInputComponent, selector: "pt-text-area-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTDropdownComponent, selector: "pt-dropdown", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "selectionChange"] }, { kind: "component", type: PTMultiSelectComponent, selector: "pt-multi-select", inputs: ["formGroup", "formField", "config", "value"], outputs: ["valueChange", "selectionChange"] }, { kind: "component", type: PTOtpInputComponent, selector: "pt-otp-input", inputs: ["formGroup", "formField"] }, { kind: "component", type: PTPasswordInputComponent, selector: "pt-password-input", inputs: ["formGroup", "formField"] }] }); }
|
|
3694
4164
|
}
|
|
3695
4165
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTDynamicFormFieldComponent, decorators: [{
|
|
3696
4166
|
type: Component,
|
|
3697
|
-
args: [{ selector: 'pt-dynamic-form-field', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-form-builder/pt-dynamic-form-field/pt-dynamic-form-field.component.html -->\n\n<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX\n ? field.width || inputWidth\n : 'auto',\n }\"\n>\n @switch (field.type) {\n <!-- TEXT -->\n @case (FormInputTypeEnum.TEXT) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- PASSWORD -->\n @case (FormInputTypeEnum.PASSWORD) {\n <pt-password-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-password-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- TEXTAREA -->\n @case (FormInputTypeEnum.TEXTAREA) {\n <pt-text-area-input\n [formGroup]=\"form\"\n [formField]=\"asTextAreaField(field)\"\n ></pt-text-area-input>\n }\n\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n\n <!-- OTP -->\n @case (FormInputTypeEnum.OTP) {\n <pt-otp-input\n [formGroup]=\"form\"\n [formField]=\"asOtpField(field)\"\n ></pt-otp-input>\n }\n\n <!-- CHECKBOX -->\n @case (FormInputTypeEnum.CHECKBOX) {\n <pt-check-box-input\n [formGroup]=\"form\"\n [formField]=\"asCheckboxField(field)\"\n ></pt-check-box-input>\n }\n\n <!-- SWITCH -->\n @case (FormInputTypeEnum.SWITCH) {\n <pt-switch-input\n [formGroup]=\"form\"\n [formField]=\"asSwitchField(field)\"\n ></pt-switch-input>\n }\n }\n</div>\n", styles: [".form-field{margin-bottom:1rem}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"] }]
|
|
4167
|
+
args: [{ selector: 'pt-dynamic-form-field', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/pt-form-builder/pt-dynamic-form-field/pt-dynamic-form-field.component.html -->\n\n<div\n [formGroup]=\"form\"\n class=\"form-field\"\n [ngStyle]=\"{\n width:\n field.type !== FormInputTypeEnum.CHECKBOX\n ? field.width || inputWidth\n : 'auto',\n }\"\n>\n @switch (field.type) {\n <!-- TEXT -->\n @case (FormInputTypeEnum.TEXT) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- EMAIL -->\n @case (FormInputTypeEnum.EMAIL) {\n <pt-text-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-text-input>\n }\n\n <!-- PASSWORD -->\n @case (FormInputTypeEnum.PASSWORD) {\n <pt-password-input\n [formGroup]=\"form\"\n [formField]=\"asTextField(field)\"\n ></pt-password-input>\n }\n\n <!-- NUMBER -->\n @case (FormInputTypeEnum.NUMBER) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- AMOUNT -->\n @case (FormInputTypeEnum.AMOUNT) {\n <pt-number-input\n [formGroup]=\"form\"\n [formField]=\"asNumberField(field)\"\n ></pt-number-input>\n }\n\n <!-- TEXTAREA -->\n @case (FormInputTypeEnum.TEXTAREA) {\n <pt-text-area-input\n [formGroup]=\"form\"\n [formField]=\"asTextAreaField(field)\"\n ></pt-text-area-input>\n }\n\n <!-- DATE -->\n @case (FormInputTypeEnum.DATE) {\n <pt-date-input\n [formGroup]=\"form\"\n [formField]=\"asDateField(field)\"\n ></pt-date-input>\n }\n\n <!-- MULTISELECT -->\n @case (FormInputTypeEnum.MULTISELECT) {\n <pt-multi-select\n [formGroup]=\"form\"\n [formField]=\"asMultiSelectField(field)\"\n ></pt-multi-select>\n }\n\n <!-- SELECT -->\n @case (FormInputTypeEnum.SELECT) {\n <pt-dropdown\n [formGroup]=\"form\"\n [formField]=\"asSelectField(field)\"\n ></pt-dropdown>\n }\n\n <!-- OTP -->\n @case (FormInputTypeEnum.OTP) {\n <pt-otp-input\n [formGroup]=\"form\"\n [formField]=\"asOtpField(field)\"\n ></pt-otp-input>\n }\n\n <!-- CHECKBOX -->\n @case (FormInputTypeEnum.CHECKBOX) {\n <pt-check-box-input\n [formGroup]=\"form\"\n [formField]=\"asCheckboxField(field)\"\n ></pt-check-box-input>\n }\n\n <!-- SWITCH -->\n @case (FormInputTypeEnum.SWITCH) {\n <pt-switch-input\n [formGroup]=\"form\"\n [formField]=\"asSwitchField(field)\"\n ></pt-switch-input>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%;min-width:0;max-width:100%}.form-field{display:block;width:100%;min-width:0;max-width:100%;margin-bottom:1rem}.form-field>pt-text-input,.form-field>pt-password-input,.form-field>pt-number-input,.form-field>pt-text-area-input,.form-field>pt-date-input,.form-field>pt-multi-select,.form-field>pt-dropdown,.form-field>pt-otp-input,.form-field>pt-switch-input{display:block;width:100%;min-width:0;max-width:100%}.form-field label{display:block;margin-bottom:.5rem;font-weight:700}\n"] }]
|
|
3698
4168
|
}], propDecorators: { field: [{
|
|
3699
4169
|
type: Input
|
|
3700
4170
|
}], form: [{
|
|
@@ -3708,7 +4178,10 @@ class PTFormBuilderComponent {
|
|
|
3708
4178
|
constructor(fb, cdr) {
|
|
3709
4179
|
this.fb = fb;
|
|
3710
4180
|
this.cdr = cdr;
|
|
3711
|
-
this.mainGroup = {
|
|
4181
|
+
this.mainGroup = {
|
|
4182
|
+
fields: [],
|
|
4183
|
+
groups: [],
|
|
4184
|
+
};
|
|
3712
4185
|
this.buttons = [];
|
|
3713
4186
|
this.inputWidth = '100%';
|
|
3714
4187
|
this.formWidth = '100%';
|
|
@@ -3722,8 +4195,12 @@ class PTFormBuilderComponent {
|
|
|
3722
4195
|
required: 'is required',
|
|
3723
4196
|
email: 'is not a valid email address',
|
|
3724
4197
|
pattern: 'is invalid',
|
|
3725
|
-
minlength: 'must
|
|
3726
|
-
maxlength: 'must
|
|
4198
|
+
minlength: 'must contain at least',
|
|
4199
|
+
maxlength: 'must contain at most',
|
|
4200
|
+
min: 'must be greater than or equal to',
|
|
4201
|
+
max: 'must be less than or equal to',
|
|
4202
|
+
invalid: 'is invalid',
|
|
4203
|
+
characters: 'characters',
|
|
3727
4204
|
},
|
|
3728
4205
|
fr: {
|
|
3729
4206
|
required: 'est requis',
|
|
@@ -3731,6 +4208,10 @@ class PTFormBuilderComponent {
|
|
|
3731
4208
|
pattern: 'est invalide',
|
|
3732
4209
|
minlength: 'doit contenir au moins',
|
|
3733
4210
|
maxlength: 'doit contenir au plus',
|
|
4211
|
+
min: 'doit être supérieur ou égal à',
|
|
4212
|
+
max: 'doit être inférieur ou égal à',
|
|
4213
|
+
invalid: 'est invalide',
|
|
4214
|
+
characters: 'caractères',
|
|
3734
4215
|
},
|
|
3735
4216
|
};
|
|
3736
4217
|
this.form = this.fb.group({});
|
|
@@ -3753,6 +4234,74 @@ class PTFormBuilderComponent {
|
|
|
3753
4234
|
}
|
|
3754
4235
|
return Boolean(hidden);
|
|
3755
4236
|
}
|
|
4237
|
+
isInvalid(field) {
|
|
4238
|
+
const control = this.form.get(field.name);
|
|
4239
|
+
return Boolean(control &&
|
|
4240
|
+
control.enabled &&
|
|
4241
|
+
control.invalid &&
|
|
4242
|
+
(control.touched || control.dirty));
|
|
4243
|
+
}
|
|
4244
|
+
getErrorMessage(field) {
|
|
4245
|
+
const control = this.form.get(field.name);
|
|
4246
|
+
if (!control?.errors) {
|
|
4247
|
+
return '';
|
|
4248
|
+
}
|
|
4249
|
+
const errorKey = this.resolveFirstErrorKey(control);
|
|
4250
|
+
if (!errorKey) {
|
|
4251
|
+
return '';
|
|
4252
|
+
}
|
|
4253
|
+
const customMessage = field.validationMessages?.[errorKey];
|
|
4254
|
+
if (customMessage) {
|
|
4255
|
+
return customMessage;
|
|
4256
|
+
}
|
|
4257
|
+
if (field.errorText) {
|
|
4258
|
+
return field.errorText;
|
|
4259
|
+
}
|
|
4260
|
+
const fieldLabel = field.label?.trim() || field.name;
|
|
4261
|
+
const messages = this.errorMessages[this.language];
|
|
4262
|
+
switch (errorKey) {
|
|
4263
|
+
case 'required':
|
|
4264
|
+
return `${fieldLabel} ${messages.required}`;
|
|
4265
|
+
case 'email':
|
|
4266
|
+
return `${fieldLabel} ${messages.email}`;
|
|
4267
|
+
case 'pattern':
|
|
4268
|
+
return `${fieldLabel} ${messages.pattern}`;
|
|
4269
|
+
case 'minlength': {
|
|
4270
|
+
const requiredLength = control.getError('minlength')?.requiredLength ?? '';
|
|
4271
|
+
return `${fieldLabel} ${messages.minlength} ${requiredLength} ${messages.characters}`;
|
|
4272
|
+
}
|
|
4273
|
+
case 'maxlength': {
|
|
4274
|
+
const requiredLength = control.getError('maxlength')?.requiredLength ?? '';
|
|
4275
|
+
return `${fieldLabel} ${messages.maxlength} ${requiredLength} ${messages.characters}`;
|
|
4276
|
+
}
|
|
4277
|
+
case 'min': {
|
|
4278
|
+
const minimum = control.getError('min')?.min ?? '';
|
|
4279
|
+
return `${fieldLabel} ${messages.min} ${minimum}`;
|
|
4280
|
+
}
|
|
4281
|
+
case 'max': {
|
|
4282
|
+
const maximum = control.getError('max')?.max ?? '';
|
|
4283
|
+
return `${fieldLabel} ${messages.max} ${maximum}`;
|
|
4284
|
+
}
|
|
4285
|
+
default:
|
|
4286
|
+
return `${fieldLabel} ${messages.invalid}`;
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
onSubmit() {
|
|
4290
|
+
this.form.markAllAsTouched();
|
|
4291
|
+
this.form.updateValueAndValidity({
|
|
4292
|
+
emitEvent: false,
|
|
4293
|
+
});
|
|
4294
|
+
if (this.form.invalid) {
|
|
4295
|
+
this.cdr.markForCheck();
|
|
4296
|
+
return;
|
|
4297
|
+
}
|
|
4298
|
+
this.formSubmit.emit(this.form.getRawValue());
|
|
4299
|
+
}
|
|
4300
|
+
onClear() {
|
|
4301
|
+
this.form.reset();
|
|
4302
|
+
this.formChange.emit(this.form.getRawValue());
|
|
4303
|
+
this.cdr.markForCheck();
|
|
4304
|
+
}
|
|
3756
4305
|
rebuildForm() {
|
|
3757
4306
|
this.formValueChangesSub?.unsubscribe();
|
|
3758
4307
|
this.form = this.fb.group({});
|
|
@@ -3765,14 +4314,17 @@ class PTFormBuilderComponent {
|
|
|
3765
4314
|
}
|
|
3766
4315
|
buildFormGroup(group) {
|
|
3767
4316
|
(group?.fields ?? []).forEach((field) => {
|
|
3768
|
-
const validators = this.buildValidators(field);
|
|
3769
|
-
const anyField = field;
|
|
3770
4317
|
this.form.addControl(field.name, this.fb.control({
|
|
3771
4318
|
value: this.resolveInitialValue(field),
|
|
3772
|
-
disabled: Boolean(
|
|
3773
|
-
},
|
|
4319
|
+
disabled: Boolean(field.disabled),
|
|
4320
|
+
}, {
|
|
4321
|
+
validators: this.buildValidators(field),
|
|
4322
|
+
updateOn: 'change',
|
|
4323
|
+
}));
|
|
4324
|
+
});
|
|
4325
|
+
(group?.groups ?? []).forEach((subGroup) => {
|
|
4326
|
+
this.buildFormGroup(subGroup);
|
|
3774
4327
|
});
|
|
3775
|
-
(group?.groups ?? []).forEach((subGroup) => this.buildFormGroup(subGroup));
|
|
3776
4328
|
}
|
|
3777
4329
|
resolveInitialValue(field) {
|
|
3778
4330
|
if (field.value !== undefined && field.value !== null) {
|
|
@@ -3788,31 +4340,29 @@ class PTFormBuilderComponent {
|
|
|
3788
4340
|
}
|
|
3789
4341
|
buildValidators(field) {
|
|
3790
4342
|
const validators = [];
|
|
3791
|
-
const anyField = field;
|
|
3792
4343
|
if (field.required) {
|
|
3793
4344
|
validators.push(Validators.required);
|
|
3794
4345
|
}
|
|
3795
|
-
if (
|
|
3796
|
-
validators.push(Validators.minLength(Number(
|
|
4346
|
+
if (field.minLength !== undefined && field.minLength !== null) {
|
|
4347
|
+
validators.push(Validators.minLength(Number(field.minLength)));
|
|
3797
4348
|
}
|
|
3798
|
-
if (
|
|
3799
|
-
validators.push(Validators.maxLength(Number(
|
|
4349
|
+
if (field.maxLength !== undefined && field.maxLength !== null) {
|
|
4350
|
+
validators.push(Validators.maxLength(Number(field.maxLength)));
|
|
3800
4351
|
}
|
|
3801
|
-
if (
|
|
3802
|
-
validators.push(Validators.pattern(new RegExp(
|
|
4352
|
+
if (field.inputValidation) {
|
|
4353
|
+
validators.push(Validators.pattern(new RegExp(field.inputValidation)));
|
|
3803
4354
|
}
|
|
3804
|
-
else if (
|
|
3805
|
-
validators.push(Validators.pattern(
|
|
4355
|
+
else if (field.pattern) {
|
|
4356
|
+
validators.push(Validators.pattern(field.pattern));
|
|
3806
4357
|
}
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
break;
|
|
4358
|
+
if (field.type === FormInputTypeEnum.EMAIL) {
|
|
4359
|
+
validators.push(Validators.email);
|
|
4360
|
+
}
|
|
4361
|
+
if (field.type === FormInputTypeEnum.OTP) {
|
|
4362
|
+
validators.push(Validators.pattern(this.buildOtpPattern(field)));
|
|
4363
|
+
}
|
|
4364
|
+
if (Array.isArray(field.validators) && field.validators.length > 0) {
|
|
4365
|
+
validators.push(...field.validators);
|
|
3816
4366
|
}
|
|
3817
4367
|
return validators;
|
|
3818
4368
|
}
|
|
@@ -3824,55 +4374,32 @@ class PTFormBuilderComponent {
|
|
|
3824
4374
|
}
|
|
3825
4375
|
return new RegExp(`^[A-Za-z0-9]{${length}}$`);
|
|
3826
4376
|
}
|
|
3827
|
-
|
|
3828
|
-
const
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
getErrorMessage(field) {
|
|
3832
|
-
const control = this.form.get(field.name);
|
|
3833
|
-
if (!control) {
|
|
3834
|
-
return '';
|
|
3835
|
-
}
|
|
3836
|
-
const lang = this.language;
|
|
3837
|
-
if (control.hasError('required')) {
|
|
3838
|
-
return (field.errorText ||
|
|
3839
|
-
`${field.label} ${this.errorMessages[lang].required}`);
|
|
3840
|
-
}
|
|
3841
|
-
if (control.hasError('email')) {
|
|
3842
|
-
return (field.errorText ||
|
|
3843
|
-
`${field.label} ${this.errorMessages[lang].email}`);
|
|
3844
|
-
}
|
|
3845
|
-
if (control.hasError('pattern')) {
|
|
3846
|
-
return (field.errorText ||
|
|
3847
|
-
`${field.label} ${this.errorMessages[lang].pattern}`);
|
|
3848
|
-
}
|
|
3849
|
-
if (control.hasError('minlength')) {
|
|
3850
|
-
const requiredLength = control.getError('minlength')?.requiredLength;
|
|
3851
|
-
return `${field.label} ${this.errorMessages[lang].minlength} ${requiredLength} ${lang === 'fr' ? 'caractères' : 'characters'}`;
|
|
3852
|
-
}
|
|
3853
|
-
if (control.hasError('maxlength')) {
|
|
3854
|
-
const requiredLength = control.getError('maxlength')?.requiredLength;
|
|
3855
|
-
return `${field.label} ${this.errorMessages[lang].maxlength} ${requiredLength} ${lang === 'fr' ? 'caractères' : 'characters'}`;
|
|
4377
|
+
resolveFirstErrorKey(control) {
|
|
4378
|
+
const errors = control.errors;
|
|
4379
|
+
if (!errors) {
|
|
4380
|
+
return undefined;
|
|
3856
4381
|
}
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
4382
|
+
const priority = [
|
|
4383
|
+
'required',
|
|
4384
|
+
'email',
|
|
4385
|
+
'minlength',
|
|
4386
|
+
'maxlength',
|
|
4387
|
+
'min',
|
|
4388
|
+
'max',
|
|
4389
|
+
'pattern',
|
|
4390
|
+
];
|
|
4391
|
+
const priorityError = priority.find((key) => errors[key] !== undefined);
|
|
4392
|
+
if (priorityError) {
|
|
4393
|
+
return priorityError;
|
|
3863
4394
|
}
|
|
3864
|
-
|
|
3865
|
-
onClear() {
|
|
3866
|
-
this.form.reset();
|
|
3867
|
-
this.formChange.emit(this.form.getRawValue());
|
|
3868
|
-
this.cdr.markForCheck();
|
|
4395
|
+
return Object.keys(errors)[0];
|
|
3869
4396
|
}
|
|
3870
4397
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTFormBuilderComponent, deps: [{ token: i2.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3871
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTFormBuilderComponent, isStandalone: false, selector: "pt-form-builder", inputs: { mainGroup: "mainGroup", buttons: "buttons", title: "title", titleStyle: "titleStyle", inputWidth: "inputWidth", formWidth: "formWidth", language: "language" }, outputs: { formSubmit: "formSubmit", formReady: "formReady", formChange: "formChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/components/pt-form-builder/pt-form-builder.component.html -->\n\n<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{
|
|
4398
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PTFormBuilderComponent, isStandalone: false, selector: "pt-form-builder", inputs: { mainGroup: "mainGroup", buttons: "buttons", title: "title", titleStyle: "titleStyle", inputWidth: "inputWidth", formWidth: "formWidth", language: "language" }, outputs: { formSubmit: "formSubmit", formReady: "formReady", formChange: "formChange" }, usesOnChanges: true, ngImport: i0, template: "<!-- projects/ng-prime-tools/src/lib/components/pt-form-builder/pt-form-builder.component.html -->\n\n<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{\n width: formWidth,\n 'max-width': formWidth,\n }\"\n>\n @if (title) {\n <div class=\"form-title\" [ngStyle]=\"titleStyle\">\n {{ title }}\n </div>\n }\n\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"onSubmit()\">\n @for (field of mainGroup.fields; track field.name) {\n @if (!isFieldHidden(field)) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n }\n\n @for (group of mainGroup.groups; track $index) {\n <div\n class=\"form-field-group\"\n [ngStyle]=\"{\n width: group.width || '100%',\n }\"\n >\n @for (field of group.fields; track field.name) {\n @if (!isFieldHidden(field)) {\n <pt-dynamic-form-field\n class=\"flex-item\"\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n }\n </div>\n }\n\n @if (buttons.length > 0) {\n <div class=\"button-group\">\n @for (button of buttons; track button.text) {\n <button\n pButton\n [type]=\"button.isSubmit ? 'submit' : 'button'\"\n [label]=\"button.text\"\n [icon]=\"button.icon || ''\"\n [class]=\"button.color || ''\"\n [disabled]=\"button.disabled || false\"\n [ngStyle]=\"{\n color: button.fontColor || null,\n 'background-color': button.backgroundColor || null,\n 'border-color':\n button.borderColor || button.backgroundColor || null,\n }\"\n (click)=\"\n button.isSubmit\n ? null\n : button.isClear\n ? onClear()\n : button.action\n ? button.action()\n : null\n \"\n ></button>\n }\n </div>\n }\n </form>\n</div>\n", styles: [".pt-form-builder-wrapper{width:100%;margin:0 auto;color:var(--pt-form-builder-text, inherit)}.form-title{text-align:center;margin-bottom:1rem;font-size:1.5rem;font-weight:700;color:var(--pt-form-builder-title, #333333)}.form-field{margin-bottom:1rem;color:var(--pt-form-builder-text, inherit)}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;color:var(--pt-form-builder-label, #333333)}::ng-deep .p-inputtext,::ng-deep .p-inputtextarea,::ng-deep .p-calendar,::ng-deep .p-inputnumber,::ng-deep .p-multiselect,::ng-deep .p-dropdown{width:100%!important}::ng-deep .p-inputnumber,::ng-deep p-inputnumber{display:flex!important}.button-group{display:flex;gap:1rem;margin-top:1rem;justify-content:space-between}.button-group button{flex:1;display:flex;align-items:center;justify-content:center}.button-group button i{margin-right:.5rem}.button-group button.p-button-primary{background-color:var(--pt-form-builder-button-primary-bg, #007bff);color:var(--pt-form-builder-button-primary-text, #ffffff)}.button-group button.p-button-secondary{background-color:var(--pt-form-builder-button-secondary-bg, #6c757d);color:var(--pt-form-builder-button-secondary-text, #ffffff)}.button-group button.p-button-success{background-color:var(--pt-form-builder-button-success-bg, #28a745);color:var(--pt-form-builder-button-success-text, #ffffff)}.button-group button:hover{opacity:.9}.form-field-group{display:flex;gap:1rem}.form-field-group .flex-item{flex:1}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: PTDynamicFormFieldComponent, selector: "pt-dynamic-form-field", inputs: ["field", "form", "inputWidth"] }] }); }
|
|
3872
4399
|
}
|
|
3873
4400
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTFormBuilderComponent, decorators: [{
|
|
3874
4401
|
type: Component,
|
|
3875
|
-
args: [{ selector: 'pt-form-builder', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/components/pt-form-builder/pt-form-builder.component.html -->\n\n<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{
|
|
4402
|
+
args: [{ selector: 'pt-form-builder', standalone: false, template: "<!-- projects/ng-prime-tools/src/lib/components/pt-form-builder/pt-form-builder.component.html -->\n\n<div\n class=\"pt-form-builder-wrapper\"\n [ngStyle]=\"{\n width: formWidth,\n 'max-width': formWidth,\n }\"\n>\n @if (title) {\n <div class=\"form-title\" [ngStyle]=\"titleStyle\">\n {{ title }}\n </div>\n }\n\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"onSubmit()\">\n @for (field of mainGroup.fields; track field.name) {\n @if (!isFieldHidden(field)) {\n <pt-dynamic-form-field\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n }\n\n @for (group of mainGroup.groups; track $index) {\n <div\n class=\"form-field-group\"\n [ngStyle]=\"{\n width: group.width || '100%',\n }\"\n >\n @for (field of group.fields; track field.name) {\n @if (!isFieldHidden(field)) {\n <pt-dynamic-form-field\n class=\"flex-item\"\n [field]=\"field\"\n [form]=\"form\"\n [inputWidth]=\"inputWidth\"\n ></pt-dynamic-form-field>\n }\n }\n </div>\n }\n\n @if (buttons.length > 0) {\n <div class=\"button-group\">\n @for (button of buttons; track button.text) {\n <button\n pButton\n [type]=\"button.isSubmit ? 'submit' : 'button'\"\n [label]=\"button.text\"\n [icon]=\"button.icon || ''\"\n [class]=\"button.color || ''\"\n [disabled]=\"button.disabled || false\"\n [ngStyle]=\"{\n color: button.fontColor || null,\n 'background-color': button.backgroundColor || null,\n 'border-color':\n button.borderColor || button.backgroundColor || null,\n }\"\n (click)=\"\n button.isSubmit\n ? null\n : button.isClear\n ? onClear()\n : button.action\n ? button.action()\n : null\n \"\n ></button>\n }\n </div>\n }\n </form>\n</div>\n", styles: [".pt-form-builder-wrapper{width:100%;margin:0 auto;color:var(--pt-form-builder-text, inherit)}.form-title{text-align:center;margin-bottom:1rem;font-size:1.5rem;font-weight:700;color:var(--pt-form-builder-title, #333333)}.form-field{margin-bottom:1rem;color:var(--pt-form-builder-text, inherit)}.form-field label{display:block;margin-bottom:.5rem;font-weight:700;color:var(--pt-form-builder-label, #333333)}::ng-deep .p-inputtext,::ng-deep .p-inputtextarea,::ng-deep .p-calendar,::ng-deep .p-inputnumber,::ng-deep .p-multiselect,::ng-deep .p-dropdown{width:100%!important}::ng-deep .p-inputnumber,::ng-deep p-inputnumber{display:flex!important}.button-group{display:flex;gap:1rem;margin-top:1rem;justify-content:space-between}.button-group button{flex:1;display:flex;align-items:center;justify-content:center}.button-group button i{margin-right:.5rem}.button-group button.p-button-primary{background-color:var(--pt-form-builder-button-primary-bg, #007bff);color:var(--pt-form-builder-button-primary-text, #ffffff)}.button-group button.p-button-secondary{background-color:var(--pt-form-builder-button-secondary-bg, #6c757d);color:var(--pt-form-builder-button-secondary-text, #ffffff)}.button-group button.p-button-success{background-color:var(--pt-form-builder-button-success-bg, #28a745);color:var(--pt-form-builder-button-success-text, #ffffff)}.button-group button:hover{opacity:.9}.form-field-group{display:flex;gap:1rem}.form-field-group .flex-item{flex:1}\n"] }]
|
|
3876
4403
|
}], ctorParameters: () => [{ type: i2.FormBuilder }, { type: i0.ChangeDetectorRef }], propDecorators: { mainGroup: [{
|
|
3877
4404
|
type: Input
|
|
3878
4405
|
}], buttons: [{
|
|
@@ -9461,6 +9988,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
9461
9988
|
}]
|
|
9462
9989
|
}] });
|
|
9463
9990
|
|
|
9991
|
+
// projects/ng-prime-tools/src/lib/models/form-multi-select.model.ts
|
|
9992
|
+
|
|
9464
9993
|
// projects/ng-prime-tools/src/lib/models/pt-accordion-config.model.ts
|
|
9465
9994
|
|
|
9466
9995
|
// nav-bar-menu-config.model.ts
|