@ng-forge/dynamic-forms-material 0.9.0-next.11 → 0.9.0-next.13

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.
@@ -1,21 +1,23 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, input, computed, ChangeDetectionStrategy, Component, linkedSignal, viewChild, afterRenderEffect, isSignal } from '@angular/core';
2
+ import { InjectionToken, inject, input, computed, ChangeDetectionStrategy, Component, signal, forwardRef, linkedSignal, isSignal } from '@angular/core';
3
3
  import { FormField } from '@angular/forms/signals';
4
4
  import { MatCheckbox } from '@angular/material/checkbox';
5
- import { DynamicTextPipe, DEFAULT_PROPS, ARRAY_CONTEXT, buildBaseInputs } from '@ng-forge/dynamic-forms';
5
+ import { DynamicTextPipe, runPresetAction, DfAddonSlot, FIELD_SIGNAL_CONTEXT, DynamicFormLogger, DEFAULT_PROPS, ARRAY_CONTEXT, buildBaseInputs, DynamicFormError, ADDON_KIND_DEFINITIONS } from '@ng-forge/dynamic-forms';
6
6
  import * as i1 from '@ng-forge/dynamic-forms/integration';
7
- import { injectNgForgeField, NgForgeControl, NgForgeFieldHost, isEqual, injectNgForgeAction, NgForgeActionHost, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, submitButtonFieldMapper, nextButtonFieldMapper, previousButtonFieldMapper, addArrayItemButtonMapper, prependArrayItemButtonMapper, insertArrayItemButtonMapper, removeArrayItemButtonMapper, popArrayItemButtonMapper, shiftArrayItemButtonMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
7
+ import { injectNgForgeField, NgForgeControl, NgForgeFieldHost, injectNgForgeAddons, ADDON_PRESET_HANDLER, NgForgeAddons, isEqual, injectNgForgeAction, NgForgeActionHost, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, submitButtonFieldMapper, nextButtonFieldMapper, previousButtonFieldMapper, addArrayItemButtonMapper, prependArrayItemButtonMapper, insertArrayItemButtonMapper, removeArrayItemButtonMapper, popArrayItemButtonMapper, shiftArrayItemButtonMapper, datepickerFieldMapper, injectNgForgeAddonAction, NgForgeAddonAction } from '@ng-forge/dynamic-forms/integration';
8
8
  import { MatError, MatInput, MatHint } from '@angular/material/input';
9
9
  import { AsyncPipe } from '@angular/common';
10
- import { MatFormField, MatLabel, MatSuffix, MatError as MatError$1 } from '@angular/material/form-field';
10
+ import { MatFormField, MatLabel, MatSuffix, MatError as MatError$1, MatPrefix } from '@angular/material/form-field';
11
11
  import { MatDatepicker, MatDatepickerInput, MatDatepickerToggle } from '@angular/material/datepicker';
12
12
  import { provideNativeDateAdapter } from '@angular/material/core';
13
13
  import { explicitEffect } from 'ngxtension/explicit-effect';
14
14
  import { MatRadioGroup, MatRadioButton } from '@angular/material/radio';
15
15
  import { MatSelect, MatOption } from '@angular/material/select';
16
16
  import { MatSlider, MatSliderThumb } from '@angular/material/slider';
17
- import { MatButton } from '@angular/material/button';
17
+ import { MatButton, MatIconButton } from '@angular/material/button';
18
18
  import { MatSlideToggle } from '@angular/material/slide-toggle';
19
+ import { MatIcon } from '@angular/material/icon';
20
+ import { MatProgressSpinner } from '@angular/material/progress-spinner';
19
21
 
20
22
  /**
21
23
  * Injection token for Material Design form configuration.
@@ -45,8 +47,8 @@ class MatCheckboxFieldComponent {
45
47
  ngf = injectNgForgeField();
46
48
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
47
49
  disableRipple = computed(() => this.props()?.disableRipple ?? this.materialConfig?.disableRipple ?? false, ...(ngDevMode ? [{ debugName: "disableRipple" }] : /* istanbul ignore next */ []));
48
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
49
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatCheckboxFieldComponent, isStandalone: true, selector: "df-mat-checkbox", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
50
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
51
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatCheckboxFieldComponent, isStandalone: true, selector: "df-mat-checkbox", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
50
52
  @let f = ngf.field();
51
53
  @let checkboxId = ngf.key() + '-checkbox';
52
54
 
@@ -70,9 +72,9 @@ class MatCheckboxFieldComponent {
70
72
  } @else if (props()?.hint; as hint) {
71
73
  <div class="mat-hint" [id]="ngf.hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
72
74
  }
73
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"], dependencies: [{ kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
75
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"], dependencies: [{ kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
74
76
  }
75
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatCheckboxFieldComponent, decorators: [{
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatCheckboxFieldComponent, decorators: [{
76
78
  type: Component,
77
79
  args: [{ selector: 'df-mat-checkbox', imports: [MatCheckbox, FormField, MatError, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
78
80
  @let f = ngf.field();
@@ -98,7 +100,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
98
100
  } @else if (props()?.hint; as hint) {
99
101
  <div class="mat-hint" [id]="ngf.hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
100
102
  }
101
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"] }]
103
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"] }]
102
104
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
103
105
 
104
106
  var matCheckbox_component = /*#__PURE__*/Object.freeze({
@@ -117,8 +119,8 @@ class MatDatepickerFieldComponent {
117
119
  subscriptSizing = computed(() => this.props()?.subscriptSizing ?? this.materialConfig?.subscriptSizing ?? 'dynamic', ...(ngDevMode ? [{ debugName: "subscriptSizing" }] : /* istanbul ignore next */ []));
118
120
  floatLabel = computed(() => this.props()?.floatLabel ?? this.materialConfig?.floatLabel ?? 'auto', ...(ngDevMode ? [{ debugName: "floatLabel" }] : /* istanbul ignore next */ []));
119
121
  hideRequiredMarker = computed(() => this.props()?.hideRequiredMarker ?? this.materialConfig?.hideRequiredMarker ?? false, ...(ngDevMode ? [{ debugName: "hideRequiredMarker" }] : /* istanbul ignore next */ []));
120
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
121
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatDatepickerFieldComponent, isStandalone: true, selector: "df-mat-datepicker", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, startAt: { classPropertyName: "startAt", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideNativeDateAdapter()], hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
122
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
123
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatDatepickerFieldComponent, isStandalone: true, selector: "df-mat-datepicker", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, startAt: { classPropertyName: "startAt", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideNativeDateAdapter()], hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
122
124
  @let inputId = ngf.key() + '-input';
123
125
 
124
126
  <mat-form-field
@@ -152,9 +154,9 @@ class MatDatepickerFieldComponent {
152
154
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
153
155
  }
154
156
  </mat-form-field>
155
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
157
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
156
158
  }
157
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatDatepickerFieldComponent, decorators: [{
159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatDatepickerFieldComponent, decorators: [{
158
160
  type: Component,
159
161
  args: [{ selector: 'df-mat-datepicker', imports: [
160
162
  MatFormField,
@@ -204,7 +206,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
204
206
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
205
207
  }
206
208
  </mat-form-field>
207
- `, providers: [provideNativeDateAdapter()], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"] }]
209
+ `, providers: [provideNativeDateAdapter()], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}\n"] }]
208
210
  }], propDecorators: { minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], startAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
209
211
 
210
212
  var matDatepicker_component = /*#__PURE__*/Object.freeze({
@@ -212,16 +214,85 @@ var matDatepicker_component = /*#__PURE__*/Object.freeze({
212
214
  default: MatDatepickerFieldComponent
213
215
  });
214
216
 
217
+ /** Material adapter binding for the shared preset runner. */
218
+ function runMatPresetAction(preset, ctx, collaborators) {
219
+ return runPresetAction(preset, ctx, collaborators, 'Material', 'mat-input');
220
+ }
221
+
222
+ /**
223
+ * Per-field writable signal that overrides the input's `type` attribute.
224
+ *
225
+ * Provided at the `mat-input` field component level. The button addon's
226
+ * `'toggle-password-visibility'` preset writes to it; the field component
227
+ * reads it to compute its effective `type`.
228
+ *
229
+ * Optional from a button's perspective — when the button is hosted inside a
230
+ * field that doesn't provide this token (e.g., textarea or a future
231
+ * non-input field), the toggle preset is a no-op.
232
+ *
233
+ * @example provided per-field:
234
+ * ```typescript
235
+ * @Component({
236
+ * providers: [{ provide: MAT_INPUT_TYPE_OVERRIDE, useValue: signal(undefined) }],
237
+ * })
238
+ * class MatInputFieldComponent { ... }
239
+ * ```
240
+ */
241
+ const MAT_INPUT_TYPE_OVERRIDE = new InjectionToken('MAT_INPUT_TYPE_OVERRIDE');
242
+
215
243
  class MatInputFieldComponent {
216
244
  materialConfig = inject(MATERIAL_CONFIG, { optional: true });
217
245
  ngf = injectNgForgeField();
246
+ ngfa = injectNgForgeAddons();
218
247
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
248
+ /**
249
+ * Wrapper-style host bag pushed by `DfFieldOutlet`. Declared at the
250
+ * component level so `setInputIfDeclared` (which uses
251
+ * `reflectComponentType`) can write it.
252
+ */
253
+ fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
254
+ /** Per-instance type override populated by `toggle-password-visibility` preset. */
255
+ typeOverride = inject(MAT_INPUT_TYPE_OVERRIDE);
219
256
  appearance = computed(() => this.props()?.appearance ?? this.materialConfig?.appearance ?? 'outline', ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
220
257
  subscriptSizing = computed(() => this.props()?.subscriptSizing ?? this.materialConfig?.subscriptSizing ?? 'dynamic', ...(ngDevMode ? [{ debugName: "subscriptSizing" }] : /* istanbul ignore next */ []));
221
258
  floatLabel = computed(() => this.props()?.floatLabel ?? this.materialConfig?.floatLabel ?? 'auto', ...(ngDevMode ? [{ debugName: "floatLabel" }] : /* istanbul ignore next */ []));
222
259
  hideRequiredMarker = computed(() => this.props()?.hideRequiredMarker ?? this.materialConfig?.hideRequiredMarker ?? false, ...(ngDevMode ? [{ debugName: "hideRequiredMarker" }] : /* istanbul ignore next */ []));
223
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
224
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatInputFieldComponent, isStandalone: true, selector: "df-mat-input", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
260
+ /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */
261
+ type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
262
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
263
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatInputFieldComponent, isStandalone: true, selector: "df-mat-input", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
264
+ {
265
+ provide: MAT_INPUT_TYPE_OVERRIDE,
266
+ useFactory: () => signal(undefined),
267
+ },
268
+ {
269
+ // Adapter-specific preset semantics for `mat-button` addons (clear /
270
+ // reset / paste / copy / toggle-password-visibility). The directive
271
+ // (`NgForgeAddonAction`) delegates here when an addon configures a
272
+ // `preset`. Per-mat-input-instance so the `typeOverride` signal is
273
+ // scoped to one field.
274
+ provide: ADDON_PRESET_HANDLER,
275
+ useFactory: () => {
276
+ const typeOverride = inject(MAT_INPUT_TYPE_OVERRIDE);
277
+ const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
278
+ const logger = inject(DynamicFormLogger);
279
+ // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.
280
+ const host = inject(forwardRef(() => MatInputFieldComponent));
281
+ return {
282
+ run: (preset, ctx) => {
283
+ const fieldKey = ctx.field.key;
284
+ return runMatPresetAction(preset, ctx, {
285
+ typeOverride,
286
+ fieldValueSetter: ctx.setValue,
287
+ fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : undefined,
288
+ baselineType: () => host.props()?.type,
289
+ logger,
290
+ });
291
+ },
292
+ };
293
+ },
294
+ },
295
+ ], hostDirectives: [{ directive: i1.NgForgeFieldHost }, { directive: i1.NgForgeAddons }], ngImport: i0, template: `
225
296
  @let inputId = ngf.key() + '-input';
226
297
 
227
298
  <mat-form-field
@@ -233,26 +304,57 @@ class MatInputFieldComponent {
233
304
  @if (ngf.label()) {
234
305
  <mat-label>{{ ngf.label() | dynamicText | async }}</mat-label>
235
306
  }
307
+ @for (a of ngfa.prefixAddons(); track $index) {
308
+ <df-addon-slot
309
+ matPrefix
310
+ [class.df-mat-addon-text]="a.kind === 'text'"
311
+ [addon]="a"
312
+ [fieldInputs]="fieldInputs()"
313
+ [hidden]="ngfa.hiddenSignalCache().get(a)"
314
+ />
315
+ }
236
316
  <input
237
317
  matInput
238
318
  ngForgeControl
239
319
  [id]="inputId"
240
320
  [formField]="ngf.field()"
241
- [type]="props()?.type ?? 'text'"
321
+ [type]="type()"
242
322
  [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
243
323
  [attr.tabindex]="ngf.tabIndex()"
244
324
  />
325
+ @for (a of ngfa.suffixAddons(); track $index) {
326
+ <df-addon-slot
327
+ matSuffix
328
+ [class.df-mat-addon-text]="a.kind === 'text'"
329
+ [addon]="a"
330
+ [fieldInputs]="fieldInputs()"
331
+ [hidden]="ngfa.hiddenSignalCache().get(a)"
332
+ />
333
+ }
245
334
  @if (ngf.errorsToDisplay()[0]; as error) {
246
335
  <mat-error [id]="ngf.errorId()">{{ error.message }}</mat-error>
247
336
  } @else if (props()?.hint; as hint) {
248
337
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
249
338
  }
250
339
  </mat-form-field>
251
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
340
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}:host([hidden]){display:none!important}:host{--df-mat-addon-prefix-outer-padding: .75em;--df-mat-addon-prefix-inner-padding: .5em;--df-mat-addon-suffix-inner-padding: .5em;--df-mat-addon-suffix-outer-padding: .75em;--df-mat-addon-prefix-text-outer-padding: 1em;--df-mat-addon-prefix-text-inner-padding: 1em;--df-mat-addon-suffix-text-inner-padding: 1em;--df-mat-addon-suffix-text-outer-padding: 1em}df-addon-slot[matprefix]{padding-left:var(--df-mat-addon-prefix-outer-padding);padding-right:var(--df-mat-addon-prefix-inner-padding)}df-addon-slot[matsuffix]{padding-left:var(--df-mat-addon-suffix-inner-padding);padding-right:var(--df-mat-addon-suffix-outer-padding)}df-addon-slot[matprefix].df-mat-addon-text{padding-left:var(--df-mat-addon-prefix-text-outer-padding);padding-right:var(--df-mat-addon-prefix-text-inner-padding)}df-addon-slot[matsuffix].df-mat-addon-text{padding-left:var(--df-mat-addon-suffix-text-inner-padding);padding-right:var(--df-mat-addon-suffix-text-outer-padding)}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "component", type: DfAddonSlot, selector: "df-addon-slot", inputs: ["addon", "fieldInputs", "hidden"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
252
341
  }
253
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatInputFieldComponent, decorators: [{
342
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatInputFieldComponent, decorators: [{
254
343
  type: Component,
255
- args: [{ selector: 'df-mat-input', imports: [MatFormField, MatLabel, MatInput, MatHint, FormField, MatError$1, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
344
+ args: [{ selector: 'df-mat-input', imports: [
345
+ MatFormField,
346
+ MatLabel,
347
+ MatInput,
348
+ MatHint,
349
+ MatError$1,
350
+ MatPrefix,
351
+ MatSuffix,
352
+ FormField,
353
+ DynamicTextPipe,
354
+ AsyncPipe,
355
+ NgForgeControl,
356
+ DfAddonSlot,
357
+ ], hostDirectives: [NgForgeFieldHost, NgForgeAddons], template: `
256
358
  @let inputId = ngf.key() + '-input';
257
359
 
258
360
  <mat-form-field
@@ -264,23 +366,73 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
264
366
  @if (ngf.label()) {
265
367
  <mat-label>{{ ngf.label() | dynamicText | async }}</mat-label>
266
368
  }
369
+ @for (a of ngfa.prefixAddons(); track $index) {
370
+ <df-addon-slot
371
+ matPrefix
372
+ [class.df-mat-addon-text]="a.kind === 'text'"
373
+ [addon]="a"
374
+ [fieldInputs]="fieldInputs()"
375
+ [hidden]="ngfa.hiddenSignalCache().get(a)"
376
+ />
377
+ }
267
378
  <input
268
379
  matInput
269
380
  ngForgeControl
270
381
  [id]="inputId"
271
382
  [formField]="ngf.field()"
272
- [type]="props()?.type ?? 'text'"
383
+ [type]="type()"
273
384
  [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
274
385
  [attr.tabindex]="ngf.tabIndex()"
275
386
  />
387
+ @for (a of ngfa.suffixAddons(); track $index) {
388
+ <df-addon-slot
389
+ matSuffix
390
+ [class.df-mat-addon-text]="a.kind === 'text'"
391
+ [addon]="a"
392
+ [fieldInputs]="fieldInputs()"
393
+ [hidden]="ngfa.hiddenSignalCache().get(a)"
394
+ />
395
+ }
276
396
  @if (ngf.errorsToDisplay()[0]; as error) {
277
397
  <mat-error [id]="ngf.errorId()">{{ error.message }}</mat-error>
278
398
  } @else if (props()?.hint; as hint) {
279
399
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
280
400
  }
281
401
  </mat-form-field>
282
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"] }]
283
- }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
402
+ `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
403
+ {
404
+ provide: MAT_INPUT_TYPE_OVERRIDE,
405
+ useFactory: () => signal(undefined),
406
+ },
407
+ {
408
+ // Adapter-specific preset semantics for `mat-button` addons (clear /
409
+ // reset / paste / copy / toggle-password-visibility). The directive
410
+ // (`NgForgeAddonAction`) delegates here when an addon configures a
411
+ // `preset`. Per-mat-input-instance so the `typeOverride` signal is
412
+ // scoped to one field.
413
+ provide: ADDON_PRESET_HANDLER,
414
+ useFactory: () => {
415
+ const typeOverride = inject(MAT_INPUT_TYPE_OVERRIDE);
416
+ const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
417
+ const logger = inject(DynamicFormLogger);
418
+ // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.
419
+ const host = inject(forwardRef(() => MatInputFieldComponent));
420
+ return {
421
+ run: (preset, ctx) => {
422
+ const fieldKey = ctx.field.key;
423
+ return runMatPresetAction(preset, ctx, {
424
+ typeOverride,
425
+ fieldValueSetter: ctx.setValue,
426
+ fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : undefined,
427
+ baselineType: () => host.props()?.type,
428
+ logger,
429
+ });
430
+ },
431
+ };
432
+ },
433
+ },
434
+ ], styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}:host([hidden]){display:none!important}:host{--df-mat-addon-prefix-outer-padding: .75em;--df-mat-addon-prefix-inner-padding: .5em;--df-mat-addon-suffix-inner-padding: .5em;--df-mat-addon-suffix-outer-padding: .75em;--df-mat-addon-prefix-text-outer-padding: 1em;--df-mat-addon-prefix-text-inner-padding: 1em;--df-mat-addon-suffix-text-inner-padding: 1em;--df-mat-addon-suffix-text-outer-padding: 1em}df-addon-slot[matprefix]{padding-left:var(--df-mat-addon-prefix-outer-padding);padding-right:var(--df-mat-addon-prefix-inner-padding)}df-addon-slot[matsuffix]{padding-left:var(--df-mat-addon-suffix-inner-padding);padding-right:var(--df-mat-addon-suffix-outer-padding)}df-addon-slot[matprefix].df-mat-addon-text{padding-left:var(--df-mat-addon-prefix-text-outer-padding);padding-right:var(--df-mat-addon-prefix-text-inner-padding)}df-addon-slot[matsuffix].df-mat-addon-text{padding-left:var(--df-mat-addon-suffix-text-inner-padding);padding-right:var(--df-mat-addon-suffix-text-outer-padding)}\n"] }]
435
+ }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
284
436
 
285
437
  var matInput_component = /*#__PURE__*/Object.freeze({
286
438
  __proto__: null,
@@ -329,8 +481,8 @@ class MatMultiCheckboxFieldComponent {
329
481
  }
330
482
  });
331
483
  }
332
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
333
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatMultiCheckboxFieldComponent, isStandalone: true, selector: "df-mat-multi-checkbox", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
484
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
485
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatMultiCheckboxFieldComponent, isStandalone: true, selector: "df-mat-multi-checkbox", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
334
486
  @let f = ngf.field();
335
487
  @let checkboxGroupId = ngf.key() + '-checkbox-group';
336
488
  @let checked = checkedValuesMap();
@@ -366,9 +518,9 @@ class MatMultiCheckboxFieldComponent {
366
518
  } @else if (props()?.hint; as hint) {
367
519
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
368
520
  }
369
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"], dependencies: [{ kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
521
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"], dependencies: [{ kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
370
522
  }
371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatMultiCheckboxFieldComponent, decorators: [{
523
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatMultiCheckboxFieldComponent, decorators: [{
372
524
  type: Component,
373
525
  args: [{ selector: 'df-mat-multi-checkbox', imports: [MatCheckbox, MatError, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
374
526
  @let f = ngf.field();
@@ -406,7 +558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
406
558
  } @else if (props()?.hint; as hint) {
407
559
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
408
560
  }
409
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"] }]
561
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"] }]
410
562
  }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
411
563
 
412
564
  var matMultiCheckbox_component = /*#__PURE__*/Object.freeze({
@@ -418,8 +570,8 @@ class MatRadioFieldComponent {
418
570
  ngf = injectNgForgeField();
419
571
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
420
572
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
421
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
422
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatRadioFieldComponent, isStandalone: true, selector: "df-mat-radio", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
573
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
574
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatRadioFieldComponent, isStandalone: true, selector: "df-mat-radio", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
423
575
  @let f = ngf.field();
424
576
  @let radioGroupId = ngf.key() + '-radio-group';
425
577
 
@@ -452,9 +604,9 @@ class MatRadioFieldComponent {
452
604
  } @else if (props()?.hint; as hint) {
453
605
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
454
606
  }
455
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"], dependencies: [{ kind: "directive", type: MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
607
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"], dependencies: [{ kind: "directive", type: MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
456
608
  }
457
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatRadioFieldComponent, decorators: [{
609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatRadioFieldComponent, decorators: [{
458
610
  type: Component,
459
611
  args: [{ selector: 'df-mat-radio', imports: [MatRadioGroup, MatRadioButton, FormField, MatError, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
460
612
  @let f = ngf.field();
@@ -489,7 +641,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
489
641
  } @else if (props()?.hint; as hint) {
490
642
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
491
643
  }
492
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"] }]
644
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"] }]
493
645
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
494
646
 
495
647
  var matRadio_component = /*#__PURE__*/Object.freeze({
@@ -507,8 +659,8 @@ class MatSelectFieldComponent {
507
659
  floatLabel = computed(() => this.props()?.floatLabel ?? this.materialConfig?.floatLabel ?? 'auto', ...(ngDevMode ? [{ debugName: "floatLabel" }] : /* istanbul ignore next */ []));
508
660
  hideRequiredMarker = computed(() => this.props()?.hideRequiredMarker ?? this.materialConfig?.hideRequiredMarker ?? false, ...(ngDevMode ? [{ debugName: "hideRequiredMarker" }] : /* istanbul ignore next */ []));
509
661
  defaultCompare = Object.is;
510
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
511
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatSelectFieldComponent, isStandalone: true, selector: "df-mat-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
662
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
663
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatSelectFieldComponent, isStandalone: true, selector: "df-mat-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
512
664
  @let selectId = ngf.key() + '-select';
513
665
 
514
666
  <mat-form-field
@@ -542,9 +694,9 @@ class MatSelectFieldComponent {
542
694
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
543
695
  }
544
696
  </mat-form-field>
545
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
697
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
546
698
  }
547
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatSelectFieldComponent, decorators: [{
699
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatSelectFieldComponent, decorators: [{
548
700
  type: Component,
549
701
  args: [{ selector: 'df-mat-select', imports: [MatFormField, MatLabel, MatSelect, MatOption, MatHint, FormField, MatError$1, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
550
702
  @let selectId = ngf.key() + '-select';
@@ -580,7 +732,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
580
732
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
581
733
  }
582
734
  </mat-form-field>
583
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"] }]
735
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}\n"] }]
584
736
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
585
737
 
586
738
  var matSelect_component = /*#__PURE__*/Object.freeze({
@@ -592,8 +744,8 @@ class MatSliderFieldComponent {
592
744
  ngf = injectNgForgeField();
593
745
  step = input(...(ngDevMode ? [undefined, { debugName: "step" }] : /* istanbul ignore next */ []));
594
746
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
595
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
596
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatSliderFieldComponent, isStandalone: true, selector: "df-mat-slider", inputs: { step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
747
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
748
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatSliderFieldComponent, isStandalone: true, selector: "df-mat-slider", inputs: { step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
597
749
  @let f = ngf.field();
598
750
  @let inputId = ngf.key() + '-input';
599
751
 
@@ -618,9 +770,9 @@ class MatSliderFieldComponent {
618
770
  } @else if (props()?.hint; as hint) {
619
771
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
620
772
  }
621
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", ".slider-container{width:100%}\n"], dependencies: [{ kind: "component", type: MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
773
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", ".slider-container{width:100%}\n"], dependencies: [{ kind: "component", type: MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
622
774
  }
623
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatSliderFieldComponent, decorators: [{
775
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatSliderFieldComponent, decorators: [{
624
776
  type: Component,
625
777
  args: [{ selector: 'df-mat-slider', imports: [MatSlider, MatSliderThumb, MatError, DynamicTextPipe, AsyncPipe, FormField, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
626
778
  @let f = ngf.field();
@@ -647,7 +799,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
647
799
  } @else if (props()?.hint; as hint) {
648
800
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
649
801
  }
650
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", ".slider-container{width:100%}\n"] }]
802
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", ".slider-container{width:100%}\n"] }]
651
803
  }], propDecorators: { step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
652
804
 
653
805
  var matSlider_component = /*#__PURE__*/Object.freeze({
@@ -665,8 +817,8 @@ class MatButtonFieldComponent {
665
817
  return;
666
818
  this.action.dispatch();
667
819
  }
668
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
669
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: MatButtonFieldComponent, isStandalone: true, selector: "df-mat-button", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeActionHost }], ngImport: i0, template: `
820
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
821
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: MatButtonFieldComponent, isStandalone: true, selector: "df-mat-button", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeActionHost }], ngImport: i0, template: `
670
822
  @let buttonId = action.key() + '-button';
671
823
  <button
672
824
  mat-raised-button
@@ -680,9 +832,9 @@ class MatButtonFieldComponent {
680
832
  >
681
833
  {{ action.label() | dynamicText | async }}
682
834
  </button>
683
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "button{min-width:fit-content}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
835
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "button{min-width:fit-content}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
684
836
  }
685
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatButtonFieldComponent, decorators: [{
837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatButtonFieldComponent, decorators: [{
686
838
  type: Component,
687
839
  args: [{ selector: 'df-mat-button', imports: [MatButton, DynamicTextPipe, AsyncPipe], hostDirectives: [NgForgeActionHost], template: `
688
840
  @let buttonId = action.key() + '-button';
@@ -698,7 +850,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
698
850
  >
699
851
  {{ action.label() | dynamicText | async }}
700
852
  </button>
701
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "button{min-width:fit-content}\n"] }]
853
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "button{min-width:fit-content}\n"] }]
702
854
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
703
855
 
704
856
  var matButton_component = /*#__PURE__*/Object.freeze({
@@ -712,50 +864,12 @@ class MatTextareaFieldComponent {
712
864
  materialConfig = inject(MATERIAL_CONFIG, { optional: true });
713
865
  ngf = injectNgForgeField();
714
866
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
715
- /**
716
- * Reference to the native textarea element.
717
- * Used to imperatively sync the readonly attribute since Angular Signal Forms'
718
- * [field] directive doesn't sync FieldState.readonly() to the DOM.
719
- */
720
- textareaRef = viewChild('textareaRef', ...(ngDevMode ? [{ debugName: "textareaRef" }] : /* istanbul ignore next */ []));
721
- /**
722
- * Computed signal that extracts the readonly state from the field.
723
- * Used by the effect to reactively sync the readonly attribute to the DOM.
724
- */
725
- isReadonly = computed(() => this.ngf.field()().readonly(), ...(ngDevMode ? [{ debugName: "isReadonly" }] : /* istanbul ignore next */ []));
726
- /**
727
- * Workaround: Angular Signal Forms' [field] directive does NOT sync the readonly
728
- * attribute to the DOM, even though FieldState.readonly() returns the correct value.
729
- * This effect imperatively sets/removes the readonly attribute on the native textarea
730
- * element whenever the readonly state changes.
731
- *
732
- * Note: We cannot use [readonly] or [attr.readonly] bindings because Angular throws
733
- * NG8022: "Binding to '[readonly]' is not allowed on nodes using the '[field]' directive"
734
- *
735
- * Uses afterRenderEffect to ensure DOM is ready before manipulating attributes.
736
- *
737
- * @see https://github.com/angular/angular/issues/65897
738
- */
739
- syncReadonlyToDom = afterRenderEffect({
740
- write: () => {
741
- const textareaRef = this.textareaRef();
742
- const isReadonly = this.isReadonly();
743
- if (textareaRef?.nativeElement) {
744
- if (isReadonly) {
745
- textareaRef.nativeElement.setAttribute('readonly', '');
746
- }
747
- else {
748
- textareaRef.nativeElement.removeAttribute('readonly');
749
- }
750
- }
751
- },
752
- });
753
867
  appearance = computed(() => this.props()?.appearance ?? this.materialConfig?.appearance ?? 'outline', ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
754
868
  subscriptSizing = computed(() => this.props()?.subscriptSizing ?? this.materialConfig?.subscriptSizing ?? 'dynamic', ...(ngDevMode ? [{ debugName: "subscriptSizing" }] : /* istanbul ignore next */ []));
755
869
  floatLabel = computed(() => this.props()?.floatLabel ?? this.materialConfig?.floatLabel ?? 'auto', ...(ngDevMode ? [{ debugName: "floatLabel" }] : /* istanbul ignore next */ []));
756
870
  hideRequiredMarker = computed(() => this.props()?.hideRequiredMarker ?? this.materialConfig?.hideRequiredMarker ?? false, ...(ngDevMode ? [{ debugName: "hideRequiredMarker" }] : /* istanbul ignore next */ []));
757
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
758
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatTextareaFieldComponent, isStandalone: true, selector: "df-mat-textarea", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "textareaRef", first: true, predicate: ["textareaRef"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
871
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
872
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatTextareaFieldComponent, isStandalone: true, selector: "df-mat-textarea", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
759
873
  @let textareaId = ngf.key() + '-textarea';
760
874
 
761
875
  <mat-form-field
@@ -770,7 +884,6 @@ class MatTextareaFieldComponent {
770
884
 
771
885
  <textarea
772
886
  ngForgeControl
773
- #textareaRef
774
887
  matInput
775
888
  [id]="textareaId"
776
889
  [formField]="ngf.field()"
@@ -785,9 +898,9 @@ class MatTextareaFieldComponent {
785
898
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
786
899
  }
787
900
  </mat-form-field>
788
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
901
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: 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: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError$1, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
789
902
  }
790
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatTextareaFieldComponent, decorators: [{
903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatTextareaFieldComponent, decorators: [{
791
904
  type: Component,
792
905
  args: [{ selector: 'df-mat-textarea', imports: [MatFormField, MatLabel, MatInput, MatHint, FormField, MatError$1, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
793
906
  @let textareaId = ngf.key() + '-textarea';
@@ -804,7 +917,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
804
917
 
805
918
  <textarea
806
919
  ngForgeControl
807
- #textareaRef
808
920
  matInput
809
921
  [id]="textareaId"
810
922
  [formField]="ngf.field()"
@@ -819,8 +931,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
819
931
  <mat-hint [id]="ngf.hintId()">{{ hint | dynamicText | async }}</mat-hint>
820
932
  }
821
933
  </mat-form-field>
822
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n", "mat-form-field{width:100%}\n"] }]
823
- }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], textareaRef: [{ type: i0.ViewChild, args: ['textareaRef', { isSignal: true }] }] } });
934
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n", "mat-form-field{width:100%}\n"] }]
935
+ }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
824
936
 
825
937
  var matTextarea_component = /*#__PURE__*/Object.freeze({
826
938
  __proto__: null,
@@ -832,8 +944,8 @@ class MatToggleFieldComponent {
832
944
  ngf = injectNgForgeField();
833
945
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
834
946
  disableRipple = computed(() => this.props()?.disableRipple ?? this.materialConfig?.disableRipple ?? false, ...(ngDevMode ? [{ debugName: "disableRipple" }] : /* istanbul ignore next */ []));
835
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
836
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: MatToggleFieldComponent, isStandalone: true, selector: "df-mat-toggle", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
947
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
948
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatToggleFieldComponent, isStandalone: true, selector: "df-mat-toggle", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
837
949
  @let f = ngf.field();
838
950
  @let toggleId = ngf.key() + '-toggle';
839
951
 
@@ -857,9 +969,9 @@ class MatToggleFieldComponent {
857
969
  } @else if (props()?.hint; as hint) {
858
970
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
859
971
  }
860
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"], dependencies: [{ kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
972
+ `, isInline: true, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"], dependencies: [{ kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
861
973
  }
862
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: MatToggleFieldComponent, decorators: [{
974
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatToggleFieldComponent, decorators: [{
863
975
  type: Component,
864
976
  args: [{ selector: 'df-mat-toggle', imports: [MatSlideToggle, FormField, MatError, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
865
977
  @let f = ngf.field();
@@ -885,7 +997,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
885
997
  } @else if (props()?.hint; as hint) {
886
998
  <div class="mat-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
887
999
  }
888
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: rgba(0, 0, 0, .6);--df-hint-font-size: .875rem;--df-error-color: #f44336;--df-error-font-size: .875rem;display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-mat-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-mat-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}\n"] }]
1000
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%}:host([hidden]){display:none!important}.df-mat-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-mat-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-mat-hint{color:var(--df-hint-color, rgba(0, 0, 0, .6));font-size:var(--df-hint-font-size, .875rem)}.df-mat-error{color:var(--df-error-color, #f44336);font-size:var(--df-error-font-size, .875rem)}\n"] }]
889
1001
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
890
1002
 
891
1003
  var matToggle_component = /*#__PURE__*/Object.freeze({
@@ -983,11 +1095,20 @@ function buttonFieldMapper(fieldDef) {
983
1095
  */
984
1096
 
985
1097
  /**
986
- * Base definition for button field types that don't use the `field` input.
987
- * Button fields render immediately without waiting for form value integration.
1098
+ * Base for value-bearing field types — waits for the mapper to emit the `field`
1099
+ * input before instantiating the component (matches NgForgeField's
1100
+ * `input.required<FieldTree<T>>()` contract).
1101
+ */
1102
+ const VALUE_FIELD_TYPES_BASE = {
1103
+ renderReadyWhen: ['field'],
1104
+ };
1105
+ /**
1106
+ * Base for action/button field types that don't bind to a form value.
1107
+ * Renders immediately, opted out of form-value collection.
988
1108
  */
989
1109
  const BUTTON_FIELD_TYPES_BASE = {
990
1110
  renderReadyWhen: [],
1111
+ valueHandling: 'exclude',
991
1112
  };
992
1113
  /**
993
1114
  * Material Design field type definitions
@@ -1000,87 +1121,83 @@ const MATERIAL_FIELD_TYPES = [
1000
1121
  mapper: valueFieldMapper,
1001
1122
  propsToMeta: ['type'],
1002
1123
  scope: ['text-input', 'numeric'],
1124
+ addons: {
1125
+ slots: ['prefix', 'suffix'],
1126
+ },
1127
+ ...VALUE_FIELD_TYPES_BASE,
1003
1128
  },
1004
1129
  {
1005
1130
  name: MatField.Select,
1006
1131
  loadComponent: () => Promise.resolve().then(function () { return matSelect_component; }),
1007
1132
  mapper: optionsFieldMapper,
1008
1133
  scope: 'single-select',
1134
+ ...VALUE_FIELD_TYPES_BASE,
1009
1135
  },
1010
1136
  {
1011
1137
  name: MatField.Checkbox,
1012
1138
  loadComponent: () => Promise.resolve().then(function () { return matCheckbox_component; }),
1013
1139
  mapper: checkboxFieldMapper,
1014
1140
  scope: 'boolean',
1141
+ ...VALUE_FIELD_TYPES_BASE,
1015
1142
  },
1016
1143
  {
1017
1144
  name: MatField.Button,
1018
1145
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1019
1146
  mapper: buttonFieldMapper,
1020
- valueHandling: 'exclude',
1021
1147
  ...BUTTON_FIELD_TYPES_BASE,
1022
1148
  },
1023
1149
  {
1024
1150
  name: MatField.Submit,
1025
1151
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1026
1152
  mapper: submitButtonFieldMapper,
1027
- valueHandling: 'exclude',
1028
1153
  ...BUTTON_FIELD_TYPES_BASE,
1029
1154
  },
1030
1155
  {
1031
1156
  name: MatField.Next,
1032
1157
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1033
1158
  mapper: nextButtonFieldMapper,
1034
- valueHandling: 'exclude',
1035
1159
  ...BUTTON_FIELD_TYPES_BASE,
1036
1160
  },
1037
1161
  {
1038
1162
  name: MatField.Previous,
1039
1163
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1040
1164
  mapper: previousButtonFieldMapper,
1041
- valueHandling: 'exclude',
1042
1165
  ...BUTTON_FIELD_TYPES_BASE,
1043
1166
  },
1044
1167
  {
1045
1168
  name: MatField.AddArrayItem,
1046
1169
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1047
1170
  mapper: addArrayItemButtonMapper,
1048
- valueHandling: 'exclude',
1049
1171
  ...BUTTON_FIELD_TYPES_BASE,
1050
1172
  },
1051
1173
  {
1052
1174
  name: MatField.PrependArrayItem,
1053
1175
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1054
1176
  mapper: prependArrayItemButtonMapper,
1055
- valueHandling: 'exclude',
1056
1177
  ...BUTTON_FIELD_TYPES_BASE,
1057
1178
  },
1058
1179
  {
1059
1180
  name: MatField.InsertArrayItem,
1060
1181
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1061
1182
  mapper: insertArrayItemButtonMapper,
1062
- valueHandling: 'exclude',
1063
1183
  ...BUTTON_FIELD_TYPES_BASE,
1064
1184
  },
1065
1185
  {
1066
1186
  name: MatField.RemoveArrayItem,
1067
1187
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1068
1188
  mapper: removeArrayItemButtonMapper,
1069
- valueHandling: 'exclude',
1070
1189
  ...BUTTON_FIELD_TYPES_BASE,
1071
1190
  },
1072
1191
  {
1073
1192
  name: MatField.PopArrayItem,
1074
1193
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1075
1194
  mapper: popArrayItemButtonMapper,
1076
- valueHandling: 'exclude',
1077
1195
  ...BUTTON_FIELD_TYPES_BASE,
1078
1196
  },
1079
1197
  {
1080
1198
  name: MatField.ShiftArrayItem,
1081
1199
  loadComponent: () => Promise.resolve().then(function () { return matButton_component; }),
1082
1200
  mapper: shiftArrayItemButtonMapper,
1083
- valueHandling: 'exclude',
1084
1201
  ...BUTTON_FIELD_TYPES_BASE,
1085
1202
  },
1086
1203
  {
@@ -1089,36 +1206,42 @@ const MATERIAL_FIELD_TYPES = [
1089
1206
  mapper: valueFieldMapper,
1090
1207
  propsToMeta: ['rows', 'cols'],
1091
1208
  scope: 'text-input',
1209
+ ...VALUE_FIELD_TYPES_BASE,
1092
1210
  },
1093
1211
  {
1094
1212
  name: MatField.Radio,
1095
1213
  loadComponent: () => Promise.resolve().then(function () { return matRadio_component; }),
1096
1214
  mapper: optionsFieldMapper,
1097
1215
  scope: 'single-select',
1216
+ ...VALUE_FIELD_TYPES_BASE,
1098
1217
  },
1099
1218
  {
1100
1219
  name: MatField.MultiCheckbox,
1101
1220
  loadComponent: () => Promise.resolve().then(function () { return matMultiCheckbox_component; }),
1102
1221
  mapper: optionsFieldMapper,
1103
1222
  scope: 'multi-select',
1223
+ ...VALUE_FIELD_TYPES_BASE,
1104
1224
  },
1105
1225
  {
1106
1226
  name: MatField.Datepicker,
1107
1227
  loadComponent: () => Promise.resolve().then(function () { return matDatepicker_component; }),
1108
1228
  mapper: datepickerFieldMapper,
1109
1229
  scope: 'date',
1230
+ ...VALUE_FIELD_TYPES_BASE,
1110
1231
  },
1111
1232
  {
1112
1233
  name: MatField.Slider,
1113
1234
  loadComponent: () => Promise.resolve().then(function () { return matSlider_component; }),
1114
1235
  mapper: valueFieldMapper,
1115
1236
  scope: 'numeric',
1237
+ ...VALUE_FIELD_TYPES_BASE,
1116
1238
  },
1117
1239
  {
1118
1240
  name: MatField.Toggle,
1119
1241
  loadComponent: () => Promise.resolve().then(function () { return matToggle_component; }),
1120
1242
  mapper: checkboxFieldMapper,
1121
1243
  scope: 'boolean',
1244
+ ...VALUE_FIELD_TYPES_BASE,
1122
1245
  },
1123
1246
  ];
1124
1247
 
@@ -1129,19 +1252,213 @@ const MATERIAL_FIELD_TYPES = [
1129
1252
  */
1130
1253
 
1131
1254
  function withMaterialFields(config) {
1132
- if (!config) {
1133
- return MATERIAL_FIELD_TYPES;
1134
- }
1135
- const fieldsWithConfig = [
1136
- ...MATERIAL_FIELD_TYPES,
1137
- {
1255
+ // Always include the addons feature — mat-icon / mat-button are part of
1256
+ // the canonical Material surface.
1257
+ const base = [...MATERIAL_FIELD_TYPES, withMaterialAddons()];
1258
+ if (config) {
1259
+ base.push({
1138
1260
  ɵkind: 'material-config',
1139
1261
  ɵproviders: [{ provide: MATERIAL_CONFIG, useValue: config }],
1140
- },
1141
- ];
1142
- // Safe: this preserves all material field definitions and appends exactly one config feature.
1143
- return fieldsWithConfig;
1262
+ });
1263
+ return base;
1264
+ }
1265
+ return base;
1266
+ }
1267
+ /* -- Material addon kinds ----------------------------------------------- */
1268
+ const MAT_ICON_KIND = {
1269
+ kind: 'mat-icon',
1270
+ loadComponent: () => Promise.resolve().then(function () { return matIconAddon_component; }).then((m) => m.MatIconAddonComponent),
1271
+ validate: (addon, fieldKey) => {
1272
+ if (typeof addon.icon !== 'string' || addon.icon.length === 0) {
1273
+ throw new DynamicFormError(`Addon kind 'mat-icon' requires a non-empty 'icon' string (field: '${fieldKey}').`);
1274
+ }
1275
+ },
1276
+ };
1277
+ const MAT_BUTTON_KIND = {
1278
+ kind: 'mat-button',
1279
+ loadComponent: () => Promise.resolve().then(function () { return matButtonAddon_component; }).then((m) => m.MatButtonAddonComponent),
1280
+ validate: (addon, fieldKey) => {
1281
+ // Exactly one of preset / actionRef / action — validator drops the addon
1282
+ // (with warning) if the rule is violated.
1283
+ const set = [addon.preset, addon.actionRef, addon.action].filter((v) => v !== undefined);
1284
+ if (set.length > 1) {
1285
+ throw new DynamicFormError(`Addon kind 'mat-button' on field '${fieldKey}' has more than one of preset/actionRef/action — exactly one allowed.`);
1286
+ }
1287
+ // Icon-only buttons require ariaLabel for screen readers.
1288
+ if (addon.icon && !addon.label && !addon.ariaLabel) {
1289
+ throw new DynamicFormError(`Addon kind 'mat-button' on field '${fieldKey}' is icon-only — provide 'ariaLabel' for accessibility.`);
1290
+ }
1291
+ },
1292
+ };
1293
+ /**
1294
+ * Register Material-shipped addon kinds (`mat-icon`, `mat-button`) standalone.
1295
+ *
1296
+ * **Most users don't need this** — `withMaterialFields()` auto-includes
1297
+ * these kinds. Call `withMaterialAddons()` directly only when you want
1298
+ * Material addon kinds without the Material field types (e.g., a custom
1299
+ * field set that wants to render `mat-icon` prefixes), or when you're
1300
+ * stitching addons through a different DI scope.
1301
+ *
1302
+ * @example
1303
+ * ```typescript
1304
+ * // Custom field types + Material addon kinds.
1305
+ * provideDynamicForm(
1306
+ * ...myCustomFields(),
1307
+ * withMaterialAddons(),
1308
+ * );
1309
+ * ```
1310
+ *
1311
+ * Adapter authors who need to override a kind with a customised renderer
1312
+ * should call `withCustomAddon(...)` directly instead.
1313
+ */
1314
+ function withMaterialAddons() {
1315
+ return {
1316
+ ɵkind: 'addons',
1317
+ ɵproviders: [
1318
+ { provide: ADDON_KIND_DEFINITIONS, useValue: MAT_ICON_KIND, multi: true },
1319
+ { provide: ADDON_KIND_DEFINITIONS, useValue: MAT_BUTTON_KIND, multi: true },
1320
+ ],
1321
+ };
1322
+ }
1323
+
1324
+ /**
1325
+ * Renderer for the `mat-icon` addon kind.
1326
+ *
1327
+ * Outputs `<mat-icon>{icon}</mat-icon>` using Material Icons ligatures. The
1328
+ * host is set `aria-hidden="true"` by default; if the addon supplies an
1329
+ * `ariaLabel`, it is applied so the icon is announced by screen readers.
1330
+ */
1331
+ class MatIconAddonComponent {
1332
+ addon = input.required(...(ngDevMode ? [{ debugName: "addon" }] : /* istanbul ignore next */ []));
1333
+ /** Accepted for contract uniformity — `NgComponentOutlet` setInput is strict; every kind must declare it. */
1334
+ fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
1335
+ ariaLabel = computed(() => this.addon().ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1336
+ hasAriaLabel = computed(() => this.addon().ariaLabel !== undefined, ...(ngDevMode ? [{ debugName: "hasAriaLabel" }] : /* istanbul ignore next */ []));
1337
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatIconAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1338
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: MatIconAddonComponent, isStandalone: true, selector: "df-mat-icon-addon", inputs: { addon: { classPropertyName: "addon", publicName: "addon", isSignal: true, isRequired: true, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-hidden": "hasAriaLabel() ? null : \"true\"" } }, ngImport: i0, template: `<mat-icon [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null">{{ addon().icon }}</mat-icon>`, isInline: true, dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1144
1339
  }
1340
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatIconAddonComponent, decorators: [{
1341
+ type: Component,
1342
+ args: [{
1343
+ selector: 'df-mat-icon-addon',
1344
+ imports: [MatIcon, AsyncPipe, DynamicTextPipe],
1345
+ template: `<mat-icon [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null">{{ addon().icon }}</mat-icon>`,
1346
+ host: {
1347
+ '[attr.aria-hidden]': 'hasAriaLabel() ? null : "true"',
1348
+ },
1349
+ changeDetection: ChangeDetectionStrategy.OnPush,
1350
+ }]
1351
+ }], propDecorators: { addon: [{ type: i0.Input, args: [{ isSignal: true, alias: "addon", required: true }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
1352
+
1353
+ var matIconAddon_component = /*#__PURE__*/Object.freeze({
1354
+ __proto__: null,
1355
+ MatIconAddonComponent: MatIconAddonComponent
1356
+ });
1357
+
1358
+ /**
1359
+ * Renderer for the `mat-button` addon kind.
1360
+ *
1361
+ * Renders `<button mat-icon-button>` when icon-only (no label), or
1362
+ * `<button mat-button>` when labeled. Click dispatch (preset / actionRef /
1363
+ * action precedence, multi-set warning, `disabled` / `loading` resolution)
1364
+ * lives on `NgForgeAddonAction`; this component focuses on the visual layer.
1365
+ */
1366
+ class MatButtonAddonComponent {
1367
+ action = injectNgForgeAddonAction();
1368
+ /** Re-exposed for template binding — same signal stored on the directive. */
1369
+ addon = this.action.addon;
1370
+ label = computed(() => this.addon().label, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1371
+ ariaLabel = computed(() => this.addon().ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1372
+ isIconOnly = computed(() => {
1373
+ const a = this.addon();
1374
+ return !!a.icon && !a.label;
1375
+ }, ...(ngDevMode ? [{ debugName: "isIconOnly" }] : /* istanbul ignore next */ []));
1376
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatButtonAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1377
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: MatButtonAddonComponent, isStandalone: true, selector: "df-mat-button-addon", hostDirectives: [{ directive: i1.NgForgeAddonAction }], ngImport: i0, template: `
1378
+ @if (isIconOnly()) {
1379
+ <button
1380
+ mat-icon-button
1381
+ type="button"
1382
+ [color]="addon().color ?? null"
1383
+ [disabled]="action.disabled() || action.loading()"
1384
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
1385
+ [attr.aria-busy]="action.loading() || null"
1386
+ (click)="action.dispatch()"
1387
+ >
1388
+ @if (action.loading()) {
1389
+ <mat-progress-spinner mode="indeterminate" diameter="18" aria-hidden="true" />
1390
+ <span class="df-mat-sr-only" role="status">Loading…</span>
1391
+ } @else {
1392
+ <mat-icon aria-hidden="true">{{ addon().icon }}</mat-icon>
1393
+ }
1394
+ </button>
1395
+ } @else {
1396
+ <button
1397
+ mat-button
1398
+ type="button"
1399
+ [color]="addon().color ?? null"
1400
+ [disabled]="action.disabled() || action.loading()"
1401
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
1402
+ [attr.aria-busy]="action.loading() || null"
1403
+ (click)="action.dispatch()"
1404
+ >
1405
+ @if (action.loading()) {
1406
+ <mat-progress-spinner mode="indeterminate" diameter="18" aria-hidden="true" />
1407
+ <span class="df-mat-sr-only" role="status">Loading…</span>
1408
+ } @else if (addon().icon; as icon) {
1409
+ <mat-icon aria-hidden="true">{{ icon }}</mat-icon>
1410
+ }
1411
+ {{ label() | dynamicText | async }}
1412
+ </button>
1413
+ }
1414
+ `, isInline: true, styles: [".df-mat-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1415
+ }
1416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MatButtonAddonComponent, decorators: [{
1417
+ type: Component,
1418
+ args: [{ selector: 'df-mat-button-addon', imports: [MatButton, MatIconButton, MatIcon, MatProgressSpinner, DynamicTextPipe, AsyncPipe], hostDirectives: [NgForgeAddonAction], template: `
1419
+ @if (isIconOnly()) {
1420
+ <button
1421
+ mat-icon-button
1422
+ type="button"
1423
+ [color]="addon().color ?? null"
1424
+ [disabled]="action.disabled() || action.loading()"
1425
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
1426
+ [attr.aria-busy]="action.loading() || null"
1427
+ (click)="action.dispatch()"
1428
+ >
1429
+ @if (action.loading()) {
1430
+ <mat-progress-spinner mode="indeterminate" diameter="18" aria-hidden="true" />
1431
+ <span class="df-mat-sr-only" role="status">Loading…</span>
1432
+ } @else {
1433
+ <mat-icon aria-hidden="true">{{ addon().icon }}</mat-icon>
1434
+ }
1435
+ </button>
1436
+ } @else {
1437
+ <button
1438
+ mat-button
1439
+ type="button"
1440
+ [color]="addon().color ?? null"
1441
+ [disabled]="action.disabled() || action.loading()"
1442
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
1443
+ [attr.aria-busy]="action.loading() || null"
1444
+ (click)="action.dispatch()"
1445
+ >
1446
+ @if (action.loading()) {
1447
+ <mat-progress-spinner mode="indeterminate" diameter="18" aria-hidden="true" />
1448
+ <span class="df-mat-sr-only" role="status">Loading…</span>
1449
+ } @else if (addon().icon; as icon) {
1450
+ <mat-icon aria-hidden="true">{{ icon }}</mat-icon>
1451
+ }
1452
+ {{ label() | dynamicText | async }}
1453
+ </button>
1454
+ }
1455
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-mat-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
1456
+ }] });
1457
+
1458
+ var matButtonAddon_component = /*#__PURE__*/Object.freeze({
1459
+ __proto__: null,
1460
+ MatButtonAddonComponent: MatButtonAddonComponent
1461
+ });
1145
1462
 
1146
1463
  // Field components
1147
1464
 
@@ -1149,5 +1466,5 @@ function withMaterialFields(config) {
1149
1466
  * Generated bundle index. Do not edit.
1150
1467
  */
1151
1468
 
1152
- export { MATERIAL_CONFIG, MATERIAL_FIELD_TYPES, MatButtonFieldComponent, MatCheckboxFieldComponent, MatDatepickerFieldComponent, MatField, MatInputFieldComponent, MatMultiCheckboxFieldComponent, MatRadioFieldComponent, MatSelectFieldComponent, MatSliderFieldComponent, MatTextareaFieldComponent, MatToggleFieldComponent, withMaterialFields };
1469
+ export { MATERIAL_CONFIG, MATERIAL_FIELD_TYPES, MAT_INPUT_TYPE_OVERRIDE, MatButtonAddonComponent, MatButtonFieldComponent, MatCheckboxFieldComponent, MatDatepickerFieldComponent, MatField, MatIconAddonComponent, MatInputFieldComponent, MatMultiCheckboxFieldComponent, MatRadioFieldComponent, MatSelectFieldComponent, MatSliderFieldComponent, MatTextareaFieldComponent, MatToggleFieldComponent, withMaterialAddons, withMaterialFields };
1153
1470
  //# sourceMappingURL=ng-forge-dynamic-forms-material.mjs.map