@ng-forge/dynamic-forms 0.1.2 → 0.2.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.
Files changed (19) hide show
  1. package/fesm2022/ng-forge-dynamic-forms-integration.mjs +313 -0
  2. package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -0
  3. package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-BWj75LVN.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-CZBdtTAU.mjs} +977 -1198
  4. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CZBdtTAU.mjs.map +1 -0
  5. package/fesm2022/{ng-forge-dynamic-forms-page-field.component-ZVrJUMNb.mjs → ng-forge-dynamic-forms-page-field.component-BM32StxL.mjs} +18 -25
  6. package/fesm2022/ng-forge-dynamic-forms-page-field.component-BM32StxL.mjs.map +1 -0
  7. package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-CbctXjtc.mjs +31 -0
  8. package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-CbctXjtc.mjs.map +1 -0
  9. package/fesm2022/ng-forge-dynamic-forms-testing.mjs +971 -0
  10. package/fesm2022/ng-forge-dynamic-forms-testing.mjs.map +1 -0
  11. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-BKTbxAKn.mjs → ng-forge-dynamic-forms-text-field.component-C0I8jf9T.mjs} +5 -5
  12. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-BKTbxAKn.mjs.map → ng-forge-dynamic-forms-text-field.component-C0I8jf9T.mjs.map} +1 -1
  13. package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
  14. package/package.json +12 -4
  15. package/types/ng-forge-dynamic-forms-integration.d.ts +327 -0
  16. package/types/ng-forge-dynamic-forms-testing.d.ts +566 -0
  17. package/types/ng-forge-dynamic-forms.d.ts +217 -495
  18. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-BWj75LVN.mjs.map +0 -1
  19. package/fesm2022/ng-forge-dynamic-forms-page-field.component-ZVrJUMNb.mjs.map +0 -1
@@ -0,0 +1,313 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, computed, signal, Injector, Pipe } from '@angular/core';
3
+ import { FIELD_SIGNAL_CONTEXT, omit, buildBaseInputs, DynamicFormLogger, dynamicTextToObservable, interpolateParams } from '@ng-forge/dynamic-forms';
4
+ import { toObservable, toSignal } from '@angular/core/rxjs-interop';
5
+ import { combineLatest, of } from 'rxjs';
6
+ import { switchMap, map } from 'rxjs/operators';
7
+
8
+ /**
9
+ * Resolves the field tree and default validation messages from the form context.
10
+ * Must be called within an injection context.
11
+ *
12
+ * Uses type-safe field tree utilities to access child FieldTrees from the parent form.
13
+ *
14
+ * @param fieldKey The key of the field to resolve
15
+ * @returns The resolved context with field tree and validation messages
16
+ */
17
+ function resolveValueFieldContext(fieldKey) {
18
+ const context = inject(FIELD_SIGNAL_CONTEXT);
19
+ const defaultValidationMessages = context.defaultValidationMessages;
20
+ const formRoot = context.form;
21
+ const fieldTree = formRoot[fieldKey];
22
+ return { fieldTree, defaultValidationMessages };
23
+ }
24
+ /**
25
+ * Builds the base inputs for a value field.
26
+ * This is a helper function used by valueFieldMapper and specialized mappers.
27
+ *
28
+ * @param fieldDef The value field definition
29
+ * @param ctx The resolved value field context
30
+ * @returns Record of input names to values
31
+ */
32
+ function buildValueFieldInputs(fieldDef, ctx) {
33
+ const omittedFields = omit(fieldDef, ['value']);
34
+ const baseInputs = buildBaseInputs(omittedFields);
35
+ const inputs = {
36
+ ...baseInputs,
37
+ validationMessages: fieldDef.validationMessages ?? {},
38
+ };
39
+ if (fieldDef.placeholder !== undefined) {
40
+ inputs['placeholder'] = fieldDef.placeholder;
41
+ }
42
+ if (ctx.defaultValidationMessages !== undefined) {
43
+ inputs['defaultValidationMessages'] = ctx.defaultValidationMessages;
44
+ }
45
+ if (ctx.fieldTree !== undefined) {
46
+ inputs['field'] = ctx.fieldTree;
47
+ }
48
+ return inputs;
49
+ }
50
+ /**
51
+ * Maps a value field definition to component inputs.
52
+ *
53
+ * Value fields are input fields that contribute to the form's value (text, number, etc.).
54
+ * This mapper injects FIELD_SIGNAL_CONTEXT to access the form structure and retrieve the field proxy.
55
+ *
56
+ * For fields with specific properties (select, datepicker, textarea, slider), use the specialized mappers:
57
+ * - selectFieldMapper: for fields with options (select, radio, multi-checkbox)
58
+ * - datepickerFieldMapper: for fields with minDate, maxDate, startAt
59
+ * - textareaFieldMapper: for fields with rows, cols
60
+ * - sliderFieldMapper: for fields with minValue, maxValue, step
61
+ *
62
+ * @param fieldDef The value field definition
63
+ * @returns Signal containing Record of input names to values for ngComponentOutlet
64
+ */
65
+ function valueFieldMapper(fieldDef) {
66
+ const ctx = resolveValueFieldContext(fieldDef.key);
67
+ return computed(() => buildValueFieldInputs(fieldDef, ctx));
68
+ }
69
+
70
+ /**
71
+ * Maps a checkbox/toggle field definition to component inputs.
72
+ *
73
+ * Checkbox fields are checked fields that contribute to the form's value as boolean.
74
+ * This mapper injects FIELD_SIGNAL_CONTEXT to access the form structure and retrieve the field tree.
75
+ *
76
+ * @param fieldDef The checkbox field definition
77
+ * @returns Signal containing Record of input names to values for ngComponentOutlet
78
+ */
79
+ function checkboxFieldMapper(fieldDef) {
80
+ const context = inject(FIELD_SIGNAL_CONTEXT);
81
+ const omittedFields = omit(fieldDef, ['value']);
82
+ const baseInputs = buildBaseInputs(omittedFields);
83
+ const defaultValidationMessages = context.defaultValidationMessages;
84
+ const formRoot = context.form;
85
+ const fieldTree = formRoot[fieldDef.key];
86
+ return computed(() => {
87
+ const inputs = {
88
+ ...baseInputs,
89
+ validationMessages: fieldDef.validationMessages ?? {},
90
+ };
91
+ if (fieldDef.placeholder !== undefined) {
92
+ inputs['placeholder'] = fieldDef.placeholder;
93
+ }
94
+ if (defaultValidationMessages !== undefined) {
95
+ inputs['defaultValidationMessages'] = defaultValidationMessages;
96
+ }
97
+ if (fieldTree !== undefined) {
98
+ inputs['field'] = fieldTree;
99
+ }
100
+ return inputs;
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Maps a datepicker field to component inputs.
106
+ *
107
+ * Extends the base value field mapper by adding datepicker-specific properties:
108
+ * - minDate: Minimum selectable date
109
+ * - maxDate: Maximum selectable date
110
+ * - startAt: Initial date to display when opening the picker
111
+ *
112
+ * @param fieldDef The datepicker field definition
113
+ * @returns Signal containing Record of input names to values for ngComponentOutlet
114
+ */
115
+ function datepickerFieldMapper(fieldDef) {
116
+ const ctx = resolveValueFieldContext(fieldDef.key);
117
+ return computed(() => {
118
+ const inputs = buildValueFieldInputs(fieldDef, ctx);
119
+ // Add datepicker-specific properties
120
+ if (fieldDef.minDate !== undefined) {
121
+ inputs['minDate'] = fieldDef.minDate;
122
+ }
123
+ if (fieldDef.maxDate !== undefined) {
124
+ inputs['maxDate'] = fieldDef.maxDate;
125
+ }
126
+ if (fieldDef.startAt !== undefined) {
127
+ inputs['startAt'] = fieldDef.startAt;
128
+ }
129
+ return inputs;
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Maps a field with options (select, radio, multi-checkbox) to component inputs.
135
+ *
136
+ * Extends the base value field mapper by adding the options property.
137
+ *
138
+ * @param fieldDef The field definition with options
139
+ * @returns Signal containing Record of input names to values for ngComponentOutlet
140
+ */
141
+ function optionsFieldMapper(fieldDef) {
142
+ const ctx = resolveValueFieldContext(fieldDef.key);
143
+ return computed(() => {
144
+ // Cast to BaseValueField - safe because all FieldWithOptions types extend BaseValueField
145
+ const inputs = buildValueFieldInputs(fieldDef, ctx);
146
+ // Add options property
147
+ inputs['options'] = fieldDef.options;
148
+ return inputs;
149
+ });
150
+ }
151
+
152
+ // UI-specific field mappers
153
+
154
+ /**
155
+ * Factory function that creates a signal of resolved validation errors
156
+ * Handles async resolution of DynamicText validation messages
157
+ *
158
+ * @param field - Signal containing FieldTree
159
+ * @param validationMessages - Signal containing custom field-level validation messages
160
+ * @param defaultValidationMessages - Signal containing default validation messages (fallback)
161
+ * @param injector - Optional injector for DynamicText resolution
162
+ * @returns Signal<ResolvedError[]> - Reactively resolved error messages
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * readonly resolvedErrors = createResolvedErrorsSignal(
167
+ * this.field,
168
+ * this.validationMessages,
169
+ * this.defaultValidationMessages
170
+ * );
171
+ * ```
172
+ */
173
+ function createResolvedErrorsSignal(field, validationMessages, defaultValidationMessages = signal(undefined), injector = inject(Injector)) {
174
+ // Get logger from injector
175
+ const logger = injector.get(DynamicFormLogger);
176
+ // Ensure validationMessages is never undefined (mappers pass {} if not defined)
177
+ const messages = computed(() => validationMessages() ?? {}, ...(ngDevMode ? [{ debugName: "messages" }] : []));
178
+ const defaultMessages = computed(() => defaultValidationMessages() ?? {}, ...(ngDevMode ? [{ debugName: "defaultMessages" }] : []));
179
+ // Create a computed signal that reads the actual errors from the field
180
+ // This ensures the signal tracks changes to field().errors(), not just the field reference
181
+ const errors = computed(() => {
182
+ const control = field()();
183
+ return control.errors();
184
+ }, ...(ngDevMode ? [{ debugName: "errors" }] : []));
185
+ // Convert signals to observables using toObservable with injector
186
+ const errors$ = toObservable(errors, { injector });
187
+ const messages$ = toObservable(messages, { injector });
188
+ const defaultMessages$ = toObservable(defaultMessages, { injector });
189
+ // Combine observables and process errors
190
+ const resolvedErrors$ = combineLatest([errors$, messages$, defaultMessages$]).pipe(switchMap(([currentErrors, msgs, defaultMsgs]) => {
191
+ // No errors - return empty array
192
+ if (!currentErrors || currentErrors.length === 0) {
193
+ return of([]);
194
+ }
195
+ // Create observable for each error's resolved message
196
+ const errorResolvers = currentErrors.map((error) => resolveErrorMessage(error, msgs, defaultMsgs, injector, logger));
197
+ // Combine all error message observables into single array emission, filtering out nulls
198
+ return errorResolvers.length > 0
199
+ ? combineLatest(errorResolvers).pipe(map((errors) => errors.filter((e) => e !== null)))
200
+ : of([]);
201
+ }));
202
+ // Convert observable back to signal using toSignal with injector
203
+ // toSignal properly handles the injection context and manages subscriptions
204
+ return toSignal(resolvedErrors$, { initialValue: [], injector });
205
+ }
206
+ /**
207
+ * Resolves a single error message from DynamicText sources with fallback logic
208
+ * Priority: field-level message → default message → no message (logs warning)
209
+ * @internal
210
+ */
211
+ function resolveErrorMessage(error, fieldMessages, defaultMessages, injector, logger) {
212
+ // Check for field-level custom message first
213
+ const fieldMessage = fieldMessages[error.kind];
214
+ // Fall back to default message if no field-level message exists
215
+ const defaultMessage = defaultMessages[error.kind];
216
+ // Determine which message to use: field-level → default
217
+ const messageToUse = fieldMessage ?? defaultMessage;
218
+ // If no message found, log warning and return null (will be filtered out)
219
+ if (!messageToUse) {
220
+ logger.warn(`No validation message found for error kind "${error.kind}". ` +
221
+ `Please provide a message via field-level validationMessages or form-level defaultValidationMessages.`);
222
+ return of(null);
223
+ }
224
+ // Convert DynamicText to Observable
225
+ const messageObservable = dynamicTextToObservable(messageToUse, injector);
226
+ // Apply parameter interpolation to support {{param}} syntax
227
+ return messageObservable.pipe(map((msg) => ({
228
+ kind: error.kind,
229
+ message: interpolateParams(msg, error),
230
+ })));
231
+ }
232
+
233
+ /**
234
+ * Computed signal that determines if errors should be displayed
235
+ * Based on field's invalid, touched, and error count
236
+ *
237
+ * @param field - Signal containing FieldTree
238
+ * @returns Signal<boolean> - True if errors should be displayed
239
+ */
240
+ function shouldShowErrors(field) {
241
+ return computed(() => {
242
+ const fieldTree = field();
243
+ const control = fieldTree();
244
+ return control.invalid() && control.touched() && control.errors().length > 0;
245
+ });
246
+ }
247
+
248
+ /**
249
+ * Performs a deep equality comparison between two values
250
+ */
251
+ function isEqual(a, b) {
252
+ if (a === b)
253
+ return true;
254
+ if (a == null || b == null)
255
+ return false;
256
+ if (typeof a !== typeof b)
257
+ return false;
258
+ if (a instanceof Date && b instanceof Date) {
259
+ return a.getTime() === b.getTime();
260
+ }
261
+ if (Array.isArray(a) && Array.isArray(b)) {
262
+ if (a.length !== b.length)
263
+ return false;
264
+ return a.every((item, index) => isEqual(item, b[index]));
265
+ }
266
+ if (typeof a === 'object' && typeof b === 'object') {
267
+ const keysA = Object.keys(a);
268
+ const keysB = Object.keys(b);
269
+ if (keysA.length !== keysB.length)
270
+ return false;
271
+ return keysA.every((key) => keysB.includes(key) && isEqual(a[key], b[key]));
272
+ }
273
+ return Object.is(a, b);
274
+ }
275
+
276
+ // Error display utilities for field components
277
+
278
+ class ValueInArrayPipe {
279
+ transform(element, array) {
280
+ return array?.includes(element) ?? false;
281
+ }
282
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ValueInArrayPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
283
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: ValueInArrayPipe, isStandalone: true, name: "inArray" });
284
+ }
285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ValueInArrayPipe, decorators: [{
286
+ type: Pipe,
287
+ args: [{
288
+ pure: true,
289
+ name: 'inArray',
290
+ }]
291
+ }] });
292
+
293
+ /**
294
+ * @ng-forge/dynamic-forms/integration
295
+ *
296
+ * Integration API for UI library authors building field implementations
297
+ * (Material, Bootstrap, PrimeNG, Ionic, etc.)
298
+ *
299
+ * This entrypoint provides:
300
+ * - Specific field type definitions (InputField, SelectField, etc.)
301
+ * - Field mappers for creating FieldTypeDefinition
302
+ * - Error display utilities for field components
303
+ */
304
+ // =============================================================================
305
+ // Field Mappers
306
+ // =============================================================================
307
+
308
+ /**
309
+ * Generated bundle index. Do not edit.
310
+ */
311
+
312
+ export { ValueInArrayPipe, buildValueFieldInputs, checkboxFieldMapper, createResolvedErrorsSignal, datepickerFieldMapper, isEqual, optionsFieldMapper, resolveValueFieldContext, shouldShowErrors, valueFieldMapper };
313
+ //# sourceMappingURL=ng-forge-dynamic-forms-integration.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-integration.mjs","sources":["../../../../packages/dynamic-forms/integration/src/mappers/value/value-field.mapper.ts","../../../../packages/dynamic-forms/integration/src/mappers/checkbox/checkbox-field-mapper.ts","../../../../packages/dynamic-forms/integration/src/mappers/datepicker/datepicker-field-mapper.ts","../../../../packages/dynamic-forms/integration/src/mappers/select/options-field-mapper.ts","../../../../packages/dynamic-forms/integration/src/mappers/index.ts","../../../../packages/dynamic-forms/integration/src/utils/create-resolved-errors-signal.ts","../../../../packages/dynamic-forms/integration/src/utils/should-show-errors.ts","../../../../packages/dynamic-forms/integration/src/utils/is-equal.ts","../../../../packages/dynamic-forms/integration/src/utils/index.ts","../../../../packages/dynamic-forms/integration/src/pipes/value-in-array.pipe.ts","../../../../packages/dynamic-forms/integration/src/public_api.ts","../../../../packages/dynamic-forms/integration/src/ng-forge-dynamic-forms-integration.ts"],"sourcesContent":["import { BaseValueField } from '@ng-forge/dynamic-forms';\nimport { computed, inject, Signal } from '@angular/core';\nimport { FieldTree } from '@angular/forms/signals';\nimport { buildBaseInputs } from '@ng-forge/dynamic-forms';\nimport { FIELD_SIGNAL_CONTEXT } from '@ng-forge/dynamic-forms';\nimport { omit } from '@ng-forge/dynamic-forms';\nimport { ValidationMessages } from '@ng-forge/dynamic-forms';\n\n/**\n * Context for value field mapping, containing resolved field tree and default validation messages.\n * Used by specialized mappers to avoid duplicate context resolution.\n */\nexport interface ValueFieldContext {\n fieldTree: FieldTree<unknown> | undefined;\n defaultValidationMessages: ValidationMessages | undefined;\n}\n\n/**\n * Resolves the field tree and default validation messages from the form context.\n * Must be called within an injection context.\n *\n * Uses type-safe field tree utilities to access child FieldTrees from the parent form.\n *\n * @param fieldKey The key of the field to resolve\n * @returns The resolved context with field tree and validation messages\n */\nexport function resolveValueFieldContext(fieldKey: string): ValueFieldContext {\n const context = inject(FIELD_SIGNAL_CONTEXT);\n const defaultValidationMessages = context.defaultValidationMessages;\n const formRoot = context.form as Record<string, FieldTree<unknown> | undefined>;\n const fieldTree = formRoot[fieldKey];\n return { fieldTree, defaultValidationMessages };\n}\n\n/**\n * Builds the base inputs for a value field.\n * This is a helper function used by valueFieldMapper and specialized mappers.\n *\n * @param fieldDef The value field definition\n * @param ctx The resolved value field context\n * @returns Record of input names to values\n */\nexport function buildValueFieldInputs<TProps, TValue = unknown>(\n fieldDef: BaseValueField<TProps, TValue>,\n ctx: ValueFieldContext,\n): Record<string, unknown> {\n const omittedFields = omit(fieldDef, ['value']);\n const baseInputs = buildBaseInputs(omittedFields);\n\n const inputs: Record<string, unknown> = {\n ...baseInputs,\n validationMessages: fieldDef.validationMessages ?? {},\n };\n\n if (fieldDef.placeholder !== undefined) {\n inputs['placeholder'] = fieldDef.placeholder;\n }\n\n if (ctx.defaultValidationMessages !== undefined) {\n inputs['defaultValidationMessages'] = ctx.defaultValidationMessages;\n }\n\n if (ctx.fieldTree !== undefined) {\n inputs['field'] = ctx.fieldTree;\n }\n\n return inputs;\n}\n\n/**\n * Maps a value field definition to component inputs.\n *\n * Value fields are input fields that contribute to the form's value (text, number, etc.).\n * This mapper injects FIELD_SIGNAL_CONTEXT to access the form structure and retrieve the field proxy.\n *\n * For fields with specific properties (select, datepicker, textarea, slider), use the specialized mappers:\n * - selectFieldMapper: for fields with options (select, radio, multi-checkbox)\n * - datepickerFieldMapper: for fields with minDate, maxDate, startAt\n * - textareaFieldMapper: for fields with rows, cols\n * - sliderFieldMapper: for fields with minValue, maxValue, step\n *\n * @param fieldDef The value field definition\n * @returns Signal containing Record of input names to values for ngComponentOutlet\n */\nexport function valueFieldMapper<TProps = unknown, TValue = unknown>(\n fieldDef: BaseValueField<TProps, TValue>,\n): Signal<Record<string, unknown>> {\n const ctx = resolveValueFieldContext(fieldDef.key);\n\n return computed(() => buildValueFieldInputs(fieldDef, ctx));\n}\n","import { BaseCheckedField } from '@ng-forge/dynamic-forms';\nimport { FieldDef } from '@ng-forge/dynamic-forms';\nimport { computed, inject, Signal } from '@angular/core';\nimport { FieldTree } from '@angular/forms/signals';\nimport { buildBaseInputs } from '@ng-forge/dynamic-forms';\nimport { FIELD_SIGNAL_CONTEXT } from '@ng-forge/dynamic-forms';\nimport { omit } from '@ng-forge/dynamic-forms';\n\n/**\n * Maps a checkbox/toggle field definition to component inputs.\n *\n * Checkbox fields are checked fields that contribute to the form's value as boolean.\n * This mapper injects FIELD_SIGNAL_CONTEXT to access the form structure and retrieve the field tree.\n *\n * @param fieldDef The checkbox field definition\n * @returns Signal containing Record of input names to values for ngComponentOutlet\n */\nexport function checkboxFieldMapper(fieldDef: BaseCheckedField<unknown>): Signal<Record<string, unknown>> {\n const context = inject(FIELD_SIGNAL_CONTEXT);\n const omittedFields = omit(fieldDef, ['value']) as FieldDef<unknown>;\n const baseInputs = buildBaseInputs(omittedFields);\n const defaultValidationMessages = context.defaultValidationMessages;\n const formRoot = context.form as Record<string, FieldTree<unknown> | undefined>;\n const fieldTree = formRoot[fieldDef.key];\n\n return computed(() => {\n const inputs: Record<string, unknown> = {\n ...baseInputs,\n validationMessages: fieldDef.validationMessages ?? {},\n };\n\n if (fieldDef.placeholder !== undefined) {\n inputs['placeholder'] = fieldDef.placeholder;\n }\n\n if (defaultValidationMessages !== undefined) {\n inputs['defaultValidationMessages'] = defaultValidationMessages;\n }\n\n if (fieldTree !== undefined) {\n inputs['field'] = fieldTree;\n }\n\n return inputs;\n });\n}\n","import { computed, Signal } from '@angular/core';\nimport { DatepickerField } from '../../definitions';\nimport { resolveValueFieldContext, buildValueFieldInputs } from '../value/value-field.mapper';\n\n/**\n * Maps a datepicker field to component inputs.\n *\n * Extends the base value field mapper by adding datepicker-specific properties:\n * - minDate: Minimum selectable date\n * - maxDate: Maximum selectable date\n * - startAt: Initial date to display when opening the picker\n *\n * @param fieldDef The datepicker field definition\n * @returns Signal containing Record of input names to values for ngComponentOutlet\n */\nexport function datepickerFieldMapper<TProps>(fieldDef: DatepickerField<TProps>): Signal<Record<string, unknown>> {\n const ctx = resolveValueFieldContext(fieldDef.key);\n\n return computed(() => {\n const inputs = buildValueFieldInputs(fieldDef, ctx);\n\n // Add datepicker-specific properties\n if (fieldDef.minDate !== undefined) {\n inputs['minDate'] = fieldDef.minDate;\n }\n if (fieldDef.maxDate !== undefined) {\n inputs['maxDate'] = fieldDef.maxDate;\n }\n if (fieldDef.startAt !== undefined) {\n inputs['startAt'] = fieldDef.startAt;\n }\n\n return inputs;\n });\n}\n","import { computed, Signal } from '@angular/core';\nimport { SelectField } from '../../definitions';\nimport { RadioField } from '../../definitions';\nimport { MultiCheckboxField } from '../../definitions';\nimport { BaseValueField } from '@ng-forge/dynamic-forms';\nimport { resolveValueFieldContext, buildValueFieldInputs } from '../value/value-field.mapper';\n\n/**\n * Field types that have an options property.\n */\nexport type FieldWithOptions<T = unknown, TProps = unknown> =\n | SelectField<T, TProps>\n | RadioField<T, TProps>\n | MultiCheckboxField<T, TProps>;\n\n/**\n * Maps a field with options (select, radio, multi-checkbox) to component inputs.\n *\n * Extends the base value field mapper by adding the options property.\n *\n * @param fieldDef The field definition with options\n * @returns Signal containing Record of input names to values for ngComponentOutlet\n */\nexport function optionsFieldMapper<T, TProps>(fieldDef: FieldWithOptions<T, TProps>): Signal<Record<string, unknown>> {\n const ctx = resolveValueFieldContext(fieldDef.key);\n\n return computed(() => {\n // Cast to BaseValueField - safe because all FieldWithOptions types extend BaseValueField\n const inputs = buildValueFieldInputs(fieldDef as BaseValueField<TProps, unknown>, ctx);\n\n // Add options property\n inputs['options'] = fieldDef.options;\n\n return inputs;\n });\n}\n","// UI-specific field mappers\nexport { valueFieldMapper, buildValueFieldInputs, resolveValueFieldContext } from './value/value-field.mapper';\nexport type { ValueFieldContext } from './value/value-field.mapper';\nexport { checkboxFieldMapper } from './checkbox/checkbox-field-mapper';\nexport { datepickerFieldMapper } from './datepicker/datepicker-field-mapper';\nexport { optionsFieldMapper } from './select/options-field-mapper';\nexport type { FieldWithOptions } from './select/options-field-mapper';\n","import { computed, inject, Injector, signal, Signal } from '@angular/core';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { FieldTree, ValidationError } from '@angular/forms/signals';\nimport { combineLatest, Observable, of } from 'rxjs';\nimport { map, switchMap } from 'rxjs/operators';\nimport { ValidationMessages } from '@ng-forge/dynamic-forms';\nimport { dynamicTextToObservable } from '@ng-forge/dynamic-forms';\nimport { interpolateParams } from '@ng-forge/dynamic-forms';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms';\nimport type { Logger } from '@ng-forge/dynamic-forms';\n\n/**\n * Resolved validation error with interpolated message\n */\nexport interface ResolvedError {\n kind: string;\n message: string;\n}\n\n/**\n * Factory function that creates a signal of resolved validation errors\n * Handles async resolution of DynamicText validation messages\n *\n * @param field - Signal containing FieldTree\n * @param validationMessages - Signal containing custom field-level validation messages\n * @param defaultValidationMessages - Signal containing default validation messages (fallback)\n * @param injector - Optional injector for DynamicText resolution\n * @returns Signal<ResolvedError[]> - Reactively resolved error messages\n *\n * @example\n * ```typescript\n * readonly resolvedErrors = createResolvedErrorsSignal(\n * this.field,\n * this.validationMessages,\n * this.defaultValidationMessages\n * );\n * ```\n */\nexport function createResolvedErrorsSignal<T>(\n field: Signal<FieldTree<T>>,\n validationMessages: Signal<ValidationMessages | undefined>,\n defaultValidationMessages: Signal<ValidationMessages | undefined> = signal(undefined),\n injector = inject(Injector),\n): Signal<ResolvedError[]> {\n // Get logger from injector\n const logger = injector.get(DynamicFormLogger);\n\n // Ensure validationMessages is never undefined (mappers pass {} if not defined)\n const messages = computed(() => validationMessages() ?? {});\n const defaultMessages = computed(() => defaultValidationMessages() ?? {});\n\n // Create a computed signal that reads the actual errors from the field\n // This ensures the signal tracks changes to field().errors(), not just the field reference\n const errors = computed(() => {\n const control = field()();\n return control.errors();\n });\n\n // Convert signals to observables using toObservable with injector\n const errors$ = toObservable(errors, { injector });\n const messages$ = toObservable(messages, { injector });\n const defaultMessages$ = toObservable(defaultMessages, { injector });\n\n // Combine observables and process errors\n const resolvedErrors$ = combineLatest([errors$, messages$, defaultMessages$]).pipe(\n switchMap(([currentErrors, msgs, defaultMsgs]) => {\n // No errors - return empty array\n if (!currentErrors || currentErrors.length === 0) {\n return of([]);\n }\n\n // Create observable for each error's resolved message\n const errorResolvers = currentErrors.map((error: ValidationError) => resolveErrorMessage(error, msgs, defaultMsgs, injector, logger));\n\n // Combine all error message observables into single array emission, filtering out nulls\n return errorResolvers.length > 0\n ? combineLatest(errorResolvers).pipe(map((errors) => errors.filter((e): e is ResolvedError => e !== null)))\n : of([]);\n }),\n );\n\n // Convert observable back to signal using toSignal with injector\n // toSignal properly handles the injection context and manages subscriptions\n return toSignal(resolvedErrors$, { initialValue: [] as ResolvedError[], injector });\n}\n\n/**\n * Resolves a single error message from DynamicText sources with fallback logic\n * Priority: field-level message → default message → no message (logs warning)\n * @internal\n */\nfunction resolveErrorMessage(\n error: ValidationError,\n fieldMessages: ValidationMessages,\n defaultMessages: ValidationMessages,\n injector: Injector,\n logger: Logger,\n): Observable<ResolvedError | null> {\n // Check for field-level custom message first\n const fieldMessage = fieldMessages[error.kind];\n\n // Fall back to default message if no field-level message exists\n const defaultMessage = defaultMessages[error.kind];\n\n // Determine which message to use: field-level → default\n const messageToUse = fieldMessage ?? defaultMessage;\n\n // If no message found, log warning and return null (will be filtered out)\n if (!messageToUse) {\n logger.warn(\n `No validation message found for error kind \"${error.kind}\". ` +\n `Please provide a message via field-level validationMessages or form-level defaultValidationMessages.`,\n );\n return of(null);\n }\n\n // Convert DynamicText to Observable\n const messageObservable = dynamicTextToObservable(messageToUse, injector);\n\n // Apply parameter interpolation to support {{param}} syntax\n return messageObservable.pipe(\n map((msg) => ({\n kind: error.kind,\n message: interpolateParams(msg, error),\n })),\n );\n}\n","import { Signal, computed } from '@angular/core';\nimport { FieldTree } from '@angular/forms/signals';\n\n/**\n * Computed signal that determines if errors should be displayed\n * Based on field's invalid, touched, and error count\n *\n * @param field - Signal containing FieldTree\n * @returns Signal<boolean> - True if errors should be displayed\n */\nexport function shouldShowErrors<T>(field: Signal<FieldTree<T>>): Signal<boolean> {\n return computed(() => {\n const fieldTree = field();\n const control = fieldTree();\n return control.invalid() && control.touched() && control.errors().length > 0;\n });\n}\n","/**\n * Performs a deep equality comparison between two values\n */\nexport function isEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (typeof a !== typeof b) return false;\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((item, index) => isEqual(item, b[index]));\n }\n\n if (typeof a === 'object' && typeof b === 'object') {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n return keysA.every((key) => keysB.includes(key) && isEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]));\n }\n\n return Object.is(a, b);\n}\n","// Error display utilities for field components\nexport { createResolvedErrorsSignal } from './create-resolved-errors-signal';\nexport type { ResolvedError } from './create-resolved-errors-signal';\nexport { shouldShowErrors } from './should-show-errors';\n\n// Value comparison utilities\nexport { isEqual } from './is-equal';\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n pure: true,\n name: 'inArray',\n})\nexport class ValueInArrayPipe implements PipeTransform {\n transform<T>(element: T, array: T[] | undefined): boolean {\n return array?.includes(element) ?? false;\n }\n}\n","/**\n * @ng-forge/dynamic-forms/integration\n *\n * Integration API for UI library authors building field implementations\n * (Material, Bootstrap, PrimeNG, Ionic, etc.)\n *\n * This entrypoint provides:\n * - Specific field type definitions (InputField, SelectField, etc.)\n * - Field mappers for creating FieldTypeDefinition\n * - Error display utilities for field components\n */\n\n// =============================================================================\n// Field Type Definitions\n// =============================================================================\n\nexport type {\n ButtonField,\n EventArgs,\n CheckboxField,\n DatepickerField,\n DatepickerProps,\n InputField,\n InputProps,\n InputType,\n InputTypeToValueType,\n StringInputType,\n MultiCheckboxField,\n RadioField,\n SelectField,\n SelectProps,\n SliderField,\n TextareaField,\n TextareaProps,\n ToggleField,\n} from './definitions';\n\n// =============================================================================\n// Field Mappers\n// =============================================================================\n\nexport {\n valueFieldMapper,\n buildValueFieldInputs,\n resolveValueFieldContext,\n checkboxFieldMapper,\n datepickerFieldMapper,\n optionsFieldMapper,\n} from './mappers';\n\nexport type { ValueFieldContext, FieldWithOptions } from './mappers';\n\n// =============================================================================\n// Error Display Utilities\n// =============================================================================\n\nexport { createResolvedErrorsSignal, shouldShowErrors } from './utils';\nexport type { ResolvedError } from './utils';\n\n// =============================================================================\n// Value Comparison Utilities\n// =============================================================================\n\nexport { isEqual } from './utils';\n\n// =============================================================================\n// Pipes\n// =============================================================================\n\nexport { ValueInArrayPipe } from './pipes';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}