@ng-forge/dynamic-forms-bootstrap 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import { AsyncPipe } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, input, computed, ChangeDetectionStrategy, Component, viewChild, effect, ElementRef, Directive, InjectionToken, linkedSignal, model, isSignal } from '@angular/core';
4
- import { EventBus, ARRAY_CONTEXT, resolveTokens, DynamicTextPipe, buildBaseInputs, FIELD_SIGNAL_CONTEXT, resolveSubmitButtonDisabled, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, DYNAMIC_FORM_LOGGER, AddArrayItemEvent, RemoveArrayItemEvent } from '@ng-forge/dynamic-forms';
5
- import { Field } from '@angular/forms/signals';
6
- import { createResolvedErrorsSignal, shouldShowErrors, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
3
+ import { inject, input, computed, ChangeDetectionStrategy, Component, ElementRef, viewChild, effect, Directive, InjectionToken, afterRenderEffect, linkedSignal, model, isSignal } from '@angular/core';
4
+ import { EventBus, ARRAY_CONTEXT, resolveTokens, DynamicTextPipe, buildBaseInputs, FIELD_SIGNAL_CONTEXT, resolveSubmitButtonDisabled, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, DynamicFormLogger, AddArrayItemEvent, RemoveArrayItemEvent } from '@ng-forge/dynamic-forms';
5
+ import { FormField } from '@angular/forms/signals';
6
+ import { createResolvedErrorsSignal, shouldShowErrors, setupMetaTracking, isEqual, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
7
7
  import { explicitEffect } from 'ngxtension/explicit-effect';
8
8
 
9
9
  class BsButtonFieldComponent {
@@ -78,8 +78,8 @@ class BsButtonFieldComponent {
78
78
  this.eventBus.dispatch(event);
79
79
  }
80
80
  }
81
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
82
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.5", type: BsButtonFieldComponent, isStandalone: true, selector: "df-bs-button", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: false, transformFunction: null }, eventArgs: { classPropertyName: "eventArgs", publicName: "eventArgs", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, eventContext: { classPropertyName: "eventContext", publicName: "eventContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "hidden": "hidden()" } }, ngImport: i0, template: `
81
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
82
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.8", type: BsButtonFieldComponent, isStandalone: true, selector: "df-bs-button", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: false, transformFunction: null }, eventArgs: { classPropertyName: "eventArgs", publicName: "eventArgs", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, eventContext: { classPropertyName: "eventContext", publicName: "eventContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "hidden": "hidden()" } }, ngImport: i0, template: `
83
83
  <button
84
84
  [id]="key()"
85
85
  [type]="buttonType()"
@@ -91,9 +91,9 @@ class BsButtonFieldComponent {
91
91
  >
92
92
  {{ label() | dynamicText | async }}
93
93
  </button>
94
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n"], dependencies: [{ kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
94
+ `, 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 });
95
95
  }
96
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsButtonFieldComponent, decorators: [{
96
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsButtonFieldComponent, decorators: [{
97
97
  type: Component,
98
98
  args: [{ selector: 'df-bs-button', imports: [DynamicTextPipe, AsyncPipe], host: {
99
99
  '[id]': '`${key()}`',
@@ -112,7 +112,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
112
112
  >
113
113
  {{ label() | dynamicText | async }}
114
114
  </button>
115
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n"] }]
115
+ `, 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"] }]
116
116
  }], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], event: [{ type: i0.Input, args: [{ isSignal: true, alias: "event", required: false }] }], eventArgs: [{ type: i0.Input, args: [{ isSignal: true, alias: "eventArgs", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], eventContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "eventContext", required: false }] }] } });
117
117
 
118
118
  var bsButton_component = /*#__PURE__*/Object.freeze({
@@ -123,6 +123,7 @@ var bsButton_component = /*#__PURE__*/Object.freeze({
123
123
  // Public API - component
124
124
 
125
125
  class BsCheckboxFieldComponent {
126
+ elementRef = inject((ElementRef));
126
127
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
127
128
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
128
129
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -132,11 +133,13 @@ class BsCheckboxFieldComponent {
132
133
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
133
134
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
134
135
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
136
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
135
137
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
136
138
  showErrors = shouldShowErrors(this.field);
137
139
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
138
140
  checkboxInput = viewChild('checkboxInput', ...(ngDevMode ? [{ debugName: "checkboxInput" }] : []));
139
141
  constructor() {
142
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input[type="checkbox"]' });
140
143
  // Handle indeterminate state
141
144
  effect(() => {
142
145
  const indeterminate = this.props()?.indeterminate;
@@ -169,8 +172,8 @@ class BsCheckboxFieldComponent {
169
172
  });
170
173
  return ids.length > 0 ? ids.join(' ') : null;
171
174
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
172
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
173
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsCheckboxFieldComponent, isStandalone: true, selector: "df-bs-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
175
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
176
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsCheckboxFieldComponent, isStandalone: true, selector: "df-bs-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
174
177
  @let f = field();
175
178
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
176
179
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -185,7 +188,7 @@ class BsCheckboxFieldComponent {
185
188
  <input
186
189
  #checkboxInput
187
190
  type="checkbox"
188
- [field]="f"
191
+ [formField]="f"
189
192
  [id]="key()"
190
193
  class="form-check-input"
191
194
  [class.is-invalid]="f().invalid() && f().touched()"
@@ -193,7 +196,6 @@ class BsCheckboxFieldComponent {
193
196
  [attr.aria-invalid]="ariaInvalid"
194
197
  [attr.aria-required]="ariaRequired"
195
198
  [attr.aria-describedby]="ariaDescribedBy"
196
- [attr.hidden]="f().hidden() || null"
197
199
  />
198
200
  <label [for]="key()" class="form-check-label">
199
201
  {{ label() | dynamicText | async }}
@@ -208,11 +210,11 @@ class BsCheckboxFieldComponent {
208
210
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
209
211
  <div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
210
212
  }
211
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
213
+ `, 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"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
212
214
  }
213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsCheckboxFieldComponent, decorators: [{
215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsCheckboxFieldComponent, decorators: [{
214
216
  type: Component,
215
- args: [{ selector: 'df-bs-checkbox', imports: [Field, DynamicTextPipe, AsyncPipe], template: `
217
+ args: [{ selector: 'df-bs-checkbox', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
216
218
  @let f = field();
217
219
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
218
220
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -227,7 +229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
227
229
  <input
228
230
  #checkboxInput
229
231
  type="checkbox"
230
- [field]="f"
232
+ [formField]="f"
231
233
  [id]="key()"
232
234
  class="form-check-input"
233
235
  [class.is-invalid]="f().invalid() && f().touched()"
@@ -235,7 +237,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
235
237
  [attr.aria-invalid]="ariaInvalid"
236
238
  [attr.aria-required]="ariaRequired"
237
239
  [attr.aria-describedby]="ariaDescribedBy"
238
- [attr.hidden]="f().hidden() || null"
239
240
  />
240
241
  <label [for]="key()" class="form-check-label">
241
242
  {{ label() | dynamicText | async }}
@@ -255,8 +256,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
255
256
  '[id]': '`${key()}`',
256
257
  '[attr.data-testid]': 'key()',
257
258
  '[attr.hidden]': 'field()().hidden() || null',
258
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
259
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], checkboxInput: [{ type: i0.ViewChild, args: ['checkboxInput', { isSignal: true }] }] } });
259
+ }, 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"] }]
260
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], checkboxInput: [{ type: i0.ViewChild, args: ['checkboxInput', { isSignal: true }] }] } });
260
261
 
261
262
  var bsCheckbox_component = /*#__PURE__*/Object.freeze({
262
263
  __proto__: null,
@@ -298,10 +299,10 @@ class InputConstraintsDirective {
298
299
  nativeElement.removeAttribute('step');
299
300
  }
300
301
  });
301
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: InputConstraintsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
302
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.5", 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 });
302
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: InputConstraintsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
303
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.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 });
303
304
  }
304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: InputConstraintsDirective, decorators: [{
305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: InputConstraintsDirective, decorators: [{
305
306
  type: Directive,
306
307
  args: [{
307
308
  selector: '[dfBsInputConstraints]',
@@ -309,6 +310,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
309
310
  }], propDecorators: { dfMin: [{ type: i0.Input, args: [{ isSignal: true, alias: "dfMin", required: false }] }], dfMax: [{ type: i0.Input, args: [{ isSignal: true, alias: "dfMax", required: false }] }], dfStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "dfStep", required: false }] }] } });
310
311
 
311
312
  class BsDatepickerFieldComponent {
313
+ elementRef = inject((ElementRef));
312
314
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
313
315
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
314
316
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -321,9 +323,13 @@ class BsDatepickerFieldComponent {
321
323
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
322
324
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
323
325
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
326
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
324
327
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
325
328
  showErrors = shouldShowErrors(this.field);
326
329
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
330
+ constructor() {
331
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input' });
332
+ }
327
333
  // Helper methods to convert Date to string for HTML attributes
328
334
  minAsString = computed(() => {
329
335
  const min = this.minDate();
@@ -356,8 +362,8 @@ class BsDatepickerFieldComponent {
356
362
  });
357
363
  return ids.length > 0 ? ids.join(' ') : null;
358
364
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
359
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
360
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsDatepickerFieldComponent, isStandalone: true, selector: "df-bs-datepicker", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, 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 }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
365
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
366
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsDatepickerFieldComponent, isStandalone: true, selector: "df-bs-datepicker", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, 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 }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
361
367
  @let f = field(); @let p = props(); @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
362
368
  @let ariaDescribedBy = this.ariaDescribedBy();
363
369
  @if (p?.floatingLabel) {
@@ -365,7 +371,7 @@ class BsDatepickerFieldComponent {
365
371
  <div class="form-floating mb-3">
366
372
  <input
367
373
  dfBsInputConstraints
368
- [field]="f"
374
+ [formField]="f"
369
375
  [id]="key()"
370
376
  type="date"
371
377
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -402,7 +408,7 @@ class BsDatepickerFieldComponent {
402
408
 
403
409
  <input
404
410
  dfBsInputConstraints
405
- [field]="f"
411
+ [formField]="f"
406
412
  [id]="key()"
407
413
  type="date"
408
414
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -434,11 +440,11 @@ class BsDatepickerFieldComponent {
434
440
  }
435
441
  </div>
436
442
  }
437
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
443
+ `, 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"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
438
444
  }
439
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsDatepickerFieldComponent, decorators: [{
445
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsDatepickerFieldComponent, decorators: [{
440
446
  type: Component,
441
- args: [{ selector: 'df-bs-datepicker', imports: [Field, DynamicTextPipe, AsyncPipe, InputConstraintsDirective], template: `
447
+ args: [{ selector: 'df-bs-datepicker', imports: [FormField, DynamicTextPipe, AsyncPipe, InputConstraintsDirective], template: `
442
448
  @let f = field(); @let p = props(); @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
443
449
  @let ariaDescribedBy = this.ariaDescribedBy();
444
450
  @if (p?.floatingLabel) {
@@ -446,7 +452,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
446
452
  <div class="form-floating mb-3">
447
453
  <input
448
454
  dfBsInputConstraints
449
- [field]="f"
455
+ [formField]="f"
450
456
  [id]="key()"
451
457
  type="date"
452
458
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -483,7 +489,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
483
489
 
484
490
  <input
485
491
  dfBsInputConstraints
486
- [field]="f"
492
+ [formField]="f"
487
493
  [id]="key()"
488
494
  type="date"
489
495
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -520,8 +526,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
520
526
  '[attr.data-testid]': 'key()',
521
527
  '[class]': 'className()',
522
528
  '[attr.hidden]': 'field()().hidden() || null',
523
- }, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"] }]
524
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], 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 }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
529
+ }, 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"] }]
530
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], 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 }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
525
531
 
526
532
  var bsDatepicker_component = /*#__PURE__*/Object.freeze({
527
533
  __proto__: null,
@@ -553,6 +559,7 @@ const BOOTSTRAP_CONFIG = new InjectionToken('BOOTSTRAP_CONFIG');
553
559
 
554
560
  class BsInputFieldComponent {
555
561
  bootstrapConfig = inject(BOOTSTRAP_CONFIG, { optional: true });
562
+ elementRef = inject((ElementRef));
556
563
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
557
564
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
558
565
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -562,6 +569,42 @@ class BsInputFieldComponent {
562
569
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
563
570
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
564
571
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
572
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
573
+ /**
574
+ * Reference to the native input element.
575
+ * Used to imperatively sync the readonly attribute since Angular Signal Forms'
576
+ * [field] directive doesn't sync FieldState.readonly() to the DOM.
577
+ */
578
+ inputRef = viewChild('inputRef', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
579
+ /**
580
+ * Computed signal that extracts the readonly state from the field.
581
+ * Used by the effect to reactively sync the readonly attribute to the DOM.
582
+ */
583
+ isReadonly = computed(() => this.field()().readonly(), ...(ngDevMode ? [{ debugName: "isReadonly" }] : []));
584
+ /**
585
+ * Workaround: Angular Signal Forms' [field] directive does NOT sync the readonly
586
+ * attribute to the DOM. This effect imperatively sets/removes the readonly attribute
587
+ * on the native input element whenever the readonly state changes.
588
+ *
589
+ * Uses afterRenderEffect to ensure DOM is ready before manipulating attributes.
590
+ */
591
+ syncReadonlyToDom = afterRenderEffect({
592
+ write: () => {
593
+ const inputRef = this.inputRef();
594
+ const isReadonly = this.isReadonly();
595
+ if (inputRef?.nativeElement) {
596
+ if (isReadonly) {
597
+ inputRef.nativeElement.setAttribute('readonly', '');
598
+ }
599
+ else {
600
+ inputRef.nativeElement.removeAttribute('readonly');
601
+ }
602
+ }
603
+ },
604
+ });
605
+ constructor() {
606
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input' });
607
+ }
565
608
  effectiveSize = computed(() => this.props()?.size ?? this.bootstrapConfig?.size, ...(ngDevMode ? [{ debugName: "effectiveSize" }] : []));
566
609
  effectiveFloatingLabel = computed(() => this.props()?.floatingLabel ?? this.bootstrapConfig?.floatingLabel ?? false, ...(ngDevMode ? [{ debugName: "effectiveFloatingLabel" }] : []));
567
610
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
@@ -595,8 +638,8 @@ class BsInputFieldComponent {
595
638
  });
596
639
  return ids.length > 0 ? ids.join(' ') : null;
597
640
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
598
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
599
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsInputFieldComponent, isStandalone: true, selector: "df-bs-input", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
641
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
642
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsInputFieldComponent, isStandalone: true, selector: "df-bs-input", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
600
643
  @let f = field(); @let p = props(); @let effectiveSize = this.effectiveSize();
601
644
  @let effectiveFloatingLabel = this.effectiveFloatingLabel();
602
645
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
@@ -604,116 +647,23 @@ class BsInputFieldComponent {
604
647
  @if (effectiveFloatingLabel) {
605
648
  <!-- Floating label variant -->
606
649
  <div class="form-floating mb-3">
607
- @switch (p?.type ?? 'text') {
608
- @case ('email') {
609
- <input
610
- type="email"
611
- [field]="f"
612
- [id]="key()"
613
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
614
- [attr.tabindex]="tabIndex()"
615
- [attr.aria-invalid]="ariaInvalid"
616
- [attr.aria-required]="ariaRequired"
617
- [attr.aria-describedby]="ariaDescribedBy"
618
- class="form-control"
619
- [class.form-control-sm]="effectiveSize === 'sm'"
620
- [class.form-control-lg]="effectiveSize === 'lg'"
621
- [class.form-control-plaintext]="p?.plaintext"
622
- [class.is-invalid]="f().invalid() && f().touched()"
623
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
624
- />
625
- }
626
- @case ('password') {
627
- <input
628
- type="password"
629
- [field]="f"
630
- [id]="key()"
631
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
632
- [attr.tabindex]="tabIndex()"
633
- [attr.aria-invalid]="ariaInvalid"
634
- [attr.aria-required]="ariaRequired"
635
- [attr.aria-describedby]="ariaDescribedBy"
636
- class="form-control"
637
- [class.form-control-sm]="effectiveSize === 'sm'"
638
- [class.form-control-lg]="effectiveSize === 'lg'"
639
- [class.form-control-plaintext]="p?.plaintext"
640
- [class.is-invalid]="f().invalid() && f().touched()"
641
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
642
- />
643
- }
644
- @case ('number') {
645
- <input
646
- type="number"
647
- [field]="f"
648
- [id]="key()"
649
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
650
- [attr.tabindex]="tabIndex()"
651
- [attr.aria-invalid]="ariaInvalid"
652
- [attr.aria-required]="ariaRequired"
653
- [attr.aria-describedby]="ariaDescribedBy"
654
- class="form-control"
655
- [class.form-control-sm]="effectiveSize === 'sm'"
656
- [class.form-control-lg]="effectiveSize === 'lg'"
657
- [class.form-control-plaintext]="p?.plaintext"
658
- [class.is-invalid]="f().invalid() && f().touched()"
659
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
660
- />
661
- }
662
- @case ('tel') {
663
- <input
664
- type="tel"
665
- [field]="f"
666
- [id]="key()"
667
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
668
- [attr.tabindex]="tabIndex()"
669
- [attr.aria-invalid]="ariaInvalid"
670
- [attr.aria-required]="ariaRequired"
671
- [attr.aria-describedby]="ariaDescribedBy"
672
- class="form-control"
673
- [class.form-control-sm]="effectiveSize === 'sm'"
674
- [class.form-control-lg]="effectiveSize === '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
- }
680
- @case ('url') {
681
- <input
682
- type="url"
683
- [field]="f"
684
- [id]="key()"
685
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
686
- [attr.tabindex]="tabIndex()"
687
- [attr.aria-invalid]="ariaInvalid"
688
- [attr.aria-required]="ariaRequired"
689
- [attr.aria-describedby]="ariaDescribedBy"
690
- class="form-control"
691
- [class.form-control-sm]="effectiveSize === 'sm'"
692
- [class.form-control-lg]="effectiveSize === 'lg'"
693
- [class.form-control-plaintext]="p?.plaintext"
694
- [class.is-invalid]="f().invalid() && f().touched()"
695
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
696
- />
697
- }
698
- @default {
699
- <input
700
- type="text"
701
- [field]="f"
702
- [id]="key()"
703
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
704
- [attr.tabindex]="tabIndex()"
705
- [attr.aria-invalid]="ariaInvalid"
706
- [attr.aria-required]="ariaRequired"
707
- [attr.aria-describedby]="ariaDescribedBy"
708
- class="form-control"
709
- [class.form-control-sm]="effectiveSize === 'sm'"
710
- [class.form-control-lg]="effectiveSize === 'lg'"
711
- [class.form-control-plaintext]="p?.plaintext"
712
- [class.is-invalid]="f().invalid() && f().touched()"
713
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
714
- />
715
- }
716
- }
650
+ <input
651
+ #inputRef
652
+ [formField]="f"
653
+ [id]="key()"
654
+ [type]="p?.type ?? 'text'"
655
+ [placeholder]="(placeholder() | dynamicText | async) ?? ''"
656
+ [attr.tabindex]="tabIndex()"
657
+ [attr.aria-invalid]="ariaInvalid"
658
+ [attr.aria-required]="ariaRequired"
659
+ [attr.aria-describedby]="ariaDescribedBy"
660
+ class="form-control"
661
+ [class.form-control-sm]="effectiveSize === 'sm'"
662
+ [class.form-control-lg]="effectiveSize === 'lg'"
663
+ [class.form-control-plaintext]="p?.plaintext"
664
+ [class.is-invalid]="f().invalid() && f().touched()"
665
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
666
+ />
717
667
  @if (label()) {
718
668
  <label [for]="key()">{{ label() | dynamicText | async }}</label>
719
669
  }
@@ -732,116 +682,23 @@ class BsInputFieldComponent {
732
682
  @if (label()) {
733
683
  <label [for]="key()" class="form-label">{{ label() | dynamicText | async }}</label>
734
684
  }
735
- @switch (p?.type ?? 'text') {
736
- @case ('email') {
737
- <input
738
- type="email"
739
- [field]="f"
740
- [id]="key()"
741
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
742
- [attr.tabindex]="tabIndex()"
743
- [attr.aria-invalid]="ariaInvalid"
744
- [attr.aria-required]="ariaRequired"
745
- [attr.aria-describedby]="ariaDescribedBy"
746
- class="form-control"
747
- [class.form-control-sm]="effectiveSize === 'sm'"
748
- [class.form-control-lg]="effectiveSize === 'lg'"
749
- [class.form-control-plaintext]="p?.plaintext"
750
- [class.is-invalid]="f().invalid() && f().touched()"
751
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
752
- />
753
- }
754
- @case ('password') {
755
- <input
756
- type="password"
757
- [field]="f"
758
- [id]="key()"
759
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
760
- [attr.tabindex]="tabIndex()"
761
- [attr.aria-invalid]="ariaInvalid"
762
- [attr.aria-required]="ariaRequired"
763
- [attr.aria-describedby]="ariaDescribedBy"
764
- class="form-control"
765
- [class.form-control-sm]="effectiveSize === 'sm'"
766
- [class.form-control-lg]="effectiveSize === 'lg'"
767
- [class.form-control-plaintext]="p?.plaintext"
768
- [class.is-invalid]="f().invalid() && f().touched()"
769
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
770
- />
771
- }
772
- @case ('number') {
773
- <input
774
- type="number"
775
- [field]="f"
776
- [id]="key()"
777
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
778
- [attr.tabindex]="tabIndex()"
779
- [attr.aria-invalid]="ariaInvalid"
780
- [attr.aria-required]="ariaRequired"
781
- [attr.aria-describedby]="ariaDescribedBy"
782
- class="form-control"
783
- [class.form-control-sm]="effectiveSize === 'sm'"
784
- [class.form-control-lg]="effectiveSize === 'lg'"
785
- [class.form-control-plaintext]="p?.plaintext"
786
- [class.is-invalid]="f().invalid() && f().touched()"
787
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
788
- />
789
- }
790
- @case ('tel') {
791
- <input
792
- type="tel"
793
- [field]="f"
794
- [id]="key()"
795
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
796
- [attr.tabindex]="tabIndex()"
797
- [attr.aria-invalid]="ariaInvalid"
798
- [attr.aria-required]="ariaRequired"
799
- [attr.aria-describedby]="ariaDescribedBy"
800
- class="form-control"
801
- [class.form-control-sm]="effectiveSize === 'sm'"
802
- [class.form-control-lg]="effectiveSize === 'lg'"
803
- [class.form-control-plaintext]="p?.plaintext"
804
- [class.is-invalid]="f().invalid() && f().touched()"
805
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
806
- />
807
- }
808
- @case ('url') {
809
- <input
810
- type="url"
811
- [field]="f"
812
- [id]="key()"
813
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
814
- [attr.tabindex]="tabIndex()"
815
- [attr.aria-invalid]="ariaInvalid"
816
- [attr.aria-required]="ariaRequired"
817
- [attr.aria-describedby]="ariaDescribedBy"
818
- class="form-control"
819
- [class.form-control-sm]="effectiveSize === 'sm'"
820
- [class.form-control-lg]="effectiveSize === 'lg'"
821
- [class.form-control-plaintext]="p?.plaintext"
822
- [class.is-invalid]="f().invalid() && f().touched()"
823
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
824
- />
825
- }
826
- @default {
827
- <input
828
- type="text"
829
- [field]="f"
830
- [id]="key()"
831
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
832
- [attr.tabindex]="tabIndex()"
833
- [attr.aria-invalid]="ariaInvalid"
834
- [attr.aria-required]="ariaRequired"
835
- [attr.aria-describedby]="ariaDescribedBy"
836
- class="form-control"
837
- [class.form-control-sm]="effectiveSize === 'sm'"
838
- [class.form-control-lg]="effectiveSize === 'lg'"
839
- [class.form-control-plaintext]="p?.plaintext"
840
- [class.is-invalid]="f().invalid() && f().touched()"
841
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
842
- />
843
- }
844
- }
685
+ <input
686
+ #inputRef
687
+ [formField]="f"
688
+ [id]="key()"
689
+ [type]="p?.type ?? 'text'"
690
+ [placeholder]="(placeholder() | dynamicText | async) ?? ''"
691
+ [attr.tabindex]="tabIndex()"
692
+ [attr.aria-invalid]="ariaInvalid"
693
+ [attr.aria-required]="ariaRequired"
694
+ [attr.aria-describedby]="ariaDescribedBy"
695
+ class="form-control"
696
+ [class.form-control-sm]="effectiveSize === 'sm'"
697
+ [class.form-control-lg]="effectiveSize === 'lg'"
698
+ [class.form-control-plaintext]="p?.plaintext"
699
+ [class.is-invalid]="f().invalid() && f().touched()"
700
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
701
+ />
845
702
  @if (p?.helpText) {
846
703
  <div class="form-text" [id]="helpTextId()">
847
704
  {{ p?.helpText | dynamicText | async }}
@@ -857,11 +714,11 @@ class BsInputFieldComponent {
857
714
  }
858
715
  </div>
859
716
  }
860
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
717
+ `, 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"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
861
718
  }
862
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsInputFieldComponent, decorators: [{
719
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsInputFieldComponent, decorators: [{
863
720
  type: Component,
864
- args: [{ selector: 'df-bs-input', imports: [Field, DynamicTextPipe, AsyncPipe], template: `
721
+ args: [{ selector: 'df-bs-input', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
865
722
  @let f = field(); @let p = props(); @let effectiveSize = this.effectiveSize();
866
723
  @let effectiveFloatingLabel = this.effectiveFloatingLabel();
867
724
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
@@ -869,116 +726,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
869
726
  @if (effectiveFloatingLabel) {
870
727
  <!-- Floating label variant -->
871
728
  <div class="form-floating mb-3">
872
- @switch (p?.type ?? 'text') {
873
- @case ('email') {
874
- <input
875
- type="email"
876
- [field]="f"
877
- [id]="key()"
878
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
879
- [attr.tabindex]="tabIndex()"
880
- [attr.aria-invalid]="ariaInvalid"
881
- [attr.aria-required]="ariaRequired"
882
- [attr.aria-describedby]="ariaDescribedBy"
883
- class="form-control"
884
- [class.form-control-sm]="effectiveSize === 'sm'"
885
- [class.form-control-lg]="effectiveSize === 'lg'"
886
- [class.form-control-plaintext]="p?.plaintext"
887
- [class.is-invalid]="f().invalid() && f().touched()"
888
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
889
- />
890
- }
891
- @case ('password') {
892
- <input
893
- type="password"
894
- [field]="f"
895
- [id]="key()"
896
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
897
- [attr.tabindex]="tabIndex()"
898
- [attr.aria-invalid]="ariaInvalid"
899
- [attr.aria-required]="ariaRequired"
900
- [attr.aria-describedby]="ariaDescribedBy"
901
- class="form-control"
902
- [class.form-control-sm]="effectiveSize === 'sm'"
903
- [class.form-control-lg]="effectiveSize === 'lg'"
904
- [class.form-control-plaintext]="p?.plaintext"
905
- [class.is-invalid]="f().invalid() && f().touched()"
906
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
907
- />
908
- }
909
- @case ('number') {
910
- <input
911
- type="number"
912
- [field]="f"
913
- [id]="key()"
914
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
915
- [attr.tabindex]="tabIndex()"
916
- [attr.aria-invalid]="ariaInvalid"
917
- [attr.aria-required]="ariaRequired"
918
- [attr.aria-describedby]="ariaDescribedBy"
919
- class="form-control"
920
- [class.form-control-sm]="effectiveSize === 'sm'"
921
- [class.form-control-lg]="effectiveSize === 'lg'"
922
- [class.form-control-plaintext]="p?.plaintext"
923
- [class.is-invalid]="f().invalid() && f().touched()"
924
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
925
- />
926
- }
927
- @case ('tel') {
928
- <input
929
- type="tel"
930
- [field]="f"
931
- [id]="key()"
932
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
933
- [attr.tabindex]="tabIndex()"
934
- [attr.aria-invalid]="ariaInvalid"
935
- [attr.aria-required]="ariaRequired"
936
- [attr.aria-describedby]="ariaDescribedBy"
937
- class="form-control"
938
- [class.form-control-sm]="effectiveSize === 'sm'"
939
- [class.form-control-lg]="effectiveSize === 'lg'"
940
- [class.form-control-plaintext]="p?.plaintext"
941
- [class.is-invalid]="f().invalid() && f().touched()"
942
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
943
- />
944
- }
945
- @case ('url') {
946
- <input
947
- type="url"
948
- [field]="f"
949
- [id]="key()"
950
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
951
- [attr.tabindex]="tabIndex()"
952
- [attr.aria-invalid]="ariaInvalid"
953
- [attr.aria-required]="ariaRequired"
954
- [attr.aria-describedby]="ariaDescribedBy"
955
- class="form-control"
956
- [class.form-control-sm]="effectiveSize === 'sm'"
957
- [class.form-control-lg]="effectiveSize === 'lg'"
958
- [class.form-control-plaintext]="p?.plaintext"
959
- [class.is-invalid]="f().invalid() && f().touched()"
960
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
961
- />
962
- }
963
- @default {
964
- <input
965
- type="text"
966
- [field]="f"
967
- [id]="key()"
968
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
969
- [attr.tabindex]="tabIndex()"
970
- [attr.aria-invalid]="ariaInvalid"
971
- [attr.aria-required]="ariaRequired"
972
- [attr.aria-describedby]="ariaDescribedBy"
973
- class="form-control"
974
- [class.form-control-sm]="effectiveSize === 'sm'"
975
- [class.form-control-lg]="effectiveSize === 'lg'"
976
- [class.form-control-plaintext]="p?.plaintext"
977
- [class.is-invalid]="f().invalid() && f().touched()"
978
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
979
- />
980
- }
981
- }
729
+ <input
730
+ #inputRef
731
+ [formField]="f"
732
+ [id]="key()"
733
+ [type]="p?.type ?? 'text'"
734
+ [placeholder]="(placeholder() | dynamicText | async) ?? ''"
735
+ [attr.tabindex]="tabIndex()"
736
+ [attr.aria-invalid]="ariaInvalid"
737
+ [attr.aria-required]="ariaRequired"
738
+ [attr.aria-describedby]="ariaDescribedBy"
739
+ class="form-control"
740
+ [class.form-control-sm]="effectiveSize === 'sm'"
741
+ [class.form-control-lg]="effectiveSize === 'lg'"
742
+ [class.form-control-plaintext]="p?.plaintext"
743
+ [class.is-invalid]="f().invalid() && f().touched()"
744
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
745
+ />
982
746
  @if (label()) {
983
747
  <label [for]="key()">{{ label() | dynamicText | async }}</label>
984
748
  }
@@ -997,116 +761,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
997
761
  @if (label()) {
998
762
  <label [for]="key()" class="form-label">{{ label() | dynamicText | async }}</label>
999
763
  }
1000
- @switch (p?.type ?? 'text') {
1001
- @case ('email') {
1002
- <input
1003
- type="email"
1004
- [field]="f"
1005
- [id]="key()"
1006
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1007
- [attr.tabindex]="tabIndex()"
1008
- [attr.aria-invalid]="ariaInvalid"
1009
- [attr.aria-required]="ariaRequired"
1010
- [attr.aria-describedby]="ariaDescribedBy"
1011
- class="form-control"
1012
- [class.form-control-sm]="effectiveSize === 'sm'"
1013
- [class.form-control-lg]="effectiveSize === 'lg'"
1014
- [class.form-control-plaintext]="p?.plaintext"
1015
- [class.is-invalid]="f().invalid() && f().touched()"
1016
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
1017
- />
1018
- }
1019
- @case ('password') {
1020
- <input
1021
- type="password"
1022
- [field]="f"
1023
- [id]="key()"
1024
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1025
- [attr.tabindex]="tabIndex()"
1026
- [attr.aria-invalid]="ariaInvalid"
1027
- [attr.aria-required]="ariaRequired"
1028
- [attr.aria-describedby]="ariaDescribedBy"
1029
- class="form-control"
1030
- [class.form-control-sm]="effectiveSize === 'sm'"
1031
- [class.form-control-lg]="effectiveSize === 'lg'"
1032
- [class.form-control-plaintext]="p?.plaintext"
1033
- [class.is-invalid]="f().invalid() && f().touched()"
1034
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
1035
- />
1036
- }
1037
- @case ('number') {
1038
- <input
1039
- type="number"
1040
- [field]="f"
1041
- [id]="key()"
1042
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1043
- [attr.tabindex]="tabIndex()"
1044
- [attr.aria-invalid]="ariaInvalid"
1045
- [attr.aria-required]="ariaRequired"
1046
- [attr.aria-describedby]="ariaDescribedBy"
1047
- class="form-control"
1048
- [class.form-control-sm]="effectiveSize === 'sm'"
1049
- [class.form-control-lg]="effectiveSize === 'lg'"
1050
- [class.form-control-plaintext]="p?.plaintext"
1051
- [class.is-invalid]="f().invalid() && f().touched()"
1052
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
1053
- />
1054
- }
1055
- @case ('tel') {
1056
- <input
1057
- type="tel"
1058
- [field]="f"
1059
- [id]="key()"
1060
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1061
- [attr.tabindex]="tabIndex()"
1062
- [attr.aria-invalid]="ariaInvalid"
1063
- [attr.aria-required]="ariaRequired"
1064
- [attr.aria-describedby]="ariaDescribedBy"
1065
- class="form-control"
1066
- [class.form-control-sm]="effectiveSize === 'sm'"
1067
- [class.form-control-lg]="effectiveSize === 'lg'"
1068
- [class.form-control-plaintext]="p?.plaintext"
1069
- [class.is-invalid]="f().invalid() && f().touched()"
1070
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
1071
- />
1072
- }
1073
- @case ('url') {
1074
- <input
1075
- type="url"
1076
- [field]="f"
1077
- [id]="key()"
1078
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1079
- [attr.tabindex]="tabIndex()"
1080
- [attr.aria-invalid]="ariaInvalid"
1081
- [attr.aria-required]="ariaRequired"
1082
- [attr.aria-describedby]="ariaDescribedBy"
1083
- class="form-control"
1084
- [class.form-control-sm]="effectiveSize === 'sm'"
1085
- [class.form-control-lg]="effectiveSize === 'lg'"
1086
- [class.form-control-plaintext]="p?.plaintext"
1087
- [class.is-invalid]="f().invalid() && f().touched()"
1088
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
1089
- />
1090
- }
1091
- @default {
1092
- <input
1093
- type="text"
1094
- [field]="f"
1095
- [id]="key()"
1096
- [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1097
- [attr.tabindex]="tabIndex()"
1098
- [attr.aria-invalid]="ariaInvalid"
1099
- [attr.aria-required]="ariaRequired"
1100
- [attr.aria-describedby]="ariaDescribedBy"
1101
- class="form-control"
1102
- [class.form-control-sm]="effectiveSize === 'sm'"
1103
- [class.form-control-lg]="effectiveSize === 'lg'"
1104
- [class.form-control-plaintext]="p?.plaintext"
1105
- [class.is-invalid]="f().invalid() && f().touched()"
1106
- [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
1107
- />
1108
- }
1109
- }
764
+ <input
765
+ #inputRef
766
+ [formField]="f"
767
+ [id]="key()"
768
+ [type]="p?.type ?? 'text'"
769
+ [placeholder]="(placeholder() | dynamicText | async) ?? ''"
770
+ [attr.tabindex]="tabIndex()"
771
+ [attr.aria-invalid]="ariaInvalid"
772
+ [attr.aria-required]="ariaRequired"
773
+ [attr.aria-describedby]="ariaDescribedBy"
774
+ class="form-control"
775
+ [class.form-control-sm]="effectiveSize === 'sm'"
776
+ [class.form-control-lg]="effectiveSize === 'lg'"
777
+ [class.form-control-plaintext]="p?.plaintext"
778
+ [class.is-invalid]="f().invalid() && f().touched()"
779
+ [class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
780
+ />
1110
781
  @if (p?.helpText) {
1111
782
  <div class="form-text" [id]="helpTextId()">
1112
783
  {{ p?.helpText | dynamicText | async }}
@@ -1127,43 +798,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1127
798
  '[attr.data-testid]': 'key()',
1128
799
  '[class]': 'className()',
1129
800
  '[attr.hidden]': 'field()().hidden() || null',
1130
- }, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"] }]
1131
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
801
+ }, 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"] }]
802
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], inputRef: [{ type: i0.ViewChild, args: ['inputRef', { isSignal: true }] }] } });
1132
803
 
1133
804
  var bsInput_component = /*#__PURE__*/Object.freeze({
1134
805
  __proto__: null,
1135
806
  default: BsInputFieldComponent
1136
807
  });
1137
808
 
1138
- /**
1139
- * Performs a deep equality comparison between two values
1140
- */
1141
- function isEqual(a, b) {
1142
- if (a === b)
1143
- return true;
1144
- if (a == null || b == null)
1145
- return false;
1146
- if (typeof a !== typeof b)
1147
- return false;
1148
- if (a instanceof Date && b instanceof Date) {
1149
- return a.getTime() === b.getTime();
1150
- }
1151
- if (Array.isArray(a) && Array.isArray(b)) {
1152
- if (a.length !== b.length)
1153
- return false;
1154
- return a.every((item, index) => isEqual(item, b[index]));
1155
- }
1156
- if (typeof a === 'object' && typeof b === 'object') {
1157
- const keysA = Object.keys(a);
1158
- const keysB = Object.keys(b);
1159
- if (keysA.length !== keysB.length)
1160
- return false;
1161
- return keysA.every((key) => keysB.includes(key) && isEqual(a[key], b[key]));
1162
- }
1163
- return Object.is(a, b);
1164
- }
1165
-
1166
809
  class BsMultiCheckboxFieldComponent {
810
+ elementRef = inject((ElementRef));
1167
811
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
1168
812
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1169
813
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -1174,6 +818,7 @@ class BsMultiCheckboxFieldComponent {
1174
818
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1175
819
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1176
820
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
821
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1177
822
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1178
823
  showErrors = shouldShowErrors(this.field);
1179
824
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
@@ -1182,6 +827,7 @@ class BsMultiCheckboxFieldComponent {
1182
827
  return this.options().filter((option) => currentValues.includes(option.value));
1183
828
  }, { ...(ngDevMode ? { debugName: "valueViewModel" } : {}), equal: isEqual });
1184
829
  constructor() {
830
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input[type="checkbox"]', dependents: [this.options] });
1185
831
  explicitEffect([this.valueViewModel], ([selectedOptions]) => {
1186
832
  const selectedValues = selectedOptions.map((option) => option.value);
1187
833
  if (!isEqual(selectedValues, this.field()().value())) {
@@ -1233,8 +879,8 @@ class BsMultiCheckboxFieldComponent {
1233
879
  });
1234
880
  return ids.length > 0 ? ids.join(' ') : null;
1235
881
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1236
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1237
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsMultiCheckboxFieldComponent, isStandalone: true, selector: "df-bs-multi-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className() || \"\"", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
882
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
883
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsMultiCheckboxFieldComponent, isStandalone: true, selector: "df-bs-multi-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className() || \"\"", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1238
884
  @let f = field();
1239
885
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1240
886
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -1278,9 +924,9 @@ class BsMultiCheckboxFieldComponent {
1278
924
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1279
925
  <div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
1280
926
  }
1281
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}.checkbox-group{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 });
927
+ `, 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: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1282
928
  }
1283
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsMultiCheckboxFieldComponent, decorators: [{
929
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsMultiCheckboxFieldComponent, decorators: [{
1284
930
  type: Component,
1285
931
  args: [{ selector: 'df-bs-multi-checkbox', imports: [DynamicTextPipe, AsyncPipe], template: `
1286
932
  @let f = field();
@@ -1331,8 +977,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1331
977
  '[id]': '`${key()}`',
1332
978
  '[attr.data-testid]': 'key()',
1333
979
  '[attr.hidden]': 'field()().hidden() || null',
1334
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}.checkbox-group{margin-bottom:.5rem}:host([hidden]){display:none!important}\n"] }]
1335
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
980
+ }, 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"] }]
981
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
1336
982
 
1337
983
  var bsMultiCheckbox_component = /*#__PURE__*/Object.freeze({
1338
984
  __proto__: null,
@@ -1340,8 +986,9 @@ var bsMultiCheckbox_component = /*#__PURE__*/Object.freeze({
1340
986
  });
1341
987
 
1342
988
  class BsRadioGroupComponent {
1343
- // Required by FormValueControl
1344
- value = model.required(...(ngDevMode ? [{ debugName: "value" }] : []));
989
+ elementRef = inject((ElementRef));
990
+ // Value model - FormField directive binds form value to this
991
+ value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
1345
992
  // Optional FormValueControl properties - Field directive will bind these
1346
993
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1347
994
  readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
@@ -1350,8 +997,12 @@ class BsRadioGroupComponent {
1350
997
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
1351
998
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
1352
999
  properties = input(...(ngDevMode ? [undefined, { debugName: "properties" }] : []));
1000
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1353
1001
  // Accessibility - this will be provided by parent component through input
1354
1002
  ariaDescribedBy = input(null, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1003
+ constructor() {
1004
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input[type="radio"]', dependents: [this.options] });
1005
+ }
1355
1006
  /**
1356
1007
  * Handle radio button change event
1357
1008
  */
@@ -1360,8 +1011,8 @@ class BsRadioGroupComponent {
1360
1011
  this.value.set(newValue);
1361
1012
  }
1362
1013
  }
1363
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsRadioGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1364
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsRadioGroupComponent, isStandalone: true, selector: "df-bs-radio-group", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, 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 }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
1014
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsRadioGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1015
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.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 }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: `
1365
1016
  @let props = properties();
1366
1017
  @let ariaDescribedBy = this.ariaDescribedBy();
1367
1018
  @if (props?.buttonGroup) {
@@ -1411,7 +1062,7 @@ class BsRadioGroupComponent {
1411
1062
  }
1412
1063
  `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1413
1064
  }
1414
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsRadioGroupComponent, decorators: [{
1065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsRadioGroupComponent, decorators: [{
1415
1066
  type: Component,
1416
1067
  args: [{ selector: 'df-bs-radio-group', imports: [DynamicTextPipe, AsyncPipe], template: `
1417
1068
  @let props = properties();
@@ -1462,9 +1113,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1462
1113
  }
1463
1114
  }
1464
1115
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
1465
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }] } });
1116
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }] } });
1466
1117
 
1467
1118
  class BsRadioFieldComponent {
1119
+ elementRef = inject((ElementRef));
1468
1120
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
1469
1121
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1470
1122
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -1473,10 +1125,17 @@ class BsRadioFieldComponent {
1473
1125
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
1474
1126
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
1475
1127
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1128
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1476
1129
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1477
1130
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1478
1131
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1479
1132
  showErrors = shouldShowErrors(this.field);
1133
+ constructor() {
1134
+ setupMetaTracking(this.elementRef, this.meta, {
1135
+ selector: 'input[type="radio"]',
1136
+ dependents: [this.options],
1137
+ });
1138
+ }
1480
1139
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
1481
1140
  // ─────────────────────────────────────────────────────────────────────────────
1482
1141
  // Accessibility
@@ -1501,8 +1160,8 @@ class BsRadioFieldComponent {
1501
1160
  });
1502
1161
  return ids.length > 0 ? ids.join(' ') : null;
1503
1162
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1504
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1505
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsRadioFieldComponent, isStandalone: true, selector: "df-bs-radio", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1164
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsRadioFieldComponent, isStandalone: true, selector: "df-bs-radio", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1506
1165
  @let f = field();
1507
1166
  @let ariaDescribedBy = this.ariaDescribedBy();
1508
1167
 
@@ -1512,7 +1171,7 @@ class BsRadioFieldComponent {
1512
1171
  }
1513
1172
 
1514
1173
  <df-bs-radio-group
1515
- [field]="$any(f)"
1174
+ [formField]="$any(f)"
1516
1175
  [label]="label()"
1517
1176
  [options]="options()"
1518
1177
  [properties]="props()"
@@ -1526,11 +1185,11 @@ class BsRadioFieldComponent {
1526
1185
  <div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
1527
1186
  }
1528
1187
  </div>
1529
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\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", "ariaDescribedBy"], outputs: ["valueChange"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1188
+ `, 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", "meta", "ariaDescribedBy"], outputs: ["valueChange"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1530
1189
  }
1531
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsRadioFieldComponent, decorators: [{
1190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsRadioFieldComponent, decorators: [{
1532
1191
  type: Component,
1533
- args: [{ selector: 'df-bs-radio', imports: [BsRadioGroupComponent, Field, DynamicTextPipe, AsyncPipe], template: `
1192
+ args: [{ selector: 'df-bs-radio', imports: [BsRadioGroupComponent, FormField, DynamicTextPipe, AsyncPipe], template: `
1534
1193
  @let f = field();
1535
1194
  @let ariaDescribedBy = this.ariaDescribedBy();
1536
1195
 
@@ -1540,7 +1199,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1540
1199
  }
1541
1200
 
1542
1201
  <df-bs-radio-group
1543
- [field]="$any(f)"
1202
+ [formField]="$any(f)"
1544
1203
  [label]="label()"
1545
1204
  [options]="options()"
1546
1205
  [properties]="props()"
@@ -1559,8 +1218,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1559
1218
  '[attr.data-testid]': 'key()',
1560
1219
  '[class]': 'className()',
1561
1220
  '[attr.hidden]': 'field()().hidden() || null',
1562
- }, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1563
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1221
+ }, 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"] }]
1222
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1564
1223
 
1565
1224
  var bsRadio_component = /*#__PURE__*/Object.freeze({
1566
1225
  __proto__: null,
@@ -1568,6 +1227,7 @@ var bsRadio_component = /*#__PURE__*/Object.freeze({
1568
1227
  });
1569
1228
 
1570
1229
  class BsSelectFieldComponent {
1230
+ elementRef = inject((ElementRef));
1571
1231
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
1572
1232
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1573
1233
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -1578,9 +1238,13 @@ class BsSelectFieldComponent {
1578
1238
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1579
1239
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1580
1240
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1241
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1581
1242
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1582
1243
  showErrors = shouldShowErrors(this.field);
1583
1244
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
1245
+ constructor() {
1246
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'select' });
1247
+ }
1584
1248
  defaultCompare = Object.is;
1585
1249
  isSelected(optionValue, fieldValue) {
1586
1250
  const compareWith = this.props()?.compareWith || this.defaultCompare;
@@ -1612,8 +1276,8 @@ class BsSelectFieldComponent {
1612
1276
  });
1613
1277
  return ids.length > 0 ? ids.join(' ') : null;
1614
1278
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1615
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1616
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsSelectFieldComponent, isStandalone: true, selector: "df-bs-select", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1279
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1280
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsSelectFieldComponent, isStandalone: true, selector: "df-bs-select", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1617
1281
  @let f = field();
1618
1282
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1619
1283
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -1623,7 +1287,7 @@ class BsSelectFieldComponent {
1623
1287
  <label [for]="key()" class="form-label">{{ label | dynamicText | async }}</label>
1624
1288
  }
1625
1289
  <select
1626
- [field]="f"
1290
+ [formField]="f"
1627
1291
  [id]="key()"
1628
1292
  class="form-select"
1629
1293
  [class.form-select-sm]="props()?.size === 'sm'"
@@ -1652,11 +1316,11 @@ class BsSelectFieldComponent {
1652
1316
  <div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
1653
1317
  }
1654
1318
  </div>
1655
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1319
+ `, 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"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1656
1320
  }
1657
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsSelectFieldComponent, decorators: [{
1321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsSelectFieldComponent, decorators: [{
1658
1322
  type: Component,
1659
- args: [{ selector: 'df-bs-select', imports: [Field, DynamicTextPipe, AsyncPipe], template: `
1323
+ args: [{ selector: 'df-bs-select', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
1660
1324
  @let f = field();
1661
1325
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1662
1326
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -1666,7 +1330,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1666
1330
  <label [for]="key()" class="form-label">{{ label | dynamicText | async }}</label>
1667
1331
  }
1668
1332
  <select
1669
- [field]="f"
1333
+ [formField]="f"
1670
1334
  [id]="key()"
1671
1335
  class="form-select"
1672
1336
  [class.form-select-sm]="props()?.size === 'sm'"
@@ -1700,8 +1364,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1700
1364
  '[attr.data-testid]': 'key()',
1701
1365
  '[class]': 'className()',
1702
1366
  '[attr.hidden]': 'field()().hidden() || null',
1703
- }, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"] }]
1704
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1367
+ }, 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"] }]
1368
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
1705
1369
 
1706
1370
  var bsSelect_component = /*#__PURE__*/Object.freeze({
1707
1371
  __proto__: null,
@@ -1709,6 +1373,7 @@ var bsSelect_component = /*#__PURE__*/Object.freeze({
1709
1373
  });
1710
1374
 
1711
1375
  class BsSliderFieldComponent {
1376
+ elementRef = inject((ElementRef));
1712
1377
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
1713
1378
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1714
1379
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -1721,9 +1386,13 @@ class BsSliderFieldComponent {
1721
1386
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1722
1387
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1723
1388
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1389
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1724
1390
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1725
1391
  showErrors = shouldShowErrors(this.field);
1726
1392
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
1393
+ constructor() {
1394
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input' });
1395
+ }
1727
1396
  // ─────────────────────────────────────────────────────────────────────────────
1728
1397
  // Accessibility
1729
1398
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1747,8 +1416,8 @@ class BsSliderFieldComponent {
1747
1416
  });
1748
1417
  return ids.length > 0 ? ids.join(' ') : null;
1749
1418
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1750
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1751
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsSliderFieldComponent, isStandalone: true, selector: "df-bs-slider", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, 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 }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1419
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1420
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsSliderFieldComponent, isStandalone: true, selector: "df-bs-slider", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, 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 }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1752
1421
  @let f = field();
1753
1422
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1754
1423
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -1766,7 +1435,7 @@ class BsSliderFieldComponent {
1766
1435
  <input
1767
1436
  type="range"
1768
1437
  dfBsInputConstraints
1769
- [field]="f"
1438
+ [formField]="f"
1770
1439
  [id]="key()"
1771
1440
  [dfMin]="props()?.min ?? min()"
1772
1441
  [dfMax]="props()?.max ?? max()"
@@ -1787,11 +1456,11 @@ class BsSliderFieldComponent {
1787
1456
  <div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
1788
1457
  }
1789
1458
  </div>
1790
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1459
+ `, 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"] }, { kind: "directive", type: InputConstraintsDirective, selector: "[dfBsInputConstraints]", inputs: ["dfMin", "dfMax", "dfStep"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1791
1460
  }
1792
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsSliderFieldComponent, decorators: [{
1461
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsSliderFieldComponent, decorators: [{
1793
1462
  type: Component,
1794
- args: [{ selector: 'df-bs-slider', imports: [Field, DynamicTextPipe, AsyncPipe, InputConstraintsDirective], template: `
1463
+ args: [{ selector: 'df-bs-slider', imports: [FormField, DynamicTextPipe, AsyncPipe, InputConstraintsDirective], template: `
1795
1464
  @let f = field();
1796
1465
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1797
1466
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -1809,7 +1478,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1809
1478
  <input
1810
1479
  type="range"
1811
1480
  dfBsInputConstraints
1812
- [field]="f"
1481
+ [formField]="f"
1813
1482
  [id]="key()"
1814
1483
  [dfMin]="props()?.min ?? min()"
1815
1484
  [dfMax]="props()?.max ?? max()"
@@ -1835,8 +1504,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1835
1504
  '[id]': '`${key()}`',
1836
1505
  '[attr.data-testid]': 'key()',
1837
1506
  '[attr.hidden]': 'field()().hidden() || null',
1838
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1839
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], 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 }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1507
+ }, 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"] }]
1508
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], 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 }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
1840
1509
 
1841
1510
  var bsSlider_component = /*#__PURE__*/Object.freeze({
1842
1511
  __proto__: null,
@@ -1844,6 +1513,7 @@ var bsSlider_component = /*#__PURE__*/Object.freeze({
1844
1513
  });
1845
1514
 
1846
1515
  class BsTextareaFieldComponent {
1516
+ elementRef = inject((ElementRef));
1847
1517
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
1848
1518
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1849
1519
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -1853,9 +1523,13 @@ class BsTextareaFieldComponent {
1853
1523
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1854
1524
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1855
1525
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1526
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1856
1527
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1857
1528
  showErrors = shouldShowErrors(this.field);
1858
1529
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
1530
+ constructor() {
1531
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'textarea' });
1532
+ }
1859
1533
  // ─────────────────────────────────────────────────────────────────────────────
1860
1534
  // Accessibility
1861
1535
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1879,18 +1553,17 @@ class BsTextareaFieldComponent {
1879
1553
  });
1880
1554
  return ids.length > 0 ? ids.join(' ') : null;
1881
1555
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
1882
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1883
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsTextareaFieldComponent, isStandalone: true, selector: "df-bs-textarea", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1556
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1557
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsTextareaFieldComponent, isStandalone: true, selector: "df-bs-textarea", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1884
1558
  @let f = field(); @let p = props(); @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1885
1559
  @let ariaDescribedBy = this.ariaDescribedBy();
1886
1560
  @if (p?.floatingLabel) {
1887
1561
  <!-- Floating label variant -->
1888
1562
  <div class="form-floating mb-3">
1889
1563
  <textarea
1890
- [field]="f"
1564
+ [formField]="f"
1891
1565
  [id]="key()"
1892
1566
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1893
- [rows]="p?.rows || 4"
1894
1567
  [attr.tabindex]="tabIndex()"
1895
1568
  [attr.aria-invalid]="ariaInvalid"
1896
1569
  [attr.aria-required]="ariaRequired"
@@ -1922,10 +1595,9 @@ class BsTextareaFieldComponent {
1922
1595
  }
1923
1596
 
1924
1597
  <textarea
1925
- [field]="f"
1598
+ [formField]="f"
1926
1599
  [id]="key()"
1927
1600
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1928
- [rows]="p?.rows || 4"
1929
1601
  [attr.tabindex]="tabIndex()"
1930
1602
  [attr.aria-invalid]="ariaInvalid"
1931
1603
  [attr.aria-required]="ariaRequired"
@@ -1952,21 +1624,20 @@ class BsTextareaFieldComponent {
1952
1624
  }
1953
1625
  </div>
1954
1626
  }
1955
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1627
+ `, 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"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1956
1628
  }
1957
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsTextareaFieldComponent, decorators: [{
1629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsTextareaFieldComponent, decorators: [{
1958
1630
  type: Component,
1959
- args: [{ selector: 'df-bs-textarea', imports: [Field, DynamicTextPipe, AsyncPipe], template: `
1631
+ args: [{ selector: 'df-bs-textarea', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
1960
1632
  @let f = field(); @let p = props(); @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
1961
1633
  @let ariaDescribedBy = this.ariaDescribedBy();
1962
1634
  @if (p?.floatingLabel) {
1963
1635
  <!-- Floating label variant -->
1964
1636
  <div class="form-floating mb-3">
1965
1637
  <textarea
1966
- [field]="f"
1638
+ [formField]="f"
1967
1639
  [id]="key()"
1968
1640
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
1969
- [rows]="p?.rows || 4"
1970
1641
  [attr.tabindex]="tabIndex()"
1971
1642
  [attr.aria-invalid]="ariaInvalid"
1972
1643
  [attr.aria-required]="ariaRequired"
@@ -1998,10 +1669,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
1998
1669
  }
1999
1670
 
2000
1671
  <textarea
2001
- [field]="f"
1672
+ [formField]="f"
2002
1673
  [id]="key()"
2003
1674
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
2004
- [rows]="p?.rows || 4"
2005
1675
  [attr.tabindex]="tabIndex()"
2006
1676
  [attr.aria-invalid]="ariaInvalid"
2007
1677
  [attr.aria-required]="ariaRequired"
@@ -2033,8 +1703,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
2033
1703
  '[attr.data-testid]': 'key()',
2034
1704
  '[class]': 'className()',
2035
1705
  '[attr.hidden]': 'field()().hidden() || null',
2036
- }, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\n", ":host([hidden]){display:none!important}\n"] }]
2037
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1706
+ }, 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"] }]
1707
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
2038
1708
 
2039
1709
  var bsTextarea_component = /*#__PURE__*/Object.freeze({
2040
1710
  __proto__: null,
@@ -2042,6 +1712,7 @@ var bsTextarea_component = /*#__PURE__*/Object.freeze({
2042
1712
  });
2043
1713
 
2044
1714
  class BsToggleFieldComponent {
1715
+ elementRef = inject((ElementRef));
2045
1716
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
2046
1717
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
2047
1718
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -2051,9 +1722,13 @@ class BsToggleFieldComponent {
2051
1722
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
2052
1723
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
2053
1724
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1725
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
2054
1726
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
2055
1727
  showErrors = shouldShowErrors(this.field);
2056
1728
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
1729
+ constructor() {
1730
+ setupMetaTracking(this.elementRef, this.meta, { selector: 'input[type="checkbox"]' });
1731
+ }
2057
1732
  // ─────────────────────────────────────────────────────────────────────────────
2058
1733
  // Accessibility
2059
1734
  // ─────────────────────────────────────────────────────────────────────────────
@@ -2077,8 +1752,8 @@ class BsToggleFieldComponent {
2077
1752
  });
2078
1753
  return ids.length > 0 ? ids.join(' ') : null;
2079
1754
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
2080
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2081
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.5", type: BsToggleFieldComponent, isStandalone: true, selector: "df-bs-toggle", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1755
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1756
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: BsToggleFieldComponent, isStandalone: true, selector: "df-bs-toggle", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
2082
1757
  @let f = field();
2083
1758
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
2084
1759
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -2093,7 +1768,7 @@ class BsToggleFieldComponent {
2093
1768
  >
2094
1769
  <input
2095
1770
  type="checkbox"
2096
- [field]="f"
1771
+ [formField]="f"
2097
1772
  [id]="key()"
2098
1773
  class="form-check-input"
2099
1774
  [class.is-invalid]="f().invalid() && f().touched()"
@@ -2101,7 +1776,6 @@ class BsToggleFieldComponent {
2101
1776
  [attr.aria-invalid]="ariaInvalid"
2102
1777
  [attr.aria-required]="ariaRequired"
2103
1778
  [attr.aria-describedby]="ariaDescribedBy"
2104
- [attr.hidden]="f().hidden() || null"
2105
1779
  />
2106
1780
  <label [for]="key()" class="form-check-label">
2107
1781
  {{ label() | dynamicText | async }}
@@ -2116,11 +1790,11 @@ class BsToggleFieldComponent {
2116
1790
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
2117
1791
  <div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
2118
1792
  }
2119
- `, isInline: true, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\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: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1793
+ `, 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"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2120
1794
  }
2121
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImport: i0, type: BsToggleFieldComponent, decorators: [{
1795
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsToggleFieldComponent, decorators: [{
2122
1796
  type: Component,
2123
- args: [{ selector: 'df-bs-toggle', imports: [Field, DynamicTextPipe, AsyncPipe], template: `
1797
+ args: [{ selector: 'df-bs-toggle', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
2124
1798
  @let f = field();
2125
1799
  @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
2126
1800
  @let ariaDescribedBy = this.ariaDescribedBy();
@@ -2135,7 +1809,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
2135
1809
  >
2136
1810
  <input
2137
1811
  type="checkbox"
2138
- [field]="f"
1812
+ [formField]="f"
2139
1813
  [id]="key()"
2140
1814
  class="form-check-input"
2141
1815
  [class.is-invalid]="f().invalid() && f().touched()"
@@ -2143,7 +1817,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
2143
1817
  [attr.aria-invalid]="ariaInvalid"
2144
1818
  [attr.aria-required]="ariaRequired"
2145
1819
  [attr.aria-describedby]="ariaDescribedBy"
2146
- [attr.hidden]="f().hidden() || null"
2147
1820
  />
2148
1821
  <label [for]="key()" class="form-check-label">
2149
1822
  {{ label() | dynamicText | async }}
@@ -2163,8 +1836,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
2163
1836
  '[id]': '`${key()}`',
2164
1837
  '[attr.data-testid]': 'key()',
2165
1838
  '[attr.hidden]': 'field()().hidden() || null',
2166
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-bs-field-gap: .5rem;--df-bs-label-font-weight: 500;--df-bs-label-color: inherit;--df-bs-hint-color: var(--bs-secondary-color, #6c757d);--df-bs-hint-font-size: .875rem;--df-bs-error-color: var(--bs-danger, #dc3545);--df-bs-error-font-size: .875rem}.df-bs-field{display:flex;flex-direction:column;gap:var(--df-bs-field-gap);width:100%;margin-bottom:1rem}.df-bs-label{font-weight:var(--df-bs-label-font-weight);color:var(--df-bs-label-color);margin-bottom:0}.df-bs-hint{color:var(--df-bs-hint-color);font-size:var(--df-bs-hint-font-size);margin-top:.25rem}.df-bs-field:has(.df-bs-hint){margin-bottom:.5rem}\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"] }]
2167
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1839
+ }, 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"] }]
1840
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
2168
1841
 
2169
1842
  var bsToggle_component = /*#__PURE__*/Object.freeze({
2170
1843
  __proto__: null,
@@ -2350,7 +2023,7 @@ function addArrayItemButtonFieldMapper(fieldDef) {
2350
2023
  // Try to get array context (available when inside an array)
2351
2024
  // Use optional injection so it doesn't fail when outside an array
2352
2025
  const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
2353
- const logger = inject(DYNAMIC_FORM_LOGGER);
2026
+ const logger = inject(DynamicFormLogger);
2354
2027
  // Determine the target array key
2355
2028
  // Priority: explicit arrayKey from fieldDef > arrayKey from context
2356
2029
  const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
@@ -2406,7 +2079,7 @@ function removeArrayItemButtonFieldMapper(fieldDef) {
2406
2079
  // Try to get array context (available when inside an array)
2407
2080
  // Use optional injection so it doesn't fail when outside an array
2408
2081
  const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
2409
- const logger = inject(DYNAMIC_FORM_LOGGER);
2082
+ const logger = inject(DynamicFormLogger);
2410
2083
  // Determine the target array key
2411
2084
  // Priority: explicit arrayKey from fieldDef > arrayKey from context
2412
2085
  const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
@@ -2455,6 +2128,7 @@ const BOOTSTRAP_FIELD_TYPES = [
2455
2128
  name: BsField.Input,
2456
2129
  loadComponent: () => Promise.resolve().then(function () { return bsInput_component; }),
2457
2130
  mapper: valueFieldMapper,
2131
+ propsToMeta: ['type'],
2458
2132
  },
2459
2133
  {
2460
2134
  name: BsField.Select,
@@ -2506,6 +2180,7 @@ const BOOTSTRAP_FIELD_TYPES = [
2506
2180
  name: BsField.Textarea,
2507
2181
  loadComponent: () => Promise.resolve().then(function () { return bsTextarea_component; }),
2508
2182
  mapper: valueFieldMapper,
2183
+ propsToMeta: ['rows'],
2509
2184
  },
2510
2185
  {
2511
2186
  name: BsField.Radio,