@dereekb/dbx-form 13.2.1 → 13.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -76,20 +76,47 @@ var DbxFormState;
76
76
  */
77
77
  DbxFormState[DbxFormState["USED"] = 1] = "USED";
78
78
  })(DbxFormState || (DbxFormState = {}));
79
+ /**
80
+ * Default key used when disabling/enabling a form without specifying a custom key.
81
+ */
79
82
  const DEFAULT_FORM_DISABLED_KEY = 'dbx_form_disabled';
80
83
  /**
81
84
  * Form that has an event stream, value, and state items.
82
85
  */
83
86
  class DbxForm {
84
87
  }
88
+ /**
89
+ * Mutable extension of {@link DbxForm} that supports setting values, resetting, and disabling the form.
90
+ *
91
+ * @typeParam T - The form value type.
92
+ */
85
93
  class DbxMutableForm extends DbxForm {
86
94
  }
95
+ /**
96
+ * Provides the given type as a {@link DbxForm} in Angular's dependency injection system.
97
+ *
98
+ * @param sourceType - The concrete form type to register as a provider.
99
+ * @returns An array of Angular providers.
100
+ */
87
101
  function provideDbxForm(sourceType) {
88
102
  return [{ provide: DbxForm, useExisting: forwardRef(() => sourceType) }];
89
103
  }
104
+ /**
105
+ * Provides the given type as both a {@link DbxForm} and {@link DbxMutableForm} in Angular's dependency injection system.
106
+ *
107
+ * @param sourceType - The concrete mutable form type to register as a provider.
108
+ * @returns An array of Angular providers.
109
+ */
90
110
  function provideDbxMutableForm(sourceType) {
91
111
  return [...provideDbxForm(sourceType), { provide: DbxMutableForm, useExisting: forwardRef(() => sourceType) }];
92
112
  }
113
+ /**
114
+ * Enables or disables an Angular form control based on the provided flag.
115
+ *
116
+ * @param form - The Angular abstract control to enable or disable.
117
+ * @param isDisabled - Whether to disable (`true`) or enable (`false`) the control.
118
+ * @param config - Optional configuration passed to the control's `disable()` or `enable()` methods.
119
+ */
93
120
  function toggleDisableFormControl(form, isDisabled, config) {
94
121
  if (isDisabled) {
95
122
  form.disable(config);
@@ -99,6 +126,9 @@ function toggleDisableFormControl(form, isDisabled, config) {
99
126
  }
100
127
  }
101
128
 
129
+ /**
130
+ * Disabled key used by {@link DbxActionFormDirective} to manage the form's disabled state during action processing.
131
+ */
102
132
  const APP_ACTION_FORM_DISABLED_KEY = 'dbx_action_form';
103
133
  /**
104
134
  * Used with an action to bind a form to an action as it's value source.
@@ -106,6 +136,11 @@ const APP_ACTION_FORM_DISABLED_KEY = 'dbx_action_form';
106
136
  * If the form has errors when the action is trigger, it will reject the action.
107
137
  *
108
138
  * If the source is not considered modified, the trigger will be ignored.
139
+ *
140
+ * @selector `[dbxActionForm]`
141
+ *
142
+ * @typeParam T - The form value type.
143
+ * @typeParam O - The output value type passed to the action source.
109
144
  */
110
145
  class DbxActionFormDirective {
111
146
  form = inject((DbxMutableForm), { host: true });
@@ -227,6 +262,13 @@ class DbxActionFormDirective {
227
262
  this.form.setDisabled(APP_ACTION_FORM_DISABLED_KEY, disable);
228
263
  });
229
264
  }
265
+ /**
266
+ * Checks whether the given form value is both valid and modified, optionally applying override functions.
267
+ *
268
+ * @param value - The current form value to check.
269
+ * @param overrides - Optional override functions for the validity and modification checks.
270
+ * @returns An observable emitting a tuple of `[isValid, isModified]`.
271
+ */
230
272
  checkIsValidAndIsModified(value, overrides) {
231
273
  const { isModifiedFunction: overrideIsModifiedFunction, isValidFunction: overrideIsValidFunction } = overrides ?? {};
232
274
  const isValidFunctionObs = overrideIsValidFunction != null ? of(overrideIsValidFunction) : this.isValidFunction$;
@@ -235,9 +277,21 @@ class DbxActionFormDirective {
235
277
  return combineLatest([isValid(value), isModified(value)]).pipe(map(([valid, modified]) => [valid, modified]));
236
278
  }));
237
279
  }
280
+ /**
281
+ * Pre-checks whether the form value is valid and modified before marking it as ready.
282
+ *
283
+ * @param value - The current form value.
284
+ * @returns An observable emitting a tuple of `[isValid, isModified]`.
285
+ */
238
286
  preCheckReadyValue(value) {
239
287
  return this.checkIsValidAndIsModified(value);
240
288
  }
289
+ /**
290
+ * Transforms the form value into an action value result, applying the optional map function if provided.
291
+ *
292
+ * @param value - The validated form value.
293
+ * @returns An observable emitting the action value getter result.
294
+ */
241
295
  readyValue(value) {
242
296
  return this.mapValueFunction$.pipe(switchMap((mapFunction) => {
243
297
  if (mapFunction) {
@@ -260,12 +314,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
260
314
  }], ctorParameters: () => [], propDecorators: { dbxActionFormDisabledOnWorking: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxActionFormDisabledOnWorking", required: false }] }], dbxActionFormIsValid: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxActionFormIsValid", required: false }] }], dbxActionFormIsEqual: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxActionFormIsEqual", required: false }] }], dbxActionFormIsModified: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxActionFormIsModified", required: false }] }], dbxActionFormMapValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxActionFormMapValue", required: false }] }] } });
261
315
 
262
316
  /**
263
- * Extension of DbxActionTransitionSafetyDirective that forces the form to update first.
317
+ * Extension of {@link DbxActionTransitionSafetyDirective} that forces the form to update before
318
+ * evaluating transition safety. This ensures the latest form state is considered when deciding
319
+ * whether to block or allow a route transition.
320
+ *
321
+ * NOTE: Only works with UIRouter.
264
322
  *
265
- * NOTE: Only works with UIRouter
323
+ * @selector `[dbxActionFormSafety]`
324
+ *
325
+ * @typeParam T - The form value type.
326
+ * @typeParam O - The output value type passed to the action source.
266
327
  */
267
328
  class DbxActionFormSafetyDirective extends DbxActionTransitionSafetyDirective {
268
329
  dbxActionForm = inject((DbxActionFormDirective), { host: true });
330
+ /**
331
+ * The safety type that controls when transitions are blocked.
332
+ *
333
+ * Defaults to `'auto'`, which blocks transitions when the form has unsaved changes.
334
+ */
269
335
  dbxActionFormSafety = input('auto', ...(ngDevMode ? [{ debugName: "dbxActionFormSafety" }] : []));
270
336
  _dbxActionFormSafetyUpdateEffect = effect(() => this._safetyType.next(this.dbxActionFormSafety()), ...(ngDevMode ? [{ debugName: "_dbxActionFormSafetyUpdateEffect" }] : []));
271
337
  _handleOnBeforeTransition(transition) {
@@ -559,9 +625,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
559
625
  }]
560
626
  }], ctorParameters: () => [], propDecorators: { formlyForm: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FormlyForm), { isSignal: true }] }] } });
561
627
 
628
+ /**
629
+ * Creates an observable that pipes input values to a form based on the specified mode.
630
+ *
631
+ * This is a convenience wrapper around {@link dbxFormSourceObservableFromStream} that
632
+ * extracts the stream from the form instance.
633
+ *
634
+ * @param form - The mutable form to derive stream state from.
635
+ * @param inputObs - The source observable or value to pipe into the form.
636
+ * @param modeObs - Observable controlling when values are forwarded (reset, always, or every).
637
+ * @returns An observable of values to be set on the form.
638
+ */
562
639
  function dbxFormSourceObservable(form, inputObs, modeObs) {
563
640
  return dbxFormSourceObservableFromStream(form.stream$, inputObs, modeObs);
564
641
  }
642
+ /**
643
+ * Creates an observable that pipes input values to a form based on the form's stream state and the specified mode.
644
+ *
645
+ * - `'reset'`: Only forwards the value when the form enters the RESET state.
646
+ * - `'always'`: Forwards values while not initializing, with throttling and loop detection.
647
+ * - `'every'`: Forwards values while not initializing, without throttling or loop protection.
648
+ *
649
+ * @param streamObs - Observable of the form's state stream.
650
+ * @param inputObs - The source observable or value to pipe into the form.
651
+ * @param modeObs - Observable or value controlling when values are forwarded.
652
+ * @returns An observable of values to be set on the form.
653
+ */
565
654
  function dbxFormSourceObservableFromStream(streamObs, inputObs, modeObs) {
566
655
  const value$ = asObservable(inputObs).pipe(shareReplay(1)); // catch/share the latest emission
567
656
  const state$ = streamObs.pipe(map((x) => x.state), distinctUntilChanged());
@@ -618,11 +707,26 @@ function dbxFormSourceObservableFromStream(streamObs, inputObs, modeObs) {
618
707
  }));
619
708
  }
620
709
  /**
621
- * Used with a FormComponent to set the value based on the input value.
710
+ * Directive that sets a form's value based on an input observable or value source.
711
+ *
712
+ * Supports different modes for when the value is forwarded to the form:
713
+ * - `'reset'` (default): Only sets the form value when the form is reset.
714
+ * - `'always'`: Sets the form value on every emission, with throttling and loop detection.
715
+ * - `'every'`: Sets the form value on every emission, without throttling.
716
+ *
717
+ * @selector `[dbxFormSource]`
718
+ *
719
+ * @typeParam T - The form value type.
622
720
  */
623
721
  class DbxFormSourceDirective {
624
722
  form = inject((DbxMutableForm), { host: true });
723
+ /**
724
+ * The mode controlling when the source value is forwarded to the form.
725
+ */
625
726
  dbxFormSourceMode = input(...(ngDevMode ? [undefined, { debugName: "dbxFormSourceMode" }] : []));
727
+ /**
728
+ * The source value or observable to pipe into the form.
729
+ */
626
730
  dbxFormSource = input(...(ngDevMode ? [undefined, { debugName: "dbxFormSource" }] : []));
627
731
  _effectSub = cleanSubscription();
628
732
  _setFormSourceObservableEffect = effect(() => {
@@ -648,7 +752,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
648
752
  }], propDecorators: { dbxFormSourceMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxFormSourceMode", required: false }] }], dbxFormSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxFormSource", required: false }] }] } });
649
753
 
650
754
  /**
755
+ * A standalone dialog component that renders a dynamic Formly form within a Material dialog.
756
+ *
757
+ * Provides a header, a configurable form, and a submit button wired to an action handler.
758
+ * The dialog closes with the submitted form value on success, or `undefined` if dismissed.
651
759
  *
760
+ * Use {@link DbxFormActionDialogComponent.openDialogWithForm} to open the dialog programmatically.
761
+ *
762
+ * @typeParam O - The form value type produced by the dialog.
652
763
  */
653
764
  class DbxFormActionDialogComponent extends AbstractDialogDirective {
654
765
  _fieldsSub = cleanSubscription();
@@ -665,10 +776,20 @@ class DbxFormActionDialogComponent extends AbstractDialogDirective {
665
776
  this.context.fields = fields;
666
777
  }));
667
778
  }
779
+ /**
780
+ * Action handler that marks the action as successful and closes the dialog with the submitted value.
781
+ */
668
782
  handleSubmitValue = (value, context) => {
669
783
  context.success();
670
784
  this.close(value);
671
785
  };
786
+ /**
787
+ * Opens a new dialog with a dynamic Formly form using the provided configuration.
788
+ *
789
+ * @param matDialog - The Angular Material dialog service.
790
+ * @param config - Configuration for the dialog, including fields, header, and initial value.
791
+ * @returns A reference to the opened dialog, which resolves to the submitted value or `undefined`.
792
+ */
672
793
  static openDialogWithForm(matDialog, config) {
673
794
  const dialogRef = matDialog.open((DbxFormActionDialogComponent), {
674
795
  width: '90vw',
@@ -710,15 +831,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
710
831
  }]
711
832
  }] });
712
833
 
834
+ /**
835
+ * Default mode for the {@link DbxFormLoadingSourceDirective}, which only passes values on form reset.
836
+ */
713
837
  const DEFAULT_DBX_FORM_LOADING_SOURCE_DIRECTIVE_MODE = 'reset';
714
838
  /**
715
- * Used with a FormComponent to set the value from a LoadingState when the value is available.
839
+ * Directive that sets a form's value from a {@link LoadingState} source once loading is complete.
716
840
  *
717
- * Only passes non-null values from the source.
841
+ * Only passes non-null values from the source. Extracts the value from the finished loading state
842
+ * and forwards it to the form using the configured mode.
843
+ *
844
+ * @selector `[dbxFormLoadingSource]`
845
+ *
846
+ * @typeParam T - The form value type (must extend object).
718
847
  */
719
848
  class DbxFormLoadingSourceDirective {
720
849
  form = inject((DbxMutableForm), { host: true });
850
+ /**
851
+ * The mode controlling when the loading source value is forwarded to the form.
852
+ *
853
+ * Defaults to `'reset'`.
854
+ */
721
855
  dbxFormLoadingSourceMode = input(DEFAULT_DBX_FORM_LOADING_SOURCE_DIRECTIVE_MODE, { ...(ngDevMode ? { debugName: "dbxFormLoadingSourceMode" } : {}), transform: (x) => x ?? DEFAULT_DBX_FORM_LOADING_SOURCE_DIRECTIVE_MODE });
856
+ /**
857
+ * The loading state source to observe. The form value is set once loading finishes with a non-null value.
858
+ */
722
859
  dbxFormLoadingSource = input(...(ngDevMode ? [undefined, { debugName: "dbxFormLoadingSource" }] : []));
723
860
  mode$ = toObservable(this.dbxFormLoadingSourceMode);
724
861
  source$ = toObservable(this.dbxFormLoadingSource).pipe(maybeValueFromObservableOrValue(), filterMaybe(), valueFromFinishedLoadingState());
@@ -739,12 +876,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
739
876
  }], ctorParameters: () => [], propDecorators: { dbxFormLoadingSourceMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxFormLoadingSourceMode", required: false }] }], dbxFormLoadingSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dbxFormLoadingSource", required: false }] }] } });
740
877
 
741
878
  /**
742
- * Used to see form value changes.
879
+ * Directive that observes form value changes and emits the current value when the form is complete/valid,
880
+ * or `undefined` when the form is incomplete.
743
881
  *
744
- * Emits undefined when the form is incomplete, and the value when the form is complete.
882
+ * Subscribes to the form's stream during `ngOnInit` to ensure the first emission occurs after initialization.
883
+ *
884
+ * @selector `[dbxFormValueChange]`
885
+ *
886
+ * @typeParam T - The form value type.
745
887
  */
746
888
  class DbxFormValueChangeDirective {
747
889
  form = inject((DbxForm), { host: true });
890
+ /**
891
+ * Emits the current form value when the form is complete/valid, or `undefined` when incomplete.
892
+ */
748
893
  dbxFormValueChange = output();
749
894
  _sub = cleanSubscription();
750
895
  ngOnInit() {
@@ -774,15 +919,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
774
919
  /**
775
920
  * Streams a value from the input control at the given path. If no path is specified, streams the value from the control.
776
921
  *
777
- * @param fromControl
778
- * @param path
779
- * @returns
922
+ * Returns `undefined` if the control at the given path does not exist.
923
+ *
924
+ * @param fromControl - The root control to retrieve the target control from.
925
+ * @param path - Optional dot-delimited path to a nested control.
926
+ * @returns An observable of the control's value changes (starting with the current value), or `undefined` if the control was not found.
927
+ *
928
+ * @example
929
+ * ```ts
930
+ * const name$ = streamValueFromControl<string>(formGroup, 'user.name');
931
+ * ```
780
932
  */
781
933
  function streamValueFromControl(fromControl, path) {
782
934
  const control = path ? fromControl.get(path) : fromControl;
783
935
  return control?.valueChanges.pipe(startWith(control.value));
784
936
  }
785
937
 
938
+ /**
939
+ * Root Angular module for the dbx-form library.
940
+ *
941
+ * Serves as the base module for form-related functionality. Import this module
942
+ * to access the core form features provided by the library.
943
+ */
786
944
  class DbxFormModule {
787
945
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
788
946
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormModule });
@@ -795,30 +953,91 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
795
953
  }]
796
954
  }] });
797
955
 
956
+ /**
957
+ * Returns a validation message indicating the minimum character length was not met.
958
+ *
959
+ * @param err - The validation error object.
960
+ * @param field - The Formly field configuration containing `minLength` in its props.
961
+ * @returns A human-readable validation message string.
962
+ */
798
963
  function minLengthValidationMessage(err, field) {
799
964
  return `Should have atleast ${field.props.minLength} characters.`;
800
965
  }
966
+ /**
967
+ * Returns a validation message indicating the maximum character length was exceeded.
968
+ *
969
+ * @param err - The validation error object.
970
+ * @param field - The Formly field configuration containing `maxLength` in its props.
971
+ * @returns A human-readable validation message string.
972
+ */
801
973
  function maxLengthValidationMessage(err, field) {
802
974
  return `This value should be less than ${field.props.maxLength} characters.`;
803
975
  }
976
+ /**
977
+ * Returns a validation message indicating the value is below the minimum allowed.
978
+ *
979
+ * @param err - The validation error object.
980
+ * @param field - The Formly field configuration containing `min` in its props.
981
+ * @returns A human-readable validation message string.
982
+ */
804
983
  function minValidationMessage(err, field) {
805
984
  return `This value should be more than or equal to ${field.props.min}.`;
806
985
  }
986
+ /**
987
+ * Returns a validation message indicating the value exceeds the maximum allowed.
988
+ *
989
+ * @param err - The validation error object.
990
+ * @param field - The Formly field configuration containing `max` in its props.
991
+ * @returns A human-readable validation message string.
992
+ */
807
993
  function maxValidationMessage(err, field) {
808
994
  return `This value should be less than or equal to ${field.props.max}.`;
809
995
  }
996
+ /**
997
+ * Validation message option for required fields.
998
+ */
810
999
  const REQUIRED_VALIDATION_MESSAGE = { name: 'required', message: 'This field is required.' };
1000
+ /**
1001
+ * Validation message option for minimum length violations.
1002
+ */
811
1003
  const MIN_LENGTH_VALIDATION_MESSAGE = { name: 'minLength', message: minLengthValidationMessage };
1004
+ /**
1005
+ * Validation message option for maximum length violations.
1006
+ */
812
1007
  const MAX_LENGTH_VALIDATION_MESSAGE = { name: 'maxLength', message: maxLengthValidationMessage };
1008
+ /**
1009
+ * Validation message option for minimum value violations.
1010
+ */
813
1011
  const MIN_VALIDATION_MESSAGE = { name: 'min', message: minValidationMessage };
1012
+ /**
1013
+ * Validation message option for maximum value violations.
1014
+ */
814
1015
  const MAX_VALIDATION_MESSAGE = { name: 'max', message: maxValidationMessage };
1016
+ /**
1017
+ * Validation message option for invalid phone numbers.
1018
+ */
815
1019
  const INVALID_PHONE_NUMBER_MESSAGE = { name: 'validatePhoneNumber', message: 'This is not a valid phone number.' };
1020
+ /**
1021
+ * Validation message option for invalid phone number extensions.
1022
+ */
816
1023
  const INVALID_PHONE_NUMBER_EXTENSION_MESSAGE = { name: 'validatePhoneNumberExtension', message: 'This is not a valid phone number extension.' };
1024
+ /**
1025
+ * Returns the full set of default validation messages used by the form system.
1026
+ *
1027
+ * Includes messages for: required, minLength, maxLength, min, max, phone number, and phone number extension.
1028
+ *
1029
+ * @returns An array of {@link ValidationMessageOption} objects.
1030
+ */
817
1031
  function defaultValidationMessages() {
818
1032
  return [REQUIRED_VALIDATION_MESSAGE, MIN_LENGTH_VALIDATION_MESSAGE, MAX_LENGTH_VALIDATION_MESSAGE, MIN_VALIDATION_MESSAGE, MAX_VALIDATION_MESSAGE, INVALID_PHONE_NUMBER_MESSAGE, INVALID_PHONE_NUMBER_EXTENSION_MESSAGE];
819
1033
  }
820
1034
 
821
1035
  // MARK: Default
1036
+ /**
1037
+ * Default display component for checklist items.
1038
+ *
1039
+ * Renders label, sublabel, and description text from the injected {@link ChecklistItemDisplayContent}.
1040
+ */
822
1041
  class DbxDefaultChecklistItemFieldDisplayComponent {
823
1042
  _displayContentSignal = signal(undefined, ...(ngDevMode ? [{ debugName: "_displayContentSignal" }] : []));
824
1043
  displayContentSignal = this._displayContentSignal.asReadonly();
@@ -866,6 +1085,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
866
1085
  }]
867
1086
  }] });
868
1087
 
1088
+ /**
1089
+ * Wrapper component that injects dynamic display content into a checklist item
1090
+ * via {@link DbxInjectionComponent}. Subscribes to the parent field's display content observable.
1091
+ */
869
1092
  class DbxChecklistItemContentComponent {
870
1093
  checklistItemFieldComponent = inject((DbxChecklistItemFieldComponent));
871
1094
  config = {
@@ -893,6 +1116,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
893
1116
  imports: [DbxInjectionComponent]
894
1117
  }]
895
1118
  }] });
1119
+ /**
1120
+ * Formly field component that renders a single checklist item with a checkbox,
1121
+ * optional anchor link, and dynamic display content.
1122
+ *
1123
+ * The display content is provided as an observable and rendered via a configurable
1124
+ * component class (defaults to {@link DbxDefaultChecklistItemFieldDisplayComponent}).
1125
+ */
896
1126
  class DbxChecklistItemFieldComponent extends FieldType {
897
1127
  _displayContentObs = signal(undefined, ...(ngDevMode ? [{ debugName: "_displayContentObs" }] : []));
898
1128
  displayContent$ = toObservable(this._displayContentObs).pipe(switchMapFilterMaybe(), distinctUntilChanged(), shareReplay(1));
@@ -936,6 +1166,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
936
1166
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [ReactiveFormsModule, MatCheckboxModule, DbxAnchorComponent, MatRippleModule, MatIconModule, DbxChecklistItemContentComponent], template: "<div class=\"dbx-checklist-item-wrapper\" [formGroup]=\"formGroup\">\n @if (label) {\n <div class=\"dbx-checklist-item-label\">{{ label }}</div>\n }\n <div class=\"dbx-checklist-item\">\n <div class=\"dbx-checklist-item-check\">\n <mat-checkbox [formControlName]=\"formControlName\"></mat-checkbox>\n </div>\n <div class=\"dbx-checklist-item-content-wrapper\">\n <dbx-anchor [block]=\"true\" [anchor]=\"anchorSignal()\">\n <div class=\"dbx-checklist-item-content\" matRipple [matRippleDisabled]=\"rippleDisabledSignal()\">\n <dbx-checklist-item-content-component></dbx-checklist-item-content-component>\n <span class=\"spacer\"></span>\n @if (!rippleDisabledSignal()) {\n <mat-icon>navigate_next</mat-icon>\n }\n </div>\n </dbx-anchor>\n </div>\n </div>\n @if (description) {\n <div class=\"dbx-hint\">{{ description }}</div>\n }\n</div>\n" }]
937
1167
  }] });
938
1168
 
1169
+ /**
1170
+ * Formly wrapper that renders a Material info icon button beside the wrapped field.
1171
+ * Clicking the button invokes the configured `onInfoClick` callback.
1172
+ *
1173
+ * Registered as Formly wrapper `'info'`.
1174
+ */
939
1175
  class DbxFormInfoWrapperComponent extends FieldWrapper {
940
1176
  get infoWrapper() {
941
1177
  return this.props;
@@ -978,6 +1214,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
978
1214
  }]
979
1215
  }] });
980
1216
 
1217
+ /**
1218
+ * Formly wrapper that renders the wrapped field inside a `dbx-section` layout
1219
+ * with an optional header and hint text.
1220
+ *
1221
+ * Registered as Formly wrapper `'section'`.
1222
+ *
1223
+ * @selector dbx-form-section-wrapper
1224
+ */
981
1225
  class DbxFormSectionWrapperComponent extends FieldWrapper {
982
1226
  get headerConfig() {
983
1227
  return this.props;
@@ -1004,6 +1248,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1004
1248
  }]
1005
1249
  }] });
1006
1250
 
1251
+ /**
1252
+ * Formly wrapper that arranges child fields in a responsive flex layout
1253
+ * using the `dbxFlexGroup` directive.
1254
+ *
1255
+ * Registered as Formly wrapper `'flex'`.
1256
+ */
1007
1257
  class DbxFormFlexWrapperComponent extends FieldWrapper {
1008
1258
  get flexWrapper() {
1009
1259
  return this.props;
@@ -1038,6 +1288,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1038
1288
  }]
1039
1289
  }] });
1040
1290
 
1291
+ /**
1292
+ * Formly wrapper that renders the wrapped field inside a `dbx-subsection` layout
1293
+ * with an optional header and hint text.
1294
+ *
1295
+ * Registered as Formly wrapper `'subsection'`.
1296
+ *
1297
+ * @selector dbx-form-subsection-wrapper
1298
+ */
1041
1299
  class DbxFormSubsectionWrapperComponent extends FieldWrapper {
1042
1300
  get headerConfig() {
1043
1301
  return this.props;
@@ -1064,7 +1322,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1064
1322
  }]
1065
1323
  }] });
1066
1324
 
1325
+ /**
1326
+ * Default value existence check that returns `true` if the object is non-empty.
1327
+ */
1067
1328
  const DEFAULT_HAS_VALUE_FN = (x) => !objectIsEmpty(x);
1329
+ /**
1330
+ * Abstract base directive for expandable form section wrappers.
1331
+ *
1332
+ * Manages the show/hide state based on whether the field has a value or
1333
+ * whether the user manually opened the section. Subclasses provide the
1334
+ * specific UI (expand button, toggle, etc.).
1335
+ */
1068
1336
  class AbstractFormExpandSectionWrapperDirective extends FieldWrapper {
1069
1337
  _formControlObs = new BehaviorSubject(undefined);
1070
1338
  _toggleOpen = new BehaviorSubject(undefined);
@@ -1223,6 +1491,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1223
1491
  }]
1224
1492
  }] });
1225
1493
 
1494
+ /**
1495
+ * Formly wrapper that applies dynamic CSS classes and inline styles to the wrapped field.
1496
+ *
1497
+ * Supports both static values and reactive observables for `[ngClass]` and `[ngStyle]`.
1498
+ *
1499
+ * Registered as Formly wrapper `'style'`.
1500
+ */
1226
1501
  class DbxFormStyleWrapperComponent extends FieldWrapper {
1227
1502
  _style = new BehaviorSubject(undefined);
1228
1503
  _class = new BehaviorSubject(undefined);
@@ -1309,14 +1584,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1309
1584
  }]
1310
1585
  }] });
1311
1586
 
1587
+ /** Formly wrapper key for the auto-touch behavior wrapper. */
1312
1588
  const AUTO_TOUCH_WRAPPER_KEY = 'autotouch';
1589
+ /** Formly wrapper key for the toggle (slide-toggle expand/collapse) wrapper. */
1313
1590
  const TOGGLE_WRAPPER_KEY = 'toggle';
1591
+ /** Formly wrapper key for the section layout wrapper. */
1314
1592
  const SECTION_WRAPPER_KEY = 'section';
1593
+ /** Formly wrapper key for the subsection layout wrapper. */
1315
1594
  const SUBSECTION_WRAPPER_KEY = 'subsection';
1595
+ /** Formly wrapper key for the info button wrapper. */
1316
1596
  const INFO_WRAPPER_KEY = 'info';
1597
+ /** Formly wrapper key for the flex layout wrapper. */
1317
1598
  const FLEX_WRAPPER_KEY = 'flex';
1599
+ /** Formly wrapper key for the dynamic style/class wrapper. */
1318
1600
  const STYLE_WRAPPER_KEY = 'style';
1601
+ /** Formly wrapper key for the async loading indicator wrapper. */
1319
1602
  const WORKING_WRAPPER_KEY = 'working';
1603
+ /** Formly wrapper key for the expand/collapse section wrapper. */
1320
1604
  const EXPAND_WRAPPER_KEY = 'expand';
1321
1605
 
1322
1606
  const importsAndExports$g = [
@@ -1333,6 +1617,7 @@ const importsAndExports$g = [
1333
1617
  FormlyModule,
1334
1618
  FormlyMaterialModule
1335
1619
  ];
1620
+ /** Registers all Formly field wrapper types (section, flex, expand, toggle, style, info, working, autotouch, subsection). */
1336
1621
  class DbxFormFormlyWrapperModule {
1337
1622
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyWrapperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1338
1623
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyWrapperModule, imports: [AutoTouchFieldWrapperComponent,
@@ -1406,6 +1691,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1406
1691
  }] });
1407
1692
 
1408
1693
  const importsAndExports$f = [DbxChecklistItemFieldComponent, DbxChecklistItemContentComponent, DbxDefaultChecklistItemFieldDisplayComponent];
1694
+ /** Registers the `checklistitem` Formly field type with wrapper support. */
1409
1695
  class DbxFormFormlyChecklistItemFieldModule {
1410
1696
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyChecklistItemFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1411
1697
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyChecklistItemFieldModule, imports: [DbxChecklistItemFieldComponent, DbxChecklistItemContentComponent, DbxDefaultChecklistItemFieldDisplayComponent, DbxFormFormlyWrapperModule, i1$1.FormlyModule], exports: [DbxChecklistItemFieldComponent, DbxChecklistItemContentComponent, DbxDefaultChecklistItemFieldDisplayComponent] });
@@ -1454,14 +1740,28 @@ function propsAndConfigForFieldConfig(fieldConfig, override) {
1454
1740
  parsers
1455
1741
  };
1456
1742
  }
1743
+ /** Keys from {@link PartialPotentialFieldConfig} that are merged into Formly props. */
1457
1744
  const partialPotentialFieldConfigKeys = ['label', 'placeholder', 'required', 'readonly', 'description', 'autocomplete'];
1745
+ /** Filter configuration for extracting field config keys from objects. */
1458
1746
  const partialPotentialFieldConfigKeysFilter = {
1459
1747
  keysFilter: partialPotentialFieldConfigKeys
1460
1748
  };
1749
+ /** Merge function that combines multiple partial field configs, picking only the recognized keys. */
1461
1750
  const mergePropsValueObjects = mergeObjectsFunction(partialPotentialFieldConfigKeysFilter);
1751
+ /** Filter function that extracts only the recognized field config keys from an object. */
1462
1752
  const filterPartialPotentialFieldConfigValuesFromObject = filterFromPOJOFunction({
1463
1753
  filter: partialPotentialFieldConfigKeysFilter
1464
1754
  });
1755
+ /**
1756
+ * Builds a Formly props object from a field config and optional overrides.
1757
+ *
1758
+ * Merges label, placeholder, required, readonly, description, attributes, and autocomplete
1759
+ * settings. When autocomplete is `false`, disables browser autofill via special attributes.
1760
+ *
1761
+ * @param fieldConfig - Base field configuration
1762
+ * @param override - Optional property overrides
1763
+ * @returns Merged props object suitable for use in a {@link FormlyFieldConfig}
1764
+ */
1465
1765
  function propsValueForFieldConfig(fieldConfig, override) {
1466
1766
  const { label, placeholder, required, readonly, description, autocomplete } = mergePropsValueObjects([fieldConfig, override]);
1467
1767
  const attributes = mergeObjects([fieldConfig.attributes, override?.attributes]);
@@ -1498,6 +1798,21 @@ function disableFormlyFieldAutofillAttributes() {
1498
1798
  autocomplete: 'off'
1499
1799
  };
1500
1800
  }
1801
+ /**
1802
+ * Converts Angular validators, async validators, and validation messages into the
1803
+ * Formly-compatible validator configuration format.
1804
+ *
1805
+ * @param input - Validators, async validators, and messages to convert
1806
+ * @returns A Formly-compatible validator config, or undefined if no validators provided
1807
+ *
1808
+ * @example
1809
+ * ```typescript
1810
+ * const config = validatorsForFieldConfig({
1811
+ * validators: [Validators.required],
1812
+ * messages: { required: 'This field is required' }
1813
+ * });
1814
+ * ```
1815
+ */
1501
1816
  function validatorsForFieldConfig(input) {
1502
1817
  const validators = asArray(input.validators);
1503
1818
  const asyncValidators = asArray(input.asyncValidators);
@@ -1524,6 +1839,21 @@ function validatorsForFieldConfig(input) {
1524
1839
  return config;
1525
1840
  }
1526
1841
 
1842
+ /**
1843
+ * Creates a Formly field configuration for a single checklist item with a checkbox
1844
+ * and display content (label, sublabel, description, anchor).
1845
+ *
1846
+ * @param config - Checklist item configuration with key and display content
1847
+ * @returns A validated {@link FormlyFieldConfig} with type `'checklistitem'`
1848
+ *
1849
+ * @example
1850
+ * ```typescript
1851
+ * const field = checklistItemField({
1852
+ * key: 'emailNotifications',
1853
+ * displayContent: of({ label: 'Email Notifications', description: 'Receive updates via email' })
1854
+ * });
1855
+ * ```
1856
+ */
1527
1857
  function checklistItemField(config) {
1528
1858
  const { key, displayContent, componentClass } = config;
1529
1859
  const fieldConfig = formlyField({
@@ -1636,6 +1966,12 @@ class ChecklistItemFieldDataSetBuilder {
1636
1966
  }
1637
1967
  }
1638
1968
 
1969
+ /**
1970
+ * Formly field component that renders a custom Angular component via dynamic injection.
1971
+ *
1972
+ * Uses {@link DbxInjectionComponent} to instantiate the component class specified in the field's
1973
+ * `componentField` configuration.
1974
+ */
1639
1975
  class DbxFormComponentFieldComponent extends FieldType {
1640
1976
  get config() {
1641
1977
  return this.field.componentField;
@@ -1658,6 +1994,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1658
1994
  }] });
1659
1995
 
1660
1996
  const importsAndExports$e = [DbxFormComponentFieldComponent];
1997
+ /** Registers the `component` Formly field type for custom Angular component injection. */
1661
1998
  class DbxFormFormlyComponentFieldModule {
1662
1999
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyComponentFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1663
2000
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyComponentFieldModule, imports: [DbxFormComponentFieldComponent, i1$1.FormlyModule], exports: [DbxFormComponentFieldComponent] });
@@ -1678,6 +2015,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1678
2015
  }]
1679
2016
  }] });
1680
2017
 
2018
+ /**
2019
+ * Creates a Formly field configuration that renders a custom Angular component.
2020
+ *
2021
+ * @param config - Component field configuration
2022
+ * @returns A {@link DbxFormComponentFormlyFieldConfig} with type `'component'`
2023
+ *
2024
+ * @example
2025
+ * ```typescript
2026
+ * const field = componentField({ componentClass: MyCustomFormComponent });
2027
+ * ```
2028
+ */
1681
2029
  function componentField(config) {
1682
2030
  return {
1683
2031
  type: 'component',
@@ -1685,6 +2033,22 @@ function componentField(config) {
1685
2033
  };
1686
2034
  }
1687
2035
 
2036
+ /**
2037
+ * Creates a Formly field configuration for a dbx selection list field.
2038
+ *
2039
+ * @param config - List field configuration including the list component class and state observable
2040
+ * @returns A validated {@link FormlyFieldConfig} with type `'dbxlistfield'`
2041
+ *
2042
+ * @example
2043
+ * ```typescript
2044
+ * const field = dbxListField({
2045
+ * key: 'selectedItems',
2046
+ * label: 'Items',
2047
+ * listComponentClass: MyListComponent,
2048
+ * state$: items$
2049
+ * });
2050
+ * ```
2051
+ */
1688
2052
  function dbxListField(config) {
1689
2053
  const { key, listComponentClass, readKey, state$, loadMore } = config;
1690
2054
  return formlyField({
@@ -1700,7 +2064,10 @@ function dbxListField(config) {
1700
2064
  }
1701
2065
 
1702
2066
  /**
1703
- * Used for picking items by identifier from a DbxList component.
2067
+ * Formly field component that allows picking items by identifier from a dynamic DbxList component.
2068
+ *
2069
+ * The list component class is provided as an observable, enabling lazy loading. Selected items
2070
+ * are tracked by key and synchronized with the form control value.
1704
2071
  */
1705
2072
  class DbxItemListFieldComponent extends FieldType {
1706
2073
  _selectionEventSub = new SubscriptionObject();
@@ -1778,6 +2145,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1778
2145
  }] });
1779
2146
 
1780
2147
  const importsAndExports$d = [DbxItemListFieldComponent];
2148
+ /** Registers the `dbxlistfield` Formly field type for item list selection. */
1781
2149
  class DbxFormFormlyDbxListFieldModule {
1782
2150
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyDbxListFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1783
2151
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyDbxListFieldModule, imports: [DbxItemListFieldComponent, i1$1.FormlyModule], exports: [DbxItemListFieldComponent] });
@@ -1799,7 +2167,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1799
2167
  }] });
1800
2168
 
1801
2169
  /**
1802
- * Used for picking pre-set values using items as the presentation.
2170
+ * Abstract base directive for pickable item fields that manages value loading,
2171
+ * display caching, text filtering, and selection state.
2172
+ *
2173
+ * Subclasses provide the specific UI presentation (chips, lists, etc.).
1803
2174
  */
1804
2175
  class AbstractDbxPickableItemFieldDirective extends FieldType$1 {
1805
2176
  filterMatInput = viewChild('matInput', { ...(ngDevMode ? { debugName: "filterMatInput" } : {}), read: MatInput });
@@ -1873,6 +2244,13 @@ class AbstractDbxPickableItemFieldDirective extends FieldType$1 {
1873
2244
  filterResultsContext = listLoadingStateContext({ obs: this.filteredSearchResultsState$, showLoadingOnNoValue: true });
1874
2245
  itemsSignal = toSignal(this.items$);
1875
2246
  noItemsAvailableSignal = toSignal(this.noItemsAvailable$);
2247
+ /**
2248
+ * Signal that is true when all visible items are currently selected.
2249
+ */
2250
+ allSelectedSignal = computed(() => {
2251
+ const items = this.itemsSignal();
2252
+ return items != null && items.length > 0 && items.every((x) => x.selected);
2253
+ }, ...(ngDevMode ? [{ debugName: "allSelectedSignal" }] : []));
1876
2254
  get readonly() {
1877
2255
  return this.props.readonly;
1878
2256
  }
@@ -1906,6 +2284,9 @@ class AbstractDbxPickableItemFieldDirective extends FieldType$1 {
1906
2284
  get changeSelectionModeToViewOnDisabled() {
1907
2285
  return this.pickableField.changeSelectionModeToViewOnDisabled ?? false;
1908
2286
  }
2287
+ get showSelectAllButton() {
2288
+ return this.pickableField.showSelectAllButton ?? false;
2289
+ }
1909
2290
  get sortItems() {
1910
2291
  return this.pickableField.sortItems;
1911
2292
  }
@@ -2033,6 +2414,31 @@ class AbstractDbxPickableItemFieldDirective extends FieldType$1 {
2033
2414
  const values = this.values.filter((x) => this.hashForValue(x) !== hashToFilter);
2034
2415
  this.setValues(values);
2035
2416
  }
2417
+ /**
2418
+ * Selects all currently visible items.
2419
+ */
2420
+ selectAll() {
2421
+ const items = this.itemsSignal() ?? [];
2422
+ const allValues = items.filter((x) => !x.disabled).map((x) => x.itemValue.value);
2423
+ this.setValues(allValues);
2424
+ }
2425
+ /**
2426
+ * Deselects all currently visible items.
2427
+ */
2428
+ deselectAll() {
2429
+ this.setValues([]);
2430
+ }
2431
+ /**
2432
+ * Toggles between selecting all and deselecting all visible items.
2433
+ */
2434
+ toggleAll() {
2435
+ if (this.allSelectedSignal()) {
2436
+ this.deselectAll();
2437
+ }
2438
+ else {
2439
+ this.selectAll();
2440
+ }
2441
+ }
2036
2442
  setValues(values) {
2037
2443
  // Use to filter non-unique values.
2038
2444
  if (this.hashForValue) {
@@ -2061,7 +2467,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2061
2467
  }], propDecorators: { filterMatInput: [{ type: i0.ViewChild, args: ['matInput', { ...{ read: MatInput }, isSignal: true }] }] } });
2062
2468
 
2063
2469
  /**
2064
- * Used for picking pre-set values using chips as the presentation.
2470
+ * Formly field component that renders pickable values as Material chips.
2471
+ *
2472
+ * Clicking a chip toggles its selection state unless the field is readonly or disabled.
2065
2473
  */
2066
2474
  class DbxPickableChipListFieldComponent extends AbstractDbxPickableItemFieldDirective {
2067
2475
  itemClicked(item) {
@@ -2075,14 +2483,17 @@ class DbxPickableChipListFieldComponent extends AbstractDbxPickableItemFieldDire
2075
2483
  }
2076
2484
  }
2077
2485
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxPickableChipListFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2078
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: DbxPickableChipListFieldComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"dbx-pickable-item-field\">\n <dbx-loading [context]=\"context\" [linear]=\"true\">\n @if (showFilterInput) {\n <ng-container *ngTemplateOutlet=\"filterTemplate\"></ng-container>\n }\n <!-- Content -->\n <div class=\"dbx-pickable-item-field-chips\">\n <mat-chip-listbox [multiple]=\"multiSelect\" [required]=\"required\" [selectable]=\"!isReadonlyOrDisabled\" [disabled]=\"readonly\" #chipList>\n @for (item of itemsSignal(); track item.itemValue.value) {\n <mat-chip-option (click)=\"itemClicked(item)\" [selected]=\"item.selected\" [disabled]=\"isReadonlyOrDisabled || item.disabled\">\n @if (item.itemValue.icon) {\n <mat-icon matChipAvatar>{{ item.itemValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ item.itemValue.label }}</span>\n @if (item.itemValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ item.itemValue.sublabel }}</span>\n }\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <dbx-injection [config]=\"footerConfig\"></dbx-injection>\n </div>\n </dbx-loading>\n</div>\n\n<!-- Filter Input -->\n<ng-template #filterTemplate>\n <div class=\"dbx-pickable-item-field-filter\">\n <div class=\"dbx-label\">{{ filterLabel }}</div>\n <input [name]=\"name\" autocomplete=\"{{ autocomplete }}\" #filterMatInput=\"matInput\" matInput [placeholder]=\"placeholder\" [formControl]=\"inputCtrl\" />\n <mat-divider></mat-divider>\n <dbx-loading [linear]=\"true\" [context]=\"filterResultsContext\"></dbx-loading>\n <!-- No items found. -->\n @if (noItemsAvailableSignal()) {\n <p class=\"dbx-label\">No items match this filter.</p>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i1$4.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i1$4.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i1$4.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: DbxLoadingComponent, selector: "dbx-loading", inputs: ["padding", "show", "text", "mode", "color", "diameter", "linear", "loading", "error", "context"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: DbxInjectionComponent, selector: "dbx-injection, [dbxInjection], [dbx-injection]", inputs: ["config", "template"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2486
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: DbxPickableChipListFieldComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"dbx-pickable-item-field\">\n <dbx-loading [context]=\"context\" [linear]=\"true\">\n @if (showFilterInput) {\n <ng-container *ngTemplateOutlet=\"filterTemplate\"></ng-container>\n }\n <!-- Content -->\n <div class=\"dbx-pickable-item-field-chips\">\n <mat-chip-listbox [multiple]=\"multiSelect\" [required]=\"required\" [selectable]=\"!isReadonlyOrDisabled\" [disabled]=\"readonly\" #chipList>\n @if (showSelectAllButton && multiSelect && !isReadonlyOrDisabled) {\n <mat-chip-option (click)=\"toggleAll()\" [selected]=\"allSelectedSignal()\">\n <span class=\"dbx-chip-label\">All</span>\n </mat-chip-option>\n }\n @for (item of itemsSignal(); track item.itemValue.value) {\n <mat-chip-option (click)=\"itemClicked(item)\" [selected]=\"item.selected\" [disabled]=\"isReadonlyOrDisabled || item.disabled\">\n @if (item.itemValue.icon) {\n <mat-icon matChipAvatar>{{ item.itemValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ item.itemValue.label }}</span>\n @if (item.itemValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ item.itemValue.sublabel }}</span>\n }\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <dbx-injection [config]=\"footerConfig\"></dbx-injection>\n </div>\n </dbx-loading>\n</div>\n\n<!-- Filter Input -->\n<ng-template #filterTemplate>\n <div class=\"dbx-pickable-item-field-filter\">\n <div class=\"dbx-label\">{{ filterLabel }}</div>\n <input [name]=\"name\" autocomplete=\"{{ autocomplete }}\" #filterMatInput=\"matInput\" matInput [placeholder]=\"placeholder\" [formControl]=\"inputCtrl\" />\n <mat-divider></mat-divider>\n <dbx-loading [linear]=\"true\" [context]=\"filterResultsContext\"></dbx-loading>\n <!-- No items found. -->\n @if (noItemsAvailableSignal()) {\n <p class=\"dbx-label\">No items match this filter.</p>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i1$4.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i1$4.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i1$4.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: DbxLoadingComponent, selector: "dbx-loading", inputs: ["padding", "show", "text", "mode", "color", "diameter", "linear", "loading", "error", "context"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: DbxInjectionComponent, selector: "dbx-injection, [dbxInjection], [dbx-injection]", inputs: ["config", "template"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2079
2487
  }
2080
2488
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxPickableChipListFieldComponent, decorators: [{
2081
2489
  type: Component,
2082
- args: [{ imports: [MatChipsModule, NgTemplateOutlet, FormsModule, ReactiveFormsModule, MatIconModule, MatInputModule, DbxLoadingComponent, MatDivider, DbxInjectionComponent], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"dbx-pickable-item-field\">\n <dbx-loading [context]=\"context\" [linear]=\"true\">\n @if (showFilterInput) {\n <ng-container *ngTemplateOutlet=\"filterTemplate\"></ng-container>\n }\n <!-- Content -->\n <div class=\"dbx-pickable-item-field-chips\">\n <mat-chip-listbox [multiple]=\"multiSelect\" [required]=\"required\" [selectable]=\"!isReadonlyOrDisabled\" [disabled]=\"readonly\" #chipList>\n @for (item of itemsSignal(); track item.itemValue.value) {\n <mat-chip-option (click)=\"itemClicked(item)\" [selected]=\"item.selected\" [disabled]=\"isReadonlyOrDisabled || item.disabled\">\n @if (item.itemValue.icon) {\n <mat-icon matChipAvatar>{{ item.itemValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ item.itemValue.label }}</span>\n @if (item.itemValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ item.itemValue.sublabel }}</span>\n }\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <dbx-injection [config]=\"footerConfig\"></dbx-injection>\n </div>\n </dbx-loading>\n</div>\n\n<!-- Filter Input -->\n<ng-template #filterTemplate>\n <div class=\"dbx-pickable-item-field-filter\">\n <div class=\"dbx-label\">{{ filterLabel }}</div>\n <input [name]=\"name\" autocomplete=\"{{ autocomplete }}\" #filterMatInput=\"matInput\" matInput [placeholder]=\"placeholder\" [formControl]=\"inputCtrl\" />\n <mat-divider></mat-divider>\n <dbx-loading [linear]=\"true\" [context]=\"filterResultsContext\"></dbx-loading>\n <!-- No items found. -->\n @if (noItemsAvailableSignal()) {\n <p class=\"dbx-label\">No items match this filter.</p>\n }\n </div>\n</ng-template>\n" }]
2490
+ args: [{ imports: [MatChipsModule, NgTemplateOutlet, FormsModule, ReactiveFormsModule, MatIconModule, MatInputModule, DbxLoadingComponent, MatDivider, DbxInjectionComponent], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"dbx-pickable-item-field\">\n <dbx-loading [context]=\"context\" [linear]=\"true\">\n @if (showFilterInput) {\n <ng-container *ngTemplateOutlet=\"filterTemplate\"></ng-container>\n }\n <!-- Content -->\n <div class=\"dbx-pickable-item-field-chips\">\n <mat-chip-listbox [multiple]=\"multiSelect\" [required]=\"required\" [selectable]=\"!isReadonlyOrDisabled\" [disabled]=\"readonly\" #chipList>\n @if (showSelectAllButton && multiSelect && !isReadonlyOrDisabled) {\n <mat-chip-option (click)=\"toggleAll()\" [selected]=\"allSelectedSignal()\">\n <span class=\"dbx-chip-label\">All</span>\n </mat-chip-option>\n }\n @for (item of itemsSignal(); track item.itemValue.value) {\n <mat-chip-option (click)=\"itemClicked(item)\" [selected]=\"item.selected\" [disabled]=\"isReadonlyOrDisabled || item.disabled\">\n @if (item.itemValue.icon) {\n <mat-icon matChipAvatar>{{ item.itemValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ item.itemValue.label }}</span>\n @if (item.itemValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ item.itemValue.sublabel }}</span>\n }\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <dbx-injection [config]=\"footerConfig\"></dbx-injection>\n </div>\n </dbx-loading>\n</div>\n\n<!-- Filter Input -->\n<ng-template #filterTemplate>\n <div class=\"dbx-pickable-item-field-filter\">\n <div class=\"dbx-label\">{{ filterLabel }}</div>\n <input [name]=\"name\" autocomplete=\"{{ autocomplete }}\" #filterMatInput=\"matInput\" matInput [placeholder]=\"placeholder\" [formControl]=\"inputCtrl\" />\n <mat-divider></mat-divider>\n <dbx-loading [linear]=\"true\" [context]=\"filterResultsContext\"></dbx-loading>\n <!-- No items found. -->\n @if (noItemsAvailableSignal()) {\n <p class=\"dbx-label\">No items match this filter.</p>\n }\n </div>\n</ng-template>\n" }]
2083
2491
  }] });
2084
2492
 
2085
2493
  // MARK: Selection List
2494
+ /**
2495
+ * Wrapper component for the pickable item selection list, providing the list view container.
2496
+ */
2086
2497
  class DbxPickableListFieldItemListComponent extends AbstractDbxSelectionListWrapperDirective {
2087
2498
  constructor() {
2088
2499
  super({
@@ -2104,7 +2515,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2104
2515
  }]
2105
2516
  }], ctorParameters: () => [] });
2106
2517
  /**
2107
- * NOTE: Values input are PickableItemFieldItem<T>, but output values are PickableValueFieldDisplayValue<T>.
2518
+ * List view component that renders pickable items with selection support.
2519
+ *
2520
+ * Input values are {@link PickableItemFieldItem}, but output selection events emit {@link PickableValueFieldDisplayValue}.
2108
2521
  */
2109
2522
  class DbxPickableListFieldItemListViewComponent extends AbstractDbxSelectionListViewDirective {
2110
2523
  dbxPickableListFieldComponent = inject((DbxPickableListFieldComponent));
@@ -2178,9 +2591,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2178
2591
  standalone: true
2179
2592
  }]
2180
2593
  }] });
2181
- // List Field Component
2594
+ // MARK: List Field Component
2182
2595
  /**
2183
- * Used for picking pre-set values using a selection list as the presentation.
2596
+ * Formly field component that renders pickable values as a selectable list.
2597
+ *
2598
+ * Delegates to {@link DbxPickableListFieldItemListComponent} for list rendering and
2599
+ * handles selection change events to update the form control value.
2184
2600
  */
2185
2601
  class DbxPickableListFieldComponent extends AbstractDbxPickableItemFieldDirective {
2186
2602
  onSelectionChange(event) {
@@ -2197,6 +2613,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2197
2613
  }] });
2198
2614
 
2199
2615
  const importsAndExports$c = [DbxPickableChipListFieldComponent, DbxPickableListFieldComponent, DbxPickableListFieldItemListComponent, DbxPickableListFieldItemListViewComponent, DbxPickableListFieldItemListViewItemComponent];
2616
+ /** Registers the `pickablechipfield` and `pickablelistfield` Formly field types. */
2200
2617
  class DbxFormFormlyPickableFieldModule {
2201
2618
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyPickableFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2202
2619
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyPickableFieldModule, imports: [DbxPickableChipListFieldComponent, DbxPickableListFieldComponent, DbxPickableListFieldItemListComponent, DbxPickableListFieldItemListViewComponent, DbxPickableListFieldItemListViewItemComponent, i1$1.FormlyModule], exports: [DbxPickableChipListFieldComponent, DbxPickableListFieldComponent, DbxPickableListFieldItemListComponent, DbxPickableListFieldItemListViewComponent, DbxPickableListFieldItemListViewItemComponent] });
@@ -2223,6 +2640,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2223
2640
  }]
2224
2641
  }] });
2225
2642
 
2643
+ /**
2644
+ * Creates a Formly field configuration for a pickable chip field that displays
2645
+ * selected values as Material chips.
2646
+ *
2647
+ * @param config - Pickable item configuration including load and display functions
2648
+ * @returns A validated {@link FormlyFieldConfig} with type `'pickablechipfield'`
2649
+ *
2650
+ * @example
2651
+ * ```typescript
2652
+ * const field = pickableItemChipField({
2653
+ * key: 'tags',
2654
+ * label: 'Tags',
2655
+ * loadValues: () => tags$,
2656
+ * hashForValue: (tag) => tag.id
2657
+ * });
2658
+ * ```
2659
+ */
2226
2660
  function pickableItemChipField(config) {
2227
2661
  const { key, materialFormField } = config;
2228
2662
  return formlyField({
@@ -2235,6 +2669,23 @@ function pickableItemChipField(config) {
2235
2669
  })
2236
2670
  });
2237
2671
  }
2672
+ /**
2673
+ * Creates a Formly field configuration for a pickable list field that displays
2674
+ * selected values in a selection list.
2675
+ *
2676
+ * @param config - Pickable item configuration including load and display functions
2677
+ * @returns A validated {@link FormlyFieldConfig} with type `'pickablelistfield'`
2678
+ *
2679
+ * @example
2680
+ * ```typescript
2681
+ * const field = pickableItemListField({
2682
+ * key: 'categories',
2683
+ * label: 'Categories',
2684
+ * loadValues: () => categories$,
2685
+ * hashForValue: (cat) => cat.id
2686
+ * });
2687
+ * ```
2688
+ */
2238
2689
  function pickableItemListField(config) {
2239
2690
  const { key, materialFormField } = config;
2240
2691
  return formlyField({
@@ -2248,10 +2699,20 @@ function pickableItemListField(config) {
2248
2699
  });
2249
2700
  }
2250
2701
 
2702
+ /** Case-insensitive filter function that matches pickable display values by their label using indexOf. */
2251
2703
  const filterPickableItemFieldValuesByLabelFilterFunction = searchStringFilterFunction({
2252
2704
  readStrings: (x) => [x.label],
2253
2705
  decisionFactory: caseInsensitiveFilterByIndexOfDecisionFactory
2254
2706
  });
2707
+ /**
2708
+ * Filters pickable display values by label text, returning their underlying values.
2709
+ *
2710
+ * Returns all values when filter text is empty.
2711
+ *
2712
+ * @param filterText - Text to filter by
2713
+ * @param values - Display values to filter
2714
+ * @returns Observable emitting the filtered value array
2715
+ */
2255
2716
  function filterPickableItemFieldValuesByLabel(filterText, values) {
2256
2717
  let filteredValues;
2257
2718
  if (filterText) {
@@ -2262,10 +2723,33 @@ function filterPickableItemFieldValuesByLabel(filterText, values) {
2262
2723
  }
2263
2724
  return of(filteredValues.map((x) => x.value));
2264
2725
  }
2726
+ /** String sort comparator that orders pickable items alphabetically by label. */
2265
2727
  const sortPickableItemsByLabelStringFunction = sortByStringFunction((x) => x.itemValue.label);
2728
+ /**
2729
+ * Sorts pickable items alphabetically by their label.
2730
+ *
2731
+ * @param chips - Items to sort
2732
+ * @returns The sorted array (mutated in place)
2733
+ */
2266
2734
  function sortPickableItemsByLabel(chips) {
2267
2735
  return chips.sort(sortPickableItemsByLabelStringFunction);
2268
2736
  }
2737
+ /**
2738
+ * Creates `loadValues`, `displayForValue`, and `filterValues` functions from a static array of labeled values.
2739
+ *
2740
+ * Simplifies pickable field setup when all options are known upfront.
2741
+ *
2742
+ * @param input - Array of labeled values or a config object with options and unknown label
2743
+ * @returns Props subset for configuring a pickable field
2744
+ *
2745
+ * @example
2746
+ * ```typescript
2747
+ * const config = pickableValueFieldValuesConfigForStaticLabeledValues([
2748
+ * { value: 'a', label: 'Option A' },
2749
+ * { value: 'b', label: 'Option B' }
2750
+ * ]);
2751
+ * ```
2752
+ */
2269
2753
  function pickableValueFieldValuesConfigForStaticLabeledValues(input) {
2270
2754
  const config = Array.isArray(input) ? { allOptions: input } : input;
2271
2755
  const { allOptions, unknownOptionLabel = 'UNKNOWN' } = config;
@@ -2281,7 +2765,14 @@ function pickableValueFieldValuesConfigForStaticLabeledValues(input) {
2281
2765
  };
2282
2766
  }
2283
2767
 
2768
+ /** Injection token providing the {@link ConfiguredSearchableValueFieldDisplayValue} to autocomplete item display components. */
2284
2769
  const DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN = new InjectionToken('DbxSearchableField');
2770
+ /**
2771
+ * Renders a single autocomplete suggestion item using dynamic component injection.
2772
+ *
2773
+ * Wraps the display component in a {@link DbxAnchorComponent} and provides the display
2774
+ * value data via {@link DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN}.
2775
+ */
2285
2776
  class DbxSearchableFieldAutocompleteItemComponent {
2286
2777
  displayValue = input.required(...(ngDevMode ? [{ debugName: "displayValue" }] : []));
2287
2778
  configSignal = computed(() => {
@@ -2320,6 +2811,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2320
2811
  }]
2321
2812
  }], propDecorators: { displayValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayValue", required: true }] }] } });
2322
2813
  // MARK: Default
2814
+ /**
2815
+ * Abstract base directive for custom searchable field display components.
2816
+ *
2817
+ * Injects the {@link ConfiguredSearchableValueFieldDisplayValue} via the
2818
+ * {@link DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN} for use in custom templates.
2819
+ */
2323
2820
  class AbstractDbxSearchableFieldDisplayDirective {
2324
2821
  displayValue = inject(DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN);
2325
2822
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AbstractDbxSearchableFieldDisplayDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -2328,6 +2825,11 @@ class AbstractDbxSearchableFieldDisplayDirective {
2328
2825
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AbstractDbxSearchableFieldDisplayDirective, decorators: [{
2329
2826
  type: Directive
2330
2827
  }] });
2828
+ /**
2829
+ * Default display component for searchable field autocomplete items.
2830
+ *
2831
+ * Renders an optional icon, a label, and an optional sublabel in a horizontal flex layout.
2832
+ */
2331
2833
  class DbxDefaultSearchableFieldDisplayComponent extends AbstractDbxSearchableFieldDisplayDirective {
2332
2834
  icon = this.displayValue.icon;
2333
2835
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxDefaultSearchableFieldDisplayComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
@@ -2564,6 +3066,7 @@ class AbstractDbxSearchableValueFieldDirective extends FieldType$1 {
2564
3066
  this.inputCtrl.setValue(text.trim());
2565
3067
  }
2566
3068
  if (!this.inputCtrl.valid) {
3069
+ this.inputCtrl.markAsTouched();
2567
3070
  return;
2568
3071
  }
2569
3072
  if (text) {
@@ -2571,6 +3074,21 @@ class AbstractDbxSearchableValueFieldDirective extends FieldType$1 {
2571
3074
  this.addValue(value);
2572
3075
  }
2573
3076
  }
3077
+ /**
3078
+ * Returns the first validation error message from the input control, if any.
3079
+ */
3080
+ get inputErrorMessage() {
3081
+ const errors = this.inputCtrl.errors;
3082
+ if (errors) {
3083
+ for (const key of Object.keys(errors)) {
3084
+ const error = errors[key];
3085
+ if (error?.message) {
3086
+ return error.message;
3087
+ }
3088
+ }
3089
+ }
3090
+ return undefined;
3091
+ }
2574
3092
  addWithDisplayValue(displayValue) {
2575
3093
  this.addValue(displayValue.value);
2576
3094
  }
@@ -2641,6 +3159,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2641
3159
  type: Directive
2642
3160
  }], propDecorators: { textInput: [{ type: i0.ViewChild, args: ['textInput', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
2643
3161
 
3162
+ /**
3163
+ * Formly field component that combines a search autocomplete with Material chips
3164
+ * for selecting multiple values.
3165
+ *
3166
+ * Supports adding values by typing (if string values are allowed), selecting from
3167
+ * autocomplete results, and removing chips. Handles tab and blur events to auto-add text input.
3168
+ */
2644
3169
  class DbxSearchableChipFieldComponent extends AbstractDbxSearchableValueFieldDirective {
2645
3170
  get multiSelect() {
2646
3171
  return this.props.multiSelect ?? true;
@@ -2684,11 +3209,11 @@ class DbxSearchableChipFieldComponent extends AbstractDbxSearchableValueFieldDir
2684
3209
  this._blur.next();
2685
3210
  }
2686
3211
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxSearchableChipFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2687
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: DbxSearchableChipFieldComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"dbx-searchable-field\">\n <!-- View -->\n <mat-chip-grid [required]=\"required\" [disabled]=\"readonly\" #chipList>\n @for (displayValue of displayValuesSignal(); track displayValue.value) {\n <mat-chip-row [removable]=\"true\" (removed)=\"removeWithDisplayValue(displayValue)\">\n @if (displayValue.icon) {\n <mat-icon matChipAvatar>{{ displayValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ displayValue.label }}</span>\n @if (displayValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ displayValue.sublabel }}</span>\n }\n @if (!readonly) {\n <mat-icon matChipRemove>cancel</mat-icon>\n }\n </mat-chip-row>\n }\n <input #textInput [name]=\"name\" [placeholder]=\"searchInputPlaceholder\" [formControl]=\"inputCtrl\" [matAutocomplete]=\"auto\" autocomplete=\"{{ autocomplete }}\" [matAutocompleteDisabled]=\"readonly\" [matChipInputFor]=\"chipList\" (keydown)=\"tabPressedOnInput($event)\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" (matChipInputTokenEnd)=\"addChip($event)\" (blur)=\"onBlur()\" />\n </mat-chip-grid>\n <div class=\"searchable-field-form-loading\">\n <dbx-loading [linear]=\"true\" [context]=\"searchContext\"></dbx-loading>\n </div>\n</div>\n\n<!-- Autocomplete -->\n<mat-autocomplete class=\"dbx-searchable-text-field-autocomplete\" #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n @for (displayValue of searchResultsSignal(); track displayValue.value) {\n <mat-option [value]=\"displayValue\">\n <dbx-searchable-field-autocomplete-item [displayValue]=\"displayValue\"></dbx-searchable-field-autocomplete-item>\n </mat-option>\n }\n</mat-autocomplete>\n", dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i1$4.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i1$4.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i1$4.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i1$4.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i1$4.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: DbxLoadingModule }, { kind: "component", type: i1$2.DbxLoadingComponent, selector: "dbx-loading", inputs: ["padding", "show", "text", "mode", "color", "diameter", "linear", "loading", "error", "context"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i5.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i5.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: DbxSearchableFieldAutocompleteItemComponent, selector: "dbx-searchable-field-autocomplete-item", inputs: ["displayValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3212
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: DbxSearchableChipFieldComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"dbx-searchable-field\">\n <!-- View -->\n <mat-chip-grid [required]=\"required\" [disabled]=\"readonly\" #chipList>\n @for (displayValue of displayValuesSignal(); track displayValue.value) {\n <mat-chip-row [removable]=\"true\" (removed)=\"removeWithDisplayValue(displayValue)\">\n @if (displayValue.icon) {\n <mat-icon matChipAvatar>{{ displayValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ displayValue.label }}</span>\n @if (displayValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ displayValue.sublabel }}</span>\n }\n @if (!readonly) {\n <mat-icon matChipRemove>cancel</mat-icon>\n }\n </mat-chip-row>\n }\n <input #textInput [name]=\"name\" [placeholder]=\"searchInputPlaceholder\" [formControl]=\"inputCtrl\" [matAutocomplete]=\"auto\" autocomplete=\"{{ autocomplete }}\" [matAutocompleteDisabled]=\"readonly\" [matChipInputFor]=\"chipList\" (keydown)=\"tabPressedOnInput($event)\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" (matChipInputTokenEnd)=\"addChip($event)\" (blur)=\"onBlur()\" />\n </mat-chip-grid>\n <div class=\"searchable-field-form-loading\">\n <dbx-loading [linear]=\"true\" [context]=\"searchContext\"></dbx-loading>\n </div>\n @if (inputCtrl.touched && inputErrorMessage) {\n <span class=\"dbx-chip-input-error\">{{ inputErrorMessage }}</span>\n }\n</div>\n\n<!-- Autocomplete -->\n<mat-autocomplete class=\"dbx-searchable-text-field-autocomplete\" #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n @for (displayValue of searchResultsSignal(); track displayValue.value) {\n <mat-option [value]=\"displayValue\">\n <dbx-searchable-field-autocomplete-item [displayValue]=\"displayValue\"></dbx-searchable-field-autocomplete-item>\n </mat-option>\n }\n</mat-autocomplete>\n", dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "directive", type: i1$4.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i1$4.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i1$4.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i1$4.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i1$4.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: DbxLoadingModule }, { kind: "component", type: i1$2.DbxLoadingComponent, selector: "dbx-loading", inputs: ["padding", "show", "text", "mode", "color", "diameter", "linear", "loading", "error", "context"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i5.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i5.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: DbxSearchableFieldAutocompleteItemComponent, selector: "dbx-searchable-field-autocomplete-item", inputs: ["displayValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2688
3213
  }
2689
3214
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxSearchableChipFieldComponent, decorators: [{
2690
3215
  type: Component,
2691
- args: [{ imports: [MatChipsModule, MatIconModule, FormsModule, ReactiveFormsModule, DbxLoadingModule, MatAutocompleteModule, MatOptionModule, DbxSearchableFieldAutocompleteItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"dbx-searchable-field\">\n <!-- View -->\n <mat-chip-grid [required]=\"required\" [disabled]=\"readonly\" #chipList>\n @for (displayValue of displayValuesSignal(); track displayValue.value) {\n <mat-chip-row [removable]=\"true\" (removed)=\"removeWithDisplayValue(displayValue)\">\n @if (displayValue.icon) {\n <mat-icon matChipAvatar>{{ displayValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ displayValue.label }}</span>\n @if (displayValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ displayValue.sublabel }}</span>\n }\n @if (!readonly) {\n <mat-icon matChipRemove>cancel</mat-icon>\n }\n </mat-chip-row>\n }\n <input #textInput [name]=\"name\" [placeholder]=\"searchInputPlaceholder\" [formControl]=\"inputCtrl\" [matAutocomplete]=\"auto\" autocomplete=\"{{ autocomplete }}\" [matAutocompleteDisabled]=\"readonly\" [matChipInputFor]=\"chipList\" (keydown)=\"tabPressedOnInput($event)\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" (matChipInputTokenEnd)=\"addChip($event)\" (blur)=\"onBlur()\" />\n </mat-chip-grid>\n <div class=\"searchable-field-form-loading\">\n <dbx-loading [linear]=\"true\" [context]=\"searchContext\"></dbx-loading>\n </div>\n</div>\n\n<!-- Autocomplete -->\n<mat-autocomplete class=\"dbx-searchable-text-field-autocomplete\" #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n @for (displayValue of searchResultsSignal(); track displayValue.value) {\n <mat-option [value]=\"displayValue\">\n <dbx-searchable-field-autocomplete-item [displayValue]=\"displayValue\"></dbx-searchable-field-autocomplete-item>\n </mat-option>\n }\n</mat-autocomplete>\n" }]
3216
+ args: [{ imports: [MatChipsModule, MatIconModule, FormsModule, ReactiveFormsModule, DbxLoadingModule, MatAutocompleteModule, MatOptionModule, DbxSearchableFieldAutocompleteItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"dbx-searchable-field\">\n <!-- View -->\n <mat-chip-grid [required]=\"required\" [disabled]=\"readonly\" #chipList>\n @for (displayValue of displayValuesSignal(); track displayValue.value) {\n <mat-chip-row [removable]=\"true\" (removed)=\"removeWithDisplayValue(displayValue)\">\n @if (displayValue.icon) {\n <mat-icon matChipAvatar>{{ displayValue.icon }}</mat-icon>\n }\n <span class=\"dbx-chip-label\">{{ displayValue.label }}</span>\n @if (displayValue.sublabel) {\n <span class=\"dbx-chip-sublabel\">{{ displayValue.sublabel }}</span>\n }\n @if (!readonly) {\n <mat-icon matChipRemove>cancel</mat-icon>\n }\n </mat-chip-row>\n }\n <input #textInput [name]=\"name\" [placeholder]=\"searchInputPlaceholder\" [formControl]=\"inputCtrl\" [matAutocomplete]=\"auto\" autocomplete=\"{{ autocomplete }}\" [matAutocompleteDisabled]=\"readonly\" [matChipInputFor]=\"chipList\" (keydown)=\"tabPressedOnInput($event)\" [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" (matChipInputTokenEnd)=\"addChip($event)\" (blur)=\"onBlur()\" />\n </mat-chip-grid>\n <div class=\"searchable-field-form-loading\">\n <dbx-loading [linear]=\"true\" [context]=\"searchContext\"></dbx-loading>\n </div>\n @if (inputCtrl.touched && inputErrorMessage) {\n <span class=\"dbx-chip-input-error\">{{ inputErrorMessage }}</span>\n }\n</div>\n\n<!-- Autocomplete -->\n<mat-autocomplete class=\"dbx-searchable-text-field-autocomplete\" #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n @for (displayValue of searchResultsSignal(); track displayValue.value) {\n <mat-option [value]=\"displayValue\">\n <dbx-searchable-field-autocomplete-item [displayValue]=\"displayValue\"></dbx-searchable-field-autocomplete-item>\n </mat-option>\n }\n</mat-autocomplete>\n" }]
2692
3217
  }] });
2693
3218
 
2694
3219
  /**
@@ -2725,12 +3250,35 @@ function makeMetaFilterSearchableFieldValueDisplayFn({ loadMetaForValues, makeDi
2725
3250
  return allValues.pipe(switchMap(makeDisplayForValues));
2726
3251
  };
2727
3252
  }
3253
+ /**
3254
+ * Creates a searchable chip field pre-configured for string values.
3255
+ *
3256
+ * @param config - String-specific searchable chip field configuration
3257
+ * @returns A {@link FormlyFieldConfig} with type `'searchablechipfield'`
3258
+ *
3259
+ * @example
3260
+ * ```typescript
3261
+ * const field = searchableStringChipField({ key: 'tags', label: 'Tags', search: searchFn });
3262
+ * ```
3263
+ */
2728
3264
  function searchableStringChipField(config) {
2729
3265
  return searchableChipField({
2730
3266
  ...config,
2731
3267
  allowStringValues: true
2732
3268
  });
2733
3269
  }
3270
+ /**
3271
+ * Creates a Formly field configuration for a searchable chip field where users
3272
+ * can search for and select values displayed as Material chips.
3273
+ *
3274
+ * @param config - Searchable chip field configuration
3275
+ * @returns A validated {@link FormlyFieldConfig} with type `'searchablechipfield'`
3276
+ *
3277
+ * @example
3278
+ * ```typescript
3279
+ * const field = searchableChipField({ key: 'skills', label: 'Skills', search: searchFn, hashForValue: (s) => s.id });
3280
+ * ```
3281
+ */
2734
3282
  function searchableChipField(config) {
2735
3283
  const { key, placeholder, materialFormField } = config;
2736
3284
  return formlyField({
@@ -2744,6 +3292,18 @@ function searchableChipField(config) {
2744
3292
  })
2745
3293
  });
2746
3294
  }
3295
+ /**
3296
+ * Creates a Formly field configuration for a searchable text field with autocomplete
3297
+ * dropdown for selecting values.
3298
+ *
3299
+ * @param config - Searchable text field configuration
3300
+ * @returns A validated {@link FormlyFieldConfig} with type `'searchabletextfield'`
3301
+ *
3302
+ * @example
3303
+ * ```typescript
3304
+ * const field = searchableTextField({ key: 'assignee', label: 'Assignee', search: searchFn });
3305
+ * ```
3306
+ */
2747
3307
  function searchableTextField(config) {
2748
3308
  const { key, materialFormField } = config;
2749
3309
  return formlyField({
@@ -2758,7 +3318,10 @@ function searchableTextField(config) {
2758
3318
  }
2759
3319
 
2760
3320
  /**
2761
- * Display component for selecting a single item/value.
3321
+ * Formly field component for selecting a single value via text search with autocomplete.
3322
+ *
3323
+ * Syncs the selected value's label back to the text input. Supports optional display
3324
+ * of the currently selected value and clear functionality.
2762
3325
  */
2763
3326
  class DbxSearchableTextFieldComponent extends AbstractDbxSearchableValueFieldDirective {
2764
3327
  allowSyncValueToInput = true;
@@ -2812,6 +3375,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2812
3375
  }] });
2813
3376
 
2814
3377
  const importsAndExports$b = [DbxSearchableChipFieldComponent, DbxSearchableTextFieldComponent, DbxSearchableFieldAutocompleteItemComponent, DbxDefaultSearchableFieldDisplayComponent];
3378
+ /** Registers the `searchablechipfield` and `searchabletextfield` Formly field types. */
2815
3379
  class DbxFormFormlySearchableFieldModule {
2816
3380
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlySearchableFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2817
3381
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlySearchableFieldModule, imports: [DbxSearchableChipFieldComponent, DbxSearchableTextFieldComponent, DbxSearchableFieldAutocompleteItemComponent, DbxDefaultSearchableFieldDisplayComponent, i1$1.FormlyModule], exports: [DbxSearchableChipFieldComponent, DbxSearchableTextFieldComponent, DbxSearchableFieldAutocompleteItemComponent, DbxDefaultSearchableFieldDisplayComponent] });
@@ -2838,6 +3402,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2838
3402
  }]
2839
3403
  }] });
2840
3404
 
3405
+ /**
3406
+ * Creates a searchable chip field for freeform text entry where each entered string
3407
+ * becomes a chip. Values are lowercased by default unless `caseSensitive` is true.
3408
+ *
3409
+ * @param config - Text chip field configuration
3410
+ * @returns A {@link FormlyFieldConfig} for text chip input
3411
+ *
3412
+ * @example
3413
+ * ```typescript
3414
+ * const field = chipTextField({ key: 'tags', label: 'Tags' });
3415
+ * ```
3416
+ */
2841
3417
  function chipTextField(config) {
2842
3418
  const convertStringValue = config.caseSensitive ? (x) => x : (x) => x?.toLowerCase();
2843
3419
  return searchableChipField({
@@ -2852,7 +3428,11 @@ function chipTextField(config) {
2852
3428
  }
2853
3429
 
2854
3430
  /**
2855
- * Component that displays a select view (multi or not)
3431
+ * Formly field component that renders a Material select dropdown populated from
3432
+ * multiple data sources (open source dialogs, loaded sources, and form control values).
3433
+ *
3434
+ * Merges values from all sources, deduplicates by value key, groups options by label,
3435
+ * and caches display values and metadata for performance.
2856
3436
  */
2857
3437
  class DbxFormSourceSelectFieldComponent extends FieldType$2 {
2858
3438
  _cacheMetaSub = new SubscriptionObject();
@@ -3164,6 +3744,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3164
3744
  args: [{ selector: 'dbx-form-sourceselectfield', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatSelect, MatOption, FormsModule, ReactiveFormsModule, DbxButtonComponent, MatOptgroup, DbxButtonSpacerDirective, DbxActionModule, DbxLoadingComponent], standalone: true, template: "<div class=\"dbx-source-select-field\">\n <div class=\"dbx-source-select-field-content\">\n <mat-select class=\"dbx-source-select-field-select\" [id]=\"id\" [formControl]=\"formControl\" [multiple]=\"props.multiple\">\n @for (value of nonGroupedValuesSignal(); track value.value) {\n <mat-option [value]=\"value.value\">\n {{ value.label }}\n </mat-option>\n }\n @for (optionGroup of groupedOptionsSignal(); track optionGroup.label) {\n <mat-optgroup [label]=\"optionGroup.label\">\n @for (value of optionGroup.values; track value.value) {\n <mat-option [value]=\"value.value\">\n {{ value.label }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </mat-select>\n @if (showOpenSourceButton) {\n <dbx-button-spacer></dbx-button-spacer>\n <dbx-action dbxActionValue [dbxActionHandler]=\"handleSelectOptions\" class=\"dbx-source-select-field-button\">\n <dbx-button #button dbxActionButton [fab]=\"true\" [iconOnly]=\"true\" [icon]=\"selectButtonIcon\"></dbx-button>\n </dbx-action>\n }\n </div>\n <dbx-loading class=\"dbx-source-select-field-loading\" [linear]=\"true\" [context]=\"context\"></dbx-loading>\n</div>\n" }]
3165
3745
  }], propDecorators: { buttonElement: [{ type: i0.ViewChild, args: ['button', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
3166
3746
 
3747
+ /**
3748
+ * Creates a Formly field configuration for a source-select field that loads and
3749
+ * displays selectable values from one or more external data sources.
3750
+ *
3751
+ * @param config - Source-select field configuration
3752
+ * @returns A validated {@link FormlyFieldConfig} with type `'sourceselectfield'`
3753
+ *
3754
+ * @example
3755
+ * ```typescript
3756
+ * const field = sourceSelectField({
3757
+ * key: 'source',
3758
+ * label: 'Source',
3759
+ * loadSources: () => sources$,
3760
+ * metaReader: (meta) => meta.id
3761
+ * });
3762
+ * ```
3763
+ */
3167
3764
  function sourceSelectField(config) {
3168
3765
  const { key, materialFormField } = config;
3169
3766
  return formlyField({
@@ -3177,6 +3774,7 @@ function sourceSelectField(config) {
3177
3774
  });
3178
3775
  }
3179
3776
 
3777
+ /** Registers the `sourceselectfield` Formly field type. */
3180
3778
  class DbxFormFormlySourceSelectModule {
3181
3779
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlySourceSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3182
3780
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlySourceSelectModule, imports: [DbxFormSourceSelectFieldComponent, i1$1.FormlyModule], exports: [DbxFormSourceSelectFieldComponent] });
@@ -3198,6 +3796,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3198
3796
  }]
3199
3797
  }] });
3200
3798
 
3799
+ /**
3800
+ * Creates a Formly select field configuration with support for native/material select,
3801
+ * clear option, multiple selection, and "select all".
3802
+ *
3803
+ * @param config - Selection field configuration
3804
+ * @returns A validated {@link FormlyFieldConfig} with type `'select'` or `'native-select'`
3805
+ *
3806
+ * @example
3807
+ * ```typescript
3808
+ * const field = valueSelectionField({
3809
+ * key: 'color',
3810
+ * label: 'Color',
3811
+ * options: [{ label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }]
3812
+ * });
3813
+ * ```
3814
+ */
3201
3815
  function valueSelectionField(config) {
3202
3816
  const { key, native = false, addClearOption = false, selectAllOption: inputSelectAllOption, options: inputOptions, materialFormField } = config;
3203
3817
  let selectAllOptionConfig;
@@ -3221,6 +3835,13 @@ function valueSelectionField(config) {
3221
3835
  parsers
3222
3836
  });
3223
3837
  }
3838
+ /**
3839
+ * Creates a function that prepends a "clear" option to the selection options array
3840
+ * if one doesn't already exist.
3841
+ *
3842
+ * @param label - Optional label for the clear option
3843
+ * @returns A function that transforms selection options by prepending a clear option
3844
+ */
3224
3845
  function addValueSelectionOptionFunction(label) {
3225
3846
  return (options) => {
3226
3847
  const hasClear = options.findIndex((x) => x.clear) !== -1;
@@ -3233,6 +3854,12 @@ function addValueSelectionOptionFunction(label) {
3233
3854
  };
3234
3855
  }
3235
3856
 
3857
+ /**
3858
+ * Formly field component providing a rich text editor powered by ngx-editor.
3859
+ *
3860
+ * Outputs HTML format and marks the form control dirty on editor value changes
3861
+ * while focused. Supports compact mode via {@link CompactContextStore}.
3862
+ */
3236
3863
  class DbxTextEditorFieldComponent extends FieldType$1 {
3237
3864
  _compactContextStore = inject(CompactContextStore, { optional: true });
3238
3865
  _editor;
@@ -3319,6 +3946,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3319
3946
  }] });
3320
3947
 
3321
3948
  const importsAndExports$a = [DbxTextEditorFieldComponent];
3949
+ /** Registers the `texteditor` Formly field type for rich text editing. */
3322
3950
  class DbxFormFormlyTextEditorFieldModule {
3323
3951
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyTextEditorFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3324
3952
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyTextEditorFieldModule, imports: [DbxTextEditorFieldComponent, i1$1.FormlyModule], exports: [DbxTextEditorFieldComponent] });
@@ -3339,6 +3967,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3339
3967
  }]
3340
3968
  }] });
3341
3969
 
3970
+ /**
3971
+ * Creates a Formly field configuration for a rich text editor.
3972
+ *
3973
+ * The field defaults to an empty string and updates the model on blur events.
3974
+ *
3975
+ * @param config - Text editor field configuration
3976
+ * @returns A validated {@link FormlyFieldConfig} with type `'texteditor'`
3977
+ *
3978
+ * @example
3979
+ * ```typescript
3980
+ * const field = textEditorField({ key: 'bio', label: 'Biography', maxLength: 2000 });
3981
+ * ```
3982
+ */
3342
3983
  function textEditorField(config) {
3343
3984
  const { key, minLength, maxLength, materialFormField } = config;
3344
3985
  const fieldConfig = formlyField({
@@ -3359,6 +4000,14 @@ function textEditorField(config) {
3359
4000
  return fieldConfig;
3360
4001
  }
3361
4002
 
4003
+ /**
4004
+ * Formly custom field type for dynamically repeatable arrays of field groups.
4005
+ *
4006
+ * Renders a list of field groups that users can add to, remove from, duplicate,
4007
+ * and rearrange via drag-and-drop. Enforces an optional maximum item count.
4008
+ *
4009
+ * Registered as Formly type `'repeatarray'`.
4010
+ */
3362
4011
  class DbxFormRepeatArrayTypeComponent extends FieldArrayType {
3363
4012
  _labelForField = cachedGetter(() => {
3364
4013
  const input = this.repeatArrayField.labelForField;
@@ -3579,6 +4228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3579
4228
  }] });
3580
4229
 
3581
4230
  const importsAndExports$9 = [DbxFormRepeatArrayTypeComponent];
4231
+ /** Registers the `repeatarray` Formly field type for dynamic array fields. */
3582
4232
  class DbxFormFormlyArrayFieldModule {
3583
4233
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyArrayFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3584
4234
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyArrayFieldModule, imports: [DbxFormRepeatArrayTypeComponent, i1$1.FormlyModule], exports: [DbxFormRepeatArrayTypeComponent] });
@@ -3599,6 +4249,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3599
4249
  }]
3600
4250
  }] });
3601
4251
 
4252
+ /**
4253
+ * Creates a Formly field configuration for a repeatable array of field groups.
4254
+ *
4255
+ * Users can dynamically add, remove, duplicate, and rearrange entries.
4256
+ *
4257
+ * @param config - Repeat array configuration including the template field group
4258
+ * @returns A validated {@link FormlyFieldConfig} with type `'repeatarray'`
4259
+ *
4260
+ * @example
4261
+ * ```typescript
4262
+ * const field = repeatArrayField({
4263
+ * key: 'items',
4264
+ * label: 'Items',
4265
+ * addText: 'Add Item',
4266
+ * removeText: 'Remove Item',
4267
+ * repeatFieldGroup: [textField({ key: 'name', label: 'Name' })]
4268
+ * });
4269
+ * ```
4270
+ */
3602
4271
  function repeatArrayField(config) {
3603
4272
  const { key, label, description, repeatFieldGroup, maxLength, addText, addTemplate, removeText, duplicateText, labelForField, disableRearrange, allowAdd, allowRemove, allowDuplicate, addDuplicateToEnd } = config;
3604
4273
  return formlyField({
@@ -3626,6 +4295,7 @@ function repeatArrayField(config) {
3626
4295
  }
3627
4296
 
3628
4297
  const importsAndExports$8 = [FormlyMaterialModule, FormlyMatCheckboxModule, FormlyMatToggleModule];
4298
+ /** Provides Formly Material checkbox and toggle field support. */
3629
4299
  class DbxFormFormlyBooleanFieldModule {
3630
4300
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyBooleanFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3631
4301
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyBooleanFieldModule, imports: [FormlyMaterialModule, FormlyMatCheckboxModule, FormlyMatToggleModule], exports: [FormlyMaterialModule, FormlyMatCheckboxModule, FormlyMatToggleModule] });
@@ -3639,6 +4309,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3639
4309
  }]
3640
4310
  }] });
3641
4311
 
4312
+ /**
4313
+ * Creates a Formly field configuration for a Material slide toggle.
4314
+ *
4315
+ * Defaults to `false` when no default value is specified. Uses auto-touch and style wrappers.
4316
+ *
4317
+ * @param config - Toggle field configuration
4318
+ * @returns A validated {@link FormlyFieldConfig} with type `'toggle'`
4319
+ *
4320
+ * @example
4321
+ * ```typescript
4322
+ * const field = toggleField({ key: 'active', label: 'Active', defaultValue: true });
4323
+ * ```
4324
+ */
3642
4325
  function toggleField(config) {
3643
4326
  const { key, defaultValue, materialFormField } = config;
3644
4327
  const classGetter = 'dbx-mat-form-toggle-field-wrapper';
@@ -3653,6 +4336,19 @@ function toggleField(config) {
3653
4336
  })
3654
4337
  });
3655
4338
  }
4339
+ /**
4340
+ * Creates a Formly field configuration for a Material checkbox.
4341
+ *
4342
+ * Defaults to `false` when no default value is specified. Uses a style wrapper.
4343
+ *
4344
+ * @param config - Checkbox field configuration
4345
+ * @returns A validated {@link FormlyFieldConfig} with type `'checkbox'`
4346
+ *
4347
+ * @example
4348
+ * ```typescript
4349
+ * const field = checkboxField({ key: 'agree', label: 'I agree to the terms' });
4350
+ * ```
4351
+ */
3656
4352
  function checkboxField(config) {
3657
4353
  const { key, defaultValue, materialFormField } = config;
3658
4354
  const classGetter = 'dbx-mat-form-checkbox-field-wrapper';
@@ -3713,7 +4409,19 @@ function dateTimePreset(config) {
3713
4409
  };
3714
4410
  }
3715
4411
 
4412
+ /**
4413
+ * Injection token for providing default date-time field menu presets application-wide.
4414
+ */
3716
4415
  const DBX_DATE_TIME_FIELD_MENU_PRESETS_TOKEN = new InjectionToken('DbxDateTimeFieldMenuPresetsServicePresets');
4416
+ /**
4417
+ * Service that manages default date-time preset configurations for all date-time fields.
4418
+ *
4419
+ * Presets are shown in the date-time field dropdown menu and allow users to quickly
4420
+ * select common date/time values (e.g., "Now", "Start of day").
4421
+ *
4422
+ * Provide default presets via {@link DBX_DATE_TIME_FIELD_MENU_PRESETS_TOKEN}, or set them
4423
+ * dynamically via the `configurations` setter.
4424
+ */
3717
4425
  class DbxDateTimeFieldMenuPresetsService {
3718
4426
  _configurations = new BehaviorSubject(inject(DBX_DATE_TIME_FIELD_MENU_PRESETS_TOKEN, { optional: true }) ?? []);
3719
4427
  configurations$ = this._configurations.asObservable();
@@ -3760,6 +4468,22 @@ var DbxDateTimeValueMode;
3760
4468
  */
3761
4469
  DbxDateTimeValueMode[DbxDateTimeValueMode["SYSTEM_MINUTE_OF_DAY"] = 5] = "SYSTEM_MINUTE_OF_DAY";
3762
4470
  })(DbxDateTimeValueMode || (DbxDateTimeValueMode = {}));
4471
+ /**
4472
+ * Creates a parser function that converts raw form input values (Date, string, or number)
4473
+ * into JavaScript Date objects based on the specified value mode.
4474
+ *
4475
+ * Handles timezone conversion when a timezone instance is provided and the mode requires it.
4476
+ *
4477
+ * @param mode - Determines how the input value is interpreted
4478
+ * @param timezoneInstance - Optional timezone converter for UTC-normal date handling
4479
+ * @returns A function that parses input values to Date objects
4480
+ *
4481
+ * @example
4482
+ * ```typescript
4483
+ * const parser = dbxDateTimeInputValueParseFactory(DbxDateTimeValueMode.DATE_STRING, timezoneInstance);
4484
+ * const date = parser('2024-01-15T10:00:00Z');
4485
+ * ```
4486
+ */
3763
4487
  function dbxDateTimeInputValueParseFactory(mode, timezoneInstance) {
3764
4488
  let factory;
3765
4489
  let useTimezoneInstance = true;
@@ -3820,6 +4544,22 @@ function dbxDateTimeInputValueParseFactory(mode, timezoneInstance) {
3820
4544
  }
3821
4545
  return factory;
3822
4546
  }
4547
+ /**
4548
+ * Creates a formatter function that converts JavaScript Date objects into the appropriate
4549
+ * output format (Date, ISO string, timestamp, or minute-of-day) based on the specified value mode.
4550
+ *
4551
+ * Handles timezone conversion when a timezone instance is provided and the mode requires it.
4552
+ *
4553
+ * @param mode - Determines the output format
4554
+ * @param timezoneInstance - Optional timezone converter for UTC-normal date handling
4555
+ * @returns A function that formats Date objects to the target output type
4556
+ *
4557
+ * @example
4558
+ * ```typescript
4559
+ * const formatter = dbxDateTimeOutputValueFactory(DbxDateTimeValueMode.DAY_STRING, null);
4560
+ * const dayString = formatter(new Date()); // e.g., '2024-01-15'
4561
+ * ```
4562
+ */
3823
4563
  function dbxDateTimeOutputValueFactory(mode, timezoneInstance) {
3824
4564
  let factory;
3825
4565
  let useTimezoneInstance = true;
@@ -3856,10 +4596,26 @@ function dbxDateTimeOutputValueFactory(mode, timezoneInstance) {
3856
4596
  }
3857
4597
  return factory;
3858
4598
  }
4599
+ /**
4600
+ * Compares two date-time field values for equality, handling Date, ISO8601DayString, and number (timestamp/minute) types.
4601
+ *
4602
+ * For string and number types, performs strict equality. For Date objects, compares hours and minutes.
4603
+ *
4604
+ * @param a - First date-time value
4605
+ * @param b - Second date-time value
4606
+ * @returns Whether the two values represent the same date-time
4607
+ */
3859
4608
  function dbxDateTimeIsSameDateTimeFieldValue(a, b) {
3860
4609
  const typeofA = typeof a;
3861
4610
  return a && b ? (typeofA === 'string' || typeofA === 'number' ? a === b : isSameDateHoursAndMinutes(a, b)) : a == b;
3862
4611
  }
4612
+ /**
4613
+ * Compares two date range field values for equality by comparing both start and end values.
4614
+ *
4615
+ * @param a - First date range value
4616
+ * @param b - Second date range value
4617
+ * @returns Whether the two date ranges represent the same range
4618
+ */
3863
4619
  function dbxDateRangeIsSameDateRangeFieldValue(a, b) {
3864
4620
  return a && b ? dbxDateTimeIsSameDateTimeFieldValue(a.start, b.start) && dbxDateTimeIsSameDateTimeFieldValue(a.end, b.end) : a == b;
3865
4621
  }
@@ -3879,9 +4635,20 @@ var DbxDateTimeFieldTimeMode;
3879
4635
  */
3880
4636
  DbxDateTimeFieldTimeMode["NONE"] = "none";
3881
4637
  })(DbxDateTimeFieldTimeMode || (DbxDateTimeFieldTimeMode = {}));
4638
+ /**
4639
+ * Type guard that checks whether the input is a {@link DbxDateTimeFieldTimeDateConfig}.
4640
+ */
3882
4641
  function isDbxDateTimeFieldTimeDateConfig(input) {
3883
4642
  return input != null && typeof input === 'object' && typeof input.path === 'string';
3884
4643
  }
4644
+ /**
4645
+ * Creates an observable that emits the current Date value from a synced field control
4646
+ * matching the specified sync type ('before' or 'after').
4647
+ *
4648
+ * @param parseConfigsObs - Observable of parsed sync field configurations
4649
+ * @param type - The sync direction to filter for
4650
+ * @returns Observable of the synced date value, or null if no matching sync config
4651
+ */
3885
4652
  function syncConfigValueObs(parseConfigsObs, type) {
3886
4653
  return parseConfigsObs.pipe(switchMap((x) => {
3887
4654
  const config = x.find((y) => y.syncType === type);
@@ -3905,6 +4672,15 @@ const DBX_DATE_TIME_FIELD_DATE_NOT_IN_SCHEDULE_ERROR = 'dateTimeFieldDateNotInSc
3905
4672
  * Error code used when the selected time/time input is not in the limited range.
3906
4673
  */
3907
4674
  const DBX_DATE_TIME_FIELD_TIME_NOT_IN_RANGE_ERROR = 'dateTimeFieldTimeNotInRange';
4675
+ /**
4676
+ * Formly custom field type for date and time selection.
4677
+ *
4678
+ * Supports date-only, time-only, and combined date-time modes. Handles timezone conversion,
4679
+ * sync with other date fields, configurable presets, and keyboard navigation (arrow keys for
4680
+ * incrementing date/time).
4681
+ *
4682
+ * Registered as Formly type `'datetime'`.
4683
+ */
3908
4684
  class DbxDateTimeFieldComponent extends FieldType$1 {
3909
4685
  dbxDateTimeFieldConfigService = inject(DbxDateTimeFieldMenuPresetsService);
3910
4686
  _sub = new SubscriptionObject();
@@ -4593,6 +5369,15 @@ function dbxFixedDateRangeOutputValueFactory(mode, timezoneInstance) {
4593
5369
  };
4594
5370
  }
4595
5371
  const TIME_OUTPUT_THROTTLE_TIME = 10;
5372
+ /**
5373
+ * Formly custom field type for selecting a fixed date range using an inline calendar.
5374
+ *
5375
+ * Supports multiple selection modes (single date, normal range, arbitrary range),
5376
+ * timezone conversion, date range input configuration, and optional text inputs for
5377
+ * start/end dates.
5378
+ *
5379
+ * Registered as Formly type `'fixeddaterange'`.
5380
+ */
4596
5381
  class DbxFixedDateRangeFieldComponent extends FieldType$1 {
4597
5382
  dbxDateTimeFieldMenuPresetsService = inject(DbxDateTimeFieldMenuPresetsService);
4598
5383
  calendar = viewChild.required(MatCalendar);
@@ -5012,6 +5797,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5012
5797
  }
5013
5798
  ], imports: [MatDatepickerModule, MatFormFieldModule, FormsModule, ReactiveFormsModule, MatInputModule, MatError, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"dbx-fixeddaterange-field\">\n <mat-calendar #calendarView [selected]=\"calendarSelectionSignal()\" [dateFilter]=\"pickerFilterSignal()\" [minDate]=\"minDateSignal()\" [maxDate]=\"maxDateSignal()\" (selectedChange)=\"selectedChange($event)\"></mat-calendar>\n <mat-form-field class=\"dbx-fixeddaterange-field-input\" appearance=\"fill\">\n @if (showRangeInput) {\n <mat-date-range-input [formGroup]=\"inputRangeForm\">\n <input #startDateInput matStartDate formControlName=\"start\" placeholder=\"Start date\" />\n <input #endDateInput [ngClass]=\"endDisabledSignal() ? 'dbx-fixeddaterange-field-input-end' : ''\" [attr.tabindex]=\"endDisabledSignal() ? -1 : 0\" matEndDate formControlName=\"end\" placeholder=\"End date\" />\n </mat-date-range-input>\n }\n </mat-form-field>\n @if (formControl.hasError('required')) {\n <mat-error>Date range is required</mat-error>\n }\n</div>\n" }]
5014
5799
  }], propDecorators: { calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatCalendar), { isSignal: true }] }], startDateInputElement: [{ type: i0.ViewChild, args: ['startDateInput', { ...{ read: ElementRef }, isSignal: true }] }], endDateInputElement: [{ type: i0.ViewChild, args: ['endDateInput', { ...{ read: ElementRef }, isSignal: true }] }] } });
5800
+ /**
5801
+ * Custom Material date range selection strategy for the fixed date range field.
5802
+ *
5803
+ * Provides preview highlighting on the calendar based on the current selection mode
5804
+ * and boundary constraints.
5805
+ */
5015
5806
  class DbxFixedDateRangeFieldSelectionStrategy {
5016
5807
  _dateAdapter = inject((DateAdapter));
5017
5808
  dbxFixedDateRangeFieldComponent = inject(DbxFixedDateRangeFieldComponent);
@@ -5068,6 +5859,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5068
5859
  }] });
5069
5860
 
5070
5861
  const importsAndExports$7 = [DbxDateTimeFieldComponent, DbxFixedDateRangeFieldComponent, DbxFormFormlyWrapperModule];
5862
+ /** Registers the `datetime` and `fixeddaterange` Formly field types with style and form-field wrappers. */
5071
5863
  class DbxFormFormlyDateFieldModule {
5072
5864
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyDateFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5073
5865
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyDateFieldModule, imports: [DbxDateTimeFieldComponent, DbxFixedDateRangeFieldComponent, DbxFormFormlyWrapperModule, i1$1.FormlyModule], exports: [DbxDateTimeFieldComponent, DbxFixedDateRangeFieldComponent, DbxFormFormlyWrapperModule] });
@@ -5096,6 +5888,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5096
5888
  }]
5097
5889
  }] });
5098
5890
 
5891
+ /**
5892
+ * Wraps a Formly field config with a named wrapper and its associated props.
5893
+ *
5894
+ * @param fieldConfig - The field config to wrap
5895
+ * @param wrapperKey - The registered wrapper key
5896
+ * @param wrapperProps - Configuration props for the wrapper
5897
+ * @returns A new field config with the wrapper applied
5898
+ *
5899
+ * @example
5900
+ * ```typescript
5901
+ * const wrapped = addWrapperToFormlyFieldConfig(myField, 'section', { header: 'Details' });
5902
+ * ```
5903
+ */
5099
5904
  function addWrapperToFormlyFieldConfig(fieldConfig, wrapperKey, wrapperProps) {
5100
5905
  return {
5101
5906
  wrappers: [wrapperKey],
@@ -5103,30 +5908,58 @@ function addWrapperToFormlyFieldConfig(fieldConfig, wrapperKey, wrapperProps) {
5103
5908
  fieldGroup: [fieldConfig]
5104
5909
  };
5105
5910
  }
5911
+ /**
5912
+ * Wraps a field with the auto-touch wrapper that marks the control as touched on value change.
5913
+ */
5106
5914
  function autoTouchWrapper(fieldConfig, autoTouchWrapper = {}) {
5107
5915
  return addWrapperToFormlyFieldConfig(fieldConfig, AUTO_TOUCH_WRAPPER_KEY, autoTouchWrapper);
5108
5916
  }
5917
+ /**
5918
+ * Wraps a field with the expand wrapper that shows/hides the field based on value or user click.
5919
+ */
5109
5920
  function expandWrapper(fieldConfig, expandWrapper = {}) {
5110
5921
  return addWrapperToFormlyFieldConfig(fieldConfig, EXPAND_WRAPPER_KEY, expandWrapper);
5111
5922
  }
5923
+ /**
5924
+ * Wraps a field with the toggle wrapper that uses a slide toggle to show/hide content.
5925
+ */
5112
5926
  function toggleWrapper(fieldConfig, toggleWrapper = {}) {
5113
5927
  return addWrapperToFormlyFieldConfig(fieldConfig, TOGGLE_WRAPPER_KEY, toggleWrapper);
5114
5928
  }
5929
+ /**
5930
+ * Wraps a field group in a section layout with an optional header and hint.
5931
+ */
5115
5932
  function sectionWrapper(fieldConfig, sectionWrapper = {}) {
5116
5933
  return addWrapperToFormlyFieldConfig(fieldConfig, SECTION_WRAPPER_KEY, sectionWrapper);
5117
5934
  }
5935
+ /**
5936
+ * Wraps a field group in a subsection layout with an optional header and hint.
5937
+ */
5118
5938
  function subsectionWrapper(fieldConfig, subsectionWrapper = {}) {
5119
5939
  return addWrapperToFormlyFieldConfig(fieldConfig, SUBSECTION_WRAPPER_KEY, subsectionWrapper);
5120
5940
  }
5941
+ /**
5942
+ * Wraps a field with an info button that triggers a callback when clicked.
5943
+ */
5121
5944
  function infoWrapper(fieldConfig, infoWrapper) {
5122
5945
  return addWrapperToFormlyFieldConfig(fieldConfig, INFO_WRAPPER_KEY, infoWrapper);
5123
5946
  }
5947
+ /**
5948
+ * Wraps a field with dynamic CSS class and style bindings.
5949
+ */
5124
5950
  function styleWrapper(fieldConfig, styleWrapper) {
5125
5951
  return addWrapperToFormlyFieldConfig(fieldConfig, STYLE_WRAPPER_KEY, styleWrapper);
5126
5952
  }
5953
+ /**
5954
+ * Wraps a field with a loading indicator that shows during async validation.
5955
+ */
5127
5956
  function workingWrapper(fieldConfig, workingWrapper = {}) {
5128
5957
  return addWrapperToFormlyFieldConfig(fieldConfig, WORKING_WRAPPER_KEY, workingWrapper);
5129
5958
  }
5959
+ /**
5960
+ * Type guard that checks if the input is a {@link DbxFlexLayoutWrapperGroupFieldConfig}
5961
+ * (has a `field` property) rather than a plain {@link FormlyFieldConfig}.
5962
+ */
5130
5963
  function checkIsFieldFlexLayoutGroupFieldConfig(input) {
5131
5964
  if (input.field != null) {
5132
5965
  return true;
@@ -5135,6 +5968,22 @@ function checkIsFieldFlexLayoutGroupFieldConfig(input) {
5135
5968
  return false;
5136
5969
  }
5137
5970
  }
5971
+ /**
5972
+ * Creates a flex-layout-wrapped field group that arranges child fields horizontally
5973
+ * with configurable sizing, breakpoints, and responsive behavior.
5974
+ *
5975
+ * @param fieldConfigs - Array of field configs or field config pairs with size overrides
5976
+ * @param options - Flex layout defaults including breakpoint, relative sizing, and default size
5977
+ * @returns A {@link FormlyFieldConfig} with flex wrapper applied
5978
+ *
5979
+ * @example
5980
+ * ```typescript
5981
+ * const layout = flexLayoutWrapper([
5982
+ * { field: textField({ key: 'first' }), size: 2 },
5983
+ * { field: textField({ key: 'last' }), size: 2 }
5984
+ * ], { relative: true });
5985
+ * ```
5986
+ */
5138
5987
  function flexLayoutWrapper(fieldConfigs, { relative, breakpoint, breakToColumn, size: defaultSize = 2 } = {}) {
5139
5988
  return {
5140
5989
  wrappers: ['flex'],
@@ -5172,6 +6021,10 @@ readonly addonLeft?: Maybe<NumberFieldAddon>;
5172
6021
  readonly addonRight?: Maybe<NumberFieldAddon>;
5173
6022
  */
5174
6023
 
6024
+ /**
6025
+ * Factory that returns an observable of a date-time picker configuration
6026
+ * that automatically selects the next upcoming time, rounded down to the nearest minute.
6027
+ */
5175
6028
  const TAKE_NEXT_UPCOMING_TIME_CONFIG_OBS = () => of({
5176
6029
  takeNextUpcomingTime: true,
5177
6030
  roundDownToMinute: true
@@ -5186,6 +6039,18 @@ function timeOnlyField(config = {}) {
5186
6039
  timeOnly: true
5187
6040
  });
5188
6041
  }
6042
+ /**
6043
+ * Creates a Formly field configuration for a date-time picker with optional time selection,
6044
+ * timezone awareness, and preset values.
6045
+ *
6046
+ * @param config - Optional overrides; defaults to key `'date'`, time mode `REQUIRED`
6047
+ * @returns A validated {@link FormlyFieldConfig} with type `'datetime'`
6048
+ *
6049
+ * @example
6050
+ * ```typescript
6051
+ * const field = dateTimeField({ key: 'startDate', label: 'Start', required: true });
6052
+ * ```
6053
+ */
5189
6054
  function dateTimeField(config = {}) {
5190
6055
  const { key = 'date', showClearButton, dateLabel, timeLabel, allDayLabel, atTimeLabel, timeDate, timezone, minuteStep, showTimezone, timeMode = DbxDateTimeFieldTimeMode.REQUIRED, valueMode, alwaysShowDateInput, autofillDateWhenTimeIsPicked, fullDayInUTC, fullDayFieldName, pickerConfig, getSyncFieldsObs, hideDatePicker, hideDateHint, timeOnly = false, presets, materialFormField } = config;
5191
6056
  const classGetter = 'dbx-mat-form-field-disable-underline dbx-mat-form-date-time-field-wrapper';
@@ -5220,6 +6085,18 @@ function dateTimeField(config = {}) {
5220
6085
  });
5221
6086
  return fieldConfig;
5222
6087
  }
6088
+ /**
6089
+ * Creates a pair of date pickers for selecting a date range (start and end dates)
6090
+ * arranged in a flex layout. The pickers are synchronized so the start date stays before the end date.
6091
+ *
6092
+ * @param config - Date range configuration with optional start/end overrides
6093
+ * @returns A {@link FormlyFieldConfig} containing the start and end date field pair
6094
+ *
6095
+ * @example
6096
+ * ```typescript
6097
+ * const field = dateRangeField({ required: true, start: { key: 'from' }, end: { key: 'to' } });
6098
+ * ```
6099
+ */
5223
6100
  function dateRangeField(config = {}) {
5224
6101
  const { required: inputRequired, start, end, timeDate, timezone, showTimezone, presets, valueMode, minuteStep } = config;
5225
6102
  const required = inputRequired ?? start?.required ?? false;
@@ -5260,6 +6137,18 @@ function dateRangeField(config = {}) {
5260
6137
  fieldGroup: [flexLayoutWrapper([startField, endField], { relative: true, breakToColumn: true, breakpoint: 'large' })]
5261
6138
  };
5262
6139
  }
6140
+ /**
6141
+ * Creates a pair of time-only pickers for selecting a time range (start and end times)
6142
+ * arranged in a flex layout.
6143
+ *
6144
+ * @param inputConfig - Time range configuration with optional start/end overrides
6145
+ * @returns A {@link FormlyFieldConfig} containing the start and end time field pair
6146
+ *
6147
+ * @example
6148
+ * ```typescript
6149
+ * const field = dateTimeRangeField({ required: true });
6150
+ * ```
6151
+ */
5263
6152
  function dateTimeRangeField(inputConfig = {}) {
5264
6153
  const { required = false, start: inputStart, end: inputEnd, timezone, timeDate, showTimezone, presets, valueMode, minuteStep } = inputConfig;
5265
6154
  function dateTimeRangeFieldConfig(config) {
@@ -5296,6 +6185,17 @@ function dateTimeRangeField(inputConfig = {}) {
5296
6185
  };
5297
6186
  return dateRangeField(config);
5298
6187
  }
6188
+ /**
6189
+ * Creates a Formly field configuration for a fixed date range picker.
6190
+ *
6191
+ * @param config - Optional overrides; defaults to key `'dateRange'`
6192
+ * @returns A validated {@link FormlyFieldConfig} with type `'fixeddaterange'`
6193
+ *
6194
+ * @example
6195
+ * ```typescript
6196
+ * const field = fixedDateRangeField({ key: 'eventDates', required: true });
6197
+ * ```
6198
+ */
5299
6199
  function fixedDateRangeField(config = {}) {
5300
6200
  const { key = 'dateRange', dateRangeInput, pickerConfig, timezone, selectionMode, showTimezone, valueMode, fullDayInUTC, presets, showRangeInput, materialFormField } = config;
5301
6201
  const classGetter = 'dbx-mat-form-field-disable-underline dbx-form-fixed-date-range-field-wrapper';
@@ -5545,31 +6445,47 @@ const IS_NOT_WEBSITE_URL_WITH_EXPECTED_DOMAIN_VALIDATION_KEY = 'isNotWebsiteUrlW
5545
6445
  * @returns
5546
6446
  */
5547
6447
  function isWebsiteUrlValidator(config) {
5548
- const { requirePrefix, validDomains: inputValidDomains } = config ?? {};
6448
+ const { requirePrefix, allowPorts, validDomains: inputValidDomains } = config ?? {};
5549
6449
  const isPrefixRequired = requirePrefix ?? true;
6450
+ const isAllowPorts = allowPorts ?? false;
5550
6451
  const validDomains = asArray(inputValidDomains);
5551
6452
  const validDomainsSet = new Set(validDomains);
5552
6453
  const validateDomains = validDomainsSet.size > 0;
6454
+ function isValidUrl(details) {
6455
+ if (isPrefixRequired) {
6456
+ if (isWebsiteUrlWithPrefix(details.input)) {
6457
+ return true;
6458
+ }
6459
+ }
6460
+ else if (details.isWebsiteUrl) {
6461
+ return true;
6462
+ }
6463
+ if (isAllowPorts && details.hasPortNumber) {
6464
+ return isPrefixRequired ? details.hasHttpPrefix : true;
6465
+ }
6466
+ return false;
6467
+ }
6468
+ const portNumbersMessagePart = isAllowPorts ? '' : ' Urls with port numbers (e.g. localhost:8080) are not allowed.';
5553
6469
  const validateWebsiteValue = isPrefixRequired
5554
6470
  ? (details) => {
5555
- return isWebsiteUrlWithPrefix(details.input)
6471
+ return isValidUrl(details)
5556
6472
  ? null
5557
6473
  : {
5558
6474
  [IS_NOT_WEBSITE_URL_WITH_PREFIX_VALIDATION_KEY]: {
5559
6475
  value: details.input,
5560
6476
  isPrefixRequired,
5561
- message: `Value is not a website url with an http/https prefix.`
6477
+ message: `Value is not a website url with an http/https prefix.${portNumbersMessagePart}`
5562
6478
  }
5563
6479
  };
5564
6480
  }
5565
6481
  : (details) => {
5566
- return details.isWebsiteUrl
6482
+ return isValidUrl(details)
5567
6483
  ? null
5568
6484
  : {
5569
6485
  [IS_NOT_WEBSITE_URL_VALIDATION_KEY]: {
5570
6486
  value: details.input,
5571
6487
  isPrefixRequired,
5572
- message: `Value is not a valid website url.`
6488
+ message: `Value is not a valid website url.${portNumbersMessagePart}`
5573
6489
  }
5574
6490
  };
5575
6491
  };
@@ -5602,6 +6518,18 @@ function isWebsiteUrlValidator(config) {
5602
6518
  };
5603
6519
  }
5604
6520
 
6521
+ /**
6522
+ * Builds an array of value parsers for a number field, incorporating any configured
6523
+ * number transformation (e.g., precision, rounding) as a parser prepended to existing parsers.
6524
+ *
6525
+ * @param config - Parser and transform configuration
6526
+ * @returns Array of value parsers, or undefined if none configured
6527
+ *
6528
+ * @example
6529
+ * ```typescript
6530
+ * const parsers = numberFieldTransformParser({ transform: { precision: 2 } });
6531
+ * ```
6532
+ */
5605
6533
  function numberFieldTransformParser(config) {
5606
6534
  const { parsers: inputParsers, transform } = config;
5607
6535
  let parsers;
@@ -5614,6 +6542,19 @@ function numberFieldTransformParser(config) {
5614
6542
  }
5615
6543
  return parsers;
5616
6544
  }
6545
+ /**
6546
+ * Creates a Formly field configuration for a numeric input.
6547
+ *
6548
+ * Adds a divisibility validator when both `step` and `enforceStep` are set.
6549
+ *
6550
+ * @param config - Number field configuration
6551
+ * @returns A validated {@link FormlyFieldConfig} with type `'input'` and input type `'number'`
6552
+ *
6553
+ * @example
6554
+ * ```typescript
6555
+ * const field = numberField({ key: 'quantity', label: 'Quantity', min: 1, max: 100, step: 1 });
6556
+ * ```
6557
+ */
5617
6558
  function numberField(config) {
5618
6559
  const { key, min, max, step, enforceStep, inputType: type = 'number', materialFormField } = config;
5619
6560
  const parsers = numberFieldTransformParser(config);
@@ -5637,6 +6578,17 @@ function numberField(config) {
5637
6578
  parsers
5638
6579
  });
5639
6580
  }
6581
+ /**
6582
+ * Creates a Formly field configuration for a Material slider input.
6583
+ *
6584
+ * @param config - Slider field configuration including max (required), thumb label, and tick interval
6585
+ * @returns A validated {@link FormlyFieldConfig} with type `'slider'`
6586
+ *
6587
+ * @example
6588
+ * ```typescript
6589
+ * const field = numberSliderField({ key: 'rating', label: 'Rating', min: 0, max: 10, step: 1 });
6590
+ * ```
6591
+ */
5640
6592
  function numberSliderField(config) {
5641
6593
  const { key, min, max, step, enforceStep, inputType: type = 'number', materialFormField, thumbLabel: inputThumbLabel, tickInterval: inputTickInterval, invertSelectionColoring: invertedSelectionColoring = false, displayWith } = config;
5642
6594
  const parsers = numberFieldTransformParser(config);
@@ -5670,11 +6622,23 @@ function numberSliderField(config) {
5670
6622
  parsers
5671
6623
  });
5672
6624
  }
6625
+ /**
6626
+ * Creates a number field pre-configured for dollar amount input with cent-level precision.
6627
+ *
6628
+ * @param config - Number field configuration (precision is overridden to dollar amount precision)
6629
+ * @returns A {@link FormlyFieldConfig} for dollar amount input
6630
+ *
6631
+ * @example
6632
+ * ```typescript
6633
+ * const field = dollarAmountField({ key: 'price', label: 'Price', min: 0, required: true });
6634
+ * ```
6635
+ */
5673
6636
  function dollarAmountField(config) {
5674
6637
  return numberField({ ...config, transform: { ...config.transform, precision: config.transform?.precision ?? DOLLAR_AMOUNT_PRECISION } }); // TODO: Add wrapper addon, addonLeft: { text: '$' }
5675
6638
  }
5676
6639
 
5677
6640
  const importsAndExports$6 = [FormlyMaterialModule, FormlyMatSliderModule];
6641
+ /** Provides Formly Material number input and slider support. */
5678
6642
  class DbxFormFormlyNumberFieldModule {
5679
6643
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyNumberFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5680
6644
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyNumberFieldModule, imports: [FormlyMaterialModule, FormlyMatSliderModule], exports: [FormlyMaterialModule, FormlyMatSliderModule] });
@@ -5688,7 +6652,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5688
6652
  }]
5689
6653
  }] });
5690
6654
 
6655
+ /** Default preferred countries shown at the top of the phone country dropdown. */
5691
6656
  const DEFAULT_PREFERRED_COUNTRIES = ['us'];
6657
+ /**
6658
+ * Formly custom field type for international phone number input with optional extension support.
6659
+ *
6660
+ * Uses ngx-mat-input-tel for the country-aware phone input and manages E.164 phone number
6661
+ * formatting. Supports splitting phone + extension pairs for storage and display.
6662
+ *
6663
+ * Registered as Formly type `'intphone'`.
6664
+ */
5692
6665
  class DbxPhoneFieldComponent extends FieldType$1 {
5693
6666
  inputSync = new SubscriptionObject();
5694
6667
  outputSync = new SubscriptionObject();
@@ -5780,6 +6753,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5780
6753
  }] });
5781
6754
 
5782
6755
  const importsAndExports$5 = [DbxPhoneFieldComponent];
6756
+ /** Registers the `intphone` Formly field type for international phone number input. */
5783
6757
  class DbxFormFormlyPhoneFieldModule {
5784
6758
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyPhoneFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
5785
6759
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyPhoneFieldModule, imports: [DbxPhoneFieldComponent, i1$1.FormlyModule], exports: [DbxPhoneFieldComponent] });
@@ -5800,6 +6774,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
5800
6774
  }]
5801
6775
  }] });
5802
6776
 
6777
+ /**
6778
+ * Builds an array of value parsers for a text field, incorporating any configured
6779
+ * string transformation (e.g., trim, lowercase) as a parser prepended to existing parsers.
6780
+ *
6781
+ * @param config - Parser and transform configuration
6782
+ * @returns Array of value parsers, or undefined if none configured
6783
+ *
6784
+ * @example
6785
+ * ```typescript
6786
+ * const parsers = textFieldTransformParser({ transform: { trim: true, toLowercase: true } });
6787
+ * ```
6788
+ */
5803
6789
  function textFieldTransformParser(config) {
5804
6790
  const { parsers: inputParsers, transform } = config;
5805
6791
  let parsers;
@@ -5812,6 +6798,17 @@ function textFieldTransformParser(config) {
5812
6798
  }
5813
6799
  return parsers;
5814
6800
  }
6801
+ /**
6802
+ * Creates a Formly field configuration for a single-line text input.
6803
+ *
6804
+ * @param config - Text field configuration including key, label, validation, and transform options
6805
+ * @returns A validated {@link FormlyFieldConfig} with type `'input'`
6806
+ *
6807
+ * @example
6808
+ * ```typescript
6809
+ * const field = textField({ key: 'username', label: 'Username', maxLength: 50, required: true });
6810
+ * ```
6811
+ */
5815
6812
  function textField(config) {
5816
6813
  const { transform, key, pattern, minLength, maxLength, inputType: type = 'text', materialFormField } = config;
5817
6814
  const parsers = textFieldTransformParser(config);
@@ -5828,6 +6825,17 @@ function textField(config) {
5828
6825
  parsers
5829
6826
  });
5830
6827
  }
6828
+ /**
6829
+ * Creates a Formly field configuration for a multi-line textarea input.
6830
+ *
6831
+ * @param config - Textarea field configuration including key, label, rows, and validation options
6832
+ * @returns A validated {@link FormlyFieldConfig} with type `'textarea'`
6833
+ *
6834
+ * @example
6835
+ * ```typescript
6836
+ * const field = textAreaField({ key: 'bio', label: 'Biography', rows: 5, maxLength: 500 });
6837
+ * ```
6838
+ */
5831
6839
  function textAreaField(config) {
5832
6840
  const { key, rows = 3, pattern, minLength, maxLength, materialFormField } = config;
5833
6841
  const parsers = textFieldTransformParser(config);
@@ -5845,6 +6853,18 @@ function textAreaField(config) {
5845
6853
  });
5846
6854
  }
5847
6855
 
6856
+ /**
6857
+ * Creates a Formly field configuration for an international phone number input
6858
+ * with E.164 validation.
6859
+ *
6860
+ * @param config - Optional overrides; defaults to key `'phone'`, label `'Phone Number'`
6861
+ * @returns A validated {@link FormlyFieldConfig} with type `'intphone'`
6862
+ *
6863
+ * @example
6864
+ * ```typescript
6865
+ * const field = phoneField({ preferredCountries: ['us', 'ca'], required: true });
6866
+ * ```
6867
+ */
5848
6868
  function phoneField(config = {}) {
5849
6869
  const { key = 'phone', label = 'Phone Number', preferredCountries, enableSearch, onlyCountries, allowExtension: inputAllowExtension } = config;
5850
6870
  const allowExtension = inputAllowExtension ?? false;
@@ -5865,9 +6885,16 @@ function phoneField(config = {}) {
5865
6885
  return fieldConfig;
5866
6886
  }
5867
6887
  /**
5868
- * Puts a phone and
5869
- * @param param0
5870
- * @returns
6888
+ * Creates a flex-layout-wrapped pair of a phone number field and a label text field,
6889
+ * useful for collecting named phone numbers (e.g., "Work", "Home").
6890
+ *
6891
+ * @param config - Optional phone and label field configurations
6892
+ * @returns A flex-layout-wrapped {@link FormlyFieldConfig}
6893
+ *
6894
+ * @example
6895
+ * ```typescript
6896
+ * const field = wrappedPhoneAndLabelField({ phoneField: { required: true } });
6897
+ * ```
5871
6898
  */
5872
6899
  function wrappedPhoneAndLabelField({ phoneField: phone, labelField: label } = {}) {
5873
6900
  return flexLayoutWrapper([
@@ -5886,6 +6913,17 @@ function wrappedPhoneAndLabelField({ phoneField: phone, labelField: label } = {}
5886
6913
  }
5887
6914
  ], { relative: true });
5888
6915
  }
6916
+ /**
6917
+ * Creates a section-wrapped phone + label field pair with a configurable header.
6918
+ *
6919
+ * @param config - Optional overrides; defaults to header `'Phone Number'`
6920
+ * @returns A section-wrapped {@link FormlyFieldConfig}
6921
+ *
6922
+ * @example
6923
+ * ```typescript
6924
+ * const field = phoneAndLabelSectionField({ header: 'Contact Phone' });
6925
+ * ```
6926
+ */
5889
6927
  function phoneAndLabelSectionField({ key, header = 'Phone Number', hint, phoneField, labelField } = {}) {
5890
6928
  return sectionWrapper({
5891
6929
  key,
@@ -5895,6 +6933,17 @@ function phoneAndLabelSectionField({ key, header = 'Phone Number', hint, phoneFi
5895
6933
  hint
5896
6934
  });
5897
6935
  }
6936
+ /**
6937
+ * Creates a repeat-array field that allows the user to add multiple phone number entries.
6938
+ *
6939
+ * @param repeatConfig - Optional overrides; defaults to key `'phones'`, label `'Phone Numbers'`
6940
+ * @returns A {@link FormlyFieldConfig} with repeat-array type for multiple phone entries
6941
+ *
6942
+ * @example
6943
+ * ```typescript
6944
+ * const field = phoneListField({ phoneAndLabel: { phoneField: { preferredCountries: ['us'] } } });
6945
+ * ```
6946
+ */
5898
6947
  function phoneListField(repeatConfig = {}) {
5899
6948
  const { key = 'phones', label = 'Phone Numbers', addText = 'Add Phone Number', removeText = 'Remove Phone Number', repeatFieldGroup, phoneAndLabel } = repeatConfig;
5900
6949
  return repeatArrayField({
@@ -5907,10 +6956,24 @@ function phoneListField(repeatConfig = {}) {
5907
6956
  });
5908
6957
  }
5909
6958
 
6959
+ /** Maximum character length for a phone label field. */
5910
6960
  const PHONE_LABEL_MAX_LENGTH = 100;
6961
+ /** Maximum character length for a generic label string field. */
5911
6962
  const LABEL_STRING_MAX_LENGTH = 100;
6963
+ /** Maximum character length for a search string field. */
5912
6964
  const SEARCH_STRING_MAX_LENGTH = 100;
5913
6965
  // MARK: Name Field
6966
+ /**
6967
+ * Creates a text field pre-configured for a person's full name.
6968
+ *
6969
+ * @param config - Optional overrides; defaults to key `'name'`, label `'Name'`
6970
+ * @returns A {@link FormlyFieldConfig} for name input
6971
+ *
6972
+ * @example
6973
+ * ```typescript
6974
+ * const field = nameField({ required: true });
6975
+ * ```
6976
+ */
5914
6977
  function nameField(config = {}) {
5915
6978
  const { key = 'name', label = 'Name', placeholder = 'John Doe', required = false, minLength, maxLength, attributes } = config;
5916
6979
  return textField({
@@ -5924,6 +6987,17 @@ function nameField(config = {}) {
5924
6987
  attributes
5925
6988
  });
5926
6989
  }
6990
+ /**
6991
+ * Creates a text field pre-configured for email address input with built-in email validation.
6992
+ *
6993
+ * @param config - Optional overrides; defaults to key `'email'`, label `'Email Address'`
6994
+ * @returns A {@link FormlyFieldConfig} with email validation
6995
+ *
6996
+ * @example
6997
+ * ```typescript
6998
+ * const field = emailField({ required: true });
6999
+ * ```
7000
+ */
5927
7001
  function emailField(config = {}) {
5928
7002
  const { key = 'email', label = 'Email Address', placeholder = 'you@example.com' } = config;
5929
7003
  const emailFieldConfig = textField({
@@ -5941,6 +7015,17 @@ function emailField(config = {}) {
5941
7015
  };
5942
7016
  return emailFieldConfig;
5943
7017
  }
7018
+ /**
7019
+ * Creates a text field pre-configured for city name input with autocomplete support.
7020
+ *
7021
+ * @param config - Optional overrides; defaults to key `'city'`, label `'City'`
7022
+ * @returns A {@link FormlyFieldConfig} for city input
7023
+ *
7024
+ * @example
7025
+ * ```typescript
7026
+ * const field = cityField({ required: true });
7027
+ * ```
7028
+ */
5944
7029
  function cityField(config = {}) {
5945
7030
  const { key = 'city', placeholder = '', label = 'City', autocomplete = 'city', maxLength = ADDRESS_CITY_MAX_LENGTH, required = false } = config;
5946
7031
  return textField({
@@ -5953,6 +7038,19 @@ function cityField(config = {}) {
5953
7038
  maxLength
5954
7039
  });
5955
7040
  }
7041
+ /**
7042
+ * Creates a text field pre-configured for US state input with optional state code validation.
7043
+ *
7044
+ * When `asCode` is true, enforces the 2-letter state code pattern and auto-uppercases input.
7045
+ *
7046
+ * @param config - Optional overrides; defaults to key `'state'`, label `'State'`
7047
+ * @returns A {@link FormlyFieldConfig} for state input
7048
+ *
7049
+ * @example
7050
+ * ```typescript
7051
+ * const field = stateField({ asCode: true, required: true });
7052
+ * ```
7053
+ */
5956
7054
  function stateField(config = {}) {
5957
7055
  const { asCode = false, pattern = asCode ? US_STATE_CODE_STRING_REGEX : undefined, key = 'state', placeholder = '', label = 'State', autocomplete = 'state', maxLength = asCode ? ADDRESS_STATE_CODE_MAX_LENGTH : ADDRESS_STATE_MAX_LENGTH, transform, required = false } = config;
5958
7056
  return textField({
@@ -5970,6 +7068,17 @@ function stateField(config = {}) {
5970
7068
  }
5971
7069
  });
5972
7070
  }
7071
+ /**
7072
+ * Creates a text field pre-configured for country name input with autocomplete support.
7073
+ *
7074
+ * @param config - Optional overrides; defaults to key `'country'`, label `'Country'`
7075
+ * @returns A {@link FormlyFieldConfig} for country input
7076
+ *
7077
+ * @example
7078
+ * ```typescript
7079
+ * const field = countryField({ required: true });
7080
+ * ```
7081
+ */
5973
7082
  function countryField(config = {}) {
5974
7083
  const { key = 'country', placeholder = '', label = 'Country', autocomplete = 'country', maxLength = ADDRESS_COUNTRY_MAX_LENGTH, required = false } = config;
5975
7084
  return textField({
@@ -5982,6 +7091,17 @@ function countryField(config = {}) {
5982
7091
  maxLength
5983
7092
  });
5984
7093
  }
7094
+ /**
7095
+ * Creates a text field pre-configured for US zip code input with pattern validation.
7096
+ *
7097
+ * @param config - Optional overrides; defaults to key `'zip'`, label `'Zip Code'`
7098
+ * @returns A {@link FormlyFieldConfig} for zip code input
7099
+ *
7100
+ * @example
7101
+ * ```typescript
7102
+ * const field = zipCodeField({ required: true });
7103
+ * ```
7104
+ */
5985
7105
  function zipCodeField(config = {}) {
5986
7106
  const { key = 'zip', placeholder = '', label = 'Zip Code', autocomplete = 'postal-code', pattern = ZIP_CODE_STRING_REGEX, maxLength = ADDRESS_ZIP_MAX_LENGTH, required = false } = config;
5987
7107
  return textField({
@@ -5996,8 +7116,21 @@ function zipCodeField(config = {}) {
5996
7116
  });
5997
7117
  }
5998
7118
  // MARK: LatLng Text Field
7119
+ /** Default placeholder text for a latitude/longitude text field. */
5999
7120
  const DEFAULT_LAT_LNG_TEXT_FIELD_PLACEHOLDER = '12.345,-67.8910';
7121
+ /** Default validation error message for invalid coordinate input. */
6000
7122
  const DEFAULT_LAT_LNG_TEXT_FIELD_PATTERN_MESSAGE = `Invalid/unknown coordinates`;
7123
+ /**
7124
+ * Creates a text field pre-configured for latitude/longitude coordinate input with pattern validation.
7125
+ *
7126
+ * @param config - Optional overrides; defaults to key `'latLng'`
7127
+ * @returns A {@link FormlyFieldConfig} for coordinate input
7128
+ *
7129
+ * @example
7130
+ * ```typescript
7131
+ * const field = latLngTextField();
7132
+ * ```
7133
+ */
6001
7134
  function latLngTextField({ key = 'latLng' } = {}) {
6002
7135
  const field = {
6003
7136
  ...textField({
@@ -6016,6 +7149,18 @@ function latLngTextField({ key = 'latLng' } = {}) {
6016
7149
  return field;
6017
7150
  }
6018
7151
 
7152
+ /**
7153
+ * Creates a text field for a single address line with autocomplete support.
7154
+ *
7155
+ * @param config - Optional overrides; line number determines key and label
7156
+ * @returns A {@link FormlyFieldConfig} for address line input
7157
+ *
7158
+ * @example
7159
+ * ```typescript
7160
+ * const line1 = addressLineField({ line: 1, required: true });
7161
+ * const line2 = addressLineField({ line: 2 });
7162
+ * ```
7163
+ */
6019
7164
  function addressLineField(config = {}) {
6020
7165
  const { line = 1 } = config;
6021
7166
  const lineCode = Math.max(1, line); // minimum of line 1
@@ -6030,6 +7175,18 @@ function addressLineField(config = {}) {
6030
7175
  maxLength
6031
7176
  });
6032
7177
  }
7178
+ /**
7179
+ * Creates the full set of address form fields (lines, city, state, zip, and optionally country)
7180
+ * arranged in a flex layout.
7181
+ *
7182
+ * @param config - Address fields configuration
7183
+ * @returns Array of {@link FormlyFieldConfig} for a complete address form section
7184
+ *
7185
+ * @example
7186
+ * ```typescript
7187
+ * const fields = addressFormlyFields({ required: true, includeCountry: false });
7188
+ * ```
7189
+ */
6033
7190
  function addressFormlyFields(config = {}) {
6034
7191
  const { required = true, includeLine2 = true, includeCountry = true } = config;
6035
7192
  const singleLineFields = [
@@ -6057,6 +7214,17 @@ function addressFormlyFields(config = {}) {
6057
7214
  }
6058
7215
  return [...lines, flexLayoutWrapper(singleLineFields, { size: 1, relative: true })];
6059
7216
  }
7217
+ /**
7218
+ * Creates a section-wrapped address field group containing all address sub-fields.
7219
+ *
7220
+ * @param config - Optional overrides; defaults to key `'address'`, header `'Address'`
7221
+ * @returns A section-wrapped {@link FormlyFieldConfig} containing address fields
7222
+ *
7223
+ * @example
7224
+ * ```typescript
7225
+ * const field = addressField({ required: true, includeCountry: true });
7226
+ * ```
7227
+ */
6060
7228
  function addressField(config = {}) {
6061
7229
  const { key = 'address', header = 'Address', hint, required = false } = config;
6062
7230
  return sectionWrapper({
@@ -6070,6 +7238,17 @@ function addressField(config = {}) {
6070
7238
  hint
6071
7239
  });
6072
7240
  }
7241
+ /**
7242
+ * Creates a repeat-array field that allows the user to add multiple addresses.
7243
+ *
7244
+ * @param config - Optional overrides; defaults to key `'addresses'`, max 6 entries
7245
+ * @returns A {@link FormlyFieldConfig} with repeat-array type for multiple addresses
7246
+ *
7247
+ * @example
7248
+ * ```typescript
7249
+ * const field = addressListField({ maxAddresses: 3, required: true });
7250
+ * ```
7251
+ */
6073
7252
  function addressListField(config = {}) {
6074
7253
  const { key = 'addresses', required = false, maxAddresses = 6 } = config;
6075
7254
  return repeatArrayField({
@@ -6085,6 +7264,7 @@ function addressListField(config = {}) {
6085
7264
  }
6086
7265
 
6087
7266
  const importsAndExports$4 = [DbxFormFormlyArrayFieldModule, FormlyMaterialModule, FormlyMatInputModule, DbxFormFormlyWrapperModule];
7267
+ /** Aggregates Formly Material input, array field, and wrapper modules for text field support. */
6088
7268
  class DbxFormFormlyTextFieldModule {
6089
7269
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyTextFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
6090
7270
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyTextFieldModule, imports: [DbxFormFormlyArrayFieldModule, FormlyMaterialModule, FormlyMatInputModule, DbxFormFormlyWrapperModule], exports: [DbxFormFormlyArrayFieldModule, FormlyMaterialModule, FormlyMatInputModule, DbxFormFormlyWrapperModule] });
@@ -6098,6 +7278,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6098
7278
  }]
6099
7279
  }] });
6100
7280
 
7281
+ /**
7282
+ * Creates a Formly field configuration for a hidden field with no visual representation.
7283
+ *
7284
+ * Useful for passing programmatic values through the form model without user interaction.
7285
+ *
7286
+ * @param config - Key and optional required flag
7287
+ * @returns A validated {@link FormlyFieldConfig} with no visible type
7288
+ *
7289
+ * @example
7290
+ * ```typescript
7291
+ * const field = hiddenField({ key: 'userId', required: true });
7292
+ * ```
7293
+ */
6101
7294
  function hiddenField({ key, required = false }) {
6102
7295
  return formlyField({
6103
7296
  key,
@@ -6106,6 +7299,7 @@ function hiddenField({ key, required = false }) {
6106
7299
  }
6107
7300
 
6108
7301
  const importsAndExports$3 = [DbxFormFormlyChecklistItemFieldModule, DbxFormFormlyComponentFieldModule, DbxFormFormlyTextEditorFieldModule, DbxFormFormlyWrapperModule];
7302
+ /** Aggregates all custom Formly field type modules (checklist, component, texteditor) and wrappers. */
6109
7303
  class DbxFormFormlyFieldModule {
6110
7304
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
6111
7305
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormFormlyFieldModule, imports: [DbxFormFormlyChecklistItemFieldModule, DbxFormFormlyComponentFieldModule, DbxFormFormlyTextEditorFieldModule, DbxFormFormlyWrapperModule], exports: [DbxFormFormlyChecklistItemFieldModule, DbxFormFormlyComponentFieldModule, DbxFormFormlyTextEditorFieldModule, DbxFormFormlyWrapperModule] });
@@ -6259,6 +7453,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6259
7453
  }]
6260
7454
  }], propDecorators: { search: [{ type: i0.Output, args: ["search"] }] } });
6261
7455
 
7456
+ /**
7457
+ * Creates a text field with an async validator that checks whether the entered value is available.
7458
+ *
7459
+ * The field is wrapped in a working wrapper to display a loading indicator during the async check.
7460
+ *
7461
+ * @param config - Configuration for the text field and availability validation.
7462
+ * @returns A Formly field configuration with async availability validation.
7463
+ *
7464
+ * @example
7465
+ * ```ts
7466
+ * const usernameField = textIsAvailableField({
7467
+ * key: 'username',
7468
+ * label: 'Username',
7469
+ * isAvailable: (value) => checkUsernameAvailable(value),
7470
+ * isNotAvailableErrorMessage: 'Username is already taken'
7471
+ * });
7472
+ * ```
7473
+ */
6262
7474
  function textIsAvailableField(config) {
6263
7475
  const field = textField(config);
6264
7476
  field.asyncValidators = {
@@ -6275,6 +7487,11 @@ function textIsAvailableField(config) {
6275
7487
  }
6276
7488
 
6277
7489
  const importsAndExports$2 = [DbxFormFormlyTextFieldModule, DbxFormFormlyWrapperModule];
7490
+ /**
7491
+ * Angular module that provides the dependencies needed for the text availability field template.
7492
+ *
7493
+ * Imports and re-exports the text field and wrapper modules required by {@link textIsAvailableField}.
7494
+ */
6278
7495
  class DbxFormTextAvailableFieldModule {
6279
7496
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormTextAvailableFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
6280
7497
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormTextAvailableFieldModule, imports: [DbxFormFormlyTextFieldModule, DbxFormFormlyWrapperModule], exports: [DbxFormFormlyTextFieldModule, DbxFormFormlyWrapperModule] });
@@ -6289,10 +7506,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6289
7506
  }] });
6290
7507
 
6291
7508
  /**
6292
- * Configured simple text password field.
7509
+ * Creates a simple text password field with the input type set to `'password'`.
6293
7510
  *
6294
- * @param config
6295
- * @returns
7511
+ * Defaults to the key `'password'` and label `'Password'` unless overridden.
7512
+ *
7513
+ * @param config - Optional configuration for the password field.
7514
+ * @returns A Formly field configuration for a password input.
6296
7515
  */
6297
7516
  function textPasswordField(config) {
6298
7517
  return textField({
@@ -6304,10 +7523,12 @@ function textPasswordField(config) {
6304
7523
  });
6305
7524
  }
6306
7525
  /**
6307
- * Configured verify field for a password.
7526
+ * Creates a verify/confirm password field, typically used alongside a primary password field.
6308
7527
  *
6309
- * @param config
6310
- * @returns
7528
+ * Defaults to the key `'verifyPassword'` and label `'Verify Password'` unless overridden.
7529
+ *
7530
+ * @param config - Optional configuration for the verify password field.
7531
+ * @returns A Formly field configuration for a verify password input.
6311
7532
  */
6312
7533
  function textVerifyPasswordField(config) {
6313
7534
  return textPasswordField({
@@ -6317,6 +7538,13 @@ function textVerifyPasswordField(config) {
6317
7538
  required: true
6318
7539
  });
6319
7540
  }
7541
+ /**
7542
+ * Creates a Formly field group containing a password field and a verify password field
7543
+ * with a cross-field validator that ensures both values match.
7544
+ *
7545
+ * @param config - Configuration for the password and verify password fields.
7546
+ * @returns A Formly field group configuration with password matching validation.
7547
+ */
6320
7548
  function textPasswordWithVerifyFieldGroup(config) {
6321
7549
  const passwordFieldConfig = textPasswordField(config.password);
6322
7550
  const verifyPasswordFieldKey = config.verifyPassword?.key ?? `verify${capitalizeFirstLetter(String(passwordFieldConfig.key))}`;
@@ -6351,6 +7579,13 @@ function usernamePasswordLoginFields({ username, password, verifyPassword }) {
6351
7579
  const passwordField = verifyPassword ? textPasswordWithVerifyFieldGroup({ password, verifyPassword: verifyPassword === true ? undefined : verifyPassword }) : textPasswordField(password);
6352
7580
  return [usernameField, passwordField];
6353
7581
  }
7582
+ /**
7583
+ * Creates a single username field for a login form. Supports email or plain text input
7584
+ * based on the provided configuration.
7585
+ *
7586
+ * @param username - Either `'email'`, `'username'`, or a full {@link UsernameLoginFieldUsernameConfig}.
7587
+ * @returns A Formly field configuration for the username input.
7588
+ */
6354
7589
  function usernameLoginField(username) {
6355
7590
  let usernameField;
6356
7591
  let usernameFieldConfig = username;
@@ -6377,6 +7612,11 @@ function usernameLoginField(username) {
6377
7612
  }
6378
7613
 
6379
7614
  const importsAndExports$1 = [DbxFormFormlyTextFieldModule];
7615
+ /**
7616
+ * Angular module that provides the dependencies needed for login form field templates.
7617
+ *
7618
+ * Imports and re-exports the text field module required by the username/password login field functions.
7619
+ */
6380
7620
  class DbxFormLoginFieldModule {
6381
7621
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormLoginFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
6382
7622
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormLoginFieldModule, imports: [DbxFormFormlyTextFieldModule], exports: [DbxFormFormlyTextFieldModule] });
@@ -6390,6 +7630,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6390
7630
  }]
6391
7631
  }] });
6392
7632
 
7633
+ /**
7634
+ * Creates a search function for timezone strings that searches across all known timezone infos.
7635
+ *
7636
+ * When the search string is empty, the system timezone is returned first, followed by all timezones.
7637
+ *
7638
+ * @returns A {@link SearchableValueFieldStringSearchFn} for searching timezone values.
7639
+ */
6393
7640
  function timezoneStringSearchFunction() {
6394
7641
  const timezoneInfos = allTimezoneInfos();
6395
7642
  return (search) => {
@@ -6403,6 +7650,12 @@ function timezoneStringSearchFunction() {
6403
7650
  return of(searchResults.map((meta) => ({ value: meta.timezone, meta })));
6404
7651
  };
6405
7652
  }
7653
+ /**
7654
+ * Display function for timezone string values in a searchable field.
7655
+ *
7656
+ * Maps each timezone value to a display object with the timezone name as the label
7657
+ * and its abbreviation as the sublabel.
7658
+ */
6406
7659
  const DISPLAY_FOR_TIMEZONE_STRING_VALUE = (values) => {
6407
7660
  const timezoneInfos = allTimezoneInfos();
6408
7661
  const displayValues = values.map((x) => {
@@ -6413,10 +7666,13 @@ const DISPLAY_FOR_TIMEZONE_STRING_VALUE = (values) => {
6413
7666
  return obs;
6414
7667
  };
6415
7668
  /**
6416
- * Template for a searchable text field for a timezone.
7669
+ * Creates a searchable text field for selecting a timezone.
6417
7670
  *
6418
- * @param param0
6419
- * @returns
7671
+ * Defaults to the key `'timezone'` and label `'Timezone'`. Searches all known timezones
7672
+ * and displays the timezone name with its abbreviation.
7673
+ *
7674
+ * @param config - Optional configuration overrides for the timezone field.
7675
+ * @returns A Formly field configuration for timezone selection.
6420
7676
  */
6421
7677
  function timezoneStringField(config = {}) {
6422
7678
  return searchableTextField({
@@ -6434,6 +7690,11 @@ function timezoneStringField(config = {}) {
6434
7690
  }
6435
7691
 
6436
7692
  const importsAndExports = [DbxFormFormlySearchableFieldModule];
7693
+ /**
7694
+ * Angular module that provides the dependencies needed for the timezone string field template.
7695
+ *
7696
+ * Imports and re-exports the searchable field module required by {@link timezoneStringField}.
7697
+ */
6437
7698
  class DbxFormTimezoneStringFieldModule {
6438
7699
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormTimezoneStringFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
6439
7700
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: DbxFormTimezoneStringFieldModule, imports: [DbxFormFormlySearchableFieldModule], exports: [DbxFormFormlySearchableFieldModule] });
@@ -6448,10 +7709,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6448
7709
  }] });
6449
7710
 
6450
7711
  /**
6451
- * Configured simple text password field.
7712
+ * Creates a text field configured for website URL input with URL validation.
6452
7713
  *
6453
- * @param config
6454
- * @returns
7714
+ * Defaults to the key `'website'` and label `'Website Url'` unless overridden in the config.
7715
+ *
7716
+ * @param config - Optional configuration for the website URL field.
7717
+ * @returns A Formly field configuration with website URL validation.
6455
7718
  */
6456
7719
  function websiteUrlField(config) {
6457
7720
  const validators = [isWebsiteUrlValidator(config)];
@@ -6493,6 +7756,10 @@ function provideDbxFormFormlyFieldDeclarations() {
6493
7756
 
6494
7757
  /**
6495
7758
  * Provides vertical spacing after a form.
7759
+ *
7760
+ * Can be used as an element (`<dbx-form-spacer>`), attribute (`[dbxFormSpacer]`), or CSS class (`.dbx-form-spacer`).
7761
+ *
7762
+ * @selector `dbx-form-spacer,[dbxFormSpacer],.dbx-form-spacer`
6496
7763
  */
6497
7764
  class DbxFormSpacerDirective {
6498
7765
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DbxFormSpacerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });