@ng-forge/dynamic-forms-bootstrap 0.3.1 → 0.4.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,7 +1,7 @@
|
|
|
1
1
|
import { AsyncPipe } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
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,
|
|
4
|
+
import { EventBus, ARRAY_CONTEXT, resolveTokens, DynamicTextPipe, DEFAULT_PROPS, buildBaseInputs, RootFormRegistryService, FORM_OPTIONS, resolveSubmitButtonDisabled, FIELD_SIGNAL_CONTEXT, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, DynamicFormLogger, AddArrayItemEvent, RemoveArrayItemEvent } from '@ng-forge/dynamic-forms';
|
|
5
5
|
import { FormField } from '@angular/forms/signals';
|
|
6
6
|
import { createResolvedErrorsSignal, shouldShowErrors, setupMetaTracking, isEqual, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
|
|
7
7
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
@@ -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
|
|
82
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0
|
|
81
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
82
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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()", "attr.hidden": "hidden() || null" } }, ngImport: i0, template: `
|
|
83
83
|
@let buttonId = key() + '-button';
|
|
84
84
|
<button
|
|
85
85
|
[id]="buttonId"
|
|
@@ -94,13 +94,13 @@ class BsButtonFieldComponent {
|
|
|
94
94
|
</button>
|
|
95
95
|
`, 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 });
|
|
96
96
|
}
|
|
97
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsButtonFieldComponent, decorators: [{
|
|
98
98
|
type: Component,
|
|
99
99
|
args: [{ selector: 'df-bs-button', imports: [DynamicTextPipe, AsyncPipe], host: {
|
|
100
100
|
'[id]': '`${key()}`',
|
|
101
101
|
'[attr.data-testid]': 'key()',
|
|
102
102
|
'[class]': 'className()',
|
|
103
|
-
'[hidden]': 'hidden()',
|
|
103
|
+
'[attr.hidden]': 'hidden() || null',
|
|
104
104
|
}, template: `
|
|
105
105
|
@let buttonId = key() + '-button';
|
|
106
106
|
<button
|
|
@@ -124,6 +124,29 @@ var bsButton_component = /*#__PURE__*/Object.freeze({
|
|
|
124
124
|
|
|
125
125
|
// Public API - component
|
|
126
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Creates a signal that computes the aria-describedby value based on errors and hint state.
|
|
129
|
+
* Errors take precedence over hints - when errors are displayed, the hint is hidden.
|
|
130
|
+
*
|
|
131
|
+
* @param errorsToDisplay Signal containing the array of errors currently being displayed
|
|
132
|
+
* @param errorId Signal containing the base ID for error elements
|
|
133
|
+
* @param hintId Signal containing the ID for the hint element
|
|
134
|
+
* @param hasHint Function that returns true if a hint is configured
|
|
135
|
+
* @returns Signal containing the aria-describedby value (space-separated IDs) or null
|
|
136
|
+
*/
|
|
137
|
+
function createAriaDescribedBySignal(errorsToDisplay, errorId, hintId, hasHint) {
|
|
138
|
+
return computed(() => {
|
|
139
|
+
const errors = errorsToDisplay();
|
|
140
|
+
if (errors.length > 0) {
|
|
141
|
+
return errors.map((_, i) => `${errorId()}-${i}`).join(' ');
|
|
142
|
+
}
|
|
143
|
+
if (hasHint()) {
|
|
144
|
+
return hintId();
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
127
150
|
class BsCheckboxFieldComponent {
|
|
128
151
|
elementRef = inject((ElementRef));
|
|
129
152
|
field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
@@ -154,7 +177,7 @@ class BsCheckboxFieldComponent {
|
|
|
154
177
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
155
178
|
// Accessibility
|
|
156
179
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
157
|
-
|
|
180
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
158
181
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
159
182
|
ariaInvalid = computed(() => {
|
|
160
183
|
const fieldState = this.field()();
|
|
@@ -163,21 +186,10 @@ class BsCheckboxFieldComponent {
|
|
|
163
186
|
ariaRequired = computed(() => {
|
|
164
187
|
return this.field()().required?.() === true ? true : null;
|
|
165
188
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
166
|
-
ariaDescribedBy =
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
const errors = this.errorsToDisplay();
|
|
172
|
-
errors.forEach((_, i) => {
|
|
173
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
174
|
-
});
|
|
175
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
176
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
177
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
178
|
-
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: `
|
|
179
|
-
@let f = field(); @let checkboxId = key() + '-checkbox'; @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
180
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
189
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
190
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
191
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
192
|
+
@let f = field(); @let checkboxId = key() + '-checkbox';
|
|
181
193
|
|
|
182
194
|
<div
|
|
183
195
|
class="form-check"
|
|
@@ -194,30 +206,28 @@ class BsCheckboxFieldComponent {
|
|
|
194
206
|
class="form-check-input"
|
|
195
207
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
196
208
|
[attr.tabindex]="tabIndex()"
|
|
197
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
198
|
-
[attr.aria-required]="ariaRequired"
|
|
199
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
209
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
210
|
+
[attr.aria-required]="ariaRequired()"
|
|
211
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
200
212
|
/>
|
|
201
213
|
<label [for]="checkboxId" class="form-check-label">
|
|
202
214
|
{{ label() | dynamicText | async }}
|
|
203
215
|
</label>
|
|
204
216
|
</div>
|
|
205
217
|
|
|
206
|
-
@if (props()?.helpText; as helpText) {
|
|
207
|
-
<div class="form-text" [id]="helpTextId()" [attr.hidden]="f().hidden() || null">
|
|
208
|
-
{{ helpText | dynamicText | async }}
|
|
209
|
-
</div>
|
|
210
|
-
}
|
|
211
218
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
212
219
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
220
|
+
} @empty {
|
|
221
|
+
@if (props()?.hint; as hint) {
|
|
222
|
+
<div class="form-text" [id]="hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
|
|
223
|
+
}
|
|
213
224
|
}
|
|
214
225
|
`, 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 });
|
|
215
226
|
}
|
|
216
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
227
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsCheckboxFieldComponent, decorators: [{
|
|
217
228
|
type: Component,
|
|
218
229
|
args: [{ selector: 'df-bs-checkbox', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
219
|
-
@let f = field(); @let checkboxId = key() + '-checkbox';
|
|
220
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
230
|
+
@let f = field(); @let checkboxId = key() + '-checkbox';
|
|
221
231
|
|
|
222
232
|
<div
|
|
223
233
|
class="form-check"
|
|
@@ -234,22 +244,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
234
244
|
class="form-check-input"
|
|
235
245
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
236
246
|
[attr.tabindex]="tabIndex()"
|
|
237
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
238
|
-
[attr.aria-required]="ariaRequired"
|
|
239
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
247
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
248
|
+
[attr.aria-required]="ariaRequired()"
|
|
249
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
240
250
|
/>
|
|
241
251
|
<label [for]="checkboxId" class="form-check-label">
|
|
242
252
|
{{ label() | dynamicText | async }}
|
|
243
253
|
</label>
|
|
244
254
|
</div>
|
|
245
255
|
|
|
246
|
-
@if (props()?.helpText; as helpText) {
|
|
247
|
-
<div class="form-text" [id]="helpTextId()" [attr.hidden]="f().hidden() || null">
|
|
248
|
-
{{ helpText | dynamicText | async }}
|
|
249
|
-
</div>
|
|
250
|
-
}
|
|
251
256
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
252
257
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
258
|
+
} @empty {
|
|
259
|
+
@if (props()?.hint; as hint) {
|
|
260
|
+
<div class="form-text" [id]="hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
|
|
261
|
+
}
|
|
253
262
|
}
|
|
254
263
|
`, host: {
|
|
255
264
|
'[class]': 'className()',
|
|
@@ -299,10 +308,10 @@ class InputConstraintsDirective {
|
|
|
299
308
|
nativeElement.removeAttribute('step');
|
|
300
309
|
}
|
|
301
310
|
});
|
|
302
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
303
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0
|
|
311
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InputConstraintsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
312
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", 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 });
|
|
304
313
|
}
|
|
305
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
314
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: InputConstraintsDirective, decorators: [{
|
|
306
315
|
type: Directive,
|
|
307
316
|
args: [{
|
|
308
317
|
selector: '[dfBsInputConstraints]',
|
|
@@ -342,7 +351,7 @@ class BsDatepickerFieldComponent {
|
|
|
342
351
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
343
352
|
// Accessibility
|
|
344
353
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
345
|
-
|
|
354
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
346
355
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
347
356
|
ariaInvalid = computed(() => {
|
|
348
357
|
const fieldState = this.field()();
|
|
@@ -351,21 +360,10 @@ class BsDatepickerFieldComponent {
|
|
|
351
360
|
ariaRequired = computed(() => {
|
|
352
361
|
return this.field()().required?.() === true ? true : null;
|
|
353
362
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
354
|
-
ariaDescribedBy =
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
const errors = this.errorsToDisplay();
|
|
360
|
-
errors.forEach((_, i) => {
|
|
361
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
362
|
-
});
|
|
363
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
364
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
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: `
|
|
367
|
-
@let f = field(); @let p = props(); @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
368
|
-
@let ariaDescribedBy = this.ariaDescribedBy(); @let inputId = key() + '-input';
|
|
363
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
364
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
365
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
366
|
+
@let f = field(); @let p = props(); @let inputId = key() + '-input';
|
|
369
367
|
@if (p?.floatingLabel) {
|
|
370
368
|
<!-- Floating label variant -->
|
|
371
369
|
<div class="form-floating mb-3">
|
|
@@ -378,9 +376,9 @@ class BsDatepickerFieldComponent {
|
|
|
378
376
|
[dfMin]="minAsString()"
|
|
379
377
|
[dfMax]="maxAsString()"
|
|
380
378
|
[attr.tabindex]="tabIndex()"
|
|
381
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
382
|
-
[attr.aria-required]="ariaRequired"
|
|
383
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
379
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
380
|
+
[attr.aria-required]="ariaRequired()"
|
|
381
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
384
382
|
class="form-control"
|
|
385
383
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
386
384
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -415,9 +413,9 @@ class BsDatepickerFieldComponent {
|
|
|
415
413
|
[dfMin]="minAsString()"
|
|
416
414
|
[dfMax]="maxAsString()"
|
|
417
415
|
[attr.tabindex]="tabIndex()"
|
|
418
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
419
|
-
[attr.aria-required]="ariaRequired"
|
|
420
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
416
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
417
|
+
[attr.aria-required]="ariaRequired()"
|
|
418
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
421
419
|
class="form-control"
|
|
422
420
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
423
421
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -425,11 +423,6 @@ class BsDatepickerFieldComponent {
|
|
|
425
423
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
426
424
|
/>
|
|
427
425
|
|
|
428
|
-
@if (p?.helpText) {
|
|
429
|
-
<div class="form-text" [id]="helpTextId()">
|
|
430
|
-
{{ p?.helpText | dynamicText | async }}
|
|
431
|
-
</div>
|
|
432
|
-
}
|
|
433
426
|
@if (p?.validFeedback && f().valid() && f().touched()) {
|
|
434
427
|
<div class="valid-feedback d-block">
|
|
435
428
|
{{ p?.validFeedback | dynamicText | async }}
|
|
@@ -437,16 +430,19 @@ class BsDatepickerFieldComponent {
|
|
|
437
430
|
}
|
|
438
431
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
439
432
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
433
|
+
} @empty {
|
|
434
|
+
@if (p?.hint) {
|
|
435
|
+
<div class="form-text" [id]="hintId()">{{ p?.hint | dynamicText | async }}</div>
|
|
436
|
+
}
|
|
440
437
|
}
|
|
441
438
|
</div>
|
|
442
439
|
}
|
|
443
440
|
`, 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 });
|
|
444
441
|
}
|
|
445
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
442
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsDatepickerFieldComponent, decorators: [{
|
|
446
443
|
type: Component,
|
|
447
444
|
args: [{ selector: 'df-bs-datepicker', imports: [FormField, DynamicTextPipe, AsyncPipe, InputConstraintsDirective], template: `
|
|
448
|
-
@let f = field(); @let p = props(); @let
|
|
449
|
-
@let ariaDescribedBy = this.ariaDescribedBy(); @let inputId = key() + '-input';
|
|
445
|
+
@let f = field(); @let p = props(); @let inputId = key() + '-input';
|
|
450
446
|
@if (p?.floatingLabel) {
|
|
451
447
|
<!-- Floating label variant -->
|
|
452
448
|
<div class="form-floating mb-3">
|
|
@@ -459,9 +455,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
459
455
|
[dfMin]="minAsString()"
|
|
460
456
|
[dfMax]="maxAsString()"
|
|
461
457
|
[attr.tabindex]="tabIndex()"
|
|
462
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
463
|
-
[attr.aria-required]="ariaRequired"
|
|
464
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
458
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
459
|
+
[attr.aria-required]="ariaRequired()"
|
|
460
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
465
461
|
class="form-control"
|
|
466
462
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
467
463
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -496,9 +492,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
496
492
|
[dfMin]="minAsString()"
|
|
497
493
|
[dfMax]="maxAsString()"
|
|
498
494
|
[attr.tabindex]="tabIndex()"
|
|
499
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
500
|
-
[attr.aria-required]="ariaRequired"
|
|
501
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
495
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
496
|
+
[attr.aria-required]="ariaRequired()"
|
|
497
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
502
498
|
class="form-control"
|
|
503
499
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
504
500
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -506,11 +502,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
506
502
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
507
503
|
/>
|
|
508
504
|
|
|
509
|
-
@if (p?.helpText) {
|
|
510
|
-
<div class="form-text" [id]="helpTextId()">
|
|
511
|
-
{{ p?.helpText | dynamicText | async }}
|
|
512
|
-
</div>
|
|
513
|
-
}
|
|
514
505
|
@if (p?.validFeedback && f().valid() && f().touched()) {
|
|
515
506
|
<div class="valid-feedback d-block">
|
|
516
507
|
{{ p?.validFeedback | dynamicText | async }}
|
|
@@ -518,6 +509,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
518
509
|
}
|
|
519
510
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
520
511
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
512
|
+
} @empty {
|
|
513
|
+
@if (p?.hint) {
|
|
514
|
+
<div class="form-text" [id]="hintId()">{{ p?.hint | dynamicText | async }}</div>
|
|
515
|
+
}
|
|
521
516
|
}
|
|
522
517
|
</div>
|
|
523
518
|
}
|
|
@@ -613,8 +608,8 @@ class BsInputFieldComponent {
|
|
|
613
608
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
614
609
|
// Accessibility
|
|
615
610
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
616
|
-
/** Unique ID for the
|
|
617
|
-
|
|
611
|
+
/** Unique ID for the hint element, used for aria-describedby */
|
|
612
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
618
613
|
/** Base ID for error elements, used for aria-describedby */
|
|
619
614
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
620
615
|
/** aria-invalid: true when field is invalid AND touched, false otherwise */
|
|
@@ -626,26 +621,12 @@ class BsInputFieldComponent {
|
|
|
626
621
|
ariaRequired = computed(() => {
|
|
627
622
|
return this.field()().required?.() === true ? true : null;
|
|
628
623
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
629
|
-
/** aria-describedby: links to
|
|
630
|
-
ariaDescribedBy =
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
const errors = this.errorsToDisplay();
|
|
636
|
-
errors.forEach((_, i) => {
|
|
637
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
638
|
-
});
|
|
639
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
640
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
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: `
|
|
643
|
-
@let f = field(); @let p = props(); @let effectiveSize = this.effectiveSize();
|
|
644
|
-
@let effectiveFloatingLabel = this.effectiveFloatingLabel();
|
|
645
|
-
@let inputId = key() + '-input';
|
|
646
|
-
@let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
647
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
648
|
-
@if (effectiveFloatingLabel) {
|
|
624
|
+
/** aria-describedby: links to hint and error messages for screen readers */
|
|
625
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
626
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
627
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
628
|
+
@let f = field(); @let p = props(); @let inputId = key() + '-input';
|
|
629
|
+
@if (effectiveFloatingLabel()) {
|
|
649
630
|
<!-- Floating label variant -->
|
|
650
631
|
<div class="form-floating mb-3">
|
|
651
632
|
<input
|
|
@@ -655,12 +636,12 @@ class BsInputFieldComponent {
|
|
|
655
636
|
[type]="p?.type ?? 'text'"
|
|
656
637
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
657
638
|
[attr.tabindex]="tabIndex()"
|
|
658
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
659
|
-
[attr.aria-required]="ariaRequired"
|
|
660
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
639
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
640
|
+
[attr.aria-required]="ariaRequired()"
|
|
641
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
661
642
|
class="form-control"
|
|
662
|
-
[class.form-control-sm]="effectiveSize === 'sm'"
|
|
663
|
-
[class.form-control-lg]="effectiveSize === 'lg'"
|
|
643
|
+
[class.form-control-sm]="effectiveSize() === 'sm'"
|
|
644
|
+
[class.form-control-lg]="effectiveSize() === 'lg'"
|
|
664
645
|
[class.form-control-plaintext]="p?.plaintext"
|
|
665
646
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
666
647
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
@@ -690,21 +671,16 @@ class BsInputFieldComponent {
|
|
|
690
671
|
[type]="p?.type ?? 'text'"
|
|
691
672
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
692
673
|
[attr.tabindex]="tabIndex()"
|
|
693
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
694
|
-
[attr.aria-required]="ariaRequired"
|
|
695
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
674
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
675
|
+
[attr.aria-required]="ariaRequired()"
|
|
676
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
696
677
|
class="form-control"
|
|
697
|
-
[class.form-control-sm]="effectiveSize === 'sm'"
|
|
698
|
-
[class.form-control-lg]="effectiveSize === 'lg'"
|
|
678
|
+
[class.form-control-sm]="effectiveSize() === 'sm'"
|
|
679
|
+
[class.form-control-lg]="effectiveSize() === 'lg'"
|
|
699
680
|
[class.form-control-plaintext]="p?.plaintext"
|
|
700
681
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
701
682
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
702
683
|
/>
|
|
703
|
-
@if (p?.helpText) {
|
|
704
|
-
<div class="form-text" [id]="helpTextId()">
|
|
705
|
-
{{ p?.helpText | dynamicText | async }}
|
|
706
|
-
</div>
|
|
707
|
-
}
|
|
708
684
|
@if (p?.validFeedback && f().valid() && f().touched()) {
|
|
709
685
|
<div class="valid-feedback d-block">
|
|
710
686
|
{{ p?.validFeedback | dynamicText | async }}
|
|
@@ -712,20 +688,20 @@ class BsInputFieldComponent {
|
|
|
712
688
|
}
|
|
713
689
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
714
690
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
691
|
+
} @empty {
|
|
692
|
+
@if (p?.hint) {
|
|
693
|
+
<div class="form-text" [id]="hintId()">{{ p?.hint | dynamicText | async }}</div>
|
|
694
|
+
}
|
|
715
695
|
}
|
|
716
696
|
</div>
|
|
717
697
|
}
|
|
718
698
|
`, 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 });
|
|
719
699
|
}
|
|
720
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
700
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsInputFieldComponent, decorators: [{
|
|
721
701
|
type: Component,
|
|
722
702
|
args: [{ selector: 'df-bs-input', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
723
|
-
@let f = field(); @let p = props(); @let
|
|
724
|
-
@
|
|
725
|
-
@let inputId = key() + '-input';
|
|
726
|
-
@let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
727
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
728
|
-
@if (effectiveFloatingLabel) {
|
|
703
|
+
@let f = field(); @let p = props(); @let inputId = key() + '-input';
|
|
704
|
+
@if (effectiveFloatingLabel()) {
|
|
729
705
|
<!-- Floating label variant -->
|
|
730
706
|
<div class="form-floating mb-3">
|
|
731
707
|
<input
|
|
@@ -735,12 +711,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
735
711
|
[type]="p?.type ?? 'text'"
|
|
736
712
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
737
713
|
[attr.tabindex]="tabIndex()"
|
|
738
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
739
|
-
[attr.aria-required]="ariaRequired"
|
|
740
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
714
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
715
|
+
[attr.aria-required]="ariaRequired()"
|
|
716
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
741
717
|
class="form-control"
|
|
742
|
-
[class.form-control-sm]="effectiveSize === 'sm'"
|
|
743
|
-
[class.form-control-lg]="effectiveSize === 'lg'"
|
|
718
|
+
[class.form-control-sm]="effectiveSize() === 'sm'"
|
|
719
|
+
[class.form-control-lg]="effectiveSize() === 'lg'"
|
|
744
720
|
[class.form-control-plaintext]="p?.plaintext"
|
|
745
721
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
746
722
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
@@ -770,21 +746,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
770
746
|
[type]="p?.type ?? 'text'"
|
|
771
747
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
772
748
|
[attr.tabindex]="tabIndex()"
|
|
773
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
774
|
-
[attr.aria-required]="ariaRequired"
|
|
775
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
749
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
750
|
+
[attr.aria-required]="ariaRequired()"
|
|
751
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
776
752
|
class="form-control"
|
|
777
|
-
[class.form-control-sm]="effectiveSize === 'sm'"
|
|
778
|
-
[class.form-control-lg]="effectiveSize === 'lg'"
|
|
753
|
+
[class.form-control-sm]="effectiveSize() === 'sm'"
|
|
754
|
+
[class.form-control-lg]="effectiveSize() === 'lg'"
|
|
779
755
|
[class.form-control-plaintext]="p?.plaintext"
|
|
780
756
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
781
757
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
782
758
|
/>
|
|
783
|
-
@if (p?.helpText) {
|
|
784
|
-
<div class="form-text" [id]="helpTextId()">
|
|
785
|
-
{{ p?.helpText | dynamicText | async }}
|
|
786
|
-
</div>
|
|
787
|
-
}
|
|
788
759
|
@if (p?.validFeedback && f().valid() && f().touched()) {
|
|
789
760
|
<div class="valid-feedback d-block">
|
|
790
761
|
{{ p?.validFeedback | dynamicText | async }}
|
|
@@ -792,6 +763,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
792
763
|
}
|
|
793
764
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
794
765
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
766
|
+
} @empty {
|
|
767
|
+
@if (p?.hint) {
|
|
768
|
+
<div class="form-text" [id]="hintId()">{{ p?.hint | dynamicText | async }}</div>
|
|
769
|
+
}
|
|
795
770
|
}
|
|
796
771
|
</div>
|
|
797
772
|
}
|
|
@@ -824,6 +799,14 @@ class BsMultiCheckboxFieldComponent {
|
|
|
824
799
|
resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
|
|
825
800
|
showErrors = shouldShowErrors(this.field);
|
|
826
801
|
errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
|
|
802
|
+
/** Computed map of checked option values for O(1) lookup in template */
|
|
803
|
+
checkedValuesMap = computed(() => {
|
|
804
|
+
const map = {};
|
|
805
|
+
for (const opt of this.valueViewModel()) {
|
|
806
|
+
map[String(opt.value)] = true;
|
|
807
|
+
}
|
|
808
|
+
return map;
|
|
809
|
+
}, ...(ngDevMode ? [{ debugName: "checkedValuesMap" }] : []));
|
|
827
810
|
valueViewModel = linkedSignal(() => {
|
|
828
811
|
const currentValues = this.field()().value();
|
|
829
812
|
return this.options().filter((option) => currentValues.includes(option.value));
|
|
@@ -845,23 +828,23 @@ class BsMultiCheckboxFieldComponent {
|
|
|
845
828
|
}
|
|
846
829
|
});
|
|
847
830
|
}
|
|
848
|
-
onCheckboxChange(option,
|
|
831
|
+
onCheckboxChange(option, event) {
|
|
832
|
+
const checked = event.target.checked;
|
|
849
833
|
this.valueViewModel.update((currentOptions) => {
|
|
850
834
|
if (checked) {
|
|
851
|
-
return currentOptions.some((opt) => opt.value === option.value)
|
|
835
|
+
return currentOptions.some((opt) => opt.value === option.value)
|
|
836
|
+
? currentOptions
|
|
837
|
+
: [...currentOptions, option];
|
|
852
838
|
}
|
|
853
839
|
else {
|
|
854
840
|
return currentOptions.filter((opt) => opt.value !== option.value);
|
|
855
841
|
}
|
|
856
842
|
});
|
|
857
843
|
}
|
|
858
|
-
isChecked(option) {
|
|
859
|
-
return this.valueViewModel().some((opt) => opt.value === option.value);
|
|
860
|
-
}
|
|
861
844
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
862
845
|
// Accessibility
|
|
863
846
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
864
|
-
|
|
847
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
865
848
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
866
849
|
ariaInvalid = computed(() => {
|
|
867
850
|
const fieldState = this.field()();
|
|
@@ -870,22 +853,11 @@ class BsMultiCheckboxFieldComponent {
|
|
|
870
853
|
ariaRequired = computed(() => {
|
|
871
854
|
return this.field()().required?.() === true ? true : null;
|
|
872
855
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
873
|
-
ariaDescribedBy =
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
ids.push(this.helpTextId());
|
|
877
|
-
}
|
|
878
|
-
const errors = this.errorsToDisplay();
|
|
879
|
-
errors.forEach((_, i) => {
|
|
880
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
881
|
-
});
|
|
882
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
883
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
884
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
885
|
-
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: `
|
|
856
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
857
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
858
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
886
859
|
@let f = field();
|
|
887
|
-
@let
|
|
888
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
860
|
+
@let checked = checkedValuesMap();
|
|
889
861
|
@if (label(); as label) {
|
|
890
862
|
<div class="form-label">{{ label | dynamicText | async }}</div>
|
|
891
863
|
}
|
|
@@ -901,15 +873,15 @@ class BsMultiCheckboxFieldComponent {
|
|
|
901
873
|
<input
|
|
902
874
|
type="checkbox"
|
|
903
875
|
[id]="key() + '_' + i"
|
|
904
|
-
[checked]="
|
|
876
|
+
[checked]="checked['' + option.value]"
|
|
905
877
|
[disabled]="f().disabled() || option.disabled"
|
|
906
|
-
(change)="onCheckboxChange(option, $
|
|
878
|
+
(change)="onCheckboxChange(option, $event)"
|
|
907
879
|
class="form-check-input"
|
|
908
880
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
909
881
|
[attr.tabindex]="tabIndex()"
|
|
910
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
911
|
-
[attr.aria-required]="ariaRequired"
|
|
912
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
882
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
883
|
+
[attr.aria-required]="ariaRequired()"
|
|
884
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
913
885
|
/>
|
|
914
886
|
<label [for]="key() + '_' + i" class="form-check-label">
|
|
915
887
|
{{ option.label | dynamicText | async }}
|
|
@@ -918,22 +890,20 @@ class BsMultiCheckboxFieldComponent {
|
|
|
918
890
|
}
|
|
919
891
|
</div>
|
|
920
892
|
|
|
921
|
-
@if (props()?.helpText; as helpText) {
|
|
922
|
-
<div class="form-text" [id]="helpTextId()">
|
|
923
|
-
{{ helpText | dynamicText | async }}
|
|
924
|
-
</div>
|
|
925
|
-
}
|
|
926
893
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
927
894
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
895
|
+
} @empty {
|
|
896
|
+
@if (props()?.hint; as hint) {
|
|
897
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
898
|
+
}
|
|
928
899
|
}
|
|
929
900
|
`, 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 });
|
|
930
901
|
}
|
|
931
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
902
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsMultiCheckboxFieldComponent, decorators: [{
|
|
932
903
|
type: Component,
|
|
933
904
|
args: [{ selector: 'df-bs-multi-checkbox', imports: [DynamicTextPipe, AsyncPipe], template: `
|
|
934
905
|
@let f = field();
|
|
935
|
-
@let
|
|
936
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
906
|
+
@let checked = checkedValuesMap();
|
|
937
907
|
@if (label(); as label) {
|
|
938
908
|
<div class="form-label">{{ label | dynamicText | async }}</div>
|
|
939
909
|
}
|
|
@@ -949,15 +919,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
949
919
|
<input
|
|
950
920
|
type="checkbox"
|
|
951
921
|
[id]="key() + '_' + i"
|
|
952
|
-
[checked]="
|
|
922
|
+
[checked]="checked['' + option.value]"
|
|
953
923
|
[disabled]="f().disabled() || option.disabled"
|
|
954
|
-
(change)="onCheckboxChange(option, $
|
|
924
|
+
(change)="onCheckboxChange(option, $event)"
|
|
955
925
|
class="form-check-input"
|
|
956
926
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
957
927
|
[attr.tabindex]="tabIndex()"
|
|
958
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
959
|
-
[attr.aria-required]="ariaRequired"
|
|
960
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
928
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
929
|
+
[attr.aria-required]="ariaRequired()"
|
|
930
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
961
931
|
/>
|
|
962
932
|
<label [for]="key() + '_' + i" class="form-check-label">
|
|
963
933
|
{{ option.label | dynamicText | async }}
|
|
@@ -966,13 +936,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
966
936
|
}
|
|
967
937
|
</div>
|
|
968
938
|
|
|
969
|
-
@if (props()?.helpText; as helpText) {
|
|
970
|
-
<div class="form-text" [id]="helpTextId()">
|
|
971
|
-
{{ helpText | dynamicText | async }}
|
|
972
|
-
</div>
|
|
973
|
-
}
|
|
974
939
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
975
940
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
941
|
+
} @empty {
|
|
942
|
+
@if (props()?.hint; as hint) {
|
|
943
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
944
|
+
}
|
|
976
945
|
}
|
|
977
946
|
`, host: {
|
|
978
947
|
'[class]': 'className() || ""',
|
|
@@ -1013,10 +982,9 @@ class BsRadioGroupComponent {
|
|
|
1013
982
|
this.value.set(newValue);
|
|
1014
983
|
}
|
|
1015
984
|
}
|
|
1016
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
1017
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0
|
|
985
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsRadioGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
986
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1018
987
|
@let props = properties();
|
|
1019
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1020
988
|
@if (props?.buttonGroup) {
|
|
1021
989
|
<div class="btn-group" role="group" [attr.aria-label]="label() | dynamicText | async">
|
|
1022
990
|
@for (option of options(); track option.value; let i = $index) {
|
|
@@ -1027,7 +995,7 @@ class BsRadioGroupComponent {
|
|
|
1027
995
|
[checked]="value() === option.value"
|
|
1028
996
|
(change)="onRadioChange(option.value)"
|
|
1029
997
|
[disabled]="disabled() || option.disabled || false"
|
|
1030
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
998
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1031
999
|
class="btn-check"
|
|
1032
1000
|
[id]="name() + '_' + i"
|
|
1033
1001
|
autocomplete="off"
|
|
@@ -1052,7 +1020,7 @@ class BsRadioGroupComponent {
|
|
|
1052
1020
|
[checked]="value() === option.value"
|
|
1053
1021
|
(change)="onRadioChange(option.value)"
|
|
1054
1022
|
[disabled]="disabled() || option.disabled || false"
|
|
1055
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1023
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1056
1024
|
class="form-check-input"
|
|
1057
1025
|
[id]="name() + '_' + i"
|
|
1058
1026
|
/>
|
|
@@ -1064,11 +1032,10 @@ class BsRadioGroupComponent {
|
|
|
1064
1032
|
}
|
|
1065
1033
|
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1066
1034
|
}
|
|
1067
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1035
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsRadioGroupComponent, decorators: [{
|
|
1068
1036
|
type: Component,
|
|
1069
1037
|
args: [{ selector: 'df-bs-radio-group', imports: [DynamicTextPipe, AsyncPipe], template: `
|
|
1070
1038
|
@let props = properties();
|
|
1071
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1072
1039
|
@if (props?.buttonGroup) {
|
|
1073
1040
|
<div class="btn-group" role="group" [attr.aria-label]="label() | dynamicText | async">
|
|
1074
1041
|
@for (option of options(); track option.value; let i = $index) {
|
|
@@ -1079,7 +1046,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1079
1046
|
[checked]="value() === option.value"
|
|
1080
1047
|
(change)="onRadioChange(option.value)"
|
|
1081
1048
|
[disabled]="disabled() || option.disabled || false"
|
|
1082
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1049
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1083
1050
|
class="btn-check"
|
|
1084
1051
|
[id]="name() + '_' + i"
|
|
1085
1052
|
autocomplete="off"
|
|
@@ -1104,7 +1071,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1104
1071
|
[checked]="value() === option.value"
|
|
1105
1072
|
(change)="onRadioChange(option.value)"
|
|
1106
1073
|
[disabled]="disabled() || option.disabled || false"
|
|
1107
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1074
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1108
1075
|
class="form-check-input"
|
|
1109
1076
|
[id]="name() + '_' + i"
|
|
1110
1077
|
/>
|
|
@@ -1142,7 +1109,7 @@ class BsRadioFieldComponent {
|
|
|
1142
1109
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1143
1110
|
// Accessibility
|
|
1144
1111
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1145
|
-
|
|
1112
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1146
1113
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1147
1114
|
ariaInvalid = computed(() => {
|
|
1148
1115
|
const fieldState = this.field()();
|
|
@@ -1151,21 +1118,10 @@ class BsRadioFieldComponent {
|
|
|
1151
1118
|
ariaRequired = computed(() => {
|
|
1152
1119
|
return this.field()().required?.() === true ? true : null;
|
|
1153
1120
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1154
|
-
ariaDescribedBy =
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
ids.push(this.helpTextId());
|
|
1158
|
-
}
|
|
1159
|
-
const errors = this.errorsToDisplay();
|
|
1160
|
-
errors.forEach((_, i) => {
|
|
1161
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
1162
|
-
});
|
|
1163
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
1164
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
1165
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1166
|
-
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: `
|
|
1121
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1123
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1167
1124
|
@let f = field();
|
|
1168
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1169
1125
|
|
|
1170
1126
|
<div class="mb-3">
|
|
1171
1127
|
@if (label(); as label) {
|
|
@@ -1173,27 +1129,27 @@ class BsRadioFieldComponent {
|
|
|
1173
1129
|
}
|
|
1174
1130
|
|
|
1175
1131
|
<df-bs-radio-group
|
|
1176
|
-
[formField]="
|
|
1132
|
+
[formField]="f"
|
|
1177
1133
|
[label]="label()"
|
|
1178
1134
|
[options]="options()"
|
|
1179
1135
|
[properties]="props()"
|
|
1180
|
-
[ariaDescribedBy]="ariaDescribedBy"
|
|
1136
|
+
[ariaDescribedBy]="ariaDescribedBy()"
|
|
1181
1137
|
/>
|
|
1182
1138
|
|
|
1183
|
-
@if (props()?.helpText; as helpText) {
|
|
1184
|
-
<div class="form-text" [id]="helpTextId()">{{ helpText | dynamicText | async }}</div>
|
|
1185
|
-
}
|
|
1186
1139
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1187
1140
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1141
|
+
} @empty {
|
|
1142
|
+
@if (props()?.hint; as hint) {
|
|
1143
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
1144
|
+
}
|
|
1188
1145
|
}
|
|
1189
1146
|
</div>
|
|
1190
1147
|
`, 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 });
|
|
1191
1148
|
}
|
|
1192
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1149
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsRadioFieldComponent, decorators: [{
|
|
1193
1150
|
type: Component,
|
|
1194
1151
|
args: [{ selector: 'df-bs-radio', imports: [BsRadioGroupComponent, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1195
1152
|
@let f = field();
|
|
1196
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1197
1153
|
|
|
1198
1154
|
<div class="mb-3">
|
|
1199
1155
|
@if (label(); as label) {
|
|
@@ -1201,18 +1157,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1201
1157
|
}
|
|
1202
1158
|
|
|
1203
1159
|
<df-bs-radio-group
|
|
1204
|
-
[formField]="
|
|
1160
|
+
[formField]="f"
|
|
1205
1161
|
[label]="label()"
|
|
1206
1162
|
[options]="options()"
|
|
1207
1163
|
[properties]="props()"
|
|
1208
|
-
[ariaDescribedBy]="ariaDescribedBy"
|
|
1164
|
+
[ariaDescribedBy]="ariaDescribedBy()"
|
|
1209
1165
|
/>
|
|
1210
1166
|
|
|
1211
|
-
@if (props()?.helpText; as helpText) {
|
|
1212
|
-
<div class="form-text" [id]="helpTextId()">{{ helpText | dynamicText | async }}</div>
|
|
1213
|
-
}
|
|
1214
1167
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1215
1168
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1169
|
+
} @empty {
|
|
1170
|
+
@if (props()?.hint; as hint) {
|
|
1171
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
1172
|
+
}
|
|
1216
1173
|
}
|
|
1217
1174
|
</div>
|
|
1218
1175
|
`, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
@@ -1258,7 +1215,7 @@ class BsSelectFieldComponent {
|
|
|
1258
1215
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1259
1216
|
// Accessibility
|
|
1260
1217
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1261
|
-
|
|
1218
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1262
1219
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1263
1220
|
ariaInvalid = computed(() => {
|
|
1264
1221
|
const fieldState = this.field()();
|
|
@@ -1267,21 +1224,10 @@ class BsSelectFieldComponent {
|
|
|
1267
1224
|
ariaRequired = computed(() => {
|
|
1268
1225
|
return this.field()().required?.() === true ? true : null;
|
|
1269
1226
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1270
|
-
ariaDescribedBy =
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
}
|
|
1275
|
-
const errors = this.errorsToDisplay();
|
|
1276
|
-
errors.forEach((_, i) => {
|
|
1277
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
1278
|
-
});
|
|
1279
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
1280
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
1281
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1282
|
-
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: `
|
|
1283
|
-
@let f = field(); @let selectId = key() + '-select'; @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
1284
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1227
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1228
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1229
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1230
|
+
@let f = field(); @let selectId = key() + '-select';
|
|
1285
1231
|
|
|
1286
1232
|
<div class="mb-3">
|
|
1287
1233
|
@if (label(); as label) {
|
|
@@ -1296,9 +1242,9 @@ class BsSelectFieldComponent {
|
|
|
1296
1242
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
1297
1243
|
[multiple]="props()?.multiple || false"
|
|
1298
1244
|
[size]="props()?.htmlSize"
|
|
1299
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1300
|
-
[attr.aria-required]="ariaRequired"
|
|
1301
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1245
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1246
|
+
[attr.aria-required]="ariaRequired()"
|
|
1247
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1302
1248
|
>
|
|
1303
1249
|
@if (placeholder(); as placeholder) {
|
|
1304
1250
|
<option value="" disabled [selected]="!f().value()">{{ placeholder | dynamicText | async }}</option>
|
|
@@ -1310,20 +1256,20 @@ class BsSelectFieldComponent {
|
|
|
1310
1256
|
}
|
|
1311
1257
|
</select>
|
|
1312
1258
|
|
|
1313
|
-
@if (props()?.helpText; as helpText) {
|
|
1314
|
-
<div class="form-text" [id]="helpTextId()">{{ helpText | dynamicText | async }}</div>
|
|
1315
|
-
}
|
|
1316
1259
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1317
1260
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1261
|
+
} @empty {
|
|
1262
|
+
@if (props()?.hint; as hint) {
|
|
1263
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
1264
|
+
}
|
|
1318
1265
|
}
|
|
1319
1266
|
</div>
|
|
1320
1267
|
`, 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 });
|
|
1321
1268
|
}
|
|
1322
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1269
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsSelectFieldComponent, decorators: [{
|
|
1323
1270
|
type: Component,
|
|
1324
1271
|
args: [{ selector: 'df-bs-select', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1325
|
-
@let f = field(); @let selectId = key() + '-select';
|
|
1326
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1272
|
+
@let f = field(); @let selectId = key() + '-select';
|
|
1327
1273
|
|
|
1328
1274
|
<div class="mb-3">
|
|
1329
1275
|
@if (label(); as label) {
|
|
@@ -1338,9 +1284,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1338
1284
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
1339
1285
|
[multiple]="props()?.multiple || false"
|
|
1340
1286
|
[size]="props()?.htmlSize"
|
|
1341
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1342
|
-
[attr.aria-required]="ariaRequired"
|
|
1343
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1287
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1288
|
+
[attr.aria-required]="ariaRequired()"
|
|
1289
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1344
1290
|
>
|
|
1345
1291
|
@if (placeholder(); as placeholder) {
|
|
1346
1292
|
<option value="" disabled [selected]="!f().value()">{{ placeholder | dynamicText | async }}</option>
|
|
@@ -1352,11 +1298,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1352
1298
|
}
|
|
1353
1299
|
</select>
|
|
1354
1300
|
|
|
1355
|
-
@if (props()?.helpText; as helpText) {
|
|
1356
|
-
<div class="form-text" [id]="helpTextId()">{{ helpText | dynamicText | async }}</div>
|
|
1357
|
-
}
|
|
1358
1301
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1359
1302
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1303
|
+
} @empty {
|
|
1304
|
+
@if (props()?.hint; as hint) {
|
|
1305
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
1306
|
+
}
|
|
1360
1307
|
}
|
|
1361
1308
|
</div>
|
|
1362
1309
|
`, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
@@ -1396,7 +1343,7 @@ class BsSliderFieldComponent {
|
|
|
1396
1343
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1397
1344
|
// Accessibility
|
|
1398
1345
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1399
|
-
|
|
1346
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1400
1347
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1401
1348
|
ariaInvalid = computed(() => {
|
|
1402
1349
|
const fieldState = this.field()();
|
|
@@ -1405,21 +1352,10 @@ class BsSliderFieldComponent {
|
|
|
1405
1352
|
ariaRequired = computed(() => {
|
|
1406
1353
|
return this.field()().required?.() === true ? true : null;
|
|
1407
1354
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1408
|
-
ariaDescribedBy =
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
}
|
|
1413
|
-
const errors = this.errorsToDisplay();
|
|
1414
|
-
errors.forEach((_, i) => {
|
|
1415
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
1416
|
-
});
|
|
1417
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
1418
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
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: `
|
|
1421
|
-
@let f = field(); @let inputId = key() + '-input'; @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
1422
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1355
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1356
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1357
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1358
|
+
@let f = field(); @let inputId = key() + '-input';
|
|
1423
1359
|
|
|
1424
1360
|
<div class="mb-3">
|
|
1425
1361
|
@if (label(); as label) {
|
|
@@ -1440,28 +1376,26 @@ class BsSliderFieldComponent {
|
|
|
1440
1376
|
[dfMax]="props()?.max ?? max()"
|
|
1441
1377
|
[dfStep]="props()?.step ?? step()"
|
|
1442
1378
|
[attr.tabindex]="tabIndex()"
|
|
1443
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1444
|
-
[attr.aria-required]="ariaRequired"
|
|
1445
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1379
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1380
|
+
[attr.aria-required]="ariaRequired()"
|
|
1381
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1446
1382
|
class="form-range"
|
|
1447
1383
|
/>
|
|
1448
1384
|
|
|
1449
|
-
@if (props()?.helpText; as helpText) {
|
|
1450
|
-
<div class="form-text" [id]="helpTextId()">
|
|
1451
|
-
{{ helpText | dynamicText | async }}
|
|
1452
|
-
</div>
|
|
1453
|
-
}
|
|
1454
1385
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1455
1386
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1387
|
+
} @empty {
|
|
1388
|
+
@if (props()?.hint; as hint) {
|
|
1389
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
1390
|
+
}
|
|
1456
1391
|
}
|
|
1457
1392
|
</div>
|
|
1458
1393
|
`, 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 });
|
|
1459
1394
|
}
|
|
1460
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1395
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsSliderFieldComponent, decorators: [{
|
|
1461
1396
|
type: Component,
|
|
1462
1397
|
args: [{ selector: 'df-bs-slider', imports: [FormField, DynamicTextPipe, AsyncPipe, InputConstraintsDirective], template: `
|
|
1463
|
-
@let f = field(); @let inputId = key() + '-input';
|
|
1464
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1398
|
+
@let f = field(); @let inputId = key() + '-input';
|
|
1465
1399
|
|
|
1466
1400
|
<div class="mb-3">
|
|
1467
1401
|
@if (label(); as label) {
|
|
@@ -1482,19 +1416,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1482
1416
|
[dfMax]="props()?.max ?? max()"
|
|
1483
1417
|
[dfStep]="props()?.step ?? step()"
|
|
1484
1418
|
[attr.tabindex]="tabIndex()"
|
|
1485
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1486
|
-
[attr.aria-required]="ariaRequired"
|
|
1487
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1419
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1420
|
+
[attr.aria-required]="ariaRequired()"
|
|
1421
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1488
1422
|
class="form-range"
|
|
1489
1423
|
/>
|
|
1490
1424
|
|
|
1491
|
-
@if (props()?.helpText; as helpText) {
|
|
1492
|
-
<div class="form-text" [id]="helpTextId()">
|
|
1493
|
-
{{ helpText | dynamicText | async }}
|
|
1494
|
-
</div>
|
|
1495
|
-
}
|
|
1496
1425
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1497
1426
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1427
|
+
} @empty {
|
|
1428
|
+
@if (props()?.hint; as hint) {
|
|
1429
|
+
<div class="form-text" [id]="hintId()">{{ hint | dynamicText | async }}</div>
|
|
1430
|
+
}
|
|
1498
1431
|
}
|
|
1499
1432
|
</div>
|
|
1500
1433
|
`, host: {
|
|
@@ -1531,7 +1464,7 @@ class BsTextareaFieldComponent {
|
|
|
1531
1464
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1532
1465
|
// Accessibility
|
|
1533
1466
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1534
|
-
|
|
1467
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1535
1468
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1536
1469
|
ariaInvalid = computed(() => {
|
|
1537
1470
|
const fieldState = this.field()();
|
|
@@ -1540,21 +1473,10 @@ class BsTextareaFieldComponent {
|
|
|
1540
1473
|
ariaRequired = computed(() => {
|
|
1541
1474
|
return this.field()().required?.() === true ? true : null;
|
|
1542
1475
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1543
|
-
ariaDescribedBy =
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
}
|
|
1548
|
-
const errors = this.errorsToDisplay();
|
|
1549
|
-
errors.forEach((_, i) => {
|
|
1550
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
1551
|
-
});
|
|
1552
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
1553
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
1554
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1555
|
-
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: `
|
|
1556
|
-
@let f = field(); @let p = props(); @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
1557
|
-
@let ariaDescribedBy = this.ariaDescribedBy(); @let textareaId = key() + '-textarea';
|
|
1476
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1477
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1478
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1479
|
+
@let f = field(); @let p = props(); @let textareaId = key() + '-textarea';
|
|
1558
1480
|
@if (p?.floatingLabel) {
|
|
1559
1481
|
<!-- Floating label variant -->
|
|
1560
1482
|
<div class="form-floating mb-3">
|
|
@@ -1563,9 +1485,9 @@ class BsTextareaFieldComponent {
|
|
|
1563
1485
|
[id]="textareaId"
|
|
1564
1486
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
1565
1487
|
[attr.tabindex]="tabIndex()"
|
|
1566
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1567
|
-
[attr.aria-required]="ariaRequired"
|
|
1568
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1488
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1489
|
+
[attr.aria-required]="ariaRequired()"
|
|
1490
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1569
1491
|
class="form-control"
|
|
1570
1492
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
1571
1493
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -1597,9 +1519,9 @@ class BsTextareaFieldComponent {
|
|
|
1597
1519
|
[id]="textareaId"
|
|
1598
1520
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
1599
1521
|
[attr.tabindex]="tabIndex()"
|
|
1600
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1601
|
-
[attr.aria-required]="ariaRequired"
|
|
1602
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1522
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1523
|
+
[attr.aria-required]="ariaRequired()"
|
|
1524
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1603
1525
|
class="form-control"
|
|
1604
1526
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
1605
1527
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -1607,11 +1529,6 @@ class BsTextareaFieldComponent {
|
|
|
1607
1529
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
1608
1530
|
></textarea>
|
|
1609
1531
|
|
|
1610
|
-
@if (p?.helpText) {
|
|
1611
|
-
<div class="form-text" [id]="helpTextId()">
|
|
1612
|
-
{{ p?.helpText | dynamicText | async }}
|
|
1613
|
-
</div>
|
|
1614
|
-
}
|
|
1615
1532
|
@if (p?.validFeedback && f().valid() && f().touched()) {
|
|
1616
1533
|
<div class="valid-feedback d-block">
|
|
1617
1534
|
{{ p?.validFeedback | dynamicText | async }}
|
|
@@ -1619,16 +1536,19 @@ class BsTextareaFieldComponent {
|
|
|
1619
1536
|
}
|
|
1620
1537
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1621
1538
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1539
|
+
} @empty {
|
|
1540
|
+
@if (p?.hint) {
|
|
1541
|
+
<div class="form-text" [id]="hintId()">{{ p?.hint | dynamicText | async }}</div>
|
|
1542
|
+
}
|
|
1622
1543
|
}
|
|
1623
1544
|
</div>
|
|
1624
1545
|
}
|
|
1625
1546
|
`, 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 });
|
|
1626
1547
|
}
|
|
1627
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1548
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsTextareaFieldComponent, decorators: [{
|
|
1628
1549
|
type: Component,
|
|
1629
1550
|
args: [{ selector: 'df-bs-textarea', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1630
|
-
@let f = field(); @let p = props(); @let
|
|
1631
|
-
@let ariaDescribedBy = this.ariaDescribedBy(); @let textareaId = key() + '-textarea';
|
|
1551
|
+
@let f = field(); @let p = props(); @let textareaId = key() + '-textarea';
|
|
1632
1552
|
@if (p?.floatingLabel) {
|
|
1633
1553
|
<!-- Floating label variant -->
|
|
1634
1554
|
<div class="form-floating mb-3">
|
|
@@ -1637,9 +1557,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1637
1557
|
[id]="textareaId"
|
|
1638
1558
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
1639
1559
|
[attr.tabindex]="tabIndex()"
|
|
1640
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1641
|
-
[attr.aria-required]="ariaRequired"
|
|
1642
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1560
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1561
|
+
[attr.aria-required]="ariaRequired()"
|
|
1562
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1643
1563
|
class="form-control"
|
|
1644
1564
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
1645
1565
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -1671,9 +1591,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1671
1591
|
[id]="textareaId"
|
|
1672
1592
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
1673
1593
|
[attr.tabindex]="tabIndex()"
|
|
1674
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1675
|
-
[attr.aria-required]="ariaRequired"
|
|
1676
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1594
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1595
|
+
[attr.aria-required]="ariaRequired()"
|
|
1596
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1677
1597
|
class="form-control"
|
|
1678
1598
|
[class.form-control-sm]="p?.size === 'sm'"
|
|
1679
1599
|
[class.form-control-lg]="p?.size === 'lg'"
|
|
@@ -1681,11 +1601,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1681
1601
|
[class.is-valid]="f().valid() && f().touched() && p?.validFeedback"
|
|
1682
1602
|
></textarea>
|
|
1683
1603
|
|
|
1684
|
-
@if (p?.helpText) {
|
|
1685
|
-
<div class="form-text" [id]="helpTextId()">
|
|
1686
|
-
{{ p?.helpText | dynamicText | async }}
|
|
1687
|
-
</div>
|
|
1688
|
-
}
|
|
1689
1604
|
@if (p?.validFeedback && f().valid() && f().touched()) {
|
|
1690
1605
|
<div class="valid-feedback d-block">
|
|
1691
1606
|
{{ p?.validFeedback | dynamicText | async }}
|
|
@@ -1693,6 +1608,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1693
1608
|
}
|
|
1694
1609
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1695
1610
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1611
|
+
} @empty {
|
|
1612
|
+
@if (p?.hint) {
|
|
1613
|
+
<div class="form-text" [id]="hintId()">{{ p?.hint | dynamicText | async }}</div>
|
|
1614
|
+
}
|
|
1696
1615
|
}
|
|
1697
1616
|
</div>
|
|
1698
1617
|
}
|
|
@@ -1730,7 +1649,7 @@ class BsToggleFieldComponent {
|
|
|
1730
1649
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1731
1650
|
// Accessibility
|
|
1732
1651
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1733
|
-
|
|
1652
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1734
1653
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1735
1654
|
ariaInvalid = computed(() => {
|
|
1736
1655
|
const fieldState = this.field()();
|
|
@@ -1739,21 +1658,10 @@ class BsToggleFieldComponent {
|
|
|
1739
1658
|
ariaRequired = computed(() => {
|
|
1740
1659
|
return this.field()().required?.() === true ? true : null;
|
|
1741
1660
|
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1742
|
-
ariaDescribedBy =
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
}
|
|
1747
|
-
const errors = this.errorsToDisplay();
|
|
1748
|
-
errors.forEach((_, i) => {
|
|
1749
|
-
ids.push(`${this.errorId()}-${i}`);
|
|
1750
|
-
});
|
|
1751
|
-
return ids.length > 0 ? ids.join(' ') : null;
|
|
1752
|
-
}, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
1753
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: BsToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1754
|
-
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: `
|
|
1755
|
-
@let f = field(); @let inputId = key() + '-input'; @let ariaInvalid = this.ariaInvalid(); @let ariaRequired = this.ariaRequired();
|
|
1756
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1661
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1662
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1663
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1664
|
+
@let f = field(); @let inputId = key() + '-input';
|
|
1757
1665
|
|
|
1758
1666
|
<div
|
|
1759
1667
|
class="form-check form-switch"
|
|
@@ -1770,30 +1678,28 @@ class BsToggleFieldComponent {
|
|
|
1770
1678
|
class="form-check-input"
|
|
1771
1679
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
1772
1680
|
[attr.tabindex]="tabIndex()"
|
|
1773
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1774
|
-
[attr.aria-required]="ariaRequired"
|
|
1775
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1681
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1682
|
+
[attr.aria-required]="ariaRequired()"
|
|
1683
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1776
1684
|
/>
|
|
1777
1685
|
<label [for]="inputId" class="form-check-label">
|
|
1778
1686
|
{{ label() | dynamicText | async }}
|
|
1779
1687
|
</label>
|
|
1780
1688
|
</div>
|
|
1781
1689
|
|
|
1782
|
-
@if (props()?.helpText; as helpText) {
|
|
1783
|
-
<div class="form-text" [id]="helpTextId()" [attr.hidden]="f().hidden() || null">
|
|
1784
|
-
{{ helpText | dynamicText | async }}
|
|
1785
|
-
</div>
|
|
1786
|
-
}
|
|
1787
1690
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1788
1691
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1692
|
+
} @empty {
|
|
1693
|
+
@if (props()?.hint; as hint) {
|
|
1694
|
+
<div class="form-text" [id]="hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
|
|
1695
|
+
}
|
|
1789
1696
|
}
|
|
1790
1697
|
`, 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 });
|
|
1791
1698
|
}
|
|
1792
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1699
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BsToggleFieldComponent, decorators: [{
|
|
1793
1700
|
type: Component,
|
|
1794
1701
|
args: [{ selector: 'df-bs-toggle', imports: [FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1795
|
-
@let f = field(); @let inputId = key() + '-input';
|
|
1796
|
-
@let ariaDescribedBy = this.ariaDescribedBy();
|
|
1702
|
+
@let f = field(); @let inputId = key() + '-input';
|
|
1797
1703
|
|
|
1798
1704
|
<div
|
|
1799
1705
|
class="form-check form-switch"
|
|
@@ -1810,22 +1716,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1810
1716
|
class="form-check-input"
|
|
1811
1717
|
[class.is-invalid]="f().invalid() && f().touched()"
|
|
1812
1718
|
[attr.tabindex]="tabIndex()"
|
|
1813
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1814
|
-
[attr.aria-required]="ariaRequired"
|
|
1815
|
-
[attr.aria-describedby]="ariaDescribedBy"
|
|
1719
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1720
|
+
[attr.aria-required]="ariaRequired()"
|
|
1721
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1816
1722
|
/>
|
|
1817
1723
|
<label [for]="inputId" class="form-check-label">
|
|
1818
1724
|
{{ label() | dynamicText | async }}
|
|
1819
1725
|
</label>
|
|
1820
1726
|
</div>
|
|
1821
1727
|
|
|
1822
|
-
@if (props()?.helpText; as helpText) {
|
|
1823
|
-
<div class="form-text" [id]="helpTextId()" [attr.hidden]="f().hidden() || null">
|
|
1824
|
-
{{ helpText | dynamicText | async }}
|
|
1825
|
-
</div>
|
|
1826
|
-
}
|
|
1827
1728
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1828
1729
|
<div class="invalid-feedback d-block" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</div>
|
|
1730
|
+
} @empty {
|
|
1731
|
+
@if (props()?.hint; as hint) {
|
|
1732
|
+
<div class="form-text" [id]="hintId()" [attr.hidden]="f().hidden() || null">{{ hint | dynamicText | async }}</div>
|
|
1733
|
+
}
|
|
1829
1734
|
}
|
|
1830
1735
|
`, host: {
|
|
1831
1736
|
'[class]': 'className()',
|
|
@@ -1873,9 +1778,9 @@ const BsField = {
|
|
|
1873
1778
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1874
1779
|
*/
|
|
1875
1780
|
function buttonFieldMapper(fieldDef) {
|
|
1876
|
-
|
|
1877
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1781
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1878
1782
|
return computed(() => {
|
|
1783
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1879
1784
|
const inputs = {
|
|
1880
1785
|
...baseInputs,
|
|
1881
1786
|
};
|
|
@@ -1913,20 +1818,21 @@ function buttonFieldMapper(fieldDef) {
|
|
|
1913
1818
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1914
1819
|
*/
|
|
1915
1820
|
function submitButtonFieldMapper(fieldDef) {
|
|
1916
|
-
|
|
1917
|
-
const
|
|
1918
|
-
|
|
1919
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1920
|
-
// Use button-logic-resolver to compute disabled state
|
|
1821
|
+
const rootFormRegistry = inject(RootFormRegistryService);
|
|
1822
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1823
|
+
const formOptions = inject(FORM_OPTIONS);
|
|
1921
1824
|
const fieldWithLogic = fieldDef;
|
|
1922
|
-
const disabledSignal = resolveSubmitButtonDisabled({
|
|
1923
|
-
form: fieldSignalContext.form,
|
|
1924
|
-
formOptions: fieldSignalContext.formOptions,
|
|
1925
|
-
fieldLogic: fieldWithLogic.logic,
|
|
1926
|
-
explicitlyDisabled: fieldDef.disabled,
|
|
1927
|
-
});
|
|
1928
|
-
// Return computed signal - evaluates disabledSignal inside for reactivity
|
|
1929
1825
|
return computed(() => {
|
|
1826
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1827
|
+
// Use rootFormRegistry instead of fieldSignalContext.form because when the submit button
|
|
1828
|
+
// is inside a group/array, fieldSignalContext.form points to the nested form tree,
|
|
1829
|
+
// not the root form. We need root form validity for submit button disabled state (#157).
|
|
1830
|
+
const disabledSignal = resolveSubmitButtonDisabled({
|
|
1831
|
+
form: rootFormRegistry.getRootForm(),
|
|
1832
|
+
formOptions: formOptions(),
|
|
1833
|
+
fieldLogic: fieldWithLogic.logic,
|
|
1834
|
+
explicitlyDisabled: fieldDef.disabled,
|
|
1835
|
+
});
|
|
1930
1836
|
const inputs = {
|
|
1931
1837
|
...baseInputs,
|
|
1932
1838
|
// No event - native form submit handles it via form's onNativeSubmit
|
|
@@ -1953,21 +1859,19 @@ function submitButtonFieldMapper(fieldDef) {
|
|
|
1953
1859
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1954
1860
|
*/
|
|
1955
1861
|
function nextButtonFieldMapper(fieldDef) {
|
|
1956
|
-
// Inject field signal context to access form state and options
|
|
1957
1862
|
const fieldSignalContext = inject(FIELD_SIGNAL_CONTEXT);
|
|
1958
|
-
|
|
1959
|
-
const
|
|
1960
|
-
// Use button-logic-resolver to compute disabled state
|
|
1863
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1864
|
+
const formOptions = inject(FORM_OPTIONS);
|
|
1961
1865
|
const fieldWithLogic = fieldDef;
|
|
1962
|
-
const disabledSignal = resolveNextButtonDisabled({
|
|
1963
|
-
form: fieldSignalContext.form,
|
|
1964
|
-
formOptions: fieldSignalContext.formOptions,
|
|
1965
|
-
fieldLogic: fieldWithLogic.logic,
|
|
1966
|
-
explicitlyDisabled: fieldDef.disabled,
|
|
1967
|
-
currentPageValid: fieldSignalContext.currentPageValid,
|
|
1968
|
-
});
|
|
1969
|
-
// Return computed signal - evaluates disabledSignal inside for reactivity
|
|
1970
1866
|
return computed(() => {
|
|
1867
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1868
|
+
const disabledSignal = resolveNextButtonDisabled({
|
|
1869
|
+
form: fieldSignalContext.form,
|
|
1870
|
+
formOptions: formOptions(),
|
|
1871
|
+
fieldLogic: fieldWithLogic.logic,
|
|
1872
|
+
explicitlyDisabled: fieldDef.disabled,
|
|
1873
|
+
currentPageValid: fieldSignalContext.currentPageValid,
|
|
1874
|
+
});
|
|
1971
1875
|
const inputs = {
|
|
1972
1876
|
...baseInputs,
|
|
1973
1877
|
event: NextPageEvent,
|
|
@@ -1988,9 +1892,9 @@ function nextButtonFieldMapper(fieldDef) {
|
|
|
1988
1892
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1989
1893
|
*/
|
|
1990
1894
|
function previousButtonFieldMapper(fieldDef) {
|
|
1991
|
-
|
|
1992
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1895
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1993
1896
|
return computed(() => {
|
|
1897
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1994
1898
|
const inputs = {
|
|
1995
1899
|
...baseInputs,
|
|
1996
1900
|
event: PreviousPageEvent,
|
|
@@ -2016,10 +1920,9 @@ function previousButtonFieldMapper(fieldDef) {
|
|
|
2016
1920
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
2017
1921
|
*/
|
|
2018
1922
|
function addArrayItemButtonFieldMapper(fieldDef) {
|
|
2019
|
-
// Try to get array context (available when inside an array)
|
|
2020
|
-
// Use optional injection so it doesn't fail when outside an array
|
|
2021
1923
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
2022
1924
|
const logger = inject(DynamicFormLogger);
|
|
1925
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
2023
1926
|
// Determine the target array key
|
|
2024
1927
|
// Priority: explicit arrayKey from fieldDef > arrayKey from context
|
|
2025
1928
|
const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
|
|
@@ -2027,13 +1930,12 @@ function addArrayItemButtonFieldMapper(fieldDef) {
|
|
|
2027
1930
|
logger.warn(`addArrayItem button "${fieldDef.key}" has no array context. ` +
|
|
2028
1931
|
'Either place it inside an array field, or provide an explicit arrayKey property.');
|
|
2029
1932
|
}
|
|
2030
|
-
// Build base inputs (static, from field definition)
|
|
2031
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
2032
1933
|
// Set default eventArgs for AddArrayItemEvent (arrayKey)
|
|
2033
1934
|
// User can override by providing eventArgs in field definition
|
|
2034
1935
|
const defaultEventArgs = ['$arrayKey'];
|
|
2035
1936
|
const eventArgs = 'eventArgs' in fieldDef && fieldDef.eventArgs !== undefined ? fieldDef.eventArgs : defaultEventArgs;
|
|
2036
1937
|
return computed(() => {
|
|
1938
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
2037
1939
|
// Read signal value if index is a signal (supports differential updates)
|
|
2038
1940
|
const getIndex = () => {
|
|
2039
1941
|
if (!arrayContext)
|
|
@@ -2072,10 +1974,9 @@ function addArrayItemButtonFieldMapper(fieldDef) {
|
|
|
2072
1974
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
2073
1975
|
*/
|
|
2074
1976
|
function removeArrayItemButtonFieldMapper(fieldDef) {
|
|
2075
|
-
// Try to get array context (available when inside an array)
|
|
2076
|
-
// Use optional injection so it doesn't fail when outside an array
|
|
2077
1977
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
2078
1978
|
const logger = inject(DynamicFormLogger);
|
|
1979
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
2079
1980
|
// Determine the target array key
|
|
2080
1981
|
// Priority: explicit arrayKey from fieldDef > arrayKey from context
|
|
2081
1982
|
const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
|
|
@@ -2083,14 +1984,13 @@ function removeArrayItemButtonFieldMapper(fieldDef) {
|
|
|
2083
1984
|
logger.warn(`removeArrayItem button "${fieldDef.key}" has no array context. ` +
|
|
2084
1985
|
'Either place it inside an array field, or provide an explicit arrayKey property.');
|
|
2085
1986
|
}
|
|
2086
|
-
// Build base inputs (static, from field definition)
|
|
2087
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
2088
1987
|
// Set default eventArgs for RemoveArrayItemEvent (arrayKey, index if inside array)
|
|
2089
1988
|
// When outside array, only pass arrayKey (removes last by default)
|
|
2090
1989
|
// User can override by providing eventArgs in field definition
|
|
2091
1990
|
const defaultEventArgs = arrayContext ? ['$arrayKey', '$index'] : ['$arrayKey'];
|
|
2092
1991
|
const eventArgs = 'eventArgs' in fieldDef && fieldDef.eventArgs !== undefined ? fieldDef.eventArgs : defaultEventArgs;
|
|
2093
1992
|
return computed(() => {
|
|
1993
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
2094
1994
|
// Read signal value if index is a signal (supports differential updates)
|
|
2095
1995
|
const getIndex = () => {
|
|
2096
1996
|
if (!arrayContext)
|