@ng-forge/dynamic-forms-bootstrap 0.9.0-next.12 → 0.9.0-next.14

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,9 +1,9 @@
1
1
  import { AsyncPipe } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { input, computed, ChangeDetectionStrategy, Component, inject, ElementRef, Directive, InjectionToken, linkedSignal, model, isSignal } from '@angular/core';
4
- import { DynamicTextPipe, DEFAULT_PROPS, ARRAY_CONTEXT, buildBaseInputs } from '@ng-forge/dynamic-forms';
3
+ import { input, computed, ChangeDetectionStrategy, Component, inject, ElementRef, Directive, InjectionToken, signal, forwardRef, linkedSignal, model, isSignal } from '@angular/core';
4
+ import { DynamicTextPipe, runPresetAction, DfAddonSlot, FIELD_SIGNAL_CONTEXT, DynamicFormLogger, DEFAULT_PROPS, ARRAY_CONTEXT, buildBaseInputs, DynamicFormError, ADDON_KIND_DEFINITIONS } from '@ng-forge/dynamic-forms';
5
5
  import * as i1 from '@ng-forge/dynamic-forms/integration';
6
- import { injectNgForgeAction, NgForgeActionHost, injectNgForgeField, NgForgeControl, NgForgeFieldHost, isEqual, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, submitButtonFieldMapper, nextButtonFieldMapper, previousButtonFieldMapper, addArrayItemButtonMapper, prependArrayItemButtonMapper, insertArrayItemButtonMapper, removeArrayItemButtonMapper, popArrayItemButtonMapper, shiftArrayItemButtonMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
6
+ import { injectNgForgeAction, NgForgeActionHost, injectNgForgeField, NgForgeControl, NgForgeFieldHost, injectNgForgeAddons, ADDON_PRESET_HANDLER, NgForgeAddons, isEqual, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, submitButtonFieldMapper, nextButtonFieldMapper, previousButtonFieldMapper, addArrayItemButtonMapper, prependArrayItemButtonMapper, insertArrayItemButtonMapper, removeArrayItemButtonMapper, popArrayItemButtonMapper, shiftArrayItemButtonMapper, datepickerFieldMapper, injectNgForgeAddonAction, NgForgeAddonAction } from '@ng-forge/dynamic-forms/integration';
7
7
  import { FormField } from '@angular/forms/signals';
8
8
  import { explicitEffect } from 'ngxtension/explicit-effect';
9
9
 
@@ -35,8 +35,8 @@ class BsButtonFieldComponent {
35
35
  return;
36
36
  this.action.dispatch();
37
37
  }
38
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
39
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: BsButtonFieldComponent, isStandalone: true, selector: "df-bs-button", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeActionHost }], ngImport: i0, template: `
38
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
39
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: BsButtonFieldComponent, isStandalone: true, selector: "df-bs-button", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeActionHost }], ngImport: i0, template: `
40
40
  @let buttonId = action.key() + '-button';
41
41
  <button
42
42
  [id]="buttonId"
@@ -49,9 +49,9 @@ class BsButtonFieldComponent {
49
49
  >
50
50
  {{ action.label() | dynamicText | async }}
51
51
  </button>
52
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
52
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
53
53
  }
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsButtonFieldComponent, decorators: [{
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsButtonFieldComponent, decorators: [{
55
55
  type: Component,
56
56
  args: [{ selector: 'df-bs-button', imports: [DynamicTextPipe, AsyncPipe], hostDirectives: [NgForgeActionHost], template: `
57
57
  @let buttonId = action.key() + '-button';
@@ -66,7 +66,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
66
66
  >
67
67
  {{ action.label() | dynamicText | async }}
68
68
  </button>
69
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n"] }]
69
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n"] }]
70
70
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
71
71
 
72
72
  var bsButton_component = /*#__PURE__*/Object.freeze({
@@ -79,8 +79,8 @@ var bsButton_component = /*#__PURE__*/Object.freeze({
79
79
  class BsCheckboxFieldComponent {
80
80
  ngf = injectNgForgeField();
81
81
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
82
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
83
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsCheckboxFieldComponent, isStandalone: true, selector: "df-bs-checkbox", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
82
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
83
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsCheckboxFieldComponent, isStandalone: true, selector: "df-bs-checkbox", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
84
84
  @let f = ngf.field(); @let checkboxId = ngf.key() + '-checkbox';
85
85
 
86
86
  <div
@@ -110,9 +110,9 @@ class BsCheckboxFieldComponent {
110
110
  } @else if (props()?.hint; as hint) {
111
111
  <div class="form-text" [id]="ngf.hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
112
112
  }
113
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
113
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
114
114
  }
115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsCheckboxFieldComponent, decorators: [{
115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsCheckboxFieldComponent, decorators: [{
116
116
  type: Component,
117
117
  args: [{ selector: 'df-bs-checkbox', imports: [FormField, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
118
118
  @let f = ngf.field(); @let checkboxId = ngf.key() + '-checkbox';
@@ -144,7 +144,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
144
144
  } @else if (props()?.hint; as hint) {
145
145
  <div class="form-text" [id]="ngf.hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
146
146
  }
147
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
147
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
148
148
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
149
149
 
150
150
  var bsCheckbox_component = /*#__PURE__*/Object.freeze({
@@ -187,10 +187,10 @@ class InputConstraintsDirective {
187
187
  nativeElement.removeAttribute('step');
188
188
  }
189
189
  });
190
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: InputConstraintsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
191
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: InputConstraintsDirective, isStandalone: true, selector: "[dfBsInputConstraints]", inputs: { dfMin: { classPropertyName: "dfMin", publicName: "dfMin", isSignal: true, isRequired: false, transformFunction: null }, dfMax: { classPropertyName: "dfMax", publicName: "dfMax", isSignal: true, isRequired: false, transformFunction: null }, dfStep: { classPropertyName: "dfStep", publicName: "dfStep", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
190
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: InputConstraintsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
191
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: InputConstraintsDirective, isStandalone: true, selector: "[dfBsInputConstraints]", inputs: { dfMin: { classPropertyName: "dfMin", publicName: "dfMin", isSignal: true, isRequired: false, transformFunction: null }, dfMax: { classPropertyName: "dfMax", publicName: "dfMax", isSignal: true, isRequired: false, transformFunction: null }, dfStep: { classPropertyName: "dfStep", publicName: "dfStep", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
192
192
  }
193
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: InputConstraintsDirective, decorators: [{
193
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: InputConstraintsDirective, decorators: [{
194
194
  type: Directive,
195
195
  args: [{
196
196
  selector: '[dfBsInputConstraints]',
@@ -212,8 +212,8 @@ class BsDatepickerFieldComponent {
212
212
  const max = this.maxDate();
213
213
  return max instanceof Date ? max.toISOString().split('T')[0] : max;
214
214
  }, ...(ngDevMode ? [{ debugName: "maxAsString" }] : /* istanbul ignore next */ []));
215
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
216
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsDatepickerFieldComponent, isStandalone: true, selector: "df-bs-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 } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
215
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
216
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsDatepickerFieldComponent, isStandalone: true, selector: "df-bs-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 } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
217
217
  @let f = ngf.field(); @let p = props(); @let inputId = ngf.key() + '-input';
218
218
  @if (p?.floatingLabel) {
219
219
  <!-- Floating label variant -->
@@ -282,9 +282,9 @@ class BsDatepickerFieldComponent {
282
282
  }
283
283
  </div>
284
284
  }
285
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
285
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
286
286
  }
287
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsDatepickerFieldComponent, decorators: [{
287
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsDatepickerFieldComponent, decorators: [{
288
288
  type: Component,
289
289
  args: [{ selector: 'df-bs-datepicker', imports: [FormField, DynamicTextPipe, AsyncPipe, InputConstraintsDirective, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
290
290
  @let f = ngf.field(); @let p = props(); @let inputId = ngf.key() + '-input';
@@ -355,7 +355,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
355
355
  }
356
356
  </div>
357
357
  }
358
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
358
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
359
359
  }], 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 }] }] } });
360
360
 
361
361
  var bsDatepicker_component = /*#__PURE__*/Object.freeze({
@@ -386,34 +386,130 @@ var bsDatepicker_component = /*#__PURE__*/Object.freeze({
386
386
  */
387
387
  const BOOTSTRAP_CONFIG = new InjectionToken('BOOTSTRAP_CONFIG');
388
388
 
389
+ /** Bootstrap adapter binding for the shared preset runner. */
390
+ function runBsPresetAction(preset, ctx, collaborators) {
391
+ return runPresetAction(preset, ctx, collaborators, 'Bootstrap', 'bs-input');
392
+ }
393
+
394
+ /**
395
+ * Per-field writable signal that overrides the input's `type` attribute.
396
+ *
397
+ * Provided at the `bs-input` field component level. The button addon's
398
+ * `'toggle-password-visibility'` preset writes to it; the field component
399
+ * reads it to compute its effective `type`.
400
+ *
401
+ * Optional from a button's perspective — when the button is hosted inside a
402
+ * field that doesn't provide this token (e.g., textarea or a future
403
+ * non-input field), the toggle preset is a no-op.
404
+ */
405
+ const BS_INPUT_TYPE_OVERRIDE = new InjectionToken('BS_INPUT_TYPE_OVERRIDE');
406
+
389
407
  class BsInputFieldComponent {
390
408
  bootstrapConfig = inject(BOOTSTRAP_CONFIG, { optional: true });
391
409
  ngf = injectNgForgeField();
410
+ ngfa = injectNgForgeAddons();
392
411
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
412
+ /**
413
+ * Wrapper-style host bag pushed by `DfFieldOutlet`. Declared at the
414
+ * component level so `setInputIfDeclared` (which uses
415
+ * `reflectComponentType`) can write it.
416
+ */
417
+ fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
418
+ /** Per-instance type override populated by `toggle-password-visibility` preset. */
419
+ typeOverride = inject(BS_INPUT_TYPE_OVERRIDE);
393
420
  size = computed(() => this.props()?.size ?? this.bootstrapConfig?.size, ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
394
421
  floatingLabel = computed(() => this.props()?.floatingLabel ?? this.bootstrapConfig?.floatingLabel ?? false, ...(ngDevMode ? [{ debugName: "floatingLabel" }] : /* istanbul ignore next */ []));
395
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
396
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsInputFieldComponent, isStandalone: true, selector: "df-bs-input", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
422
+ /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */
423
+ type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
424
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
425
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsInputFieldComponent, isStandalone: true, selector: "df-bs-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: [
426
+ {
427
+ provide: BS_INPUT_TYPE_OVERRIDE,
428
+ useFactory: () => signal(undefined),
429
+ },
430
+ {
431
+ // Adapter-specific preset semantics for `bs-button` addons (clear /
432
+ // reset / paste / copy / toggle-password-visibility). The directive
433
+ // (`NgForgeAddonAction`) delegates here when an addon configures a
434
+ // `preset`. Per-bs-input-instance so the `typeOverride` signal is
435
+ // scoped to one field.
436
+ provide: ADDON_PRESET_HANDLER,
437
+ useFactory: () => {
438
+ const typeOverride = inject(BS_INPUT_TYPE_OVERRIDE);
439
+ const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
440
+ const logger = inject(DynamicFormLogger);
441
+ // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.
442
+ const host = inject(forwardRef(() => BsInputFieldComponent));
443
+ return {
444
+ run: (preset, ctx) => {
445
+ const fieldKey = ctx.field.key;
446
+ return runBsPresetAction(preset, ctx, {
447
+ typeOverride,
448
+ fieldValueSetter: ctx.setValue,
449
+ fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : undefined,
450
+ baselineType: () => host.props()?.type,
451
+ logger,
452
+ });
453
+ },
454
+ };
455
+ },
456
+ },
457
+ ], hostDirectives: [{ directive: i1.NgForgeFieldHost }, { directive: i1.NgForgeAddons }], ngImport: i0, template: `
397
458
  @let f = ngf.field(); @let p = props(); @let inputId = ngf.key() + '-input';
398
459
  @if (floatingLabel()) {
399
- <!-- Floating label variant -->
400
- <div class="form-floating mb-3">
401
- <input
402
- ngForgeControl
403
- [formField]="f"
404
- [id]="inputId"
405
- [type]="p?.type ?? 'text'"
406
- [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
407
- [attr.tabindex]="ngf.tabIndex()"
408
- class="form-control"
409
- [class.form-control-sm]="size() === 'sm'"
410
- [class.form-control-lg]="size() === 'lg'"
411
- [class.form-control-plaintext]="p?.plaintext"
412
- [class.is-invalid]="f().invalid() && f().touched()"
413
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
414
- />
415
- @if (ngf.label()) {
416
- <label [for]="inputId">{{ ngf.label() | dynamicText | async }}</label>
460
+ <div class="mb-3">
461
+ @if (ngfa.hasAddons()) {
462
+ <div class="input-group">
463
+ @for (a of ngfa.prefixAddons(); track $index) {
464
+ <span class="input-group-text">
465
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
466
+ </span>
467
+ }
468
+ <div class="form-floating">
469
+ <input
470
+ ngForgeControl
471
+ [formField]="f"
472
+ [id]="inputId"
473
+ [type]="type()"
474
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
475
+ [attr.tabindex]="ngf.tabIndex()"
476
+ class="form-control"
477
+ [class.form-control-sm]="size() === 'sm'"
478
+ [class.form-control-lg]="size() === 'lg'"
479
+ [class.form-control-plaintext]="p?.plaintext"
480
+ [class.is-invalid]="f().invalid() && f().touched()"
481
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
482
+ />
483
+ @if (ngf.label()) {
484
+ <label [for]="inputId">{{ ngf.label() | dynamicText | async }}</label>
485
+ }
486
+ </div>
487
+ @for (a of ngfa.suffixAddons(); track $index) {
488
+ <span class="input-group-text">
489
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
490
+ </span>
491
+ }
492
+ </div>
493
+ } @else {
494
+ <div class="form-floating">
495
+ <input
496
+ ngForgeControl
497
+ [formField]="f"
498
+ [id]="inputId"
499
+ [type]="type()"
500
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
501
+ [attr.tabindex]="ngf.tabIndex()"
502
+ class="form-control"
503
+ [class.form-control-sm]="size() === 'sm'"
504
+ [class.form-control-lg]="size() === 'lg'"
505
+ [class.form-control-plaintext]="p?.plaintext"
506
+ [class.is-invalid]="f().invalid() && f().touched()"
507
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
508
+ />
509
+ @if (ngf.label()) {
510
+ <label [for]="inputId">{{ ngf.label() | dynamicText | async }}</label>
511
+ }
512
+ </div>
417
513
  }
418
514
  @if (p?.validFeedback && f().valid() && f().touched()) {
419
515
  <div class="valid-feedback d-block">
@@ -425,25 +521,53 @@ class BsInputFieldComponent {
425
521
  }
426
522
  </div>
427
523
  } @else {
428
- <!-- Standard variant -->
429
524
  <div class="mb-3">
430
525
  @if (ngf.label()) {
431
526
  <label [for]="inputId" class="form-label">{{ ngf.label() | dynamicText | async }}</label>
432
527
  }
433
- <input
434
- ngForgeControl
435
- [formField]="f"
436
- [id]="inputId"
437
- [type]="p?.type ?? 'text'"
438
- [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
439
- [attr.tabindex]="ngf.tabIndex()"
440
- class="form-control"
441
- [class.form-control-sm]="size() === 'sm'"
442
- [class.form-control-lg]="size() === 'lg'"
443
- [class.form-control-plaintext]="p?.plaintext"
444
- [class.is-invalid]="f().invalid() && f().touched()"
445
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
446
- />
528
+ @if (ngfa.hasAddons()) {
529
+ <div class="input-group">
530
+ @for (a of ngfa.prefixAddons(); track $index) {
531
+ <span class="input-group-text">
532
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
533
+ </span>
534
+ }
535
+ <input
536
+ ngForgeControl
537
+ [formField]="f"
538
+ [id]="inputId"
539
+ [type]="type()"
540
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
541
+ [attr.tabindex]="ngf.tabIndex()"
542
+ class="form-control"
543
+ [class.form-control-sm]="size() === 'sm'"
544
+ [class.form-control-lg]="size() === 'lg'"
545
+ [class.form-control-plaintext]="p?.plaintext"
546
+ [class.is-invalid]="f().invalid() && f().touched()"
547
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
548
+ />
549
+ @for (a of ngfa.suffixAddons(); track $index) {
550
+ <span class="input-group-text">
551
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
552
+ </span>
553
+ }
554
+ </div>
555
+ } @else {
556
+ <input
557
+ ngForgeControl
558
+ [formField]="f"
559
+ [id]="inputId"
560
+ [type]="type()"
561
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
562
+ [attr.tabindex]="ngf.tabIndex()"
563
+ class="form-control"
564
+ [class.form-control-sm]="size() === 'sm'"
565
+ [class.form-control-lg]="size() === 'lg'"
566
+ [class.form-control-plaintext]="p?.plaintext"
567
+ [class.is-invalid]="f().invalid() && f().touched()"
568
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
569
+ />
570
+ }
447
571
  @if (p?.validFeedback && f().valid() && f().touched()) {
448
572
  <div class="valid-feedback d-block">
449
573
  {{ p?.validFeedback | dynamicText | async }}
@@ -456,31 +580,66 @@ class BsInputFieldComponent {
456
580
  }
457
581
  </div>
458
582
  }
459
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
583
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}:host{--df-bs-addon-prefix-outer-padding: .75rem;--df-bs-addon-prefix-inner-padding: .75rem;--df-bs-addon-suffix-inner-padding: .75rem;--df-bs-addon-suffix-outer-padding: .75rem}:host ::ng-deep .input-group>.input-group-text:first-child{padding-left:var(--df-bs-addon-prefix-outer-padding);padding-right:var(--df-bs-addon-prefix-inner-padding)}:host ::ng-deep .input-group>.input-group-text:last-child{padding-left:var(--df-bs-addon-suffix-inner-padding);padding-right:var(--df-bs-addon-suffix-outer-padding)}:host ::ng-deep .input-group-text df-bs-button-addon .btn{--bs-btn-bg: transparent;--bs-btn-color: var(--bs-body-color);--bs-btn-border-color: transparent;--bs-btn-hover-bg: rgba(127, 127, 127, .12);--bs-btn-hover-color: var(--bs-body-color);--bs-btn-hover-border-color: transparent;--bs-btn-active-bg: rgba(127, 127, 127, .18);--bs-btn-active-border-color: transparent;--bs-btn-focus-shadow-rgb: 0, 0, 0;--bs-btn-padding-x: 0;--bs-btn-padding-y: 0;box-shadow:none}:host ::ng-deep .input-group-text df-bs-button-addon .btn:focus-visible{box-shadow:none;outline:2px solid currentColor;outline-offset:2px}\n"], dependencies: [{ 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 });
460
584
  }
461
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsInputFieldComponent, decorators: [{
585
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsInputFieldComponent, decorators: [{
462
586
  type: Component,
463
- args: [{ selector: 'df-bs-input', imports: [FormField, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
587
+ args: [{ selector: 'df-bs-input', imports: [FormField, DynamicTextPipe, AsyncPipe, NgForgeControl, DfAddonSlot], hostDirectives: [NgForgeFieldHost, NgForgeAddons], template: `
464
588
  @let f = ngf.field(); @let p = props(); @let inputId = ngf.key() + '-input';
465
589
  @if (floatingLabel()) {
466
- <!-- Floating label variant -->
467
- <div class="form-floating mb-3">
468
- <input
469
- ngForgeControl
470
- [formField]="f"
471
- [id]="inputId"
472
- [type]="p?.type ?? 'text'"
473
- [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
474
- [attr.tabindex]="ngf.tabIndex()"
475
- class="form-control"
476
- [class.form-control-sm]="size() === 'sm'"
477
- [class.form-control-lg]="size() === 'lg'"
478
- [class.form-control-plaintext]="p?.plaintext"
479
- [class.is-invalid]="f().invalid() && f().touched()"
480
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
481
- />
482
- @if (ngf.label()) {
483
- <label [for]="inputId">{{ ngf.label() | dynamicText | async }}</label>
590
+ <div class="mb-3">
591
+ @if (ngfa.hasAddons()) {
592
+ <div class="input-group">
593
+ @for (a of ngfa.prefixAddons(); track $index) {
594
+ <span class="input-group-text">
595
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
596
+ </span>
597
+ }
598
+ <div class="form-floating">
599
+ <input
600
+ ngForgeControl
601
+ [formField]="f"
602
+ [id]="inputId"
603
+ [type]="type()"
604
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
605
+ [attr.tabindex]="ngf.tabIndex()"
606
+ class="form-control"
607
+ [class.form-control-sm]="size() === 'sm'"
608
+ [class.form-control-lg]="size() === 'lg'"
609
+ [class.form-control-plaintext]="p?.plaintext"
610
+ [class.is-invalid]="f().invalid() && f().touched()"
611
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
612
+ />
613
+ @if (ngf.label()) {
614
+ <label [for]="inputId">{{ ngf.label() | dynamicText | async }}</label>
615
+ }
616
+ </div>
617
+ @for (a of ngfa.suffixAddons(); track $index) {
618
+ <span class="input-group-text">
619
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
620
+ </span>
621
+ }
622
+ </div>
623
+ } @else {
624
+ <div class="form-floating">
625
+ <input
626
+ ngForgeControl
627
+ [formField]="f"
628
+ [id]="inputId"
629
+ [type]="type()"
630
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
631
+ [attr.tabindex]="ngf.tabIndex()"
632
+ class="form-control"
633
+ [class.form-control-sm]="size() === 'sm'"
634
+ [class.form-control-lg]="size() === 'lg'"
635
+ [class.form-control-plaintext]="p?.plaintext"
636
+ [class.is-invalid]="f().invalid() && f().touched()"
637
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
638
+ />
639
+ @if (ngf.label()) {
640
+ <label [for]="inputId">{{ ngf.label() | dynamicText | async }}</label>
641
+ }
642
+ </div>
484
643
  }
485
644
  @if (p?.validFeedback && f().valid() && f().touched()) {
486
645
  <div class="valid-feedback d-block">
@@ -492,25 +651,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
492
651
  }
493
652
  </div>
494
653
  } @else {
495
- <!-- Standard variant -->
496
654
  <div class="mb-3">
497
655
  @if (ngf.label()) {
498
656
  <label [for]="inputId" class="form-label">{{ ngf.label() | dynamicText | async }}</label>
499
657
  }
500
- <input
501
- ngForgeControl
502
- [formField]="f"
503
- [id]="inputId"
504
- [type]="p?.type ?? 'text'"
505
- [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
506
- [attr.tabindex]="ngf.tabIndex()"
507
- class="form-control"
508
- [class.form-control-sm]="size() === 'sm'"
509
- [class.form-control-lg]="size() === 'lg'"
510
- [class.form-control-plaintext]="p?.plaintext"
511
- [class.is-invalid]="f().invalid() && f().touched()"
512
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
513
- />
658
+ @if (ngfa.hasAddons()) {
659
+ <div class="input-group">
660
+ @for (a of ngfa.prefixAddons(); track $index) {
661
+ <span class="input-group-text">
662
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
663
+ </span>
664
+ }
665
+ <input
666
+ ngForgeControl
667
+ [formField]="f"
668
+ [id]="inputId"
669
+ [type]="type()"
670
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
671
+ [attr.tabindex]="ngf.tabIndex()"
672
+ class="form-control"
673
+ [class.form-control-sm]="size() === 'sm'"
674
+ [class.form-control-lg]="size() === 'lg'"
675
+ [class.form-control-plaintext]="p?.plaintext"
676
+ [class.is-invalid]="f().invalid() && f().touched()"
677
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
678
+ />
679
+ @for (a of ngfa.suffixAddons(); track $index) {
680
+ <span class="input-group-text">
681
+ <df-addon-slot [addon]="a" [fieldInputs]="fieldInputs()" [hidden]="ngfa.hiddenSignalCache().get(a)" />
682
+ </span>
683
+ }
684
+ </div>
685
+ } @else {
686
+ <input
687
+ ngForgeControl
688
+ [formField]="f"
689
+ [id]="inputId"
690
+ [type]="type()"
691
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
692
+ [attr.tabindex]="ngf.tabIndex()"
693
+ class="form-control"
694
+ [class.form-control-sm]="size() === 'sm'"
695
+ [class.form-control-lg]="size() === 'lg'"
696
+ [class.form-control-plaintext]="p?.plaintext"
697
+ [class.is-invalid]="f().invalid() && f().touched()"
698
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
699
+ />
700
+ }
514
701
  @if (p?.validFeedback && f().valid() && f().touched()) {
515
702
  <div class="valid-feedback d-block">
516
703
  {{ p?.validFeedback | dynamicText | async }}
@@ -523,8 +710,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
523
710
  }
524
711
  </div>
525
712
  }
526
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
527
- }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
713
+ `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
714
+ {
715
+ provide: BS_INPUT_TYPE_OVERRIDE,
716
+ useFactory: () => signal(undefined),
717
+ },
718
+ {
719
+ // Adapter-specific preset semantics for `bs-button` addons (clear /
720
+ // reset / paste / copy / toggle-password-visibility). The directive
721
+ // (`NgForgeAddonAction`) delegates here when an addon configures a
722
+ // `preset`. Per-bs-input-instance so the `typeOverride` signal is
723
+ // scoped to one field.
724
+ provide: ADDON_PRESET_HANDLER,
725
+ useFactory: () => {
726
+ const typeOverride = inject(BS_INPUT_TYPE_OVERRIDE);
727
+ const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
728
+ const logger = inject(DynamicFormLogger);
729
+ // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.
730
+ const host = inject(forwardRef(() => BsInputFieldComponent));
731
+ return {
732
+ run: (preset, ctx) => {
733
+ const fieldKey = ctx.field.key;
734
+ return runBsPresetAction(preset, ctx, {
735
+ typeOverride,
736
+ fieldValueSetter: ctx.setValue,
737
+ fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : undefined,
738
+ baselineType: () => host.props()?.type,
739
+ logger,
740
+ });
741
+ },
742
+ };
743
+ },
744
+ },
745
+ ], styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}:host{--df-bs-addon-prefix-outer-padding: .75rem;--df-bs-addon-prefix-inner-padding: .75rem;--df-bs-addon-suffix-inner-padding: .75rem;--df-bs-addon-suffix-outer-padding: .75rem}:host ::ng-deep .input-group>.input-group-text:first-child{padding-left:var(--df-bs-addon-prefix-outer-padding);padding-right:var(--df-bs-addon-prefix-inner-padding)}:host ::ng-deep .input-group>.input-group-text:last-child{padding-left:var(--df-bs-addon-suffix-inner-padding);padding-right:var(--df-bs-addon-suffix-outer-padding)}:host ::ng-deep .input-group-text df-bs-button-addon .btn{--bs-btn-bg: transparent;--bs-btn-color: var(--bs-body-color);--bs-btn-border-color: transparent;--bs-btn-hover-bg: rgba(127, 127, 127, .12);--bs-btn-hover-color: var(--bs-body-color);--bs-btn-hover-border-color: transparent;--bs-btn-active-bg: rgba(127, 127, 127, .18);--bs-btn-active-border-color: transparent;--bs-btn-focus-shadow-rgb: 0, 0, 0;--bs-btn-padding-x: 0;--bs-btn-padding-y: 0;box-shadow:none}:host ::ng-deep .input-group-text df-bs-button-addon .btn:focus-visible{box-shadow:none;outline:2px solid currentColor;outline-offset:2px}\n"] }]
746
+ }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
528
747
 
529
748
  var bsInput_component = /*#__PURE__*/Object.freeze({
530
749
  __proto__: null,
@@ -576,8 +795,8 @@ class BsMultiCheckboxFieldComponent {
576
795
  }
577
796
  });
578
797
  }
579
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
580
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsMultiCheckboxFieldComponent, isStandalone: true, selector: "df-bs-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: `
798
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
799
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsMultiCheckboxFieldComponent, isStandalone: true, selector: "df-bs-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: `
581
800
  @let f = ngf.field();
582
801
  @let checked = checkedValuesMap();
583
802
  @if (ngf.label(); as label) {
@@ -615,9 +834,9 @@ class BsMultiCheckboxFieldComponent {
615
834
  } @else if (props()?.hint; as hint) {
616
835
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
617
836
  }
618
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}.checkbox-group{margin-bottom:.5rem}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
837
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}.checkbox-group{margin-bottom:.5rem}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
619
838
  }
620
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsMultiCheckboxFieldComponent, decorators: [{
839
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsMultiCheckboxFieldComponent, decorators: [{
621
840
  type: Component,
622
841
  args: [{ selector: 'df-bs-multi-checkbox', imports: [DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
623
842
  @let f = ngf.field();
@@ -657,7 +876,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
657
876
  } @else if (props()?.hint; as hint) {
658
877
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
659
878
  }
660
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}.checkbox-group{margin-bottom:.5rem}:host([hidden]){display:none!important}\n"] }]
879
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}.checkbox-group{margin-bottom:.5rem}:host([hidden]){display:none!important}\n"] }]
661
880
  }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
662
881
 
663
882
  var bsMultiCheckbox_component = /*#__PURE__*/Object.freeze({
@@ -689,8 +908,8 @@ class BsRadioGroupComponent {
689
908
  this.value.set(newValue);
690
909
  }
691
910
  }
692
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsRadioGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
693
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsRadioGroupComponent, isStandalone: true, selector: "df-bs-radio-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
911
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsRadioGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
912
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsRadioGroupComponent, isStandalone: true, selector: "df-bs-radio-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
694
913
  @let props = properties();
695
914
  @if (props?.buttonGroup) {
696
915
  <div class="btn-group" role="group" [attr.aria-label]="label() | dynamicText | async">
@@ -739,7 +958,7 @@ class BsRadioGroupComponent {
739
958
  }
740
959
  `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
741
960
  }
742
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsRadioGroupComponent, decorators: [{
961
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsRadioGroupComponent, decorators: [{
743
962
  type: Component,
744
963
  args: [{ selector: 'df-bs-radio-group', imports: [DynamicTextPipe, AsyncPipe, NgForgeControl], template: `
745
964
  @let props = properties();
@@ -795,8 +1014,8 @@ class BsRadioFieldComponent {
795
1014
  ngf = injectNgForgeField();
796
1015
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
797
1016
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
798
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
799
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsRadioFieldComponent, isStandalone: true, selector: "df-bs-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: `
1017
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1018
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsRadioFieldComponent, isStandalone: true, selector: "df-bs-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: `
800
1019
  @let f = ngf.field();
801
1020
 
802
1021
  <div class="mb-3">
@@ -812,9 +1031,9 @@ class BsRadioFieldComponent {
812
1031
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
813
1032
  }
814
1033
  </div>
815
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: BsRadioGroupComponent, selector: "df-bs-radio-group", inputs: ["value", "disabled", "readonly", "name", "label", "options", "properties"], outputs: ["valueChange"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1034
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: BsRadioGroupComponent, selector: "df-bs-radio-group", inputs: ["value", "disabled", "readonly", "name", "label", "options", "properties"], outputs: ["valueChange"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
816
1035
  }
817
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsRadioFieldComponent, decorators: [{
1036
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsRadioFieldComponent, decorators: [{
818
1037
  type: Component,
819
1038
  args: [{ selector: 'df-bs-radio', imports: [BsRadioGroupComponent, FormField, DynamicTextPipe, AsyncPipe], hostDirectives: [NgForgeFieldHost], template: `
820
1039
  @let f = ngf.field();
@@ -832,7 +1051,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
832
1051
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
833
1052
  }
834
1053
  </div>
835
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1054
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
836
1055
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
837
1056
 
838
1057
  var bsRadio_component = /*#__PURE__*/Object.freeze({
@@ -852,8 +1071,8 @@ class BsSelectFieldComponent {
852
1071
  }
853
1072
  return fieldValue !== null && compareWith(fieldValue, optionValue);
854
1073
  }
855
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
856
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsSelectFieldComponent, isStandalone: true, selector: "df-bs-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: `
1074
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1075
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsSelectFieldComponent, isStandalone: true, selector: "df-bs-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: `
857
1076
  @let f = ngf.field(); @let selectId = ngf.key() + '-select';
858
1077
 
859
1078
  <div class="mb-3">
@@ -888,9 +1107,9 @@ class BsSelectFieldComponent {
888
1107
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
889
1108
  }
890
1109
  </div>
891
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
1110
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
892
1111
  }
893
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsSelectFieldComponent, decorators: [{
1112
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsSelectFieldComponent, decorators: [{
894
1113
  type: Component,
895
1114
  args: [{ selector: 'df-bs-select', imports: [FormField, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
896
1115
  @let f = ngf.field(); @let selectId = ngf.key() + '-select';
@@ -927,7 +1146,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
927
1146
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
928
1147
  }
929
1148
  </div>
930
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
1149
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
931
1150
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
932
1151
 
933
1152
  var bsSelect_component = /*#__PURE__*/Object.freeze({
@@ -941,8 +1160,8 @@ class BsSliderFieldComponent {
941
1160
  max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
942
1161
  step = input(...(ngDevMode ? [undefined, { debugName: "step" }] : /* istanbul ignore next */ []));
943
1162
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
944
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
945
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsSliderFieldComponent, isStandalone: true, selector: "df-bs-slider", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, 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: `
1163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1164
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsSliderFieldComponent, isStandalone: true, selector: "df-bs-slider", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, 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: `
946
1165
  @let f = ngf.field(); @let inputId = ngf.key() + '-input';
947
1166
 
948
1167
  <div class="mb-3">
@@ -974,9 +1193,9 @@ class BsSliderFieldComponent {
974
1193
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
975
1194
  }
976
1195
  </div>
977
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1196
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
978
1197
  }
979
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsSliderFieldComponent, decorators: [{
1198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsSliderFieldComponent, decorators: [{
980
1199
  type: Component,
981
1200
  args: [{ selector: 'df-bs-slider', imports: [FormField, DynamicTextPipe, AsyncPipe, InputConstraintsDirective, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
982
1201
  @let f = ngf.field(); @let inputId = ngf.key() + '-input';
@@ -1010,7 +1229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1010
1229
  <div class="form-text" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</div>
1011
1230
  }
1012
1231
  </div>
1013
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1232
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1014
1233
  }], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
1015
1234
 
1016
1235
  var bsSlider_component = /*#__PURE__*/Object.freeze({
@@ -1021,8 +1240,8 @@ var bsSlider_component = /*#__PURE__*/Object.freeze({
1021
1240
  class BsTextareaFieldComponent {
1022
1241
  ngf = injectNgForgeField();
1023
1242
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
1024
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1025
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsTextareaFieldComponent, isStandalone: true, selector: "df-bs-textarea", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
1243
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1244
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsTextareaFieldComponent, isStandalone: true, selector: "df-bs-textarea", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
1026
1245
  @let f = ngf.field(); @let p = props(); @let textareaId = ngf.key() + '-textarea';
1027
1246
  @if (p?.floatingLabel) {
1028
1247
  <!-- Floating label variant -->
@@ -1086,9 +1305,9 @@ class BsTextareaFieldComponent {
1086
1305
  }
1087
1306
  </div>
1088
1307
  }
1089
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
1308
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ 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 });
1090
1309
  }
1091
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsTextareaFieldComponent, decorators: [{
1310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsTextareaFieldComponent, decorators: [{
1092
1311
  type: Component,
1093
1312
  args: [{ selector: 'df-bs-textarea', imports: [FormField, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
1094
1313
  @let f = ngf.field(); @let p = props(); @let textareaId = ngf.key() + '-textarea';
@@ -1154,7 +1373,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1154
1373
  }
1155
1374
  </div>
1156
1375
  }
1157
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
1376
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}\n"] }]
1158
1377
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
1159
1378
 
1160
1379
  var bsTextarea_component = /*#__PURE__*/Object.freeze({
@@ -1165,8 +1384,8 @@ var bsTextarea_component = /*#__PURE__*/Object.freeze({
1165
1384
  class BsToggleFieldComponent {
1166
1385
  ngf = injectNgForgeField();
1167
1386
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
1168
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1169
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: BsToggleFieldComponent, isStandalone: true, selector: "df-bs-toggle", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
1387
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1388
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsToggleFieldComponent, isStandalone: true, selector: "df-bs-toggle", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
1170
1389
  @let f = ngf.field(); @let inputId = ngf.key() + '-input';
1171
1390
 
1172
1391
  <div
@@ -1196,9 +1415,9 @@ class BsToggleFieldComponent {
1196
1415
  } @else if (props()?.hint; as hint) {
1197
1416
  <div class="form-text" [id]="ngf.hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
1198
1417
  }
1199
- `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}.form-switch-sm .form-check-input{width:1.75rem;height:1rem;font-size:.875rem}.form-switch-lg .form-check-input{width:3rem;height:1.75rem;font-size:1.125rem}\n"], dependencies: [{ 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 });
1418
+ `, isInline: true, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}.form-switch-sm .form-check-input{width:1.75rem;height:1rem;font-size:.875rem}.form-switch-lg .form-check-input{width:3rem;height:1.75rem;font-size:1.125rem}\n"], dependencies: [{ 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 });
1200
1419
  }
1201
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BsToggleFieldComponent, decorators: [{
1420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsToggleFieldComponent, decorators: [{
1202
1421
  type: Component,
1203
1422
  args: [{ selector: 'df-bs-toggle', imports: [FormField, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
1204
1423
  @let f = ngf.field(); @let inputId = ngf.key() + '-input';
@@ -1230,7 +1449,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1230
1449
  } @else if (props()?.hint; as hint) {
1231
1450
  <div class="form-text" [id]="ngf.hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
1232
1451
  }
1233
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--bs-secondary-color, #6c757d);--df-hint-font-size: .875rem;--df-error-color: var(--bs-danger, #dc3545);--df-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}.form-switch-sm .form-check-input{width:1.75rem;height:1rem;font-size:.875rem}.form-switch-lg .form-check-input{width:3rem;height:1.75rem;font-size:1.125rem}\n"] }]
1452
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-bs-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%;margin-bottom:var(--df-bs-field-margin-bottom, 1rem)}.df-bs-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit);margin-bottom:0}.df-bs-hint{color:var(--df-hint-color, var(--bs-secondary-color, #6c757d));font-size:var(--df-hint-font-size, .875rem);margin-top:var(--df-bs-hint-margin-top, .25rem)}.df-bs-field:has(.df-bs-hint){margin-bottom:var(--df-bs-field-with-hint-margin-bottom, .5rem)}:host([hidden]){display:none!important}\n", ":host{display:block}:host([hidden]){display:none!important}.form-switch-sm .form-check-input{width:1.75rem;height:1rem;font-size:.875rem}.form-switch-lg .form-check-input{width:3rem;height:1.75rem;font-size:1.125rem}\n"] }]
1234
1453
  }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
1235
1454
 
1236
1455
  var bsToggle_component = /*#__PURE__*/Object.freeze({
@@ -1341,6 +1560,9 @@ const BOOTSTRAP_FIELD_TYPES = [
1341
1560
  mapper: valueFieldMapper,
1342
1561
  propsToMeta: ['type'],
1343
1562
  scope: ['text-input', 'numeric'],
1563
+ addons: {
1564
+ slots: ['prefix', 'suffix'],
1565
+ },
1344
1566
  ...VALUE_FIELD_TYPES_BASE,
1345
1567
  },
1346
1568
  {
@@ -1469,19 +1691,187 @@ const BOOTSTRAP_FIELD_TYPES = [
1469
1691
  */
1470
1692
 
1471
1693
  function withBootstrapFields(config) {
1472
- if (!config) {
1473
- return BOOTSTRAP_FIELD_TYPES;
1474
- }
1475
- const fieldsWithConfig = [
1476
- ...BOOTSTRAP_FIELD_TYPES,
1477
- {
1694
+ // Always include the addons feature — bs-icon / bs-button are part of
1695
+ // the canonical Bootstrap surface.
1696
+ const base = [...BOOTSTRAP_FIELD_TYPES, withBootstrapAddons()];
1697
+ if (config) {
1698
+ base.push({
1478
1699
  ɵkind: 'bootstrap-config',
1479
1700
  ɵproviders: [{ provide: BOOTSTRAP_CONFIG, useValue: config }],
1480
- },
1481
- ];
1482
- // Safe: this preserves all bootstrap field definitions and appends exactly one config feature.
1483
- return fieldsWithConfig;
1701
+ });
1702
+ return base;
1703
+ }
1704
+ return base;
1484
1705
  }
1706
+ /* -- Bootstrap addon kinds --------------------------------------------- */
1707
+ const BS_ICON_KIND = {
1708
+ kind: 'bs-icon',
1709
+ loadComponent: () => Promise.resolve().then(function () { return bsIconAddon_component; }).then((m) => m.BsIconAddonComponent),
1710
+ validate: (addon, fieldKey) => {
1711
+ if (typeof addon.icon !== 'string' || addon.icon.length === 0) {
1712
+ throw new DynamicFormError(`Addon kind 'bs-icon' requires a non-empty 'icon' string (field: '${fieldKey}').`);
1713
+ }
1714
+ },
1715
+ };
1716
+ const BS_BUTTON_KIND = {
1717
+ kind: 'bs-button',
1718
+ loadComponent: () => Promise.resolve().then(function () { return bsButtonAddon_component; }).then((m) => m.BsButtonAddonComponent),
1719
+ validate: (addon, fieldKey) => {
1720
+ // Exactly one of preset / actionRef / action — validator drops the addon
1721
+ // (with warning) if the rule is violated.
1722
+ const set = [addon.preset, addon.actionRef, addon.action].filter((v) => v !== undefined);
1723
+ if (set.length > 1) {
1724
+ throw new DynamicFormError(`Addon kind 'bs-button' on field '${fieldKey}' has more than one of preset/actionRef/action — exactly one allowed.`);
1725
+ }
1726
+ // Icon-only buttons require ariaLabel for screen readers.
1727
+ if (addon.icon && !addon.label && !addon.ariaLabel) {
1728
+ throw new DynamicFormError(`Addon kind 'bs-button' on field '${fieldKey}' is icon-only — provide 'ariaLabel' for accessibility.`);
1729
+ }
1730
+ },
1731
+ };
1732
+ /**
1733
+ * Register Bootstrap-shipped addon kinds (`bs-icon`, `bs-button`) standalone.
1734
+ *
1735
+ * **Most users don't need this** — `withBootstrapFields()` auto-includes
1736
+ * these kinds. Call `withBootstrapAddons()` directly only when you want
1737
+ * Bootstrap addon kinds without the Bootstrap field types (e.g., a custom
1738
+ * field set that wants to render `bs-icon` prefixes), or when you're
1739
+ * stitching addons through a different DI scope.
1740
+ *
1741
+ * @example
1742
+ * ```typescript
1743
+ * // Custom field types + Bootstrap addon kinds.
1744
+ * provideDynamicForm(
1745
+ * ...myCustomFields(),
1746
+ * withBootstrapAddons(),
1747
+ * );
1748
+ * ```
1749
+ *
1750
+ * Adapter authors who need to override a kind with a customised renderer
1751
+ * should call `withCustomAddon(...)` directly instead.
1752
+ */
1753
+ function withBootstrapAddons() {
1754
+ return {
1755
+ ɵkind: 'addons',
1756
+ ɵproviders: [
1757
+ { provide: ADDON_KIND_DEFINITIONS, useValue: BS_ICON_KIND, multi: true },
1758
+ { provide: ADDON_KIND_DEFINITIONS, useValue: BS_BUTTON_KIND, multi: true },
1759
+ ],
1760
+ };
1761
+ }
1762
+
1763
+ /**
1764
+ * Renderer for the `bs-icon` addon kind.
1765
+ *
1766
+ * Outputs `<i class="bi bi-{icon}">`. The host is set `aria-hidden="true"`
1767
+ * by default; if the addon supplies an `ariaLabel`, it is applied so the
1768
+ * icon is announced by screen readers.
1769
+ */
1770
+ class BsIconAddonComponent {
1771
+ addon = input.required(...(ngDevMode ? [{ debugName: "addon" }] : /* istanbul ignore next */ []));
1772
+ /** Accepted for contract uniformity — `NgComponentOutlet` setInput is strict; every kind must declare it. */
1773
+ fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
1774
+ iconClass = computed(() => `bi bi-${this.addon().icon}`, ...(ngDevMode ? [{ debugName: "iconClass" }] : /* istanbul ignore next */ []));
1775
+ ariaLabel = computed(() => this.addon().ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1776
+ hasAriaLabel = computed(() => this.addon().ariaLabel !== undefined, ...(ngDevMode ? [{ debugName: "hasAriaLabel" }] : /* istanbul ignore next */ []));
1777
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsIconAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1778
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: BsIconAddonComponent, isStandalone: true, selector: "df-bs-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: `<i [class]="iconClass()" [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"></i>`, isInline: true, dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1779
+ }
1780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsIconAddonComponent, decorators: [{
1781
+ type: Component,
1782
+ args: [{
1783
+ selector: 'df-bs-icon-addon',
1784
+ imports: [AsyncPipe, DynamicTextPipe],
1785
+ template: `<i [class]="iconClass()" [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"></i>`,
1786
+ host: {
1787
+ '[attr.aria-hidden]': 'hasAriaLabel() ? null : "true"',
1788
+ },
1789
+ changeDetection: ChangeDetectionStrategy.OnPush,
1790
+ }]
1791
+ }], propDecorators: { addon: [{ type: i0.Input, args: [{ isSignal: true, alias: "addon", required: true }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
1792
+
1793
+ var bsIconAddon_component = /*#__PURE__*/Object.freeze({
1794
+ __proto__: null,
1795
+ BsIconAddonComponent: BsIconAddonComponent
1796
+ });
1797
+
1798
+ /**
1799
+ * Renderer for the `bs-button` addon kind.
1800
+ *
1801
+ * Renders a Bootstrap `btn-outline-{severity}` button. Click dispatch
1802
+ * (preset / actionRef / action precedence, multi-set warning, `disabled` /
1803
+ * `loading` resolution) lives on `NgForgeAddonAction`; this component
1804
+ * focuses on the visual layer.
1805
+ */
1806
+ class BsButtonAddonComponent {
1807
+ action = injectNgForgeAddonAction();
1808
+ /** Re-exposed for template binding — same signal stored on the directive. */
1809
+ addon = this.action.addon;
1810
+ label = computed(() => this.addon().label, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1811
+ ariaLabel = computed(() => this.addon().ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1812
+ iconClass = computed(() => {
1813
+ const icon = this.addon().icon;
1814
+ return icon ? `bi bi-${icon}` : '';
1815
+ }, ...(ngDevMode ? [{ debugName: "iconClass" }] : /* istanbul ignore next */ []));
1816
+ buttonClass = computed(() => `btn btn-outline-${this.addon().severity ?? 'secondary'}`, ...(ngDevMode ? [{ debugName: "buttonClass" }] : /* istanbul ignore next */ []));
1817
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsButtonAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1818
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: BsButtonAddonComponent, isStandalone: true, selector: "df-bs-button-addon", hostDirectives: [{ directive: i1.NgForgeAddonAction }], ngImport: i0, template: `
1819
+ <button
1820
+ type="button"
1821
+ [class]="buttonClass()"
1822
+ [disabled]="action.disabled() || action.loading()"
1823
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
1824
+ [attr.aria-busy]="action.loading() || null"
1825
+ (click)="action.dispatch()"
1826
+ >
1827
+ @if (action.loading()) {
1828
+ <!-- Visually-hidden role=status text gives a reliable AT announcement (VO/JAWS/NVDA). -->
1829
+ <span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
1830
+ <span class="visually-hidden" role="status">Loading…</span>
1831
+ } @else if (iconClass(); as ic) {
1832
+ <i [class]="ic" aria-hidden="true"></i>
1833
+ }
1834
+ @if (label(); as l) {
1835
+ <span>{{ l | dynamicText | async }}</span>
1836
+ }
1837
+ </button>
1838
+ `, isInline: true, dependencies: [{ kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1839
+ }
1840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: BsButtonAddonComponent, decorators: [{
1841
+ type: Component,
1842
+ args: [{
1843
+ selector: 'df-bs-button-addon',
1844
+ imports: [DynamicTextPipe, AsyncPipe],
1845
+ hostDirectives: [NgForgeAddonAction],
1846
+ template: `
1847
+ <button
1848
+ type="button"
1849
+ [class]="buttonClass()"
1850
+ [disabled]="action.disabled() || action.loading()"
1851
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
1852
+ [attr.aria-busy]="action.loading() || null"
1853
+ (click)="action.dispatch()"
1854
+ >
1855
+ @if (action.loading()) {
1856
+ <!-- Visually-hidden role=status text gives a reliable AT announcement (VO/JAWS/NVDA). -->
1857
+ <span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
1858
+ <span class="visually-hidden" role="status">Loading…</span>
1859
+ } @else if (iconClass(); as ic) {
1860
+ <i [class]="ic" aria-hidden="true"></i>
1861
+ }
1862
+ @if (label(); as l) {
1863
+ <span>{{ l | dynamicText | async }}</span>
1864
+ }
1865
+ </button>
1866
+ `,
1867
+ changeDetection: ChangeDetectionStrategy.OnPush,
1868
+ }]
1869
+ }] });
1870
+
1871
+ var bsButtonAddon_component = /*#__PURE__*/Object.freeze({
1872
+ __proto__: null,
1873
+ BsButtonAddonComponent: BsButtonAddonComponent
1874
+ });
1485
1875
 
1486
1876
  // Field components
1487
1877
 
@@ -1489,5 +1879,5 @@ function withBootstrapFields(config) {
1489
1879
  * Generated bundle index. Do not edit.
1490
1880
  */
1491
1881
 
1492
- export { BOOTSTRAP_CONFIG, BOOTSTRAP_FIELD_TYPES, BsButtonFieldComponent, BsCheckboxFieldComponent, BsDatepickerFieldComponent, BsField, BsInputFieldComponent, BsMultiCheckboxFieldComponent, BsRadioFieldComponent, BsSelectFieldComponent, BsSliderFieldComponent, BsTextareaFieldComponent, BsToggleFieldComponent, withBootstrapFields };
1882
+ export { BOOTSTRAP_CONFIG, BOOTSTRAP_FIELD_TYPES, BS_INPUT_TYPE_OVERRIDE, BsButtonAddonComponent, BsButtonFieldComponent, BsCheckboxFieldComponent, BsDatepickerFieldComponent, BsField, BsIconAddonComponent, BsInputFieldComponent, BsMultiCheckboxFieldComponent, BsRadioFieldComponent, BsSelectFieldComponent, BsSliderFieldComponent, BsTextareaFieldComponent, BsToggleFieldComponent, withBootstrapAddons, withBootstrapFields };
1493
1883
  //# sourceMappingURL=ng-forge-dynamic-forms-bootstrap.mjs.map