@ng-modular-forms/material 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ron Bodnar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # @ng-modular-forms/material
2
+
3
+ Angular Material implementation of ng-modular-forms inputs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ng-modular-forms/material
9
+ ```
10
+
11
+ ## Example
12
+
13
+ ```ts
14
+ import { InputComponent } from "@ng-modular-forms/input";
15
+
16
+ @Component({
17
+ template: `
18
+ <form [formGroup]="form" (ngSubmit)="submit()">
19
+ <nmf-mat-input formControlName="fieldA" label="Field A" />
20
+ <nmf-mat-input formControlName="fieldB" label="Field B" />
21
+
22
+ <button type="submit">Submit</button>
23
+ </form>
24
+ `,
25
+ })
26
+ export class ExampleComponent {
27
+ form = new FormGroup({
28
+ fieldA: new FormControl(null),
29
+ fieldB: new FormControl(null),
30
+ });
31
+ }
32
+ ```
33
+
34
+ ## Built On
35
+
36
+ - Angular Material
37
+ - MatFormFieldControl
38
+ - ControlValueAccessor
39
+
40
+ ## Features
41
+
42
+ - Material styling
43
+ - Floating labels
44
+ - Validation UI
45
+ - Loading states
46
+
47
+ ### Requires
48
+
49
+ - @ng-modular-forms/core
50
+ - @ng-modular-forms/behavior
51
+ - @angular/material
52
+ - @angular/cdk
53
+
54
+ ## License
55
+
56
+ MIT
@@ -0,0 +1,835 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, signal, ViewChild, Directive, ChangeDetectionStrategy, Component, inject, forwardRef } from '@angular/core';
3
+ import { FormControlBase, parseCurrency } from '@ng-modular-forms/core';
4
+ import { Subject } from 'rxjs';
5
+ import * as i4$1 from '@angular/forms';
6
+ import { ReactiveFormsModule } from '@angular/forms';
7
+ import * as i1 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import * as i2 from '@angular/material/form-field';
10
+ import { MatFormFieldModule, MatFormFieldControl } from '@angular/material/form-field';
11
+ import { InputCurrencyBehavior, InputSelectBehavior, InputTextBehavior, InputTextareaBehavior } from '@ng-modular-forms/behavior';
12
+ import * as i3 from '@angular/material/progress-spinner';
13
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
14
+ import { DateAdapter, MatNativeDateModule } from '@angular/material/core';
15
+ import * as i3$1 from '@angular/material/datepicker';
16
+ import { MatDatepickerModule } from '@angular/material/datepicker';
17
+ import * as i4 from '@angular/material/select';
18
+ import { MatSelectModule } from '@angular/material/select';
19
+ import * as i3$2 from '@angular/material/input';
20
+ import { MatInputModule } from '@angular/material/input';
21
+ import * as i5 from '@angular/material/icon';
22
+ import { MatIconModule } from '@angular/material/icon';
23
+
24
+ /**
25
+ * Base implementation for custom form controls that integrate with:
26
+ * - Angular Reactive Forms (ControlValueAccessor)
27
+ * - Angular Material form-field (MatFormFieldControl)
28
+ */
29
+ class MatFormControlBase extends FormControlBase {
30
+ detachLabel = input(false);
31
+ hint = input();
32
+ hintClassList = input('');
33
+ appearance = input();
34
+ _formDisabled = signal(false);
35
+ /**
36
+ * Notifies Angular Material form-field of state changes
37
+ * (label float, error state, UI refresh)
38
+ */
39
+ stateChanges = new Subject();
40
+ set value(val) {
41
+ super.value = val;
42
+ this.stateChanges.next();
43
+ }
44
+ focused = false;
45
+ /**
46
+ * Assumes derived component exposes an element with #input reference.
47
+ */
48
+ input;
49
+ focus() {
50
+ const nativeElement = this.input?.nativeElement;
51
+ if (!nativeElement) {
52
+ console.warn('Tried to focus an input from FormControlBase that does not exist');
53
+ return;
54
+ }
55
+ this.focused = true;
56
+ nativeElement.focus();
57
+ }
58
+ get disabled() {
59
+ return this._disabled() || this._formDisabled();
60
+ }
61
+ get errorState() {
62
+ const control = this.ngControl?.control;
63
+ return !!control && control.invalid && control.touched;
64
+ }
65
+ get empty() {
66
+ return this.value === null || this.value === '' || this.value === undefined;
67
+ }
68
+ get shouldLabelFloat() {
69
+ return this.focused || !this.empty;
70
+ }
71
+ controlType = 'custom-form-control';
72
+ autofilled = false;
73
+ userAriaDescribedBy;
74
+ disableAutomaticLabeling;
75
+ writeValue(value) {
76
+ super.writeValue(value);
77
+ this.stateChanges.next();
78
+ }
79
+ setDisabledState(isDisabled) {
80
+ this._formDisabled.set(isDisabled);
81
+ this.stateChanges.next();
82
+ this.cdr.markForCheck();
83
+ }
84
+ setDescribedByIds(ids) {
85
+ this.userAriaDescribedBy = ids.join(' ');
86
+ }
87
+ onContainerClick(event) {
88
+ const target = event.target;
89
+ target?.focus();
90
+ this.stateChanges.next();
91
+ }
92
+ ngOnDestroy() {
93
+ this.stateChanges.complete();
94
+ }
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: MatFormControlBase, deps: null, target: i0.ɵɵFactoryTarget.Directive });
96
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: MatFormControlBase, isStandalone: true, inputs: { detachLabel: { classPropertyName: "detachLabel", publicName: "detachLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, hintClassList: { classPropertyName: "hintClassList", publicName: "hintClassList", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "input", first: true, predicate: ["nmf-input"], descendants: true }], usesInheritance: true, ngImport: i0 });
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: MatFormControlBase, decorators: [{
99
+ type: Directive
100
+ }], propDecorators: { input: [{
101
+ type: ViewChild,
102
+ args: ['nmf-input']
103
+ }] } });
104
+
105
+ class MatInputCurrencyComponent extends MatFormControlBase {
106
+ behavior = new InputCurrencyBehavior();
107
+ writeValue(value) {
108
+ super.writeValue(this.behavior.formatCurrency(value ?? ''));
109
+ }
110
+ handleKeyDown(event) {
111
+ this.behavior.handleKeyDown(event);
112
+ }
113
+ onInput(event) {
114
+ this.behavior.onInput(this, event);
115
+ }
116
+ textColor(value) {
117
+ if (this.disabled) {
118
+ return 'default';
119
+ }
120
+ if (!value) {
121
+ return '--mat-form-field-outlined-input-text-text';
122
+ }
123
+ return parseCurrency(value) >= 0
124
+ ? '--mat-form-field-outlined-input-text-text'
125
+ : 'red';
126
+ }
127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: MatInputCurrencyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: MatInputCurrencyComponent, isStandalone: true, selector: "nmf-mat-input-currency", usesInheritance: true, ngImport: i0, template: `
129
+ @if (label() && detachLabel()) {
130
+ <label class="font-medium text-base">{{ label() }}</label>
131
+ }
132
+ <mat-form-field
133
+ appearance="outline"
134
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
135
+ >
136
+ @if (label() && !detachLabel()) {
137
+ <mat-label>{{ label() }}</mat-label>
138
+ }
139
+
140
+ <span
141
+ [style.color]="
142
+ control().disabled || readonly
143
+ ? 'var(--mat-form-field-outlined-disabled-input-text-text)'
144
+ : 'inherit'
145
+ "
146
+ matTextPrefix
147
+ >
148
+ $
149
+ </span>
150
+
151
+ <input
152
+ matInput
153
+ type="text"
154
+ autocomplete="off"
155
+ [id]="id"
156
+ [name]="name"
157
+ [value]="value"
158
+ [disabled]="disabled"
159
+ [readonly]="readonly"
160
+ [ngClass]="classList().concat(readonly ? ['opacity-60'] : [])"
161
+ [placeholder]="placeholder || '0.00'"
162
+ (keydown)="handleKeyDown($event)"
163
+ (input)="onInput($event)"
164
+ (blur)="onTouched()"
165
+ style="padding-top: 5px; color: {{ textColor(value) }} !important"
166
+ />
167
+
168
+ <span matTextSuffix><ng-content></ng-content></span>
169
+
170
+ @if (loading()) {
171
+ <div class="absolute top-5 right-5 z-10">
172
+ <mat-spinner diameter="20" strokeWidth="3"></mat-spinner>
173
+ </div>
174
+ }
175
+
176
+ @if (hint()) {
177
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
178
+ }
179
+
180
+ @if (control().invalid && control().touched) {
181
+ <mat-error>
182
+ {{ getErrorMessage() }}
183
+ </mat-error>
184
+ }
185
+ </mat-form-field>
186
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
187
+ }
188
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: MatInputCurrencyComponent, decorators: [{
189
+ type: Component,
190
+ args: [{
191
+ selector: 'nmf-mat-input-currency',
192
+ imports: [
193
+ CommonModule,
194
+ MatFormFieldModule,
195
+ ReactiveFormsModule,
196
+ MatProgressSpinnerModule,
197
+ ],
198
+ changeDetection: ChangeDetectionStrategy.OnPush,
199
+ template: `
200
+ @if (label() && detachLabel()) {
201
+ <label class="font-medium text-base">{{ label() }}</label>
202
+ }
203
+ <mat-form-field
204
+ appearance="outline"
205
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
206
+ >
207
+ @if (label() && !detachLabel()) {
208
+ <mat-label>{{ label() }}</mat-label>
209
+ }
210
+
211
+ <span
212
+ [style.color]="
213
+ control().disabled || readonly
214
+ ? 'var(--mat-form-field-outlined-disabled-input-text-text)'
215
+ : 'inherit'
216
+ "
217
+ matTextPrefix
218
+ >
219
+ $
220
+ </span>
221
+
222
+ <input
223
+ matInput
224
+ type="text"
225
+ autocomplete="off"
226
+ [id]="id"
227
+ [name]="name"
228
+ [value]="value"
229
+ [disabled]="disabled"
230
+ [readonly]="readonly"
231
+ [ngClass]="classList().concat(readonly ? ['opacity-60'] : [])"
232
+ [placeholder]="placeholder || '0.00'"
233
+ (keydown)="handleKeyDown($event)"
234
+ (input)="onInput($event)"
235
+ (blur)="onTouched()"
236
+ style="padding-top: 5px; color: {{ textColor(value) }} !important"
237
+ />
238
+
239
+ <span matTextSuffix><ng-content></ng-content></span>
240
+
241
+ @if (loading()) {
242
+ <div class="absolute top-5 right-5 z-10">
243
+ <mat-spinner diameter="20" strokeWidth="3"></mat-spinner>
244
+ </div>
245
+ }
246
+
247
+ @if (hint()) {
248
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
249
+ }
250
+
251
+ @if (control().invalid && control().touched) {
252
+ <mat-error>
253
+ {{ getErrorMessage() }}
254
+ </mat-error>
255
+ }
256
+ </mat-form-field>
257
+ `,
258
+ }]
259
+ }] });
260
+
261
+ class MatInputDatepickerComponent extends MatFormControlBase {
262
+ minDate = input(null);
263
+ maxDate = input(null);
264
+ picker;
265
+ dateAdapter = inject((DateAdapter));
266
+ setToday(dp) {
267
+ const today = this.dateAdapter.today();
268
+ dp.select(today);
269
+ }
270
+ ngOnInit() {
271
+ super.ngOnInit();
272
+ this.picker.minDate = this.minDate();
273
+ this.picker.maxDate = this.maxDate();
274
+ }
275
+ onInput(event) {
276
+ const value = event.value;
277
+ if (!value) {
278
+ this.value = null;
279
+ this.onChange(this.value);
280
+ this.stateChanges.next();
281
+ return;
282
+ }
283
+ this.value = value;
284
+ this.onChange(this.value);
285
+ this.stateChanges.next();
286
+ }
287
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: MatInputDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
288
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: MatInputDatepickerComponent, isStandalone: true, selector: "nmf-mat-input-datepicker", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
289
+ @if (label() && detachLabel()) {
290
+ <label class="font-medium text-base">{{ label() }}</label>
291
+ }
292
+ <mat-form-field
293
+ appearance="outline"
294
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
295
+ >
296
+ @if (label() && !detachLabel()) {
297
+ <mat-label>{{ label() }}</mat-label>
298
+ }
299
+
300
+ <input
301
+ matInput
302
+ autocomplete="off"
303
+ [id]="id"
304
+ [name]="name"
305
+ [value]="value"
306
+ [type]="'text'"
307
+ [readonly]="readonly"
308
+ [placeholder]="placeholder || 'Select a date'"
309
+ [disabled]="disabled"
310
+ [matDatepicker]="picker"
311
+ (dateInput)="onInput($event)"
312
+ (dateChange)="onInput($event)"
313
+ (blur)="onTouched()"
314
+ style="padding-top: 5px"
315
+ />
316
+
317
+ <mat-datepicker-toggle
318
+ [hidden]="loading()"
319
+ matSuffix
320
+ [for]="picker"
321
+ ></mat-datepicker-toggle>
322
+
323
+ <mat-datepicker [hidden]="loading()" #picker>
324
+ <!-- <mat-datepicker-actions>
325
+ <button matButton (click)="setToday(picker)">Hoy</button>
326
+ <button matButton matDatepickerCancel>Cancelar</button>
327
+ <button matButton="elevated" matDatepickerApply>Aplicar</button>
328
+ </mat-datepicker-actions> -->
329
+ </mat-datepicker>
330
+
331
+ @if (loading()) {
332
+ <div class="absolute top-2 right-2">
333
+ <mat-spinner diameter="24" strokeWidth="3"></mat-spinner>
334
+ </div>
335
+ }
336
+
337
+ @if (hint()) {
338
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
339
+ }
340
+
341
+ @if (control().invalid && control().touched) {
342
+ <mat-error>
343
+ {{ getErrorMessage() }}
344
+ </mat-error>
345
+ }
346
+ </mat-form-field>
347
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i3$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i3$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
348
+ }
349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: MatInputDatepickerComponent, decorators: [{
350
+ type: Component,
351
+ args: [{
352
+ selector: 'nmf-mat-input-datepicker',
353
+ imports: [
354
+ CommonModule,
355
+ MatFormFieldModule,
356
+ ReactiveFormsModule,
357
+ MatDatepickerModule,
358
+ MatNativeDateModule,
359
+ MatProgressSpinnerModule,
360
+ ],
361
+ changeDetection: ChangeDetectionStrategy.OnPush,
362
+ template: `
363
+ @if (label() && detachLabel()) {
364
+ <label class="font-medium text-base">{{ label() }}</label>
365
+ }
366
+ <mat-form-field
367
+ appearance="outline"
368
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
369
+ >
370
+ @if (label() && !detachLabel()) {
371
+ <mat-label>{{ label() }}</mat-label>
372
+ }
373
+
374
+ <input
375
+ matInput
376
+ autocomplete="off"
377
+ [id]="id"
378
+ [name]="name"
379
+ [value]="value"
380
+ [type]="'text'"
381
+ [readonly]="readonly"
382
+ [placeholder]="placeholder || 'Select a date'"
383
+ [disabled]="disabled"
384
+ [matDatepicker]="picker"
385
+ (dateInput)="onInput($event)"
386
+ (dateChange)="onInput($event)"
387
+ (blur)="onTouched()"
388
+ style="padding-top: 5px"
389
+ />
390
+
391
+ <mat-datepicker-toggle
392
+ [hidden]="loading()"
393
+ matSuffix
394
+ [for]="picker"
395
+ ></mat-datepicker-toggle>
396
+
397
+ <mat-datepicker [hidden]="loading()" #picker>
398
+ <!-- <mat-datepicker-actions>
399
+ <button matButton (click)="setToday(picker)">Hoy</button>
400
+ <button matButton matDatepickerCancel>Cancelar</button>
401
+ <button matButton="elevated" matDatepickerApply>Aplicar</button>
402
+ </mat-datepicker-actions> -->
403
+ </mat-datepicker>
404
+
405
+ @if (loading()) {
406
+ <div class="absolute top-2 right-2">
407
+ <mat-spinner diameter="24" strokeWidth="3"></mat-spinner>
408
+ </div>
409
+ }
410
+
411
+ @if (hint()) {
412
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
413
+ }
414
+
415
+ @if (control().invalid && control().touched) {
416
+ <mat-error>
417
+ {{ getErrorMessage() }}
418
+ </mat-error>
419
+ }
420
+ </mat-form-field>
421
+ `,
422
+ }]
423
+ }] });
424
+
425
+ class InputSelectComponent extends MatFormControlBase {
426
+ options = input([]);
427
+ emptyOptionLabel = input('forms.emptyOption');
428
+ showClearOption = input(false);
429
+ panelWidth = input('auto');
430
+ behavior = new InputSelectBehavior();
431
+ onSelectionClosed() {
432
+ this.behavior.onSelectionClosed(this);
433
+ }
434
+ ngOnInit() {
435
+ super.ngOnInit();
436
+ this.behavior.setInitialValue(this.value);
437
+ }
438
+ onSelectionChange(event) {
439
+ this.behavior.onSelectionChange(this, event);
440
+ }
441
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
442
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: InputSelectComponent, isStandalone: true, selector: "nmf-mat-input-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionLabel: { classPropertyName: "emptyOptionLabel", publicName: "emptyOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, showClearOption: { classPropertyName: "showClearOption", publicName: "showClearOption", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
443
+ @if (label() && detachLabel()) {
444
+ <label class="font-medium text-base">{{ label() }}</label>
445
+ }
446
+ <mat-form-field
447
+ appearance="outline"
448
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
449
+ >
450
+ @if (label() && !detachLabel()) {
451
+ <mat-label>{{ label() }}</mat-label>
452
+ }
453
+
454
+ <mat-select
455
+ [value]="value"
456
+ [disabled]="disabled"
457
+ [panelWidth]="panelWidth()"
458
+ [ngClass]="disabled ? 'hide-arrow' : ''"
459
+ (blur)="onTouched()"
460
+ (selectionChange)="onSelectionChange($event)"
461
+ (closed)="onSelectionClosed()"
462
+ >
463
+ <mat-option [value]="value === -1 ? -1 : ''" selected disabled>
464
+ {{ emptyOptionLabel() }}
465
+ </mat-option>
466
+
467
+ <!-- All Options -->
468
+ @for (option of options(); track option.label) {
469
+ <mat-option [value]="option.key" [disabled]="option.disabled">
470
+ {{ option.label }}
471
+ </mat-option>
472
+ }
473
+
474
+ <!-- Clear Selection Option -->
475
+ @if (showClearOption()) {
476
+ <mat-option value="NONE">{{ 'forms.clearSelection' }}</mat-option>
477
+ }
478
+ </mat-select>
479
+
480
+ @if (loading()) {
481
+ <div class="absolute top-2 right-2">
482
+ <mat-spinner diameter="24" strokeWidth="3"></mat-spinner>
483
+ </div>
484
+ }
485
+
486
+ @if (hint()) {
487
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
488
+ }
489
+
490
+ @if (control().invalid && control().touched) {
491
+ <mat-error>{{ getErrorMessage() }}</mat-error>
492
+ }
493
+ </mat-form-field>
494
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
495
+ }
496
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputSelectComponent, decorators: [{
497
+ type: Component,
498
+ args: [{
499
+ selector: 'nmf-mat-input-select',
500
+ imports: [
501
+ CommonModule,
502
+ MatFormFieldModule,
503
+ MatProgressSpinnerModule,
504
+ ReactiveFormsModule,
505
+ MatSelectModule,
506
+ ],
507
+ changeDetection: ChangeDetectionStrategy.OnPush,
508
+ template: `
509
+ @if (label() && detachLabel()) {
510
+ <label class="font-medium text-base">{{ label() }}</label>
511
+ }
512
+ <mat-form-field
513
+ appearance="outline"
514
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
515
+ >
516
+ @if (label() && !detachLabel()) {
517
+ <mat-label>{{ label() }}</mat-label>
518
+ }
519
+
520
+ <mat-select
521
+ [value]="value"
522
+ [disabled]="disabled"
523
+ [panelWidth]="panelWidth()"
524
+ [ngClass]="disabled ? 'hide-arrow' : ''"
525
+ (blur)="onTouched()"
526
+ (selectionChange)="onSelectionChange($event)"
527
+ (closed)="onSelectionClosed()"
528
+ >
529
+ <mat-option [value]="value === -1 ? -1 : ''" selected disabled>
530
+ {{ emptyOptionLabel() }}
531
+ </mat-option>
532
+
533
+ <!-- All Options -->
534
+ @for (option of options(); track option.label) {
535
+ <mat-option [value]="option.key" [disabled]="option.disabled">
536
+ {{ option.label }}
537
+ </mat-option>
538
+ }
539
+
540
+ <!-- Clear Selection Option -->
541
+ @if (showClearOption()) {
542
+ <mat-option value="NONE">{{ 'forms.clearSelection' }}</mat-option>
543
+ }
544
+ </mat-select>
545
+
546
+ @if (loading()) {
547
+ <div class="absolute top-2 right-2">
548
+ <mat-spinner diameter="24" strokeWidth="3"></mat-spinner>
549
+ </div>
550
+ }
551
+
552
+ @if (hint()) {
553
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
554
+ }
555
+
556
+ @if (control().invalid && control().touched) {
557
+ <mat-error>{{ getErrorMessage() }}</mat-error>
558
+ }
559
+ </mat-form-field>
560
+ `,
561
+ }]
562
+ }] });
563
+
564
+ class InputComponent extends MatFormControlBase {
565
+ type = input('text');
566
+ behavior = new InputTextBehavior();
567
+ toggleShowPassword(event) {
568
+ this.behavior.toggleShowPassword(event);
569
+ }
570
+ onInput(event) {
571
+ this.behavior.onInput(this, event);
572
+ }
573
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
574
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: InputComponent, isStandalone: true, selector: "nmf-mat-input-text", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
575
+ {
576
+ provide: MatFormFieldControl,
577
+ useExisting: forwardRef(() => InputComponent),
578
+ },
579
+ ], usesInheritance: true, ngImport: i0, template: `
580
+ <div class="relative">
581
+ @if (label() && detachLabel()) {
582
+ <label class="font-medium text-base">{{ label() }}</label>
583
+ }
584
+ <mat-form-field
585
+ appearance="outline"
586
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
587
+ >
588
+ @if (label() && !detachLabel()) {
589
+ <mat-label>{{ label() }}</mat-label>
590
+ }
591
+
592
+ <input
593
+ matInput
594
+ autocomplete="off"
595
+ [ngClass]="classList"
596
+ [id]="id"
597
+ [name]="name === 'identificationNumber' ? 'idummyi' : name"
598
+ [type]="behavior.hidePassword() ? type() : 'text'"
599
+ [readonly]="readonly"
600
+ [placeholder]="placeholder"
601
+ (input)="onInput($event)"
602
+ (blur)="onTouched()"
603
+ [formControlName]="controlName()"
604
+ [required]="isRequired()"
605
+ style="padding-top: 5px"
606
+ />
607
+
608
+ @if (loading()) {
609
+ <div class="absolute top-5 right-5 z-10">
610
+ <mat-spinner diameter="20" strokeWidth="3"></mat-spinner>
611
+ </div>
612
+ }
613
+
614
+ @if (hint()) {
615
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
616
+ }
617
+
618
+ @if (type() === 'password') {
619
+ <button matIconSuffix (click)="toggleShowPassword($event)">
620
+ <mat-icon>{{
621
+ behavior.hidePassword() ? 'visibility_off' : 'visibility'
622
+ }}</mat-icon>
623
+ </button>
624
+ }
625
+
626
+ <ng-content></ng-content>
627
+
628
+ @if (control().invalid && control().touched) {
629
+ <mat-error>{{ getErrorMessage() }}</mat-error>
630
+ }
631
+ </mat-form-field>
632
+ </div>
633
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4$1.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: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
634
+ }
635
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputComponent, decorators: [{
636
+ type: Component,
637
+ args: [{
638
+ selector: 'nmf-mat-input-text',
639
+ imports: [
640
+ CommonModule,
641
+ MatFormFieldModule,
642
+ MatInputModule,
643
+ ReactiveFormsModule,
644
+ MatIconModule,
645
+ MatProgressSpinnerModule,
646
+ ],
647
+ providers: [
648
+ {
649
+ provide: MatFormFieldControl,
650
+ useExisting: forwardRef(() => InputComponent),
651
+ },
652
+ ],
653
+ changeDetection: ChangeDetectionStrategy.OnPush,
654
+ template: `
655
+ <div class="relative">
656
+ @if (label() && detachLabel()) {
657
+ <label class="font-medium text-base">{{ label() }}</label>
658
+ }
659
+ <mat-form-field
660
+ appearance="outline"
661
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
662
+ >
663
+ @if (label() && !detachLabel()) {
664
+ <mat-label>{{ label() }}</mat-label>
665
+ }
666
+
667
+ <input
668
+ matInput
669
+ autocomplete="off"
670
+ [ngClass]="classList"
671
+ [id]="id"
672
+ [name]="name === 'identificationNumber' ? 'idummyi' : name"
673
+ [type]="behavior.hidePassword() ? type() : 'text'"
674
+ [readonly]="readonly"
675
+ [placeholder]="placeholder"
676
+ (input)="onInput($event)"
677
+ (blur)="onTouched()"
678
+ [formControlName]="controlName()"
679
+ [required]="isRequired()"
680
+ style="padding-top: 5px"
681
+ />
682
+
683
+ @if (loading()) {
684
+ <div class="absolute top-5 right-5 z-10">
685
+ <mat-spinner diameter="20" strokeWidth="3"></mat-spinner>
686
+ </div>
687
+ }
688
+
689
+ @if (hint()) {
690
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
691
+ }
692
+
693
+ @if (type() === 'password') {
694
+ <button matIconSuffix (click)="toggleShowPassword($event)">
695
+ <mat-icon>{{
696
+ behavior.hidePassword() ? 'visibility_off' : 'visibility'
697
+ }}</mat-icon>
698
+ </button>
699
+ }
700
+
701
+ <ng-content></ng-content>
702
+
703
+ @if (control().invalid && control().touched) {
704
+ <mat-error>{{ getErrorMessage() }}</mat-error>
705
+ }
706
+ </mat-form-field>
707
+ </div>
708
+ `,
709
+ }]
710
+ }] });
711
+
712
+ class InputTextareaComponent extends MatFormControlBase {
713
+ rows = input(5);
714
+ cols = input(5);
715
+ behavior = new InputTextareaBehavior();
716
+ onEnter() {
717
+ this.behavior.onEnter(this);
718
+ }
719
+ onInput(event) {
720
+ this.behavior.onInput(this, event);
721
+ }
722
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
723
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: InputTextareaComponent, isStandalone: true, selector: "nmf-mat-input-textarea", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
724
+ @if (label() && detachLabel()) {
725
+ <label class="font-medium text-base">{{ label() }}</label>
726
+ }
727
+ <mat-form-field
728
+ appearance="outline"
729
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
730
+ >
731
+ @if (label() && !detachLabel()) {
732
+ <mat-label>{{ label() }}</mat-label>
733
+ }
734
+
735
+ <textarea
736
+ matInput
737
+ [id]="id"
738
+ [rows]="rows()"
739
+ [cols]="cols()"
740
+ [value]="value"
741
+ [readonly]="readonly"
742
+ [disabled]="disabled"
743
+ [placeholder]="placeholder"
744
+ style="padding-top: 5px"
745
+ (blur)="onTouched()"
746
+ (input)="onInput($event)"
747
+ (keydown.enter)="onEnter()"
748
+ ></textarea>
749
+
750
+ @if (loading()) {
751
+ <div class="absolute top-5 right-5 z-10">
752
+ <mat-spinner diameter="20" strokeWidth="3"></mat-spinner>
753
+ </div>
754
+ }
755
+
756
+ @if (hint()) {
757
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
758
+ }
759
+
760
+ @if (control().invalid && control().touched) {
761
+ <mat-error>
762
+ {{ getErrorMessage() }}
763
+ </mat-error>
764
+ }
765
+ </mat-form-field>
766
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
767
+ }
768
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTextareaComponent, decorators: [{
769
+ type: Component,
770
+ args: [{
771
+ selector: 'nmf-mat-input-textarea',
772
+ imports: [
773
+ CommonModule,
774
+ MatFormFieldModule,
775
+ ReactiveFormsModule,
776
+ MatProgressSpinnerModule,
777
+ ],
778
+ changeDetection: ChangeDetectionStrategy.OnPush,
779
+ template: `
780
+ @if (label() && detachLabel()) {
781
+ <label class="font-medium text-base">{{ label() }}</label>
782
+ }
783
+ <mat-form-field
784
+ appearance="outline"
785
+ [floatLabel]="shouldLabelFloat ? 'always' : 'auto'"
786
+ >
787
+ @if (label() && !detachLabel()) {
788
+ <mat-label>{{ label() }}</mat-label>
789
+ }
790
+
791
+ <textarea
792
+ matInput
793
+ [id]="id"
794
+ [rows]="rows()"
795
+ [cols]="cols()"
796
+ [value]="value"
797
+ [readonly]="readonly"
798
+ [disabled]="disabled"
799
+ [placeholder]="placeholder"
800
+ style="padding-top: 5px"
801
+ (blur)="onTouched()"
802
+ (input)="onInput($event)"
803
+ (keydown.enter)="onEnter()"
804
+ ></textarea>
805
+
806
+ @if (loading()) {
807
+ <div class="absolute top-5 right-5 z-10">
808
+ <mat-spinner diameter="20" strokeWidth="3"></mat-spinner>
809
+ </div>
810
+ }
811
+
812
+ @if (hint()) {
813
+ <mat-hint [ngClass]="hintClassList()">{{ hint() }}</mat-hint>
814
+ }
815
+
816
+ @if (control().invalid && control().touched) {
817
+ <mat-error>
818
+ {{ getErrorMessage() }}
819
+ </mat-error>
820
+ }
821
+ </mat-form-field>
822
+ `,
823
+ }]
824
+ }] });
825
+
826
+ /*
827
+ * Public API Surface of material
828
+ */
829
+
830
+ /**
831
+ * Generated bundle index. Do not edit.
832
+ */
833
+
834
+ export { InputComponent, InputSelectComponent, InputTextareaComponent, MatFormControlBase, MatInputCurrencyComponent, MatInputDatepickerComponent };
835
+ //# sourceMappingURL=ng-modular-forms-material.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-modular-forms-material.mjs","sources":["../../../projects/material/src/lib/mat-form-control-base.ts","../../../projects/material/src/lib/mat-input-currency.component.ts","../../../projects/material/src/lib/mat-input-datepicker.component.ts","../../../projects/material/src/lib/mat-input-select.component.ts","../../../projects/material/src/lib/mat-input-text.component.ts","../../../projects/material/src/lib/mat-input-textarea.component.ts","../../../projects/material/src/public-api.ts","../../../projects/material/src/ng-modular-forms-material.ts"],"sourcesContent":["import { Directive, ElementRef, input, signal, ViewChild } from '@angular/core';\nimport { MatFormFieldControl } from '@angular/material/form-field';\nimport { FormControlBase } from '@ng-modular-forms/core';\nimport { Subject } from 'rxjs';\n\n/**\n * Base implementation for custom form controls that integrate with:\n * - Angular Reactive Forms (ControlValueAccessor)\n * - Angular Material form-field (MatFormFieldControl)\n */\n\n@Directive()\nexport abstract class MatFormControlBase<T>\n extends FormControlBase<T>\n implements MatFormFieldControl<T>\n{\n detachLabel = input<boolean>(false);\n hint = input<string>();\n hintClassList = input<string>('');\n appearance = input<'outline' | 'fill'>();\n\n protected readonly _formDisabled = signal(false);\n\n /**\n * Notifies Angular Material form-field of state changes\n * (label float, error state, UI refresh)\n */\n stateChanges = new Subject<void>();\n\n override set value(val: T | null) {\n super.value = val;\n this.stateChanges.next();\n }\n\n focused = false;\n\n /**\n * Assumes derived component exposes an element with #input reference.\n */\n @ViewChild('nmf-input') input!: ElementRef<HTMLInputElement>;\n\n focus(): void {\n const nativeElement = this.input?.nativeElement;\n\n if (!nativeElement) {\n console.warn(\n 'Tried to focus an input from FormControlBase that does not exist',\n );\n return;\n }\n\n this.focused = true;\n nativeElement.focus();\n }\n\n override get disabled(): boolean {\n return this._disabled() || this._formDisabled();\n }\n\n get errorState(): boolean {\n const control = this.ngControl?.control;\n return !!control && control.invalid && control.touched;\n }\n\n get empty(): boolean {\n return this.value === null || this.value === '' || this.value === undefined;\n }\n\n get shouldLabelFloat(): boolean {\n return this.focused || !this.empty;\n }\n\n controlType: string | undefined = 'custom-form-control';\n autofilled: boolean | undefined = false;\n\n userAriaDescribedBy?: string | undefined;\n disableAutomaticLabeling?: boolean | undefined;\n\n override writeValue(value: T): void {\n super.writeValue(value);\n this.stateChanges.next();\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._formDisabled.set(isDisabled);\n this.stateChanges.next();\n this.cdr.markForCheck();\n }\n\n setDescribedByIds(ids: string[]): void {\n this.userAriaDescribedBy = ids.join(' ');\n }\n\n onContainerClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n target?.focus();\n this.stateChanges.next();\n }\n\n ngOnDestroy(): void {\n this.stateChanges.complete();\n }\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { CommonModule } from '@angular/common';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatFormControlBase } from './mat-form-control-base';\nimport { parseCurrency } from '@ng-modular-forms/core';\nimport { InputCurrencyBehavior } from '@ng-modular-forms/behavior';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\n\n@Component({\n selector: 'nmf-mat-input-currency',\n imports: [\n CommonModule,\n MatFormFieldModule,\n ReactiveFormsModule,\n MatProgressSpinnerModule,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (label() && detachLabel()) {\n <label class=\"font-medium text-base\">{{ label() }}</label>\n }\n <mat-form-field\n appearance=\"outline\"\n [floatLabel]=\"shouldLabelFloat ? 'always' : 'auto'\"\n >\n @if (label() && !detachLabel()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <span\n [style.color]=\"\n control().disabled || readonly\n ? 'var(--mat-form-field-outlined-disabled-input-text-text)'\n : 'inherit'\n \"\n matTextPrefix\n >\n $\n </span>\n\n <input\n matInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id\"\n [name]=\"name\"\n [value]=\"value\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [ngClass]=\"classList().concat(readonly ? ['opacity-60'] : [])\"\n [placeholder]=\"placeholder || '0.00'\"\n (keydown)=\"handleKeyDown($event)\"\n (input)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n style=\"padding-top: 5px; color: {{ textColor(value) }} !important\"\n />\n\n <span matTextSuffix><ng-content></ng-content></span>\n\n @if (loading()) {\n <div class=\"absolute top-5 right-5 z-10\">\n <mat-spinner diameter=\"20\" strokeWidth=\"3\"></mat-spinner>\n </div>\n }\n\n @if (hint()) {\n <mat-hint [ngClass]=\"hintClassList()\">{{ hint() }}</mat-hint>\n }\n\n @if (control().invalid && control().touched) {\n <mat-error>\n {{ getErrorMessage() }}\n </mat-error>\n }\n </mat-form-field>\n `,\n})\nexport class MatInputCurrencyComponent extends MatFormControlBase<\n string | null\n> {\n behavior = new InputCurrencyBehavior();\n\n override writeValue(value: string | null): void {\n super.writeValue(this.behavior.formatCurrency(value ?? ''));\n }\n\n handleKeyDown(event: KeyboardEvent) {\n this.behavior.handleKeyDown(event);\n }\n\n onInput(event: Event) {\n this.behavior.onInput(this, event);\n }\n\n textColor(value: string | number | null): string {\n if (this.disabled) {\n return 'default';\n }\n if (!value) {\n return '--mat-form-field-outlined-input-text-text';\n }\n return parseCurrency(value) >= 0\n ? '--mat-form-field-outlined-input-text-text'\n : 'red';\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n inject,\n input,\n} from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { DateAdapter, MatNativeDateModule } from '@angular/material/core';\nimport {\n MatCalendar,\n MatDatepicker,\n MatDatepickerInputEvent,\n MatDatepickerModule,\n} from '@angular/material/datepicker';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatFormControlBase } from './mat-form-control-base';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'nmf-mat-input-datepicker',\n imports: [\n CommonModule,\n MatFormFieldModule,\n ReactiveFormsModule,\n MatDatepickerModule,\n MatNativeDateModule,\n MatProgressSpinnerModule,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (label() && detachLabel()) {\n <label class=\"font-medium text-base\">{{ label() }}</label>\n }\n <mat-form-field\n appearance=\"outline\"\n [floatLabel]=\"shouldLabelFloat ? 'always' : 'auto'\"\n >\n @if (label() && !detachLabel()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n matInput\n autocomplete=\"off\"\n [id]=\"id\"\n [name]=\"name\"\n [value]=\"value\"\n [type]=\"'text'\"\n [readonly]=\"readonly\"\n [placeholder]=\"placeholder || 'Select a date'\"\n [disabled]=\"disabled\"\n [matDatepicker]=\"picker\"\n (dateInput)=\"onInput($event)\"\n (dateChange)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n style=\"padding-top: 5px\"\n />\n\n <mat-datepicker-toggle\n [hidden]=\"loading()\"\n matSuffix\n [for]=\"picker\"\n ></mat-datepicker-toggle>\n\n <mat-datepicker [hidden]=\"loading()\" #picker>\n <!-- <mat-datepicker-actions>\n <button matButton (click)=\"setToday(picker)\">Hoy</button>\n <button matButton matDatepickerCancel>Cancelar</button>\n <button matButton=\"elevated\" matDatepickerApply>Aplicar</button>\n </mat-datepicker-actions> -->\n </mat-datepicker>\n\n @if (loading()) {\n <div class=\"absolute top-2 right-2\">\n <mat-spinner diameter=\"24\" strokeWidth=\"3\"></mat-spinner>\n </div>\n }\n\n @if (hint()) {\n <mat-hint [ngClass]=\"hintClassList()\">{{ hint() }}</mat-hint>\n }\n\n @if (control().invalid && control().touched) {\n <mat-error>\n {{ getErrorMessage() }}\n </mat-error>\n }\n </mat-form-field>\n `,\n})\nexport class MatInputDatepickerComponent extends MatFormControlBase<Date | null> {\n minDate = input<Date | null>(null);\n maxDate = input<Date | null>(null);\n\n picker!: MatCalendar<Date>;\n\n private readonly dateAdapter = inject(DateAdapter<Date>);\n\n setToday(dp: MatDatepicker<Date>) {\n const today = this.dateAdapter.today();\n dp.select(today);\n }\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.picker.minDate = this.minDate();\n this.picker.maxDate = this.maxDate();\n }\n\n onInput(event: Partial<MatDatepickerInputEvent<Date>>): void {\n const value = event.value;\n\n if (!value) {\n this.value = null;\n this.onChange(this.value);\n this.stateChanges.next();\n return;\n }\n\n this.value = value;\n this.onChange(this.value);\n this.stateChanges.next();\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatSelectChange, MatSelectModule } from '@angular/material/select';\nimport { CommonModule } from '@angular/common';\nimport { MatFormControlBase } from './mat-form-control-base';\nimport { InputSelectBehavior } from '@ng-modular-forms/behavior';\n\nexport interface SelectOption {\n key: string | number;\n label: string | number;\n disabled?: boolean;\n}\n\n@Component({\n selector: 'nmf-mat-input-select',\n imports: [\n CommonModule,\n MatFormFieldModule,\n MatProgressSpinnerModule,\n ReactiveFormsModule,\n MatSelectModule,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (label() && detachLabel()) {\n <label class=\"font-medium text-base\">{{ label() }}</label>\n }\n <mat-form-field\n appearance=\"outline\"\n [floatLabel]=\"shouldLabelFloat ? 'always' : 'auto'\"\n >\n @if (label() && !detachLabel()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <mat-select\n [value]=\"value\"\n [disabled]=\"disabled\"\n [panelWidth]=\"panelWidth()\"\n [ngClass]=\"disabled ? 'hide-arrow' : ''\"\n (blur)=\"onTouched()\"\n (selectionChange)=\"onSelectionChange($event)\"\n (closed)=\"onSelectionClosed()\"\n >\n <mat-option [value]=\"value === -1 ? -1 : ''\" selected disabled>\n {{ emptyOptionLabel() }}\n </mat-option>\n\n <!-- All Options -->\n @for (option of options(); track option.label) {\n <mat-option [value]=\"option.key\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </mat-option>\n }\n\n <!-- Clear Selection Option -->\n @if (showClearOption()) {\n <mat-option value=\"NONE\">{{ 'forms.clearSelection' }}</mat-option>\n }\n </mat-select>\n\n @if (loading()) {\n <div class=\"absolute top-2 right-2\">\n <mat-spinner diameter=\"24\" strokeWidth=\"3\"></mat-spinner>\n </div>\n }\n\n @if (hint()) {\n <mat-hint [ngClass]=\"hintClassList()\">{{ hint() }}</mat-hint>\n }\n\n @if (control().invalid && control().touched) {\n <mat-error>{{ getErrorMessage() }}</mat-error>\n }\n </mat-form-field>\n `,\n})\nexport class InputSelectComponent extends MatFormControlBase<\n string | number | null\n> {\n options = input<SelectOption[]>([]);\n emptyOptionLabel = input<string>('forms.emptyOption');\n showClearOption = input<boolean>(false);\n panelWidth = input<string | number | null>('auto');\n\n behavior = new InputSelectBehavior();\n\n onSelectionClosed(): void {\n this.behavior.onSelectionClosed(this);\n }\n\n override ngOnInit() {\n super.ngOnInit();\n this.behavior.setInitialValue(this.value);\n }\n\n onSelectionChange(event: MatSelectChange): void {\n this.behavior.onSelectionChange(this, event);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n forwardRef,\n input,\n} from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { CommonModule } from '@angular/common';\nimport {\n MatFormFieldControl,\n MatFormFieldModule,\n} from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatFormControlBase } from './mat-form-control-base';\nimport { InputTextBehavior } from '@ng-modular-forms/behavior';\n\n@Component({\n selector: 'nmf-mat-input-text',\n imports: [\n CommonModule,\n MatFormFieldModule,\n MatInputModule,\n ReactiveFormsModule,\n MatIconModule,\n MatProgressSpinnerModule,\n ],\n providers: [\n {\n provide: MatFormFieldControl,\n useExisting: forwardRef(() => InputComponent),\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"relative\">\n @if (label() && detachLabel()) {\n <label class=\"font-medium text-base\">{{ label() }}</label>\n }\n <mat-form-field\n appearance=\"outline\"\n [floatLabel]=\"shouldLabelFloat ? 'always' : 'auto'\"\n >\n @if (label() && !detachLabel()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n matInput\n autocomplete=\"off\"\n [ngClass]=\"classList\"\n [id]=\"id\"\n [name]=\"name === 'identificationNumber' ? 'idummyi' : name\"\n [type]=\"behavior.hidePassword() ? type() : 'text'\"\n [readonly]=\"readonly\"\n [placeholder]=\"placeholder\"\n (input)=\"onInput($event)\"\n (blur)=\"onTouched()\"\n [formControlName]=\"controlName()\"\n [required]=\"isRequired()\"\n style=\"padding-top: 5px\"\n />\n\n @if (loading()) {\n <div class=\"absolute top-5 right-5 z-10\">\n <mat-spinner diameter=\"20\" strokeWidth=\"3\"></mat-spinner>\n </div>\n }\n\n @if (hint()) {\n <mat-hint [ngClass]=\"hintClassList()\">{{ hint() }}</mat-hint>\n }\n\n @if (type() === 'password') {\n <button matIconSuffix (click)=\"toggleShowPassword($event)\">\n <mat-icon>{{\n behavior.hidePassword() ? 'visibility_off' : 'visibility'\n }}</mat-icon>\n </button>\n }\n\n <ng-content></ng-content>\n\n @if (control().invalid && control().touched) {\n <mat-error>{{ getErrorMessage() }}</mat-error>\n }\n </mat-form-field>\n </div>\n `,\n})\nexport class InputComponent extends MatFormControlBase<string | number | null> {\n type = input<'text' | 'email' | 'tel' | 'url' | 'password'>('text');\n\n behavior = new InputTextBehavior();\n\n toggleShowPassword(event: MouseEvent) {\n this.behavior.toggleShowPassword(event);\n }\n\n onInput(event: Event): void {\n this.behavior.onInput(this, event);\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatFormControlBase } from './mat-form-control-base';\nimport { InputTextareaBehavior } from '@ng-modular-forms/behavior';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\n\n@Component({\n selector: 'nmf-mat-input-textarea',\n imports: [\n CommonModule,\n MatFormFieldModule,\n ReactiveFormsModule,\n MatProgressSpinnerModule,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (label() && detachLabel()) {\n <label class=\"font-medium text-base\">{{ label() }}</label>\n }\n <mat-form-field\n appearance=\"outline\"\n [floatLabel]=\"shouldLabelFloat ? 'always' : 'auto'\"\n >\n @if (label() && !detachLabel()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <textarea\n matInput\n [id]=\"id\"\n [rows]=\"rows()\"\n [cols]=\"cols()\"\n [value]=\"value\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n style=\"padding-top: 5px\"\n (blur)=\"onTouched()\"\n (input)=\"onInput($event)\"\n (keydown.enter)=\"onEnter()\"\n ></textarea>\n\n @if (loading()) {\n <div class=\"absolute top-5 right-5 z-10\">\n <mat-spinner diameter=\"20\" strokeWidth=\"3\"></mat-spinner>\n </div>\n }\n\n @if (hint()) {\n <mat-hint [ngClass]=\"hintClassList()\">{{ hint() }}</mat-hint>\n }\n\n @if (control().invalid && control().touched) {\n <mat-error>\n {{ getErrorMessage() }}\n </mat-error>\n }\n </mat-form-field>\n `,\n})\nexport class InputTextareaComponent extends MatFormControlBase<string | null> {\n rows = input<number>(5);\n cols = input<number>(5);\n\n behavior = new InputTextareaBehavior();\n\n onEnter() {\n this.behavior.onEnter(this);\n }\n\n onInput(event: Event): void {\n this.behavior.onInput(this, event);\n }\n}\n","/*\n * Public API Surface of material\n */\n\nexport * from './lib/mat-form-control-base';\nexport * from './lib/mat-input-currency.component';\nexport * from './lib/mat-input-datepicker.component';\nexport * from './lib/mat-input-select.component';\nexport * from './lib/mat-input-text.component';\nexport * from './lib/mat-input-textarea.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i3","i4","i6"],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@ng-modular-forms/material" />
5
+ export * from './public-api';
@@ -0,0 +1,44 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import { MatFormFieldControl } from '@angular/material/form-field';
3
+ import { FormControlBase } from '@ng-modular-forms/core';
4
+ import { Subject } from 'rxjs';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * Base implementation for custom form controls that integrate with:
8
+ * - Angular Reactive Forms (ControlValueAccessor)
9
+ * - Angular Material form-field (MatFormFieldControl)
10
+ */
11
+ export declare abstract class MatFormControlBase<T> extends FormControlBase<T> implements MatFormFieldControl<T> {
12
+ detachLabel: import("@angular/core").InputSignal<boolean>;
13
+ hint: import("@angular/core").InputSignal<string | undefined>;
14
+ hintClassList: import("@angular/core").InputSignal<string>;
15
+ appearance: import("@angular/core").InputSignal<"outline" | "fill" | undefined>;
16
+ protected readonly _formDisabled: import("@angular/core").WritableSignal<boolean>;
17
+ /**
18
+ * Notifies Angular Material form-field of state changes
19
+ * (label float, error state, UI refresh)
20
+ */
21
+ stateChanges: Subject<void>;
22
+ set value(val: T | null);
23
+ focused: boolean;
24
+ /**
25
+ * Assumes derived component exposes an element with #input reference.
26
+ */
27
+ input: ElementRef<HTMLInputElement>;
28
+ focus(): void;
29
+ get disabled(): boolean;
30
+ get errorState(): boolean;
31
+ get empty(): boolean;
32
+ get shouldLabelFloat(): boolean;
33
+ controlType: string | undefined;
34
+ autofilled: boolean | undefined;
35
+ userAriaDescribedBy?: string | undefined;
36
+ disableAutomaticLabeling?: boolean | undefined;
37
+ writeValue(value: T): void;
38
+ setDisabledState(isDisabled: boolean): void;
39
+ setDescribedByIds(ids: string[]): void;
40
+ onContainerClick(event: MouseEvent): void;
41
+ ngOnDestroy(): void;
42
+ static ɵfac: i0.ɵɵFactoryDeclaration<MatFormControlBase<any>, never>;
43
+ static ɵdir: i0.ɵɵDirectiveDeclaration<MatFormControlBase<any>, never, never, { "detachLabel": { "alias": "detachLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "hintClassList": { "alias": "hintClassList"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
44
+ }
@@ -0,0 +1,12 @@
1
+ import { MatFormControlBase } from './mat-form-control-base';
2
+ import { InputCurrencyBehavior } from '@ng-modular-forms/behavior';
3
+ import * as i0 from "@angular/core";
4
+ export declare class MatInputCurrencyComponent extends MatFormControlBase<string | null> {
5
+ behavior: InputCurrencyBehavior;
6
+ writeValue(value: string | null): void;
7
+ handleKeyDown(event: KeyboardEvent): void;
8
+ onInput(event: Event): void;
9
+ textColor(value: string | number | null): string;
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<MatInputCurrencyComponent, never>;
11
+ static ɵcmp: i0.ɵɵComponentDeclaration<MatInputCurrencyComponent, "nmf-mat-input-currency", never, {}, {}, never, ["*"], true, never>;
12
+ }
@@ -0,0 +1,14 @@
1
+ import { MatCalendar, MatDatepicker, MatDatepickerInputEvent } from '@angular/material/datepicker';
2
+ import { MatFormControlBase } from './mat-form-control-base';
3
+ import * as i0 from "@angular/core";
4
+ export declare class MatInputDatepickerComponent extends MatFormControlBase<Date | null> {
5
+ minDate: import("@angular/core").InputSignal<Date | null>;
6
+ maxDate: import("@angular/core").InputSignal<Date | null>;
7
+ picker: MatCalendar<Date>;
8
+ private readonly dateAdapter;
9
+ setToday(dp: MatDatepicker<Date>): void;
10
+ ngOnInit(): void;
11
+ onInput(event: Partial<MatDatepickerInputEvent<Date>>): void;
12
+ static ɵfac: i0.ɵɵFactoryDeclaration<MatInputDatepickerComponent, never>;
13
+ static ɵcmp: i0.ɵɵComponentDeclaration<MatInputDatepickerComponent, "nmf-mat-input-datepicker", never, { "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
14
+ }
@@ -0,0 +1,21 @@
1
+ import { MatSelectChange } from '@angular/material/select';
2
+ import { MatFormControlBase } from './mat-form-control-base';
3
+ import { InputSelectBehavior } from '@ng-modular-forms/behavior';
4
+ import * as i0 from "@angular/core";
5
+ export interface SelectOption {
6
+ key: string | number;
7
+ label: string | number;
8
+ disabled?: boolean;
9
+ }
10
+ export declare class InputSelectComponent extends MatFormControlBase<string | number | null> {
11
+ options: import("@angular/core").InputSignal<SelectOption[]>;
12
+ emptyOptionLabel: import("@angular/core").InputSignal<string>;
13
+ showClearOption: import("@angular/core").InputSignal<boolean>;
14
+ panelWidth: import("@angular/core").InputSignal<string | number | null>;
15
+ behavior: InputSelectBehavior;
16
+ onSelectionClosed(): void;
17
+ ngOnInit(): void;
18
+ onSelectionChange(event: MatSelectChange): void;
19
+ static ɵfac: i0.ɵɵFactoryDeclaration<InputSelectComponent, never>;
20
+ static ɵcmp: i0.ɵɵComponentDeclaration<InputSelectComponent, "nmf-mat-input-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "emptyOptionLabel": { "alias": "emptyOptionLabel"; "required": false; "isSignal": true; }; "showClearOption": { "alias": "showClearOption"; "required": false; "isSignal": true; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
21
+ }
@@ -0,0 +1,11 @@
1
+ import { MatFormControlBase } from './mat-form-control-base';
2
+ import { InputTextBehavior } from '@ng-modular-forms/behavior';
3
+ import * as i0 from "@angular/core";
4
+ export declare class InputComponent extends MatFormControlBase<string | number | null> {
5
+ type: import("@angular/core").InputSignal<"text" | "email" | "tel" | "url" | "password">;
6
+ behavior: InputTextBehavior;
7
+ toggleShowPassword(event: MouseEvent): void;
8
+ onInput(event: Event): void;
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<InputComponent, never>;
10
+ static ɵcmp: i0.ɵɵComponentDeclaration<InputComponent, "nmf-mat-input-text", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
11
+ }
@@ -0,0 +1,12 @@
1
+ import { MatFormControlBase } from './mat-form-control-base';
2
+ import { InputTextareaBehavior } from '@ng-modular-forms/behavior';
3
+ import * as i0 from "@angular/core";
4
+ export declare class InputTextareaComponent extends MatFormControlBase<string | null> {
5
+ rows: import("@angular/core").InputSignal<number>;
6
+ cols: import("@angular/core").InputSignal<number>;
7
+ behavior: InputTextareaBehavior;
8
+ onEnter(): void;
9
+ onInput(event: Event): void;
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<InputTextareaComponent, never>;
11
+ static ɵcmp: i0.ɵɵComponentDeclaration<InputTextareaComponent, "nmf-mat-input-textarea", never, { "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "cols": { "alias": "cols"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
12
+ }
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@ng-modular-forms/material",
3
+ "version": "0.1.0",
4
+ "peerDependencies": {
5
+ "@angular/core": ">=17 <22",
6
+ "@angular/common": ">=17 <22",
7
+ "@angular/forms": ">=17 <22",
8
+ "@angular/material": ">=17 <22",
9
+ "@angular/cdk": ">=17 <22",
10
+ "rxjs": ">=7 <8",
11
+ "@ng-modular-forms/core": ">=0.2.0 <2",
12
+ "@ng-modular-forms/behavior": ">=0.0.1"
13
+ },
14
+ "dependencies": {
15
+ "tslib": "^2.6.0"
16
+ },
17
+ "sideEffects": false,
18
+ "module": "fesm2022/ng-modular-forms-material.mjs",
19
+ "typings": "index.d.ts",
20
+ "exports": {
21
+ "./package.json": {
22
+ "default": "./package.json"
23
+ },
24
+ ".": {
25
+ "types": "./index.d.ts",
26
+ "default": "./fesm2022/ng-modular-forms-material.mjs"
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,6 @@
1
+ export * from './lib/mat-form-control-base';
2
+ export * from './lib/mat-input-currency.component';
3
+ export * from './lib/mat-input-datepicker.component';
4
+ export * from './lib/mat-input-select.component';
5
+ export * from './lib/mat-input-text.component';
6
+ export * from './lib/mat-input-textarea.component';