@ng-forge/dynamic-forms 0.3.0 → 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.
Files changed (20) hide show
  1. package/README.md +3 -2
  2. package/fesm2022/ng-forge-dynamic-forms-integration.mjs +23 -18
  3. package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
  4. package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-DHxoGouT.mjs} +248 -61
  5. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-DHxoGouT.mjs.map +1 -0
  6. package/fesm2022/{ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs → ng-forge-dynamic-forms-page-field.component-Bt6blv9I.mjs} +13 -7
  7. package/fesm2022/ng-forge-dynamic-forms-page-field.component-Bt6blv9I.mjs.map +1 -0
  8. package/fesm2022/{ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs → ng-forge-dynamic-forms-testing-test-button.harness-C79EBW0o.mjs} +4 -4
  9. package/fesm2022/{ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs.map → ng-forge-dynamic-forms-testing-test-button.harness-C79EBW0o.mjs.map} +1 -1
  10. package/fesm2022/ng-forge-dynamic-forms-testing.mjs +32 -30
  11. package/fesm2022/ng-forge-dynamic-forms-testing.mjs.map +1 -1
  12. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs → ng-forge-dynamic-forms-text-field.component-DKCx7Z_U.mjs} +5 -5
  13. package/fesm2022/{ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs.map → ng-forge-dynamic-forms-text-field.component-DKCx7Z_U.mjs.map} +1 -1
  14. package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
  15. package/package.json +9 -9
  16. package/types/ng-forge-dynamic-forms-integration.d.ts +58 -18
  17. package/types/ng-forge-dynamic-forms-testing.d.ts +7 -1
  18. package/types/ng-forge-dynamic-forms.d.ts +375 -167
  19. package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs.map +0 -1
  20. package/fesm2022/ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs.map +0 -1
@@ -83,6 +83,48 @@ function getGridClassString(fieldDef) {
83
83
  }
84
84
  return '';
85
85
  }
86
+ /**
87
+ * Builds a combined className string from a field definition.
88
+ *
89
+ * Combines user-provided className with generated grid classes into a single string.
90
+ * Returns undefined if no classes are present (allowing conditional spreading in objects).
91
+ *
92
+ * @param fieldDef - Field definition containing className and col properties
93
+ * @returns Combined class string, or undefined if no classes
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // With both className and col
98
+ * buildClassName({ key: 'test', type: 'group', className: 'my-class', col: 6 });
99
+ * // Returns: 'df-col-6 my-class'
100
+ *
101
+ * // With only className
102
+ * buildClassName({ key: 'test', type: 'group', className: 'my-class' });
103
+ * // Returns: 'my-class'
104
+ *
105
+ * // With only col
106
+ * buildClassName({ key: 'test', type: 'group', col: 6 });
107
+ * // Returns: 'df-col-6'
108
+ *
109
+ * // With neither
110
+ * buildClassName({ key: 'test', type: 'group' });
111
+ * // Returns: undefined
112
+ * ```
113
+ *
114
+ * @public
115
+ */
116
+ function buildClassName(fieldDef) {
117
+ const gridClass = getGridClassString(fieldDef);
118
+ const userClass = fieldDef.className;
119
+ const classes = [];
120
+ if (gridClass) {
121
+ classes.push(gridClass);
122
+ }
123
+ if (userClass) {
124
+ classes.push(userClass);
125
+ }
126
+ return classes.length > 0 ? classes.join(' ') : undefined;
127
+ }
86
128
 
87
129
  /**
88
130
  * Builds base input properties from a field definition.
@@ -91,9 +133,10 @@ function getGridClassString(fieldDef) {
91
133
  * Used by mappers to build the inputs record.
92
134
  *
93
135
  * @param fieldDef The field definition to extract properties from
136
+ * @param defaultProps Optional form-level default props to merge with field props
94
137
  * @returns Record of input names to values
95
138
  */
96
- function buildBaseInputs(fieldDef) {
139
+ function buildBaseInputs(fieldDef, defaultProps) {
97
140
  const { key, label, className, tabIndex, props, meta } = fieldDef;
98
141
  const inputs = {};
99
142
  // Always include key - required by components for accessibility and identification
@@ -116,8 +159,12 @@ function buildBaseInputs(fieldDef) {
116
159
  if (tabIndex !== undefined) {
117
160
  inputs['tabIndex'] = tabIndex;
118
161
  }
119
- if (props !== undefined) {
120
- inputs['props'] = props;
162
+ // Merge props: form-level defaultProps as base, field-level props override
163
+ // Cast props to Record since it's typed as unknown but always represents an object at runtime
164
+ const fieldProps = props;
165
+ const mergedProps = fieldProps !== undefined || defaultProps !== undefined ? { ...(defaultProps ?? {}), ...(fieldProps ?? {}) } : undefined;
166
+ if (mergedProps !== undefined) {
167
+ inputs['props'] = mergedProps;
121
168
  }
122
169
  if (meta !== undefined) {
123
170
  inputs['meta'] = meta;
@@ -586,6 +633,82 @@ const FIELD_SIGNAL_CONTEXT = new InjectionToken('FIELD_SIGNAL_CONTEXT', {
586
633
  * ```
587
634
  */
588
635
  const ARRAY_CONTEXT = new InjectionToken('ARRAY_CONTEXT');
636
+ /**
637
+ * Injection token for form-level default props.
638
+ *
639
+ * Default props are form-wide property defaults that are merged with field-level props.
640
+ * Field props take precedence over default props.
641
+ *
642
+ * Unlike FIELD_SIGNAL_CONTEXT which is re-provided by container components (Group, Array),
643
+ * DEFAULT_PROPS is provided ONCE at the DynamicForm level and inherited by all children
644
+ * via Angular's hierarchical injector.
645
+ *
646
+ * The token provides a Signal to enable reactivity - when config changes, mappers
647
+ * that read the signal inside their computed() will automatically update.
648
+ *
649
+ * @example
650
+ * ```typescript
651
+ * // In a mapper function
652
+ * const defaultPropsSignal = inject(DEFAULT_PROPS);
653
+ *
654
+ * return computed(() => {
655
+ * const defaultProps = defaultPropsSignal?.(); // Read inside computed for reactivity
656
+ * const baseInputs = buildBaseInputs(fieldDef, defaultProps);
657
+ * // ...
658
+ * });
659
+ * ```
660
+ */
661
+ const DEFAULT_PROPS = new InjectionToken('DEFAULT_PROPS');
662
+ /**
663
+ * Injection token for form-level default validation messages.
664
+ *
665
+ * Default validation messages act as fallbacks when fields have validation
666
+ * errors but no field-level `validationMessages` defined.
667
+ *
668
+ * Like DEFAULT_PROPS, this token is provided ONCE at the DynamicForm level
669
+ * and inherited by all children via Angular's hierarchical injector.
670
+ *
671
+ * The token provides a Signal to enable reactivity - when config changes, mappers
672
+ * that read the signal inside their computed() will automatically update.
673
+ *
674
+ * @example
675
+ * ```typescript
676
+ * // In a mapper or component
677
+ * const defaultMessagesSignal = inject(DEFAULT_VALIDATION_MESSAGES);
678
+ *
679
+ * return computed(() => {
680
+ * const defaultMessages = defaultMessagesSignal?.(); // Read inside computed for reactivity
681
+ * const message = defaultMessages?.required ?? 'Field is required';
682
+ * // ...
683
+ * });
684
+ * ```
685
+ */
686
+ const DEFAULT_VALIDATION_MESSAGES = new InjectionToken('DEFAULT_VALIDATION_MESSAGES');
687
+ /**
688
+ * Injection token for form-level options.
689
+ *
690
+ * Form options control form-wide behavior including button disabled states.
691
+ * Used by button mappers to determine default disabled behavior.
692
+ *
693
+ * Like DEFAULT_PROPS, this token is provided ONCE at the DynamicForm level
694
+ * and inherited by all children via Angular's hierarchical injector.
695
+ *
696
+ * The token provides a Signal to enable reactivity - when config changes, mappers
697
+ * that read the signal inside their computed() will automatically update.
698
+ *
699
+ * @example
700
+ * ```typescript
701
+ * // In a button mapper
702
+ * const formOptionsSignal = inject(FORM_OPTIONS);
703
+ *
704
+ * return computed(() => {
705
+ * const formOptions = formOptionsSignal?.(); // Read inside computed for reactivity
706
+ * const disableWhenInvalid = formOptions?.submitButton?.disableWhenInvalid ?? true;
707
+ * // ...
708
+ * });
709
+ * ```
710
+ */
711
+ const FORM_OPTIONS = new InjectionToken('FORM_OPTIONS');
589
712
 
590
713
  /**
591
714
  * Base error class for all Dynamic Forms errors.
@@ -972,10 +1095,10 @@ class RootFormRegistryService {
972
1095
  this._formValueSignals.set(new Map());
973
1096
  this.formContexts.clear();
974
1097
  }
975
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RootFormRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
976
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RootFormRegistryService });
1098
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RootFormRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1099
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RootFormRegistryService });
977
1100
  }
978
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RootFormRegistryService, decorators: [{
1101
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RootFormRegistryService, decorators: [{
979
1102
  type: Injectable
980
1103
  }] });
981
1104
 
@@ -1099,10 +1222,10 @@ class FieldContextRegistryService {
1099
1222
  logger: this.logger,
1100
1223
  };
1101
1224
  }
1102
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FieldContextRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1103
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FieldContextRegistryService });
1225
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FieldContextRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1226
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FieldContextRegistryService });
1104
1227
  }
1105
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FieldContextRegistryService, decorators: [{
1228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FieldContextRegistryService, decorators: [{
1106
1229
  type: Injectable
1107
1230
  }] });
1108
1231
 
@@ -1442,10 +1565,10 @@ class FunctionRegistryService {
1442
1565
  this.clearAsyncValidators();
1443
1566
  this.clearHttpValidators();
1444
1567
  }
1445
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FunctionRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1446
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FunctionRegistryService });
1568
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FunctionRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1569
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FunctionRegistryService });
1447
1570
  }
1448
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: FunctionRegistryService, decorators: [{
1571
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: FunctionRegistryService, decorators: [{
1449
1572
  type: Injectable
1450
1573
  }] });
1451
1574
 
@@ -3130,10 +3253,10 @@ class SchemaRegistryService {
3130
3253
  }
3131
3254
  return schema;
3132
3255
  }
3133
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SchemaRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3134
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SchemaRegistryService });
3256
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SchemaRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3257
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SchemaRegistryService });
3135
3258
  }
3136
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SchemaRegistryService, decorators: [{
3259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SchemaRegistryService, decorators: [{
3137
3260
  type: Injectable
3138
3261
  }] });
3139
3262
 
@@ -4104,10 +4227,10 @@ class EventBus {
4104
4227
  }
4105
4228
  return this.pipeline$.pipe(filter((event) => event.type === eventType));
4106
4229
  }
4107
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: EventBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4108
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: EventBus });
4230
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: EventBus, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4231
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: EventBus });
4109
4232
  }
4110
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: EventBus, decorators: [{
4233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: EventBus, decorators: [{
4111
4234
  type: Injectable
4112
4235
  }] });
4113
4236
 
@@ -4952,7 +5075,6 @@ class PageOrchestratorComponent {
4952
5075
  eventBus = inject(EventBus);
4953
5076
  fieldContextRegistry = inject(FieldContextRegistryService);
4954
5077
  functionRegistry = inject(FunctionRegistryService);
4955
- logger = inject(DynamicFormLogger);
4956
5078
  /**
4957
5079
  * Array of page field definitions to render
4958
5080
  */
@@ -5227,8 +5349,8 @@ class PageOrchestratorComponent {
5227
5349
  }
5228
5350
  return false;
5229
5351
  }
5230
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: PageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5231
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: PageOrchestratorComponent, isStandalone: true, selector: "div[page-orchestrator]", inputs: { pageFields: { classPropertyName: "pageFields", publicName: "pageFields", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, fieldSignalContext: { classPropertyName: "fieldSignalContext", publicName: "fieldSignalContext", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-current-page": "state().currentPageIndex", "attr.data-total-pages": "state().totalPages" }, classAttribute: "df-page-orchestrator" }, providers: [
5352
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: PageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5353
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: PageOrchestratorComponent, isStandalone: true, selector: "div[page-orchestrator]", inputs: { pageFields: { classPropertyName: "pageFields", publicName: "pageFields", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, fieldSignalContext: { classPropertyName: "fieldSignalContext", publicName: "fieldSignalContext", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-current-page": "state().currentPageIndex", "attr.data-total-pages": "state().totalPages" }, classAttribute: "df-page-orchestrator" }, providers: [
5232
5354
  {
5233
5355
  provide: FIELD_SIGNAL_CONTEXT,
5234
5356
  useFactory: (orchestrator) => orchestrator.extendedFieldSignalContext(),
@@ -5258,9 +5380,9 @@ class PageOrchestratorComponent {
5258
5380
  }
5259
5381
  }
5260
5382
  }
5261
- `, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs').then(m => m.default)], () => [import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs').then(m => m.default)]] });
5383
+ `, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [import('./ng-forge-dynamic-forms-page-field.component-Bt6blv9I.mjs').then(m => m.default)], () => [import('./ng-forge-dynamic-forms-page-field.component-Bt6blv9I.mjs').then(m => m.default)]] });
5262
5384
  }
5263
- i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.0.8", ngImport: i0, type: PageOrchestratorComponent, resolveDeferredDeps: () => [import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs').then(m => m.default)], resolveMetadata: PageFieldComponent => ({ decorators: [{
5385
+ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.1.0", ngImport: i0, type: PageOrchestratorComponent, resolveDeferredDeps: () => [import('./ng-forge-dynamic-forms-page-field.component-Bt6blv9I.mjs').then(m => m.default)], resolveMetadata: PageFieldComponent => ({ decorators: [{
5264
5386
  type: Component,
5265
5387
  args: [{ selector: 'div[page-orchestrator]', imports: [PageFieldComponent], template: `
5266
5388
  @for (pageField of pageFields(); track pageField.key; let i = $index) {
@@ -5425,17 +5547,14 @@ class DynamicForm {
5425
5547
  value: this.value,
5426
5548
  defaultValues: this.defaultValues,
5427
5549
  form: this.form(),
5428
- defaultValidationMessages: this.config().defaultValidationMessages,
5429
- formOptions: this.effectiveFormOptions(),
5430
5550
  }), ...(ngDevMode ? [{ debugName: "fieldSignalContext" }] : []));
5551
+ /**
5552
+ * Injector for field components with FIELD_SIGNAL_CONTEXT.
5553
+ * Other form-level tokens (DEFAULT_PROPS, etc.) are provided at component level.
5554
+ */
5431
5555
  fieldInjector = computed(() => Injector.create({
5432
5556
  parent: this.injector,
5433
- providers: [
5434
- {
5435
- provide: FIELD_SIGNAL_CONTEXT,
5436
- useValue: this.fieldSignalContext(),
5437
- },
5438
- ],
5557
+ providers: [{ provide: FIELD_SIGNAL_CONTEXT, useValue: this.fieldSignalContext() }],
5439
5558
  }), ...(ngDevMode ? [{ debugName: "fieldInjector" }] : []));
5440
5559
  defaultValues = linkedSignal(() => this.formSetup().defaultValues, ...(ngDevMode ? [{ debugName: "defaultValues" }] : []));
5441
5560
  entity = linkedSignal(() => {
@@ -5713,8 +5832,30 @@ class DynamicForm {
5713
5832
  ngOnDestroy() {
5714
5833
  this.rootFormRegistry.unregisterForm();
5715
5834
  }
5716
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
5717
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: DynamicForm, isStandalone: true, selector: "form[dynamic-form]", inputs: { config: { classPropertyName: "config", publicName: "dynamic-form", isSignal: true, isRequired: true, transformFunction: null }, formOptions: { classPropertyName: "formOptions", publicName: "formOptions", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted", reset: "reset", cleared: "cleared", events: "events", initialized: "initialized", onPageChange: "onPageChange", onPageNavigationStateChange: "onPageNavigationStateChange" }, host: { attributes: { "novalidate": "" }, listeners: { "submit": "onNativeSubmit($event)" }, properties: { "class.disabled": "disabled()", "class.df-form-paged": "formModeDetection().mode === \"paged\"", "class.df-form-non-paged": "formModeDetection().mode === \"non-paged\"", "attr.data-form-mode": "formModeDetection().mode" }, classAttribute: "df-dynamic-form df-form" }, providers: [EventBus, SchemaRegistryService, FunctionRegistryService, RootFormRegistryService, FieldContextRegistryService], ngImport: i0, template: `
5835
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DynamicForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
5836
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: DynamicForm, isStandalone: true, selector: "form[dynamic-form]", inputs: { config: { classPropertyName: "config", publicName: "dynamic-form", isSignal: true, isRequired: true, transformFunction: null }, formOptions: { classPropertyName: "formOptions", publicName: "formOptions", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted", reset: "reset", cleared: "cleared", events: "events", initialized: "initialized", onPageChange: "onPageChange", onPageNavigationStateChange: "onPageNavigationStateChange" }, host: { attributes: { "novalidate": "" }, listeners: { "submit": "onNativeSubmit($event)" }, properties: { "class.disabled": "disabled()", "class.df-form-paged": "formModeDetection().mode === \"paged\"", "class.df-form-non-paged": "formModeDetection().mode === \"non-paged\"", "attr.data-form-mode": "formModeDetection().mode" }, classAttribute: "df-dynamic-form df-form" }, providers: [
5837
+ EventBus,
5838
+ SchemaRegistryService,
5839
+ FunctionRegistryService,
5840
+ RootFormRegistryService,
5841
+ FieldContextRegistryService,
5842
+ // Form-level config tokens provided via useFactory to enable reactive updates
5843
+ {
5844
+ provide: DEFAULT_PROPS,
5845
+ useFactory: (form) => computed(() => form.config().defaultProps),
5846
+ deps: [DynamicForm],
5847
+ },
5848
+ {
5849
+ provide: DEFAULT_VALIDATION_MESSAGES,
5850
+ useFactory: (form) => computed(() => form.config().defaultValidationMessages),
5851
+ deps: [DynamicForm],
5852
+ },
5853
+ {
5854
+ provide: FORM_OPTIONS,
5855
+ useFactory: (form) => form.effectiveFormOptions,
5856
+ deps: [DynamicForm],
5857
+ },
5858
+ ], ngImport: i0, template: `
5718
5859
  @if (formModeDetection().mode === 'paged') {
5719
5860
  <div page-orchestrator [pageFields]="pageFieldDefinitions()" [form]="form()" [fieldSignalContext]="fieldSignalContext()"></div>
5720
5861
  } @else {
@@ -5724,7 +5865,7 @@ class DynamicForm {
5724
5865
  }
5725
5866
  `, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}:host>*{grid-column:1/-1}:host.df-form-spacing-custom{--df-grid-row-gap: var(--form-custom-spacing, 1.5rem)}:host.df-form-gap-none{--df-grid-row-gap: 0}:host.df-form-gap-xs{--df-grid-row-gap: .25rem}:host.df-form-gap-sm{--df-grid-row-gap: .5rem}:host.df-form-gap-md{--df-grid-row-gap: 1rem}:host.df-form-gap-lg{--df-grid-row-gap: 1.5rem}:host.df-form-gap-xl{--df-grid-row-gap: 2rem}:host.df-form-paged{--df-grid-row-gap: 0}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: PageOrchestratorComponent, selector: "div[page-orchestrator]", inputs: ["pageFields", "form", "fieldSignalContext"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5726
5867
  }
5727
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicForm, decorators: [{
5868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DynamicForm, decorators: [{
5728
5869
  type: Component,
5729
5870
  args: [{ selector: 'form[dynamic-form]', imports: [NgComponentOutlet, PageOrchestratorComponent], template: `
5730
5871
  @if (formModeDetection().mode === 'paged') {
@@ -5734,7 +5875,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
5734
5875
  <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
5735
5876
  }
5736
5877
  }
5737
- `, providers: [EventBus, SchemaRegistryService, FunctionRegistryService, RootFormRegistryService, FieldContextRegistryService], host: {
5878
+ `, providers: [
5879
+ EventBus,
5880
+ SchemaRegistryService,
5881
+ FunctionRegistryService,
5882
+ RootFormRegistryService,
5883
+ FieldContextRegistryService,
5884
+ // Form-level config tokens provided via useFactory to enable reactive updates
5885
+ {
5886
+ provide: DEFAULT_PROPS,
5887
+ useFactory: (form) => computed(() => form.config().defaultProps),
5888
+ deps: [DynamicForm],
5889
+ },
5890
+ {
5891
+ provide: DEFAULT_VALIDATION_MESSAGES,
5892
+ useFactory: (form) => computed(() => form.config().defaultValidationMessages),
5893
+ deps: [DynamicForm],
5894
+ },
5895
+ {
5896
+ provide: FORM_OPTIONS,
5897
+ useFactory: (form) => form.effectiveFormOptions,
5898
+ deps: [DynamicForm],
5899
+ },
5900
+ ], host: {
5738
5901
  class: 'df-dynamic-form df-form',
5739
5902
  novalidate: '', // Disable browser validation - Angular Signal Forms handles validation
5740
5903
  '[class.disabled]': 'disabled()',
@@ -5756,10 +5919,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
5756
5919
  * @returns Signal containing Record of input names to values for ngComponentOutlet
5757
5920
  */
5758
5921
  function arrayFieldMapper(fieldDef) {
5922
+ const className = buildClassName(fieldDef);
5759
5923
  // Array inputs are static (no reactive dependencies)
5760
5924
  return computed(() => ({
5761
5925
  key: fieldDef.key,
5762
5926
  field: fieldDef,
5927
+ ...(className !== undefined && { className }),
5763
5928
  }));
5764
5929
  }
5765
5930
 
@@ -5774,10 +5939,12 @@ function arrayFieldMapper(fieldDef) {
5774
5939
  * @returns Signal containing Record of input names to values for ngComponentOutlet
5775
5940
  */
5776
5941
  function groupFieldMapper(fieldDef) {
5942
+ const className = buildClassName(fieldDef);
5777
5943
  // Group inputs are static (no reactive dependencies)
5778
5944
  return computed(() => ({
5779
5945
  key: fieldDef.key,
5780
5946
  field: fieldDef,
5947
+ ...(className !== undefined && { className }),
5781
5948
  }));
5782
5949
  }
5783
5950
 
@@ -5791,10 +5958,12 @@ function groupFieldMapper(fieldDef) {
5791
5958
  * @returns Signal containing Record of input names to values for ngComponentOutlet
5792
5959
  */
5793
5960
  function rowFieldMapper(fieldDef) {
5961
+ const className = buildClassName(fieldDef);
5794
5962
  // Row inputs are static (no reactive dependencies)
5795
5963
  return computed(() => ({
5796
5964
  key: fieldDef.key,
5797
5965
  field: fieldDef,
5966
+ ...(className !== undefined && { className }),
5798
5967
  }));
5799
5968
  }
5800
5969
 
@@ -5808,10 +5977,12 @@ function rowFieldMapper(fieldDef) {
5808
5977
  * @returns Signal containing Record of input names to values for ngComponentOutlet
5809
5978
  */
5810
5979
  function pageFieldMapper(fieldDef) {
5980
+ const className = buildClassName(fieldDef);
5811
5981
  // Page inputs are static (no reactive dependencies)
5812
5982
  return computed(() => ({
5813
5983
  key: fieldDef.key,
5814
5984
  field: fieldDef,
5985
+ ...(className !== undefined && { className }),
5815
5986
  }));
5816
5987
  }
5817
5988
 
@@ -5828,12 +5999,12 @@ function pageFieldMapper(fieldDef) {
5828
5999
  function textFieldMapper(fieldDef) {
5829
6000
  const fieldContextRegistry = inject(FieldContextRegistryService);
5830
6001
  const functionRegistry = inject(FunctionRegistryService);
5831
- // Build base inputs (static, from field definition)
5832
- const baseInputs = buildBaseInputs(fieldDef);
6002
+ const defaultProps = inject(DEFAULT_PROPS);
5833
6003
  // Create computed signal for hidden state based on logic configuration
5834
6004
  const hiddenLogic = fieldDef.logic?.filter((l) => l.type === 'hidden') ?? [];
5835
6005
  // Return computed signal for reactive updates
5836
6006
  return computed(() => {
6007
+ const baseInputs = buildBaseInputs(fieldDef, defaultProps());
5837
6008
  const inputs = { ...baseInputs };
5838
6009
  // Evaluate hidden logic if present
5839
6010
  if (hiddenLogic.length > 0) {
@@ -5910,13 +6081,13 @@ const BUILT_IN_FIELDS = [
5910
6081
  },
5911
6082
  {
5912
6083
  name: 'page',
5913
- loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs'),
6084
+ loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-Bt6blv9I.mjs'),
5914
6085
  mapper: pageFieldMapper,
5915
6086
  valueHandling: 'flatten',
5916
6087
  },
5917
6088
  {
5918
6089
  name: 'text',
5919
- loadComponent: () => import('./ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs'),
6090
+ loadComponent: () => import('./ng-forge-dynamic-forms-text-field.component-DKCx7Z_U.mjs'),
5920
6091
  mapper: textFieldMapper,
5921
6092
  valueHandling: 'exclude',
5922
6093
  },
@@ -6470,10 +6641,10 @@ class DynamicTextPipe {
6470
6641
  }
6471
6642
  return of(value || '');
6472
6643
  }
6473
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicTextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
6474
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.8", ngImport: i0, type: DynamicTextPipe, isStandalone: true, name: "dynamicText" });
6644
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DynamicTextPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
6645
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: DynamicTextPipe, isStandalone: true, name: "dynamicText" });
6475
6646
  }
6476
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: DynamicTextPipe, decorators: [{
6647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DynamicTextPipe, decorators: [{
6477
6648
  type: Pipe,
6478
6649
  args: [{
6479
6650
  name: 'dynamicText',
@@ -6525,9 +6696,15 @@ class RowFieldComponent {
6525
6696
  // ─────────────────────────────────────────────────────────────────────────────
6526
6697
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
6527
6698
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
6699
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
6528
6700
  // ─────────────────────────────────────────────────────────────────────────────
6529
6701
  // Computed Signals
6530
6702
  // ─────────────────────────────────────────────────────────────────────────────
6703
+ hostClasses = computed(() => {
6704
+ const base = 'df-field df-row';
6705
+ const custom = this.className();
6706
+ return custom ? `${base} ${custom}` : base;
6707
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
6531
6708
  disabled = computed(() => {
6532
6709
  try {
6533
6710
  return this.field().disabled || false;
@@ -6576,26 +6753,26 @@ class RowFieldComponent {
6576
6753
  }
6577
6754
  });
6578
6755
  }
6579
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RowFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6580
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: RowFieldComponent, isStandalone: true, selector: "div[row-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.disabled": "disabled()", "id": "`${key()}`", "attr.data-testid": "key()" }, classAttribute: "df-field df-row" }, ngImport: i0, template: `
6756
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RowFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6757
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: RowFieldComponent, isStandalone: true, selector: "div[row-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "class.disabled": "disabled()", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
6581
6758
  @for (field of resolvedFields(); track field.key) {
6582
6759
  <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
6583
6760
  }
6584
6761
  `, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:flex;flex-wrap:wrap;gap:var(--df-grid-gap);align-items:flex-start;width:100%}:host ::ng-deep>*:not([class*=df-col-]){flex:0 0 auto}:host ::ng-deep>.df-col-1{flex:0 0 calc(8.3333333333% - var(--df-grid-gap) * .9166666667);max-width:calc(8.3333333333% - var(--df-grid-gap) * .9166666667)}:host ::ng-deep>.df-col-2{flex:0 0 calc(16.6666666667% - var(--df-grid-gap) * .8333333333);max-width:calc(16.6666666667% - var(--df-grid-gap) * .8333333333)}:host ::ng-deep>.df-col-3{flex:0 0 calc(25% - var(--df-grid-gap) * .75);max-width:calc(25% - var(--df-grid-gap) * .75)}:host ::ng-deep>.df-col-4{flex:0 0 calc(33.3333333333% - var(--df-grid-gap) * .6666666667);max-width:calc(33.3333333333% - var(--df-grid-gap) * .6666666667)}:host ::ng-deep>.df-col-5{flex:0 0 calc(41.6666666667% - var(--df-grid-gap) * .5833333333);max-width:calc(41.6666666667% - var(--df-grid-gap) * .5833333333)}:host ::ng-deep>.df-col-6{flex:0 0 calc(50% - var(--df-grid-gap) * .5);max-width:calc(50% - var(--df-grid-gap) * .5)}:host ::ng-deep>.df-col-7{flex:0 0 calc(58.3333333333% - var(--df-grid-gap) * .4166666667);max-width:calc(58.3333333333% - var(--df-grid-gap) * .4166666667)}:host ::ng-deep>.df-col-8{flex:0 0 calc(66.6666666667% - var(--df-grid-gap) * .3333333333);max-width:calc(66.6666666667% - var(--df-grid-gap) * .3333333333)}:host ::ng-deep>.df-col-9{flex:0 0 calc(75% - var(--df-grid-gap) * .25);max-width:calc(75% - var(--df-grid-gap) * .25)}:host ::ng-deep>.df-col-10{flex:0 0 calc(83.3333333333% - var(--df-grid-gap) * .1666666667);max-width:calc(83.3333333333% - var(--df-grid-gap) * .1666666667)}:host ::ng-deep>.df-col-11{flex:0 0 calc(91.6666666667% - var(--df-grid-gap) * .0833333333);max-width:calc(91.6666666667% - var(--df-grid-gap) * .0833333333)}:host ::ng-deep>.df-col-12{flex:0 0 calc(100% - var(--df-grid-gap) * 0);max-width:calc(100% - var(--df-grid-gap) * 0)}:host.df-gap-custom{--df-grid-gap: var(--row-custom-gap, 1rem)}@media(max-width:576px){:host.df-row-mobile-stack{flex-direction:column}:host.df-row-mobile-stack ::ng-deep>*{flex:0 0 100%!important;max-width:100%!important}}@media(min-width:577px)and (max-width:768px){:host.df-row-tablet-2col ::ng-deep>*{flex:0 0 calc(50% - var(--df-grid-gap) / 2);max-width:calc(50% - var(--df-grid-gap) / 2)}}@media(max-width:576px){:host{flex-direction:column}:host ::ng-deep>*{flex:0 0 100%!important;max-width:100%!important}:host.df-row-mobile-keep-cols{flex-direction:row}:host.df-row-mobile-keep-cols ::ng-deep>*:not([class*=df-col-]){flex:0 0 auto!important;max-width:none!important}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6585
6762
  }
6586
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: RowFieldComponent, decorators: [{
6763
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RowFieldComponent, decorators: [{
6587
6764
  type: Component,
6588
6765
  args: [{ selector: 'div[row-field]', imports: [NgComponentOutlet], template: `
6589
6766
  @for (field of resolvedFields(); track field.key) {
6590
6767
  <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
6591
6768
  }
6592
6769
  `, host: {
6593
- class: 'df-field df-row',
6770
+ '[class]': 'hostClasses()',
6594
6771
  '[class.disabled]': 'disabled()',
6595
6772
  '[id]': '`${key()}`',
6596
6773
  '[attr.data-testid]': 'key()',
6597
6774
  }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:flex;flex-wrap:wrap;gap:var(--df-grid-gap);align-items:flex-start;width:100%}:host ::ng-deep>*:not([class*=df-col-]){flex:0 0 auto}:host ::ng-deep>.df-col-1{flex:0 0 calc(8.3333333333% - var(--df-grid-gap) * .9166666667);max-width:calc(8.3333333333% - var(--df-grid-gap) * .9166666667)}:host ::ng-deep>.df-col-2{flex:0 0 calc(16.6666666667% - var(--df-grid-gap) * .8333333333);max-width:calc(16.6666666667% - var(--df-grid-gap) * .8333333333)}:host ::ng-deep>.df-col-3{flex:0 0 calc(25% - var(--df-grid-gap) * .75);max-width:calc(25% - var(--df-grid-gap) * .75)}:host ::ng-deep>.df-col-4{flex:0 0 calc(33.3333333333% - var(--df-grid-gap) * .6666666667);max-width:calc(33.3333333333% - var(--df-grid-gap) * .6666666667)}:host ::ng-deep>.df-col-5{flex:0 0 calc(41.6666666667% - var(--df-grid-gap) * .5833333333);max-width:calc(41.6666666667% - var(--df-grid-gap) * .5833333333)}:host ::ng-deep>.df-col-6{flex:0 0 calc(50% - var(--df-grid-gap) * .5);max-width:calc(50% - var(--df-grid-gap) * .5)}:host ::ng-deep>.df-col-7{flex:0 0 calc(58.3333333333% - var(--df-grid-gap) * .4166666667);max-width:calc(58.3333333333% - var(--df-grid-gap) * .4166666667)}:host ::ng-deep>.df-col-8{flex:0 0 calc(66.6666666667% - var(--df-grid-gap) * .3333333333);max-width:calc(66.6666666667% - var(--df-grid-gap) * .3333333333)}:host ::ng-deep>.df-col-9{flex:0 0 calc(75% - var(--df-grid-gap) * .25);max-width:calc(75% - var(--df-grid-gap) * .25)}:host ::ng-deep>.df-col-10{flex:0 0 calc(83.3333333333% - var(--df-grid-gap) * .1666666667);max-width:calc(83.3333333333% - var(--df-grid-gap) * .1666666667)}:host ::ng-deep>.df-col-11{flex:0 0 calc(91.6666666667% - var(--df-grid-gap) * .0833333333);max-width:calc(91.6666666667% - var(--df-grid-gap) * .0833333333)}:host ::ng-deep>.df-col-12{flex:0 0 calc(100% - var(--df-grid-gap) * 0);max-width:calc(100% - var(--df-grid-gap) * 0)}:host.df-gap-custom{--df-grid-gap: var(--row-custom-gap, 1rem)}@media(max-width:576px){:host.df-row-mobile-stack{flex-direction:column}:host.df-row-mobile-stack ::ng-deep>*{flex:0 0 100%!important;max-width:100%!important}}@media(min-width:577px)and (max-width:768px){:host.df-row-tablet-2col ::ng-deep>*{flex:0 0 calc(50% - var(--df-grid-gap) / 2);max-width:calc(50% - var(--df-grid-gap) / 2)}}@media(max-width:576px){:host{flex-direction:column}:host ::ng-deep>*{flex:0 0 100%!important;max-width:100%!important}:host.df-row-mobile-keep-cols{flex-direction:row}:host.df-row-mobile-keep-cols ::ng-deep>*:not([class*=df-col-]){flex:0 0 auto!important;max-width:none!important}}\n"] }]
6598
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }] } });
6775
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
6599
6776
 
6600
6777
  var rowField_component = /*#__PURE__*/Object.freeze({
6601
6778
  __proto__: null,
@@ -6640,9 +6817,15 @@ class GroupFieldComponent {
6640
6817
  // ─────────────────────────────────────────────────────────────────────────────
6641
6818
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
6642
6819
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
6820
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
6643
6821
  // ─────────────────────────────────────────────────────────────────────────────
6644
6822
  // Computed Signals
6645
6823
  // ─────────────────────────────────────────────────────────────────────────────
6824
+ hostClasses = computed(() => {
6825
+ const base = 'df-field df-group';
6826
+ const custom = this.className();
6827
+ return custom ? `${base} ${custom}` : base;
6828
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
6646
6829
  rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : []));
6647
6830
  formSetup = computed(() => {
6648
6831
  const groupField = this.field();
@@ -6708,7 +6891,6 @@ class GroupFieldComponent {
6708
6891
  value: this.parentFieldSignalContext.value,
6709
6892
  defaultValues: this.defaultValues,
6710
6893
  form: this.nestedFieldTree(),
6711
- defaultValidationMessages: this.parentFieldSignalContext.defaultValidationMessages,
6712
6894
  };
6713
6895
  return Injector.create({
6714
6896
  parent: this.injector,
@@ -6753,27 +6935,27 @@ class GroupFieldComponent {
6753
6935
  }
6754
6936
  });
6755
6937
  }
6756
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: GroupFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6757
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: GroupFieldComponent, isStandalone: true, selector: "fieldset[group-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted" }, host: { attributes: { "role": "group" }, properties: { "class.disabled": "disabled()", "id": "`${key()}`", "attr.data-testid": "key()" }, classAttribute: "df-field df-group" }, ngImport: i0, template: `
6938
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: GroupFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6939
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: GroupFieldComponent, isStandalone: true, selector: "fieldset[group-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { validityChange: "validityChange", dirtyChange: "dirtyChange", submitted: "submitted" }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()", "class.disabled": "disabled()", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
6758
6940
  @for (field of resolvedFields(); track field.key) {
6759
6941
  <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
6760
6942
  }
6761
6943
  `, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{border:none;margin:0;padding:0;min-width:0;display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}:host>*{grid-column:1/-1}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6762
6944
  }
6763
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: GroupFieldComponent, decorators: [{
6945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: GroupFieldComponent, decorators: [{
6764
6946
  type: Component,
6765
6947
  args: [{ selector: 'fieldset[group-field]', imports: [NgComponentOutlet], template: `
6766
6948
  @for (field of resolvedFields(); track field.key) {
6767
6949
  <ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
6768
6950
  }
6769
6951
  `, host: {
6770
- class: 'df-field df-group',
6952
+ '[class]': 'hostClasses()',
6771
6953
  role: 'group',
6772
6954
  '[class.disabled]': 'disabled()',
6773
6955
  '[id]': '`${key()}`',
6774
6956
  '[attr.data-testid]': 'key()',
6775
6957
  }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{border:none;margin:0;padding:0;min-width:0;display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}:host>*{grid-column:1/-1}\n"] }]
6776
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], validityChange: [{ type: i0.Output, args: ["validityChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], submitted: [{ type: i0.Output, args: ["submitted"] }] } });
6958
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], validityChange: [{ type: i0.Output, args: ["validityChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], submitted: [{ type: i0.Output, args: ["submitted"] }] } });
6777
6959
 
6778
6960
  var groupField_component = /*#__PURE__*/Object.freeze({
6779
6961
  __proto__: null,
@@ -6937,7 +7119,6 @@ function createItemInjector(options) {
6937
7119
  value: parentFieldSignalContext.value,
6938
7120
  defaultValues: () => ({}),
6939
7121
  form: formRef,
6940
- defaultValidationMessages: parentFieldSignalContext.defaultValidationMessages,
6941
7122
  };
6942
7123
  const injector = Injector.create({
6943
7124
  parent: parentInjector,
@@ -7023,9 +7204,15 @@ class ArrayFieldComponent {
7023
7204
  // ─────────────────────────────────────────────────────────────────────────────
7024
7205
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
7025
7206
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
7207
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7026
7208
  // ─────────────────────────────────────────────────────────────────────────────
7027
7209
  // Computed Signals
7028
7210
  // ─────────────────────────────────────────────────────────────────────────────
7211
+ hostClasses = computed(() => {
7212
+ const base = 'df-field df-array';
7213
+ const custom = this.className();
7214
+ return custom ? `${base} ${custom}` : base;
7215
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
7029
7216
  rawFieldRegistry = computed(() => this.fieldRegistry.raw, ...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : []));
7030
7217
  fieldTemplate = computed(() => {
7031
7218
  const arrayField = this.field();
@@ -7193,25 +7380,25 @@ class ArrayFieldComponent {
7193
7380
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7194
7381
  parentForm().value.set({ ...currentValue, [arrayKey]: newArray });
7195
7382
  }
7196
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ArrayFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7197
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: ArrayFieldComponent, isStandalone: true, selector: "array-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()" }, classAttribute: "df-field df-array" }, ngImport: i0, template: `
7383
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ArrayFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7384
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: ArrayFieldComponent, isStandalone: true, selector: "array-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
7198
7385
  @for (item of resolvedItems(); track item.id) {
7199
7386
  <ng-container *ngComponentOutlet="item.component; injector: item.injector; inputs: item.inputs()" />
7200
7387
  }
7201
7388
  `, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}:host>*{grid-column:1/-1}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7202
7389
  }
7203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: ArrayFieldComponent, decorators: [{
7390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ArrayFieldComponent, decorators: [{
7204
7391
  type: Component,
7205
7392
  args: [{ selector: 'array-field', imports: [NgComponentOutlet], template: `
7206
7393
  @for (item of resolvedItems(); track item.id) {
7207
7394
  <ng-container *ngComponentOutlet="item.component; injector: item.injector; inputs: item.inputs()" />
7208
7395
  }
7209
7396
  `, host: {
7210
- class: 'df-field df-array',
7397
+ '[class]': 'hostClasses()',
7211
7398
  '[id]': '`${key()}`',
7212
7399
  '[attr.data-testid]': 'key()',
7213
7400
  }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md);--df-grid-row-gap: var(--df-grid-row-gap-md)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}:host>*{grid-column:1/-1}\n"] }]
7214
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }] } });
7401
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7215
7402
 
7216
7403
  var arrayField_component = /*#__PURE__*/Object.freeze({
7217
7404
  __proto__: null,
@@ -7362,5 +7549,5 @@ function extractErrorParams(error) {
7362
7549
  * Generated bundle index. Do not edit.
7363
7550
  */
7364
7551
 
7365
- export { BUILT_IN_FIELDS as $, AddArrayItemEvent as A, baseFieldMapper as B, ConsoleLogger as C, DynamicFormLogger as D, EventBus as E, FormClearEvent as F, buildBaseInputs as G, arrayFieldMapper as H, groupFieldMapper as I, pageFieldMapper as J, rowFieldMapper as K, textFieldMapper as L, FIELD_REGISTRY as M, NoopLogger as N, ARRAY_CONTEXT as O, PageChangeEvent as P, FIELD_SIGNAL_CONTEXT as Q, RemoveArrayItemEvent as R, SubmitEvent as S, dynamicTextToObservable as T, ArrayFieldComponent as U, GroupFieldComponent as V, RowFieldComponent as W, applyValidator as X, applyValidators as Y, getArrayLength as Z, resolveTokens as _, DynamicTextPipe as a, omit as a0, interpolateParams as a1, applyMetaToElement as a2, DynamicForm as b, createFieldResolutionPipe as c, derivedFromDeferred as d, emitComponentInitialized as e, isFormStateCondition as f, resolveNextButtonDisabled as g, isCheckedField as h, injectFieldRegistry as i, isValueField as j, isRowField as k, isArrayField as l, isContainerField as m, isDisplayOnlyField as n, isGroupField as o, provideDynamicForm as p, isLeafField as q, resolveSubmitButtonDisabled as r, isPageField as s, isValueBearingField as t, FormResetEvent as u, validatePageNesting as v, withLoggerConfig as w, NextPageEvent as x, PreviousPageEvent as y, DynamicFormError as z };
7366
- //# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs.map
7552
+ export { applyValidators as $, AddArrayItemEvent as A, baseFieldMapper as B, ConsoleLogger as C, DynamicFormLogger as D, EventBus as E, FormClearEvent as F, buildBaseInputs as G, arrayFieldMapper as H, groupFieldMapper as I, pageFieldMapper as J, rowFieldMapper as K, textFieldMapper as L, FIELD_REGISTRY as M, NoopLogger as N, ARRAY_CONTEXT as O, PageChangeEvent as P, DEFAULT_PROPS as Q, RemoveArrayItemEvent as R, SubmitEvent as S, DEFAULT_VALIDATION_MESSAGES as T, FIELD_SIGNAL_CONTEXT as U, FORM_OPTIONS as V, dynamicTextToObservable as W, ArrayFieldComponent as X, GroupFieldComponent as Y, RowFieldComponent as Z, applyValidator as _, DynamicTextPipe as a, getArrayLength as a0, resolveTokens as a1, BUILT_IN_FIELDS as a2, omit as a3, interpolateParams as a4, applyMetaToElement as a5, RootFormRegistryService as a6, DynamicForm as b, createFieldResolutionPipe as c, derivedFromDeferred as d, emitComponentInitialized as e, isFormStateCondition as f, resolveNextButtonDisabled as g, isCheckedField as h, injectFieldRegistry as i, isValueField as j, isRowField as k, isArrayField as l, isContainerField as m, isDisplayOnlyField as n, isGroupField as o, provideDynamicForm as p, isLeafField as q, resolveSubmitButtonDisabled as r, isPageField as s, isValueBearingField as t, FormResetEvent as u, validatePageNesting as v, withLoggerConfig as w, NextPageEvent as x, PreviousPageEvent as y, DynamicFormError as z };
7553
+ //# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-DHxoGouT.mjs.map