@webilix/ngx-form-m3 0.0.42 → 0.0.43
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.
- package/fesm2022/webilix-ngx-form-m3.mjs +93 -1
- package/fesm2022/webilix-ngx-form-m3.mjs.map +1 -1
- package/index.d.ts +9 -1
- package/ngx-form-m3.css +26 -10
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { HostBinding, Directive, Input, HostListener, Optional, Pipe, InjectionToken, inject, Component, Injector, EventEmitter, Output, makeEnvironmentProviders, ViewChild, Inject } from '@angular/core';
|
|
2
|
+
import { HostBinding, Directive, Input, HostListener, Optional, Pipe, InjectionToken, inject, Component, Injector, EventEmitter, Output, model, computed, makeEnvironmentProviders, ViewChild, Inject } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { ReactiveFormsModule, FormControl, Validators, FormsModule, FormGroup } from '@angular/forms';
|
|
5
5
|
import { MatIconButton, MatButton } from '@angular/material/button';
|
|
@@ -24,6 +24,9 @@ import * as i3$1 from '@angular/material/menu';
|
|
|
24
24
|
import { MatMenuModule } from '@angular/material/menu';
|
|
25
25
|
import * as i4 from '@angular/material/select';
|
|
26
26
|
import { MatSelectModule } from '@angular/material/select';
|
|
27
|
+
import { ENTER, COMMA } from '@angular/cdk/keycodes';
|
|
28
|
+
import * as i3$2 from '@angular/material/chips';
|
|
29
|
+
import { MatChipsModule } from '@angular/material/chips';
|
|
27
30
|
import * as i1$5 from '@angular/router';
|
|
28
31
|
|
|
29
32
|
class AutoCompleteDirective {
|
|
@@ -1752,6 +1755,93 @@ class InputSelectMethods extends InputMethods {
|
|
|
1752
1755
|
}
|
|
1753
1756
|
}
|
|
1754
1757
|
|
|
1758
|
+
class InputTagComponent {
|
|
1759
|
+
formControl = inject(INPUT_CONTROL);
|
|
1760
|
+
input = inject(INPUT_TYPE);
|
|
1761
|
+
config = inject(INPUT_CONFIG);
|
|
1762
|
+
values;
|
|
1763
|
+
isButtonDisabled;
|
|
1764
|
+
separatorKeysCodes = [ENTER, COMMA];
|
|
1765
|
+
inputValue = model('', ...(ngDevMode ? [{ debugName: "inputValue" }] : []));
|
|
1766
|
+
tags = Array.isArray(this.formControl.value) ? this.formControl.value : [];
|
|
1767
|
+
filteredTags = computed(() => {
|
|
1768
|
+
const value = this.inputValue().toLowerCase();
|
|
1769
|
+
const options = this.input.tags
|
|
1770
|
+
.filter((tag) => !this.tags.includes(tag))
|
|
1771
|
+
.filter((t, i, a) => a.indexOf(t) === i)
|
|
1772
|
+
.sort((t1, t2) => t1.localeCompare(t2));
|
|
1773
|
+
return value ? options.filter((option) => option.toLowerCase().includes(value)) : options;
|
|
1774
|
+
}, ...(ngDevMode ? [{ debugName: "filteredTags" }] : []));
|
|
1775
|
+
setValues() {
|
|
1776
|
+
this.tags = this.tags.sort((t1, t2) => t1.localeCompare(t2));
|
|
1777
|
+
this.formControl.setValue(this.tags.length === 0 ? null : this.tags);
|
|
1778
|
+
this.formControl.markAsTouched();
|
|
1779
|
+
this.inputValue.set('');
|
|
1780
|
+
}
|
|
1781
|
+
addTag(event) {
|
|
1782
|
+
const value = (event.value || '').trim();
|
|
1783
|
+
if (!value || this.tags.includes(value))
|
|
1784
|
+
return;
|
|
1785
|
+
this.tags.push(value);
|
|
1786
|
+
this.setValues();
|
|
1787
|
+
}
|
|
1788
|
+
removeTag(tag) {
|
|
1789
|
+
if (!this.tags.includes(tag))
|
|
1790
|
+
return;
|
|
1791
|
+
this.tags = this.tags.filter((t) => t !== tag);
|
|
1792
|
+
this.setValues();
|
|
1793
|
+
}
|
|
1794
|
+
selectTag(event) {
|
|
1795
|
+
const value = event.option.viewValue;
|
|
1796
|
+
if (!value || this.tags.includes(value))
|
|
1797
|
+
return;
|
|
1798
|
+
this.tags.push(value);
|
|
1799
|
+
this.setValues();
|
|
1800
|
+
event.option.deselect();
|
|
1801
|
+
}
|
|
1802
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: InputTagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1803
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: InputTagComponent, isStandalone: true, selector: "ng-component", inputs: { values: { classPropertyName: "values", publicName: "values", isSignal: false, isRequired: true, transformFunction: null }, isButtonDisabled: { classPropertyName: "isButtonDisabled", publicName: "isButtonDisabled", isSignal: false, isRequired: true, transformFunction: null }, inputValue: { classPropertyName: "inputValue", publicName: "inputValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { inputValue: "inputValueChange" }, host: { attributes: { "selector": "input-tag" } }, ngImport: i0, template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"tags.length === 0 ? 'auto' : 'always'\">\n <mat-label>{{ input.title || '\u062A\u06AF' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <mat-chip-grid #chipGrid [formControl]=\"formControl\" class=\"ngx-helper-form-m3-tag-input\">\n @for (tag of tags; track $index) {\n <mat-chip-row (removed)=\"removeTag(tag); tagInput.value = ''\">\n <span class=\"tag\">{{ tag }}</span>\n <button matChipRemove type=\"button\"><mat-icon>cancel</mat-icon></button>\n </mat-chip-row>\n }\n </mat-chip-grid>\n <input\n type=\"text\"\n name=\"inputValue\"\n [(ngModel)]=\"inputValue\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [matChipInputFor]=\"chipGrid\"\n [matAutocomplete]=\"auto\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n (matChipInputTokenEnd)=\"addTag($event); tagInput.value = ''\"\n #tagInput\n />\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selectTag($event); tagInput.value = ''\">\n @for (option of filteredTags(); track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-autocomplete>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i3$2.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i3$2.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i3$2.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i3$2.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: AutoCompleteDirective, selector: "input[type=\"text\"]" }, { kind: "directive", type: AutoFocusDirective, selector: "[AutoFocusDirective]", inputs: ["AutoFocusDirective"] }, { kind: "pipe", type: InputErrorPipe, name: "InputErrorPipe" }, { kind: "pipe", type: MultiLinePipe, name: "MultiLinePipe" }] });
|
|
1804
|
+
}
|
|
1805
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: InputTagComponent, decorators: [{
|
|
1806
|
+
type: Component,
|
|
1807
|
+
args: [{ host: { selector: 'input-tag' }, imports: [
|
|
1808
|
+
ReactiveFormsModule,
|
|
1809
|
+
FormsModule,
|
|
1810
|
+
MatAutocompleteModule,
|
|
1811
|
+
MatChipsModule,
|
|
1812
|
+
MatFormField,
|
|
1813
|
+
MatIcon,
|
|
1814
|
+
MatIconButton,
|
|
1815
|
+
MatInputModule,
|
|
1816
|
+
AutoCompleteDirective,
|
|
1817
|
+
AutoFocusDirective,
|
|
1818
|
+
InputErrorPipe,
|
|
1819
|
+
MultiLinePipe,
|
|
1820
|
+
], template: "<mat-form-field [appearance]=\"input.appearance || config.appearance\" [floatLabel]=\"tags.length === 0 ? 'auto' : 'always'\">\n <mat-label>{{ input.title || '\u062A\u06AF' }}</mat-label>\n @if (formControl.invalid) { <mat-error>{{ formControl.errors | InputErrorPipe : input.type }}</mat-error> }\n\n <!-- HINT -->\n @if (input.hint) { <mat-hint>{{ input.hint }}</mat-hint> }\n\n <!-- BUTTON -->\n @if (input.button) {\n <span matIconSuffix>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"isButtonDisabled\"\n (click)=\"input.button.onClick(values)\"\n [tabIndex]=\"-1\"\n >\n <mat-icon [style.color]=\"isButtonDisabled ? undefined : input.button.color\">\n {{ input.button.icon }}\n </mat-icon>\n </button>\n </span>\n }\n\n <mat-chip-grid #chipGrid [formControl]=\"formControl\" class=\"ngx-helper-form-m3-tag-input\">\n @for (tag of tags; track $index) {\n <mat-chip-row (removed)=\"removeTag(tag); tagInput.value = ''\">\n <span class=\"tag\">{{ tag }}</span>\n <button matChipRemove type=\"button\"><mat-icon>cancel</mat-icon></button>\n </mat-chip-row>\n }\n </mat-chip-grid>\n <input\n type=\"text\"\n name=\"inputValue\"\n [(ngModel)]=\"inputValue\"\n [AutoFocusDirective]=\"config.autoFocus === input.name\"\n [matChipInputFor]=\"chipGrid\"\n [matAutocomplete]=\"auto\"\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\n (matChipInputTokenEnd)=\"addTag($event); tagInput.value = ''\"\n #tagInput\n />\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selectTag($event); tagInput.value = ''\">\n @for (option of filteredTags(); track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-autocomplete>\n\n <!-- DESCRIPTION -->\n @if (input.description) {\n <div\n class=\"ngx-form-m3-input-description\"\n [class.ngx-form-m3-disabled-input]=\"formControl.disabled\"\n [innerHTML]=\"input.description | MultiLinePipe\"\n ></div>\n }\n</mat-form-field>\n" }]
|
|
1821
|
+
}], propDecorators: { values: [{
|
|
1822
|
+
type: Input,
|
|
1823
|
+
args: [{ required: true }]
|
|
1824
|
+
}], isButtonDisabled: [{
|
|
1825
|
+
type: Input,
|
|
1826
|
+
args: [{ required: true }]
|
|
1827
|
+
}] } });
|
|
1828
|
+
|
|
1829
|
+
class InputTagMethods extends InputMethods {
|
|
1830
|
+
control(input, validators) {
|
|
1831
|
+
if (input.minCount)
|
|
1832
|
+
validators.push(MinCountValidator(input.minCount));
|
|
1833
|
+
if (input.maxCount)
|
|
1834
|
+
validators.push(MaxCountValidator(input.maxCount));
|
|
1835
|
+
const value = (Array.isArray(input.value) ? input.value : [])
|
|
1836
|
+
.filter((value) => Helper.IS.string(value) && value !== '')
|
|
1837
|
+
.filter((value, index, arr) => arr.indexOf(value) === index);
|
|
1838
|
+
return new FormControl(value, validators);
|
|
1839
|
+
}
|
|
1840
|
+
value(value, input) {
|
|
1841
|
+
return Array.isArray(value) && value.length > 0 ? value : null;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1755
1845
|
class InputTextComponent {
|
|
1756
1846
|
formControl = inject(INPUT_CONTROL);
|
|
1757
1847
|
input = inject(INPUT_TYPE);
|
|
@@ -1961,6 +2051,7 @@ const InputInfo = {
|
|
|
1961
2051
|
PRICE: { title: 'قیمت', methods: new InputPriceMethods(), component: InputPriceComponent },
|
|
1962
2052
|
ROUTE: { title: 'مسیر', methods: new InputRouteMethods(), component: InputRouteComponent },
|
|
1963
2053
|
SELECT: { title: 'لیست کشویی', methods: new InputSelectMethods(), component: InputSelectComponent },
|
|
2054
|
+
TAG: { title: 'تگ', methods: new InputTagMethods(), component: InputTagComponent },
|
|
1964
2055
|
TEXT: { title: 'متن یک خطی', methods: new InputTextMethods(), component: InputTextComponent },
|
|
1965
2056
|
TEXTAREA: { title: 'متن چند خطی', methods: new InputTextareaMethods(), component: InputTextareaComponent },
|
|
1966
2057
|
URL: { title: 'آدرس سایت', methods: new InputUrlMethods(), component: InputUrlComponent },
|
|
@@ -2170,6 +2261,7 @@ class NgxFormComponent {
|
|
|
2170
2261
|
input.type === 'ITEM-LIST' ||
|
|
2171
2262
|
input.type === 'MULTI-SELECT' ||
|
|
2172
2263
|
input.type === 'OPTION-LIST' ||
|
|
2264
|
+
input.type === 'TAG' ||
|
|
2173
2265
|
input.optional ||
|
|
2174
2266
|
readonly
|
|
2175
2267
|
? []
|