@dereekb/dbx-form 9.15.6 → 9.15.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/esm2020/lib/form/form.mjs +1 -1
  2. package/esm2020/lib/form/io/form.input.directive.mjs +49 -10
  3. package/esm2020/lib/form/io/form.loading.directive.mjs +3 -3
  4. package/esm2020/lib/formly/field/checklist/checklist.item.field.mjs +3 -3
  5. package/esm2020/lib/formly/field/field.mjs +19 -3
  6. package/esm2020/lib/formly/field/selection/pickable/pickable.field.mjs +4 -4
  7. package/esm2020/lib/formly/field/selection/searchable/searchable.field.mjs +4 -4
  8. package/esm2020/lib/formly/field/selection/selection.field.mjs +3 -3
  9. package/esm2020/lib/formly/field/texteditor/texteditor.field.mjs +3 -3
  10. package/esm2020/lib/formly/field/value/array/array.field.mjs +3 -3
  11. package/esm2020/lib/formly/field/value/boolean/boolean.field.mjs +4 -4
  12. package/esm2020/lib/formly/field/value/date/datetime.field.component.mjs +110 -15
  13. package/esm2020/lib/formly/field/value/date/datetime.field.mjs +32 -6
  14. package/esm2020/lib/formly/field/value/number/number.field.mjs +19 -4
  15. package/esm2020/lib/formly/field/value/phone/phone.field.mjs +3 -3
  16. package/esm2020/lib/formly/field/value/text/text.additional.field.mjs +5 -2
  17. package/esm2020/lib/formly/field/value/text/text.field.mjs +24 -7
  18. package/esm2020/lib/formly/field/wrapper/section.wrapper.component.mjs +1 -1
  19. package/esm2020/lib/formly/field/wrapper/subsection.wrapper.component.mjs +1 -1
  20. package/esm2020/lib/validator/number.mjs +7 -1
  21. package/esm2020/mapbox/lib/field/latlng/latlng.field.mjs +3 -3
  22. package/esm2020/mapbox/lib/field/zoom/zoom.field.mjs +3 -3
  23. package/fesm2015/dereekb-dbx-form-mapbox.mjs +3 -3
  24. package/fesm2015/dereekb-dbx-form-mapbox.mjs.map +1 -1
  25. package/fesm2015/dereekb-dbx-form.mjs +243 -48
  26. package/fesm2015/dereekb-dbx-form.mjs.map +1 -1
  27. package/fesm2020/dereekb-dbx-form-mapbox.mjs +3 -3
  28. package/fesm2020/dereekb-dbx-form-mapbox.mjs.map +1 -1
  29. package/fesm2020/dereekb-dbx-form.mjs +262 -47
  30. package/fesm2020/dereekb-dbx-form.mjs.map +1 -1
  31. package/lib/form/form.d.ts +4 -2
  32. package/lib/form/io/form.input.directive.d.ts +2 -1
  33. package/lib/formly/field/field.d.ts +29 -3
  34. package/lib/formly/field/value/array/array.field.d.ts +6 -0
  35. package/lib/formly/field/value/date/datetime.field.component.d.ts +45 -3
  36. package/lib/formly/field/value/date/datetime.field.d.ts +5 -0
  37. package/lib/formly/field/value/number/number.field.d.ts +4 -2
  38. package/lib/formly/field/value/text/text.additional.field.d.ts +3 -6
  39. package/lib/formly/field/value/text/text.field.d.ts +6 -3
  40. package/lib/formly/field/wrapper/section.wrapper.component.d.ts +1 -2
  41. package/lib/formly/field/wrapper/subsection.wrapper.component.d.ts +1 -2
  42. package/lib/formly/field/wrapper/wrapper.d.ts +2 -2
  43. package/lib/validator/number.d.ts +6 -0
  44. package/mapbox/esm2020/lib/field/latlng/latlng.field.mjs +3 -3
  45. package/mapbox/esm2020/lib/field/zoom/zoom.field.mjs +3 -3
  46. package/mapbox/fesm2015/dereekb-dbx-form-mapbox.mjs +3 -3
  47. package/mapbox/fesm2015/dereekb-dbx-form-mapbox.mjs.map +1 -1
  48. package/mapbox/fesm2020/dereekb-dbx-form-mapbox.mjs +3 -3
  49. package/mapbox/fesm2020/dereekb-dbx-form-mapbox.mjs.map +1 -1
  50. package/mapbox/package.json +4 -4
  51. package/package.json +4 -4
@@ -4,9 +4,9 @@ import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i1$1 from '@dereekb/dbx-web';
6
6
  import { DbxActionTransitionSafetyDirective, DbxTextModule, DbxLoadingModule, DbxFlexLayoutModule, DbxSectionLayoutModule, DbxRouterAnchorModule, AbstractDbxSelectionListWrapperDirective, DEFAULT_LIST_WRAPPER_DIRECTIVE_TEMPLATE, AbstractDbxSelectionListViewDirective, addConfigToValueListItems, provideDbxListView, AbstractDbxValueListViewItemComponent, DbxButtonModule, DbxListLayoutModule, mapCompactModeObs, DbxBarLayoutModule } from '@dereekb/dbx-web';
7
- import { isPast, addSeconds, isSameMinute, startOfDay, isSameDay, addMinutes } from 'date-fns';
8
- import { BehaviorSubject, switchMap, first, exhaustMap, of, catchError, delay, filter, combineLatest, map, distinctUntilChanged, mergeMap, shareReplay, startWith, debounceTime, Subject, skipWhile, interval, tap, merge, throttleTime, scan, timer } from 'rxjs';
9
- import { LockSet, SubscriptionObject, asObservable, loadingStateHasFinishedLoading, switchMapMaybeObs, filterMaybe, switchMapMaybeDefault, SimpleLoadingContext, startWithBeginLoading, mapLoadingStateResults, successResult, ListLoadingStateContextInstance, isListLoadingStateEmpty, LoadingStateContextInstance, tapLog, skipFirstMaybe, asyncPusherCache, scanCount } from '@dereekb/rxjs';
7
+ import { isPast, addSeconds, isSameMinute, startOfDay, isSameDay, addMinutes, addDays } from 'date-fns';
8
+ import { BehaviorSubject, switchMap, first, exhaustMap, of, catchError, delay, filter, combineLatest, map, distinctUntilChanged, shareReplay, Subject, tap, takeUntil, EMPTY, mergeMap, startWith, debounceTime, skipWhile, interval, merge, throttleTime, scan, timer } from 'rxjs';
9
+ import { LockSet, SubscriptionObject, asObservable, cleanup, loadingStateHasFinishedLoading, switchMapMaybeObs, filterMaybe, switchMapMaybeDefault, SimpleLoadingContext, startWithBeginLoading, mapLoadingStateResults, successResult, ListLoadingStateContextInstance, isListLoadingStateEmpty, LoadingStateContextInstance, skipFirstMaybe, asyncPusherCache, scanCount } from '@dereekb/rxjs';
10
10
  import * as i2 from '@dereekb/dbx-core';
11
11
  import { AbstractSubscriptionDirective, safeDetectChanges, DbxInjectionComponentModule, DbxDatePipeModule, mergeDbxInjectionComponentConfigs, tapDetectChanges } from '@dereekb/dbx-core';
12
12
  import * as i3 from '@uirouter/core';
@@ -26,7 +26,7 @@ import * as i1$2 from '@angular/material/button';
26
26
  import { MatButtonModule } from '@angular/material/button';
27
27
  import * as i3$3 from '@angular/flex-layout/flex';
28
28
  import { FlexLayoutModule } from '@angular/flex-layout';
29
- import { objectIsEmpty, mergeObjectsFunction, filterFromPOJOFunction, mergeObjects, filterFromPOJO, asArray, objectHasNoKeys, addPlusPrefixToNumber, convertMaybeToArray, makeValuesGroupMap, findUnique, searchStringFilterFunction, caseInsensitiveFilterByIndexOfDecisionFactory, mergeIntoArray, lastValue, separateValues, arrayToMap, getValueFromGetter, dateFromLogicalDate, WEBSITE_DOMAIN_NAME_REGEX, KeyValueTypleValueFilter, valuesFromPOJO, allObjectsAreEqual, isNumberDivisibleBy, nearestDivisibleValues, US_STATE_CODE_STRING_REGEX, ZIP_CODE_STRING_REGEX, LAT_LNG_PATTERN, capitalizeFirstLetter, BooleanStringKeyArrayUtilityInstance } from '@dereekb/util';
29
+ import { objectIsEmpty, mergeObjectsFunction, filterFromPOJOFunction, mergeObjects, filterFromPOJO, asArray, objectHasNoKeys, addPlusPrefixToNumber, convertMaybeToArray, makeValuesGroupMap, findUnique, searchStringFilterFunction, caseInsensitiveFilterByIndexOfDecisionFactory, mergeIntoArray, lastValue, separateValues, arrayToMap, getValueFromGetter, filterMaybeValues, dateFromLogicalDate, WEBSITE_DOMAIN_NAME_REGEX, KeyValueTypleValueFilter, valuesFromPOJO, allObjectsAreEqual, isNumberDivisibleBy, nearestDivisibleValues, transformNumberFunction, concatArrays, transformStringFunction, US_STATE_CODE_STRING_REGEX, ZIP_CODE_STRING_REGEX, LAT_LNG_PATTERN, capitalizeFirstLetter, BooleanStringKeyArrayUtilityInstance } from '@dereekb/util';
30
30
  import * as i2$1 from '@angular/material/slide-toggle';
31
31
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
32
32
  import * as i2$2 from '@angular/flex-layout/extended';
@@ -44,7 +44,7 @@ import { MatListModule } from '@angular/material/list';
44
44
  import * as i3$4 from '@angular/material/form-field';
45
45
  import { MatFormFieldModule } from '@angular/material/form-field';
46
46
  import { ENTER, COMMA } from '@angular/cdk/keycodes';
47
- import { skipUntilTimeElapsedAfterLastEmission, toJsDate, parseISO8601DayStringToDate, formatToISO8601DayString, formatToISO8601DateString, guessCurrentTimezone, toReadableTimeString, utcDayForDate, readableTimeStringToDate, DateTimeMinuteInstance, toLocalReadableTimeString, allTimezoneInfos, timezoneInfoForSystem, searchTimezoneInfos } from '@dereekb/date';
47
+ import { skipUntilTimeElapsedAfterLastEmission, toJsDate, parseISO8601DayStringToDate, formatToISO8601DayString, formatToISO8601DateString, safeToJsDate, guessCurrentTimezone, toReadableTimeString, utcDayForDate, readableTimeStringToDate, findMinDate, findMaxDate, DateTimeMinuteInstance, toLocalReadableTimeString, allTimezoneInfos, timezoneInfoForSystem, searchTimezoneInfos } from '@dereekb/date';
48
48
  import * as i4$4 from 'ngx-editor';
49
49
  import { Editor, NgxEditorModule } from 'ngx-editor';
50
50
  import * as i4$5 from '@angular/cdk/drag-drop';
@@ -295,12 +295,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
295
295
  }] });
296
296
 
297
297
  function dbxFormSourceObservable(form, inputObs, mode$) {
298
- const observable = asObservable(inputObs);
299
- return combineLatest([observable.pipe(distinctUntilChanged()), mode$.pipe(distinctUntilChanged())]).pipe(switchMap(([value, mode]) => form.stream$.pipe(
300
- // wait for the form to finish initializing.
301
- filter((x) => x.state !== DbxFormState.INITIALIZING),
302
- // if mode is reset, then filter out changes until the form is reset again.
303
- filter((x) => (mode === 'reset' ? x.state === DbxFormState.RESET : true)), first(), map(() => value))));
298
+ return dbxFormSourceObservableFromStream(form.stream$, inputObs, mode$);
299
+ }
300
+ function dbxFormSourceObservableFromStream(stream$, inputObs, mode$) {
301
+ const value$ = asObservable(inputObs).pipe(shareReplay(1)); // catch/share the latest emission
302
+ const state$ = stream$.pipe(map((x) => x.state), distinctUntilChanged());
303
+ return combineLatest([mode$, value$]).pipe(map((x) => x[0]), distinctUntilChanged(), switchMap((mode) => {
304
+ if (mode === 'reset') {
305
+ // reset only
306
+ return state$.pipe(exhaustMap((state) => {
307
+ if (state === DbxFormState.RESET) {
308
+ let firstValueSent = false;
309
+ const doneSubject = new Subject();
310
+ return combineLatest([value$, state$]).pipe(map(([value, state]) => {
311
+ if (!firstValueSent || state === DbxFormState.RESET) {
312
+ return [value, true]; // always forward the first value.
313
+ }
314
+ else {
315
+ return [value, false];
316
+ }
317
+ }), tap(([value, send]) => {
318
+ firstValueSent = true;
319
+ if (!send) {
320
+ doneSubject.next(undefined);
321
+ }
322
+ }), filter(([value, send]) => send), map((x) => x[0]), takeUntil(doneSubject), cleanup(() => {
323
+ doneSubject.complete();
324
+ }));
325
+ }
326
+ else {
327
+ return EMPTY;
328
+ }
329
+ }));
330
+ }
331
+ else {
332
+ // pass any updated value while not initializing.
333
+ return state$.pipe(map((x) => x === DbxFormState.INITIALIZING), switchMap((initializing) => {
334
+ if (initializing) {
335
+ return EMPTY;
336
+ }
337
+ else {
338
+ return value$;
339
+ }
340
+ }));
341
+ }
342
+ }));
304
343
  }
305
344
  /**
306
345
  * Used with a FormComponent to set the value based on the input value.
@@ -323,7 +362,7 @@ class DbxFormSourceDirective extends AbstractSubscriptionDirective {
323
362
  setObs(inputObs) {
324
363
  let subscription;
325
364
  if (inputObs) {
326
- subscription = dbxFormSourceObservable(this.form, inputObs, this._mode).subscribe((x) => {
365
+ subscription = dbxFormSourceObservableFromStream(this.form.stream$, inputObs, this._mode).subscribe((x) => {
327
366
  this.form.setValue(x);
328
367
  });
329
368
  }
@@ -377,7 +416,7 @@ class DbxFormLoadingSourceDirective extends AbstractSubscriptionDirective {
377
416
  _setObs(inputObs) {
378
417
  let subscription;
379
418
  if (inputObs) {
380
- subscription = dbxFormSourceObservable(this.form, inputObs, this._mode).subscribe((x) => {
419
+ subscription = dbxFormSourceObservableFromStream(this.form.stream$, inputObs, this._mode).subscribe((x) => {
381
420
  if (loadingStateHasFinishedLoading(x)) {
382
421
  this.form.setValue(x.value);
383
422
  }
@@ -1179,10 +1218,20 @@ function formlyField(fieldConfig) {
1179
1218
  }
1180
1219
  return fieldConfig;
1181
1220
  }
1182
- function propsForFieldConfig(fieldConfig, override) {
1221
+ /**
1222
+ * Creates an object with propers, expressions, and parsers properly configured from the input FieldConfig.
1223
+ *
1224
+ * @param fieldConfig
1225
+ * @param override
1226
+ * @returns
1227
+ */
1228
+ function propsAndConfigForFieldConfig(fieldConfig, override) {
1229
+ const { expressions, parsers } = fieldConfig;
1183
1230
  const props = propsValueForFieldConfig(fieldConfig, override);
1184
1231
  return {
1185
- props
1232
+ props,
1233
+ expressions,
1234
+ parsers
1186
1235
  };
1187
1236
  }
1188
1237
  const partialPotentialFieldConfigKeys = ['label', 'placeholder', 'required', 'readonly', 'description', 'autocomplete'];
@@ -1248,10 +1297,16 @@ function validatorsForFieldConfig(input) {
1248
1297
  }
1249
1298
  return config;
1250
1299
  }
1300
+ /**
1301
+ * MARK: Compat
1302
+ *
1303
+ * @deprecated use propsAndConfigForFieldConfig instead.
1304
+ */
1305
+ const propsForFieldConfig = propsAndConfigForFieldConfig;
1251
1306
 
1252
1307
  function checklistItemField(config) {
1253
1308
  const { key, displayContentObs, componentClass } = config;
1254
- const fieldConfig = formlyField(Object.assign({ key, type: 'checklistitem' }, propsForFieldConfig(config, {
1309
+ const fieldConfig = formlyField(Object.assign({ key, type: 'checklistitem' }, propsAndConfigForFieldConfig(config, {
1255
1310
  displayContentObs,
1256
1311
  componentClass
1257
1312
  })));
@@ -1860,11 +1915,11 @@ function sortPickableItemsByLabel(chips) {
1860
1915
  }
1861
1916
  function pickableItemChipField(config) {
1862
1917
  const { key } = config;
1863
- return formlyField(Object.assign({ key, type: 'pickablechipfield' }, propsForFieldConfig(config, Object.assign(Object.assign({}, config), { autocomplete: false }))));
1918
+ return formlyField(Object.assign({ key, type: 'pickablechipfield' }, propsAndConfigForFieldConfig(config, Object.assign(Object.assign({}, config), { autocomplete: false }))));
1864
1919
  }
1865
1920
  function pickableItemListField(config) {
1866
1921
  const { key } = config;
1867
- return formlyField(Object.assign({ key, type: 'pickablelistfield' }, propsForFieldConfig(config, Object.assign(Object.assign({}, config), { autocomplete: false }))));
1922
+ return formlyField(Object.assign({ key, type: 'pickablelistfield' }, propsAndConfigForFieldConfig(config, Object.assign(Object.assign({}, config), { autocomplete: false }))));
1868
1923
  }
1869
1924
 
1870
1925
  const DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN = new InjectionToken('DbxSearchableField');
@@ -2280,11 +2335,11 @@ function searchableStringChipField(config) {
2280
2335
  }
2281
2336
  function searchableChipField(config) {
2282
2337
  const { key, placeholder } = config;
2283
- return formlyField(Object.assign({ key, type: 'searchablechipfield' }, propsForFieldConfig(config, Object.assign(Object.assign({}, config), { placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : 'Add...', autocomplete: false }))));
2338
+ return formlyField(Object.assign({ key, type: 'searchablechipfield' }, propsAndConfigForFieldConfig(config, Object.assign(Object.assign({}, config), { placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : 'Add...', autocomplete: false }))));
2284
2339
  }
2285
2340
  function searchableTextField(config) {
2286
2341
  const { key } = config;
2287
- return formlyField(Object.assign({ key, type: 'searchabletextfield' }, propsForFieldConfig(config, Object.assign(Object.assign({}, config), { autocomplete: false }))));
2342
+ return formlyField(Object.assign({ key, type: 'searchabletextfield' }, propsAndConfigForFieldConfig(config, Object.assign(Object.assign({}, config), { autocomplete: false }))));
2288
2343
  }
2289
2344
 
2290
2345
  /**
@@ -2418,7 +2473,7 @@ function valueSelectionField(config) {
2418
2473
  selectAllOption: typeof inputSelectAllOption === 'boolean' ? 'Select All' : inputSelectAllOption
2419
2474
  };
2420
2475
  }
2421
- return formlyField(Object.assign({ key, type: native ? 'native-select' : 'select' }, propsForFieldConfig(config, Object.assign({ options: config.options, multiple: (_a = config.multiple) !== null && _a !== void 0 ? _a : false }, selectAllOptionConfig))));
2476
+ return formlyField(Object.assign({ key, type: native ? 'native-select' : 'select' }, propsAndConfigForFieldConfig(config, Object.assign({ options: config.options, multiple: (_a = config.multiple) !== null && _a !== void 0 ? _a : false }, selectAllOptionConfig))));
2422
2477
  }
2423
2478
 
2424
2479
  class DbxFormFormlySelectionModule {
@@ -2565,7 +2620,7 @@ function textEditorField(config) {
2565
2620
  // https://formly.dev/examples/validation/async-validation-update-on
2566
2621
  // Set to trigger value update on blurs with the form. However, the value is set internally too.
2567
2622
  updateOn: 'blur'
2568
- } }, propsForFieldConfig(config, {
2623
+ } }, propsAndConfigForFieldConfig(config, {
2569
2624
  minLength,
2570
2625
  maxLength
2571
2626
  })));
@@ -2748,7 +2803,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
2748
2803
 
2749
2804
  function repeatArrayField(config) {
2750
2805
  const { key, repeatFieldGroup, maxLength, addText, removeText, labelForField } = config;
2751
- return formlyField(Object.assign(Object.assign({ key, type: 'repeatarray' }, propsForFieldConfig(config, {
2806
+ return formlyField(Object.assign(Object.assign({ key, type: 'repeatarray' }, propsAndConfigForFieldConfig(config, {
2752
2807
  maxLength,
2753
2808
  labelForField,
2754
2809
  addText,
@@ -2774,11 +2829,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
2774
2829
 
2775
2830
  function toggleField(config) {
2776
2831
  const { key, defaultValue } = config;
2777
- return formlyField(Object.assign({ key, type: 'toggle', wrappers: ['autotouch', 'form-field'], defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : false }, propsForFieldConfig(config)));
2832
+ return formlyField(Object.assign({ key, type: 'toggle', wrappers: ['autotouch', 'form-field'], defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : false }, propsAndConfigForFieldConfig(config)));
2778
2833
  }
2779
2834
  function checkboxField(config) {
2780
2835
  const { key, defaultValue } = config;
2781
- return formlyField(Object.assign({ key, type: 'checkbox', defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : false }, propsForFieldConfig(config)));
2836
+ return formlyField(Object.assign({ key, type: 'checkbox', defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : false }, propsAndConfigForFieldConfig(config)));
2782
2837
  }
2783
2838
  /*
2784
2839
  export function acceptTermsField({ key = 'accept', label = 'Accept Terms', description = 'In order to proceed, please accept terms', required = true }
@@ -2861,6 +2916,20 @@ function dbxDateTimeOutputValueFactory(mode) {
2861
2916
  }
2862
2917
  return factory;
2863
2918
  }
2919
+ function syncConfigValueObs(parseConfigsObs, type) {
2920
+ return parseConfigsObs.pipe(switchMap((x) => {
2921
+ const config = x.find((y) => y.syncType === type);
2922
+ let result;
2923
+ if (config) {
2924
+ const { control } = config;
2925
+ result = control.valueChanges.pipe(startWith(control.value), map(safeToJsDate));
2926
+ }
2927
+ else {
2928
+ result = of(undefined);
2929
+ }
2930
+ return result;
2931
+ }), distinctUntilChanged(), shareReplay(1));
2932
+ }
2864
2933
  class DbxDateTimeFieldComponent extends FieldType$1 {
2865
2934
  constructor(cdRef) {
2866
2935
  super();
@@ -2890,13 +2959,37 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
2890
2959
  validators: [Validators.pattern(/^(now)$|^([0-9]|(0[0-9])|(1[0-9])|(2[0-3]))(:)?([0-5][0-9])?(\s)?([apAP][Mm])?(\\s)*$/)]
2891
2960
  });
2892
2961
  this._config = new BehaviorSubject(undefined);
2962
+ this._syncConfigObs = new BehaviorSubject(undefined);
2893
2963
  this.fullDay$ = this.fullDayControl$.pipe(switchMap((control) => control.valueChanges.pipe(startWith(control.value))));
2894
2964
  this.showTimeInput$ = this.fullDay$.pipe(map((x) => !x && this.timeMode !== DbxDateTimeFieldTimeMode.NONE));
2895
2965
  this.showAddTime$ = this.showTimeInput$.pipe(map((x) => !x && this.timeMode === DbxDateTimeFieldTimeMode.OPTIONAL), shareReplay(1));
2896
2966
  this.date$ = this.dateInputCtrl.valueChanges.pipe(startWith(this.dateInputCtrl.value), filterMaybe(), shareReplay(1));
2897
- this.dateValue$ = merge(this.date$.pipe(tapLog('date')), this.value$.pipe(skipFirstMaybe())).pipe(map((x) => (x ? startOfDay(x) : x)), distinctUntilChanged((a, b) => a != null && b != null && isSameDay(a, b)), shareReplay(1));
2967
+ this.dateValue$ = merge(this.date$, this.value$.pipe(skipFirstMaybe())).pipe(map((x) => (x ? startOfDay(x) : x)), distinctUntilChanged((a, b) => a != null && b != null && isSameDay(a, b)), shareReplay(1));
2898
2968
  this.timeInput$ = this._updateTime.pipe(debounceTime(5), map(() => this.timeInputCtrl.value || ''), distinctUntilChanged());
2899
- this.config$ = this._config.pipe(switchMapMaybeDefault(), shareReplay(1));
2969
+ this.syncConfigObs$ = this._syncConfigObs.pipe(switchMapMaybeDefault(), shareReplay(1));
2970
+ this.parsedSyncConfigs$ = this.syncConfigObs$.pipe(map((x) => {
2971
+ let parsed;
2972
+ if (x) {
2973
+ parsed = filterMaybeValues(asArray(x).map((y) => {
2974
+ const control = this.form.get(y.syncWith);
2975
+ if (control) {
2976
+ return Object.assign({ control }, y);
2977
+ }
2978
+ else {
2979
+ return undefined;
2980
+ }
2981
+ }));
2982
+ }
2983
+ else {
2984
+ parsed = [];
2985
+ }
2986
+ return parsed;
2987
+ }), shareReplay(1));
2988
+ this.syncConfigBeforeValue$ = syncConfigValueObs(this.parsedSyncConfigs$, 'before');
2989
+ this.syncConfigAfterValue$ = syncConfigValueObs(this.parsedSyncConfigs$, 'after');
2990
+ // TODO: Get min/max using the DateTimePickerConfiguration too
2991
+ this.dateInputMin$ = this.syncConfigBeforeValue$;
2992
+ this.dateInputMax$ = this.syncConfigAfterValue$;
2900
2993
  this.rawDateTime$ = combineLatest([this.dateValue$, this.timeInput$.pipe(startWith(null)), this.fullDay$]).pipe(map(([date, timeString, fullDay]) => {
2901
2994
  var _a;
2902
2995
  let result;
@@ -2922,7 +3015,19 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
2922
3015
  }
2923
3016
  return result;
2924
3017
  }), distinctUntilChanged((a, b) => a != null && b != null && isSameMinute(a, b)), shareReplay(1));
2925
- this.timeOutput$ = combineLatest([this.rawDateTime$, this._offset, this.config$.pipe(distinctUntilChanged())]).pipe(throttleTime(40, undefined, { leading: false, trailing: true }), distinctUntilChanged((current, next) => current[0] === next[0] && next[1] === 0), tap(([, stepsOffset]) => (stepsOffset ? this._offset.next(0) : 0)), map(([date, stepsOffset, config]) => {
3018
+ this.config$ = combineLatest([this._config.pipe(switchMapMaybeDefault(), shareReplay(1)), this.dateInputMin$, this.dateInputMax$]).pipe(map(([x, dateInputMin, dateInputMax]) => {
3019
+ var _a;
3020
+ let result = x;
3021
+ if (dateInputMin != null || dateInputMax != null) {
3022
+ const { min: limitMin, max: limitMax } = (_a = x === null || x === void 0 ? void 0 : x.limits) !== null && _a !== void 0 ? _a : {};
3023
+ const min = findMinDate([dateInputMin, limitMin]);
3024
+ const max = findMaxDate([dateInputMax, limitMax]);
3025
+ result = Object.assign(Object.assign({}, x), { limits: Object.assign(Object.assign({}, x === null || x === void 0 ? void 0 : x.limits), { min,
3026
+ max }) });
3027
+ }
3028
+ return result;
3029
+ }), distinctUntilChanged(), shareReplay(1));
3030
+ this.timeOutput$ = combineLatest([this.rawDateTime$, this._offset, this.config$]).pipe(throttleTime(40, undefined, { leading: false, trailing: true }), distinctUntilChanged((current, next) => current[0] === next[0] && next[1] === 0), tap(([, stepsOffset]) => (stepsOffset ? this._offset.next(0) : 0)), map(([date, stepsOffset, config]) => {
2926
3031
  if (date != null) {
2927
3032
  const instance = new DateTimeMinuteInstance(Object.assign(Object.assign({ date }, config), { roundDownToMinute: true }));
2928
3033
  date = instance.limit(date);
@@ -2932,6 +3037,14 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
2932
3037
  return date;
2933
3038
  }), distinctUntilChanged((a, b) => a != null && b != null && isSameMinute(a, b)), shareReplay(1));
2934
3039
  }
3040
+ get dateLabel() {
3041
+ var _a;
3042
+ return (_a = this.props.dateLabel) !== null && _a !== void 0 ? _a : 'Date';
3043
+ }
3044
+ get timeLabel() {
3045
+ var _a;
3046
+ return (_a = this.props.timeLabel) !== null && _a !== void 0 ? _a : 'Time';
3047
+ }
2935
3048
  get dateOnly() {
2936
3049
  return this.timeMode === DbxDateTimeFieldTimeMode.NONE;
2937
3050
  }
@@ -2960,9 +3073,10 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
2960
3073
  return (_a = this.field.props.hideDateHint) !== null && _a !== void 0 ? _a : false;
2961
3074
  }
2962
3075
  ngOnInit() {
2963
- var _a, _b;
3076
+ var _a, _b, _c, _d;
2964
3077
  this._formControlObs.next(this.formControl);
2965
3078
  this._config.next((_b = (_a = this.dateTimeField).getConfigObs) === null || _b === void 0 ? void 0 : _b.call(_a));
3079
+ this._syncConfigObs.next((_d = (_c = this.dateTimeField).getSyncFieldsObs) === null || _d === void 0 ? void 0 : _d.call(_c));
2966
3080
  const valueFactory = dbxDateTimeOutputValueFactory(this.valueMode);
2967
3081
  this._sub.subscription = this.timeOutput$.pipe(skipFirstMaybe()).subscribe((dateValue) => {
2968
3082
  const value = valueFactory(dateValue);
@@ -3020,15 +3134,14 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3020
3134
  this._formControlObs.complete();
3021
3135
  this._config.complete();
3022
3136
  this._updateTime.complete();
3137
+ this._syncConfigObs.complete();
3023
3138
  this._sub.destroy();
3024
3139
  this._valueSub.destroy();
3025
3140
  }
3026
3141
  datePicked(event) {
3027
3142
  const date = event.value;
3028
- console.log('date picked?', event);
3029
3143
  if (date) {
3030
- this.dateInputCtrl.setValue(date);
3031
- this._updateTime.next();
3144
+ this.setDateInputValue(date);
3032
3145
  }
3033
3146
  }
3034
3147
  setLogicalTime(time) {
@@ -3038,12 +3151,44 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3038
3151
  this.setTime(timeString);
3039
3152
  }
3040
3153
  }
3154
+ setDateInputValue(date) {
3155
+ this.dateInputCtrl.setValue(date);
3156
+ this._updateTime.next();
3157
+ }
3041
3158
  setTime(time) {
3042
3159
  this.timeInputCtrl.setValue(time);
3043
3160
  this._offset.next(0);
3044
3161
  this._updateTime.next();
3045
3162
  }
3046
- keydownOnInput(event) {
3163
+ keydownOnDateInput(event) {
3164
+ var _a;
3165
+ let direction = 0;
3166
+ switch ((_a = event.key) === null || _a === void 0 ? void 0 : _a.toLowerCase()) {
3167
+ case 'arrowup':
3168
+ direction = 1;
3169
+ break;
3170
+ case 'arrowdown':
3171
+ direction = -1;
3172
+ break;
3173
+ }
3174
+ let offset = 1;
3175
+ if (event.ctrlKey && event.shiftKey) {
3176
+ offset = 365;
3177
+ }
3178
+ else if (event.ctrlKey) {
3179
+ offset = 30;
3180
+ }
3181
+ else if (event.shiftKey) {
3182
+ offset = 7;
3183
+ }
3184
+ if (direction !== 0) {
3185
+ this.date$.pipe(first()).subscribe((date) => {
3186
+ const newDate = addDays(date, offset * direction);
3187
+ this.setDateInputValue(newDate);
3188
+ });
3189
+ }
3190
+ }
3191
+ keydownOnTimeInput(event) {
3047
3192
  var _a;
3048
3193
  let direction = 0;
3049
3194
  switch ((_a = event.key) === null || _a === void 0 ? void 0 : _a.toLowerCase()) {
@@ -3088,10 +3233,10 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3088
3233
  }
3089
3234
  }
3090
3235
  DbxDateTimeFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: DbxDateTimeFieldComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3091
- DbxDateTimeFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.2", type: DbxDateTimeFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"dbx-datetime-field\" fxLayout=\"row wrap\" fxLayout.xs=\"column wrap\" fxLayoutAlign=\"space-evenly stretch\">\n <!-- Date -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"dateOnly ? '100' : '50'\" *ngIf=\"showDateInput\">\n <ng-container *ngTemplateOutlet=\"dateInputTemplate\"></ng-container>\n </div>\n <!-- Time -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"showDateInput ? '50' : '100'\">\n <ng-container *ngIf=\"showTimeInput$ | async\">\n <ng-container *ngTemplateOutlet=\"timeMenuAndInputTemplate\"></ng-container>\n </ng-container>\n <div class=\"add-time-button-wrapper\" *ngIf=\"showAddTime$ | async\">\n <button mat-button class=\"add-time-button\" ngClass.lt-sm=\"add-time-button-full\" (click)=\"addTime()\">\n <mat-icon>timer</mat-icon>\n Add Time\n </button>\n </div>\n </div>\n <div *ngIf=\"!hideDateHint\" class=\"dbx-datetime-row dbx-datetime-hint-row\" fxFlex=\"100\">\n <div class=\"dbx-hint\" [ngSwitch]=\"fullDay$ | async\">\n <small *ngSwitchCase=\"true\">\n <b class=\"dbx-ok\">All Day</b>\n {{ dateValue$ | async | date: 'fullDate' }} ({{ dateValue$ | async | dateDistance }})\n </small>\n <small *ngSwitchCase=\"false\">\n <ng-container *ngIf=\"value$ | async\">\n <b class=\"dbx-ok\">At</b>\n {{ displayValue$ | async | date: 'medium' }} ({{ displayValue$ | async | timeDistance }})\n </ng-container>\n </small>\n </div>\n </div>\n</div>\n\n<!-- Date Input Template -->\n<ng-template #dateInputTemplate>\n <button mat-icon-button (click)=\"picker.open()\" [disabled]=\"disabled\">\n <mat-icon>calendar_today</mat-icon>\n </button>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>Date</mat-label>\n <input #dateInput matInput [matDatepicker]=\"picker\" (dateChange)=\"datePicked($event)\" [value]=\"dateValue$ | async\" />\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n</ng-template>\n\n<!-- Time Menu/Input Template -->\n<ng-template #timeMenuAndInputTemplate>\n <button mat-icon-button [matMenuTriggerFor]=\"timemenu\" aria-label=\"opens the time menu\" [disabled]=\"disabled\">\n <mat-icon>timer</mat-icon>\n </button>\n <mat-menu #timemenu=\"matMenu\">\n <ng-container *ngIf=\"timeMode === 'optional'\">\n <button mat-menu-item (click)=\"removeTime()\">\n <span>Remove Time</span>\n </button>\n <mat-divider></mat-divider>\n </ng-container>\n <button mat-menu-item (click)=\"setLogicalTime('now')\">\n <span>Now</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00AM')\">\n <span>Midnight</span>\n </button>\n <button mat-menu-item (click)=\"setTime('6:00AM')\">\n <span>6:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('8:00AM')\">\n <span>8:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('10:00AM')\">\n <span>10:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00PM')\">\n <span>Noon</span>\n </button>\n <button mat-menu-item (click)=\"setTime('2:00PM')\">\n <span>2:00PM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('5:00PM')\">\n <span>5:00PM</span>\n </button>\n </mat-menu>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>Time</mat-label>\n <input #timeInput matInput [formControl]=\"timeInputCtrl\" (focus)=\"focusTime()\" (focusout)=\"focusOutTime()\" (keydown)=\"keydownOnInput($event)\" />\n </mat-form-field>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3$1.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: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i3$4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i1$2.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i7.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i8.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i8.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i3$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$3.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i3$3.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i3$3.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2$2.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "pipe", type: i2.TimeDistancePipe, name: "timeDistance" }, { kind: "pipe", type: i2.DateDistancePipe, name: "dateDistance" }] });
3236
+ DbxDateTimeFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.2", type: DbxDateTimeFieldComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"dbx-datetime-field\" fxLayout=\"row wrap\" fxLayout.xs=\"column wrap\" fxLayoutAlign=\"space-evenly stretch\">\n <!-- Date -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"dateOnly ? '100' : '50'\" *ngIf=\"showDateInput\">\n <ng-container *ngTemplateOutlet=\"dateInputTemplate\"></ng-container>\n </div>\n <!-- Time -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"showDateInput ? '50' : '100'\">\n <ng-container *ngIf=\"showTimeInput$ | async\">\n <ng-container *ngTemplateOutlet=\"timeMenuAndInputTemplate\"></ng-container>\n </ng-container>\n <div class=\"add-time-button-wrapper\" *ngIf=\"showAddTime$ | async\">\n <button mat-button class=\"add-time-button\" ngClass.lt-sm=\"add-time-button-full\" (click)=\"addTime()\">\n <mat-icon>timer</mat-icon>\n Add Time\n </button>\n </div>\n </div>\n <div *ngIf=\"!hideDateHint\" class=\"dbx-datetime-row dbx-datetime-hint-row\" fxFlex=\"100\">\n <div class=\"dbx-hint\" [ngSwitch]=\"fullDay$ | async\">\n <small *ngSwitchCase=\"true\">\n <b class=\"dbx-ok\">All Day</b>\n {{ displayValue$ | async | date: 'fullDate' }} ({{ displayValue$ | async | dateDistance }})\n </small>\n <small *ngSwitchCase=\"false\">\n <ng-container *ngIf=\"value$ | async\">\n <b class=\"dbx-ok\">At</b>\n {{ displayValue$ | async | date: 'medium' }} ({{ displayValue$ | async | timeDistance }})\n </ng-container>\n </small>\n </div>\n </div>\n</div>\n\n<!-- Date Input Template -->\n<ng-template #dateInputTemplate>\n <button mat-icon-button (click)=\"picker.open()\" [disabled]=\"disabled\">\n <mat-icon>calendar_today</mat-icon>\n </button>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>{{ dateLabel }}</mat-label>\n <input #dateInput matInput [min]=\"dateInputMin$ | async\" [max]=\"dateInputMax$ | async\" [matDatepicker]=\"picker\" (dateChange)=\"datePicked($event)\" [value]=\"dateValue$ | async\" (keydown)=\"keydownOnDateInput($event)\" />\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n</ng-template>\n\n<!-- Time Menu/Input Template -->\n<ng-template #timeMenuAndInputTemplate>\n <button mat-icon-button [matMenuTriggerFor]=\"timemenu\" aria-label=\"opens the time menu\" [disabled]=\"disabled\">\n <mat-icon>timer</mat-icon>\n </button>\n <mat-menu #timemenu=\"matMenu\">\n <ng-container *ngIf=\"timeMode === 'optional'\">\n <button mat-menu-item (click)=\"removeTime()\">\n <span>Remove Time</span>\n </button>\n <mat-divider></mat-divider>\n </ng-container>\n <button mat-menu-item (click)=\"setLogicalTime('now')\">\n <span>Now</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00AM')\">\n <span>Midnight</span>\n </button>\n <button mat-menu-item (click)=\"setTime('6:00AM')\">\n <span>6:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('8:00AM')\">\n <span>8:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('10:00AM')\">\n <span>10:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00PM')\">\n <span>Noon</span>\n </button>\n <button mat-menu-item (click)=\"setTime('2:00PM')\">\n <span>2:00PM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('5:00PM')\">\n <span>5:00PM</span>\n </button>\n </mat-menu>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>{{ timeLabel }}</mat-label>\n <input #timeInput matInput [formControl]=\"timeInputCtrl\" (focus)=\"focusTime()\" (focusout)=\"focusOutTime()\" (keydown)=\"keydownOnTimeInput($event)\" />\n </mat-form-field>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3$1.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: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: i3$4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i1$2.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i7.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i8.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i8.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i3$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3$3.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i3$3.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i3$3.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i2$2.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "pipe", type: i2.TimeDistancePipe, name: "timeDistance" }, { kind: "pipe", type: i2.DateDistancePipe, name: "dateDistance" }] });
3092
3237
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: DbxDateTimeFieldComponent, decorators: [{
3093
3238
  type: Component,
3094
- args: [{ template: "<div class=\"dbx-datetime-field\" fxLayout=\"row wrap\" fxLayout.xs=\"column wrap\" fxLayoutAlign=\"space-evenly stretch\">\n <!-- Date -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"dateOnly ? '100' : '50'\" *ngIf=\"showDateInput\">\n <ng-container *ngTemplateOutlet=\"dateInputTemplate\"></ng-container>\n </div>\n <!-- Time -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"showDateInput ? '50' : '100'\">\n <ng-container *ngIf=\"showTimeInput$ | async\">\n <ng-container *ngTemplateOutlet=\"timeMenuAndInputTemplate\"></ng-container>\n </ng-container>\n <div class=\"add-time-button-wrapper\" *ngIf=\"showAddTime$ | async\">\n <button mat-button class=\"add-time-button\" ngClass.lt-sm=\"add-time-button-full\" (click)=\"addTime()\">\n <mat-icon>timer</mat-icon>\n Add Time\n </button>\n </div>\n </div>\n <div *ngIf=\"!hideDateHint\" class=\"dbx-datetime-row dbx-datetime-hint-row\" fxFlex=\"100\">\n <div class=\"dbx-hint\" [ngSwitch]=\"fullDay$ | async\">\n <small *ngSwitchCase=\"true\">\n <b class=\"dbx-ok\">All Day</b>\n {{ dateValue$ | async | date: 'fullDate' }} ({{ dateValue$ | async | dateDistance }})\n </small>\n <small *ngSwitchCase=\"false\">\n <ng-container *ngIf=\"value$ | async\">\n <b class=\"dbx-ok\">At</b>\n {{ displayValue$ | async | date: 'medium' }} ({{ displayValue$ | async | timeDistance }})\n </ng-container>\n </small>\n </div>\n </div>\n</div>\n\n<!-- Date Input Template -->\n<ng-template #dateInputTemplate>\n <button mat-icon-button (click)=\"picker.open()\" [disabled]=\"disabled\">\n <mat-icon>calendar_today</mat-icon>\n </button>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>Date</mat-label>\n <input #dateInput matInput [matDatepicker]=\"picker\" (dateChange)=\"datePicked($event)\" [value]=\"dateValue$ | async\" />\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n</ng-template>\n\n<!-- Time Menu/Input Template -->\n<ng-template #timeMenuAndInputTemplate>\n <button mat-icon-button [matMenuTriggerFor]=\"timemenu\" aria-label=\"opens the time menu\" [disabled]=\"disabled\">\n <mat-icon>timer</mat-icon>\n </button>\n <mat-menu #timemenu=\"matMenu\">\n <ng-container *ngIf=\"timeMode === 'optional'\">\n <button mat-menu-item (click)=\"removeTime()\">\n <span>Remove Time</span>\n </button>\n <mat-divider></mat-divider>\n </ng-container>\n <button mat-menu-item (click)=\"setLogicalTime('now')\">\n <span>Now</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00AM')\">\n <span>Midnight</span>\n </button>\n <button mat-menu-item (click)=\"setTime('6:00AM')\">\n <span>6:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('8:00AM')\">\n <span>8:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('10:00AM')\">\n <span>10:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00PM')\">\n <span>Noon</span>\n </button>\n <button mat-menu-item (click)=\"setTime('2:00PM')\">\n <span>2:00PM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('5:00PM')\">\n <span>5:00PM</span>\n </button>\n </mat-menu>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>Time</mat-label>\n <input #timeInput matInput [formControl]=\"timeInputCtrl\" (focus)=\"focusTime()\" (focusout)=\"focusOutTime()\" (keydown)=\"keydownOnInput($event)\" />\n </mat-form-field>\n</ng-template>\n" }]
3239
+ args: [{ template: "<div class=\"dbx-datetime-field\" fxLayout=\"row wrap\" fxLayout.xs=\"column wrap\" fxLayoutAlign=\"space-evenly stretch\">\n <!-- Date -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"dateOnly ? '100' : '50'\" *ngIf=\"showDateInput\">\n <ng-container *ngTemplateOutlet=\"dateInputTemplate\"></ng-container>\n </div>\n <!-- Time -->\n <div class=\"dbx-datetime-row\" fxFlex.lt-sm=\"100\" [fxFlex]=\"showDateInput ? '50' : '100'\">\n <ng-container *ngIf=\"showTimeInput$ | async\">\n <ng-container *ngTemplateOutlet=\"timeMenuAndInputTemplate\"></ng-container>\n </ng-container>\n <div class=\"add-time-button-wrapper\" *ngIf=\"showAddTime$ | async\">\n <button mat-button class=\"add-time-button\" ngClass.lt-sm=\"add-time-button-full\" (click)=\"addTime()\">\n <mat-icon>timer</mat-icon>\n Add Time\n </button>\n </div>\n </div>\n <div *ngIf=\"!hideDateHint\" class=\"dbx-datetime-row dbx-datetime-hint-row\" fxFlex=\"100\">\n <div class=\"dbx-hint\" [ngSwitch]=\"fullDay$ | async\">\n <small *ngSwitchCase=\"true\">\n <b class=\"dbx-ok\">All Day</b>\n {{ displayValue$ | async | date: 'fullDate' }} ({{ displayValue$ | async | dateDistance }})\n </small>\n <small *ngSwitchCase=\"false\">\n <ng-container *ngIf=\"value$ | async\">\n <b class=\"dbx-ok\">At</b>\n {{ displayValue$ | async | date: 'medium' }} ({{ displayValue$ | async | timeDistance }})\n </ng-container>\n </small>\n </div>\n </div>\n</div>\n\n<!-- Date Input Template -->\n<ng-template #dateInputTemplate>\n <button mat-icon-button (click)=\"picker.open()\" [disabled]=\"disabled\">\n <mat-icon>calendar_today</mat-icon>\n </button>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>{{ dateLabel }}</mat-label>\n <input #dateInput matInput [min]=\"dateInputMin$ | async\" [max]=\"dateInputMax$ | async\" [matDatepicker]=\"picker\" (dateChange)=\"datePicked($event)\" [value]=\"dateValue$ | async\" (keydown)=\"keydownOnDateInput($event)\" />\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n</ng-template>\n\n<!-- Time Menu/Input Template -->\n<ng-template #timeMenuAndInputTemplate>\n <button mat-icon-button [matMenuTriggerFor]=\"timemenu\" aria-label=\"opens the time menu\" [disabled]=\"disabled\">\n <mat-icon>timer</mat-icon>\n </button>\n <mat-menu #timemenu=\"matMenu\">\n <ng-container *ngIf=\"timeMode === 'optional'\">\n <button mat-menu-item (click)=\"removeTime()\">\n <span>Remove Time</span>\n </button>\n <mat-divider></mat-divider>\n </ng-container>\n <button mat-menu-item (click)=\"setLogicalTime('now')\">\n <span>Now</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00AM')\">\n <span>Midnight</span>\n </button>\n <button mat-menu-item (click)=\"setTime('6:00AM')\">\n <span>6:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('8:00AM')\">\n <span>8:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('10:00AM')\">\n <span>10:00AM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('12:00PM')\">\n <span>Noon</span>\n </button>\n <button mat-menu-item (click)=\"setTime('2:00PM')\">\n <span>2:00PM</span>\n </button>\n <button mat-menu-item (click)=\"setTime('5:00PM')\">\n <span>5:00PM</span>\n </button>\n </mat-menu>\n <mat-form-field class=\"dbx-datetime-row-field\">\n <mat-label>{{ timeLabel }}</mat-label>\n <input #timeInput matInput [formControl]=\"timeInputCtrl\" (focus)=\"focusTime()\" (focusout)=\"focusOutTime()\" (keydown)=\"keydownOnTimeInput($event)\" />\n </mat-form-field>\n</ng-template>\n" }]
3095
3240
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
3096
3241
 
3097
3242
  class DbxFormFormlyDateFieldModule {
@@ -3166,20 +3311,35 @@ function timeOnlyField(config = {}) {
3166
3311
  return dateTimeField(Object.assign(Object.assign({}, config), { timeMode: DbxDateTimeFieldTimeMode.REQUIRED, timeOnly: true }));
3167
3312
  }
3168
3313
  function dateTimeField(config = {}) {
3169
- const { key = 'date', timeMode = DbxDateTimeFieldTimeMode.REQUIRED, valueMode, fullDayInUTC, fullDayFieldName, getConfigObs, hideDateHint, timeOnly = false } = config;
3170
- const fieldConfig = formlyField(Object.assign({ key, type: 'datetime' }, propsForFieldConfig(config, {
3314
+ const { key = 'date', dateLabel, timeLabel, timeMode = DbxDateTimeFieldTimeMode.REQUIRED, valueMode, fullDayInUTC, fullDayFieldName, getConfigObs, getSyncFieldsObs, hideDateHint, timeOnly = false } = config;
3315
+ const fieldConfig = formlyField(Object.assign({ key, type: 'datetime' }, propsAndConfigForFieldConfig(config, {
3316
+ dateLabel,
3317
+ timeLabel,
3171
3318
  valueMode,
3172
3319
  timeOnly,
3173
3320
  timeMode: timeOnly ? DbxDateTimeFieldTimeMode.REQUIRED : timeMode,
3174
3321
  fullDayFieldName,
3175
3322
  fullDayInUTC,
3176
3323
  hideDateHint,
3177
- getConfigObs
3324
+ getConfigObs,
3325
+ getSyncFieldsObs
3178
3326
  })));
3179
3327
  return styleWrapper(fieldConfig, {
3180
3328
  classGetter: 'dbx-mat-form-field-disable-underline'
3181
3329
  });
3182
3330
  }
3331
+ function dateRangeField(config = {}) {
3332
+ var _a, _b;
3333
+ const { start, end } = config;
3334
+ const startFieldKey = (_a = start === null || start === void 0 ? void 0 : start.key) !== null && _a !== void 0 ? _a : 'start';
3335
+ const endFieldKey = (_b = end === null || end === void 0 ? void 0 : end.key) !== null && _b !== void 0 ? _b : 'end';
3336
+ const startField = dateTimeField(Object.assign(Object.assign({ dateLabel: 'Start', timeMode: DbxDateTimeFieldTimeMode.NONE, getSyncFieldsObs: () => of([{ syncWith: endFieldKey, syncType: 'after' }]) }, start), { key: startFieldKey }));
3337
+ const endField = dateTimeField(Object.assign(Object.assign({ dateLabel: 'End', timeMode: DbxDateTimeFieldTimeMode.NONE, getSyncFieldsObs: () => of([{ syncWith: startFieldKey, syncType: 'before' }]) }, end), { key: endFieldKey }));
3338
+ return {
3339
+ key: undefined,
3340
+ fieldGroup: [flexLayoutWrapper([startField, endField], { size: 1, relative: true })]
3341
+ };
3342
+ }
3183
3343
 
3184
3344
  function isTruthy() {
3185
3345
  return (control) => {
@@ -3248,6 +3408,12 @@ function isInRange(min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER)
3248
3408
  };
3249
3409
  }
3250
3410
  const IS_DIVISIBLE_BY_VALIDATION_KEY = 'isDivisibleBy';
3411
+ /**
3412
+ * Angular Form ValidationFn for checking isDivisibleBy the input divisor.
3413
+ *
3414
+ * @param divisor
3415
+ * @returns
3416
+ */
3251
3417
  function isDivisibleBy(divisor) {
3252
3418
  if (divisor === 0) {
3253
3419
  throw new Error('Divisior must be greater than zero.');
@@ -3298,20 +3464,33 @@ function fieldValueIsAvailableValidator(config) {
3298
3464
  })), first());
3299
3465
  }
3300
3466
 
3467
+ function numberFieldTransformParser(config) {
3468
+ const { parsers: inputParsers, transform } = config;
3469
+ let parsers;
3470
+ if (inputParsers) {
3471
+ parsers = inputParsers;
3472
+ }
3473
+ if (transform) {
3474
+ const transformParser = transformNumberFunction(transform);
3475
+ parsers = concatArrays([transformParser], parsers);
3476
+ }
3477
+ return parsers;
3478
+ }
3301
3479
  function numberField(config) {
3302
3480
  const { key, min, max, step, enforceStep, inputType: type = 'number' } = config;
3481
+ const parsers = numberFieldTransformParser(config);
3303
3482
  const validators = [];
3304
3483
  if (step && enforceStep) {
3305
3484
  validators.push(isDivisibleBy(step));
3306
3485
  }
3307
- return formlyField(Object.assign(Object.assign({ key, type: 'input' }, propsForFieldConfig(config, {
3486
+ return formlyField(Object.assign(Object.assign(Object.assign({ key, type: 'input' }, propsAndConfigForFieldConfig(config, {
3308
3487
  type,
3309
3488
  min,
3310
3489
  max,
3311
3490
  step
3312
3491
  })), validatorsForFieldConfig({
3313
3492
  validators
3314
- })));
3493
+ })), { parsers }));
3315
3494
  }
3316
3495
 
3317
3496
  class DbxFormFormlyNumberFieldModule {
@@ -3397,28 +3576,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
3397
3576
  }]
3398
3577
  }] });
3399
3578
 
3579
+ function textFieldTransformParser(config) {
3580
+ const { parsers: inputParsers, transform } = config;
3581
+ let parsers;
3582
+ if (inputParsers) {
3583
+ parsers = inputParsers;
3584
+ }
3585
+ if (transform) {
3586
+ const transformParser = transformStringFunction(transform);
3587
+ parsers = concatArrays([transformParser], parsers);
3588
+ }
3589
+ return parsers;
3590
+ }
3400
3591
  function textField(config) {
3401
- const { key, pattern, minLength, maxLength, inputType: type = 'text' } = config;
3402
- return formlyField(Object.assign({ key, type: 'input' }, propsForFieldConfig(config, {
3592
+ const { transform, key, pattern, minLength, maxLength, inputType: type = 'text' } = config;
3593
+ const parsers = textFieldTransformParser(config);
3594
+ return formlyField(Object.assign(Object.assign({ key, type: 'input' }, propsAndConfigForFieldConfig(config, {
3403
3595
  type,
3404
3596
  minLength,
3405
3597
  maxLength,
3406
3598
  pattern
3407
- })));
3599
+ })), { parsers }));
3408
3600
  }
3409
3601
  function textAreaField(config) {
3410
3602
  const { key, rows = 3, pattern, minLength, maxLength } = config;
3411
- return formlyField(Object.assign({ key, type: 'textarea' }, propsForFieldConfig(config, {
3603
+ const parsers = textFieldTransformParser(config);
3604
+ return formlyField(Object.assign(Object.assign({ key, type: 'textarea' }, propsAndConfigForFieldConfig(config, {
3412
3605
  rows,
3413
3606
  minLength,
3414
3607
  maxLength,
3415
3608
  pattern
3416
- })));
3609
+ })), { parsers }));
3417
3610
  }
3418
3611
 
3419
3612
  function phoneField(config = {}) {
3420
3613
  const { key = 'phone', preferredCountries, onlyCountries } = config;
3421
- const fieldConfig = formlyField(Object.assign({ key, type: 'intphone' }, propsForFieldConfig(config, {
3614
+ const fieldConfig = formlyField(Object.assign({ key, type: 'intphone' }, propsAndConfigForFieldConfig(config, {
3422
3615
  preferredCountries,
3423
3616
  onlyCountries
3424
3617
  })));
@@ -3502,7 +3695,9 @@ function stateField(config = {}) {
3502
3695
  pattern,
3503
3696
  autocomplete,
3504
3697
  required,
3505
- maxLength }));
3698
+ maxLength, transform: {
3699
+ toUppercase: true
3700
+ } }));
3506
3701
  }
3507
3702
  function countryField(config = {}) {
3508
3703
  const { key = 'country', placeholder = '', label = 'Country', autocomplete = 'country', maxLength = ADDRESS_COUNTRY_MAX_LENGTH, required = false } = config;
@@ -4237,5 +4432,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
4237
4432
  * Generated bundle index. Do not edit.
4238
4433
  */
4239
4434
 
4240
- export { APP_ACTION_FORM_DISABLED_KEY, AUTO_TOUCH_WRAPPER_KEY, AbstractAsyncFormlyFormDirective, AbstractConfigAsyncFormlyFormDirective, AbstractDbxPickableItemFieldDirective, AbstractDbxSearchableFieldDisplayDirective, AbstractDbxSearchableValueFieldDirective, AbstractFormExpandableSectionWrapperDirective, AbstractFormlyFormDirective, AbstractSyncFormlyFormDirective, AutoTouchFieldWrapperComponent, ChecklistItemFieldDataSetBuilder, DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN, DEFAULT_FORM_DISABLED_KEY, DEFAULT_HAS_VALUE_FN, DEFAULT_LAT_LNG_TEXT_FIELD_PATTERN_MESSAGE, DEFAULT_LAT_LNG_TEXT_FIELD_PLACEHOLDER, DEFAULT_PREFERRED_COUNTRIES, DISPLAY_FOR_TIMEZONE_STRING_VALUE, DbxActionFormDirective, DbxActionFormSafetyDirective, DbxChecklistItemContentComponent, DbxChecklistItemFieldComponent, DbxDateTimeFieldComponent, DbxDateTimeFieldTimeMode, DbxDateTimeValueMode, DbxDefaultChecklistItemFieldDisplayComponent, DbxDefaultSearchableFieldDisplayComponent, DbxForm, DbxFormActionModule, DbxFormActionTransitionModule, DbxFormComponentFieldComponent, DbxFormExpandWrapperComponent, DbxFormExtensionModule, DbxFormFlexWrapperComponent, DbxFormFormlyArrayFieldModule, DbxFormFormlyBooleanFieldModule, DbxFormFormlyChecklistItemFieldModule, DbxFormFormlyComponentFieldModule, DbxFormFormlyDateFieldModule, DbxFormFormlyFieldModule, DbxFormFormlyNumberFieldModule, DbxFormFormlyPhoneFieldModule, DbxFormFormlyPickableFieldModule, DbxFormFormlySearchableFieldModule, DbxFormFormlySelectionModule, DbxFormFormlyTextEditorFieldModule, DbxFormFormlyTextFieldModule, DbxFormFormlyValueModule, DbxFormFormlyWrapperModule, DbxFormInfoWrapperComponent, DbxFormIoModule, DbxFormLayoutModule, DbxFormLoadingSourceDirective, DbxFormModule, DbxFormRepeatArrayTypeComponent, DbxFormSectionWrapperComponent, DbxFormSourceDirective, DbxFormSpacerComponent, DbxFormState, DbxFormSubsectionWrapperComponent, DbxFormToggleWrapperComponent, DbxFormValueChangesDirective, DbxFormWorkingWrapperComponent, DbxFormlyContext, DbxFormlyFieldsContextDirective, DbxFormlyFormComponent, DbxFormlyModule, DbxMutableForm, DbxPhoneFieldComponent, DbxPickableChipListFieldComponent, DbxPickableListFieldComponent, DbxPickableListFieldItemListComponent, DbxPickableListFieldItemListViewComponent, DbxPickableListFieldItemListViewItemComponent, DbxSearchableChipFieldComponent, DbxSearchableFieldAutocompleteItemComponent, DbxSearchableTextFieldComponent, DbxTextEditorFieldComponent, EXPANDABLE_WRAPPER_KEY, FIELD_VALUES_ARE_EQUAL_VALIDATION_KEY, FIELD_VALUE_IS_AVAILABLE_ERROR_VALIDATION_KEY, FIELD_VALUE_IS_AVAILABLE_VALIDATION_KEY, FLEX_WRAPPER_KEY, INFO_WRAPPER_KEY, INVALID_PHONE_NUMBER_MESSAGE, IS_DIVISIBLE_BY_VALIDATION_KEY, LABEL_STRING_MAX_LENGTH, MAX_LENGTH_VALIDATION_MESSAGE, MAX_VALIDATION_MESSAGE, MIN_LENGTH_VALIDATION_MESSAGE, MIN_VALIDATION_MESSAGE, PHONE_LABEL_MAX_LENGTH, REQUIRED_VALIDATION_MESSAGE, SEARCH_STRING_MAX_LENGTH, SECTION_WRAPPER_KEY, STYLE_WRAPPER_KEY, SUBSECTION_WRAPPER_KEY, TAKE_NEXT_UPCOMING_TIME_CONFIG_OBS, TOGGLE_WRAPPER_KEY, WORKING_WRAPPER_KEY, addWrapperToFormlyFieldConfig, addressField, addressFormlyFields, addressLineField, addressListField, autoTouchWrapper, checkIsFieldFlexLayoutGroupFieldConfig, checkboxField, checklistItemField, chipTextField, cityField, componentField, countryField, dateTimeField, dbxDateTimeInputValueParseFactory, dbxDateTimeOutputValueFactory, dbxFormSourceObservable, defaultValidationMessages, disableFormlyFieldAutofillAttributes, emailField, expandWrapper, fieldValueIsAvailableValidator, fieldValuesAreEqualValidator, filterPartialPotentialFieldConfigValuesFromObject, filterPickableItemFieldValuesByLabel, filterPickableItemFieldValuesByLabelFilterFunction, flexLayoutWrapper, formlyField, hiddenField, infoWrapper, isDivisibleBy, isDomain, isInRange, isTruthy, latLngTextField, makeMetaFilterSearchableFieldValueDisplayFn, maxLengthValidationMessage, maxValidationMessage, mergePropsValueObjects, minLengthValidationMessage, minValidationMessage, nameField, numberField, partialPotentialFieldConfigKeys, partialPotentialFieldConfigKeysFilter, phoneAndLabelSectionField, phoneField, phoneListField, pickableItemChipField, pickableItemListField, propsForFieldConfig, propsValueForFieldConfig, provideDbxForm, provideDbxMutableForm, provideFormlyContext, repeatArrayField, searchableChipField, searchableStringChipField, searchableTextField, sectionWrapper, sortPickableItemsByLabel, stateField, styleWrapper, subsectionWrapper, textAreaField, textEditorField, textField, textIsAvailableField, textPasswordField, textPasswordWithVerifyFieldGroup, textVerifyPasswordField, timeOnlyField, timezoneStringField, timezoneStringSearchFunction, toggleField, toggleWrapper, usernamePasswordLoginFields, validatorsForFieldConfig, valueSelectionField, workingWrapper, wrappedPhoneAndLabelField, zipCodeField };
4435
+ export { APP_ACTION_FORM_DISABLED_KEY, AUTO_TOUCH_WRAPPER_KEY, AbstractAsyncFormlyFormDirective, AbstractConfigAsyncFormlyFormDirective, AbstractDbxPickableItemFieldDirective, AbstractDbxSearchableFieldDisplayDirective, AbstractDbxSearchableValueFieldDirective, AbstractFormExpandableSectionWrapperDirective, AbstractFormlyFormDirective, AbstractSyncFormlyFormDirective, AutoTouchFieldWrapperComponent, ChecklistItemFieldDataSetBuilder, DBX_SEARCHABLE_FIELD_COMPONENT_DATA_TOKEN, DEFAULT_FORM_DISABLED_KEY, DEFAULT_HAS_VALUE_FN, DEFAULT_LAT_LNG_TEXT_FIELD_PATTERN_MESSAGE, DEFAULT_LAT_LNG_TEXT_FIELD_PLACEHOLDER, DEFAULT_PREFERRED_COUNTRIES, DISPLAY_FOR_TIMEZONE_STRING_VALUE, DbxActionFormDirective, DbxActionFormSafetyDirective, DbxChecklistItemContentComponent, DbxChecklistItemFieldComponent, DbxDateTimeFieldComponent, DbxDateTimeFieldTimeMode, DbxDateTimeValueMode, DbxDefaultChecklistItemFieldDisplayComponent, DbxDefaultSearchableFieldDisplayComponent, DbxForm, DbxFormActionModule, DbxFormActionTransitionModule, DbxFormComponentFieldComponent, DbxFormExpandWrapperComponent, DbxFormExtensionModule, DbxFormFlexWrapperComponent, DbxFormFormlyArrayFieldModule, DbxFormFormlyBooleanFieldModule, DbxFormFormlyChecklistItemFieldModule, DbxFormFormlyComponentFieldModule, DbxFormFormlyDateFieldModule, DbxFormFormlyFieldModule, DbxFormFormlyNumberFieldModule, DbxFormFormlyPhoneFieldModule, DbxFormFormlyPickableFieldModule, DbxFormFormlySearchableFieldModule, DbxFormFormlySelectionModule, DbxFormFormlyTextEditorFieldModule, DbxFormFormlyTextFieldModule, DbxFormFormlyValueModule, DbxFormFormlyWrapperModule, DbxFormInfoWrapperComponent, DbxFormIoModule, DbxFormLayoutModule, DbxFormLoadingSourceDirective, DbxFormModule, DbxFormRepeatArrayTypeComponent, DbxFormSectionWrapperComponent, DbxFormSourceDirective, DbxFormSpacerComponent, DbxFormState, DbxFormSubsectionWrapperComponent, DbxFormToggleWrapperComponent, DbxFormValueChangesDirective, DbxFormWorkingWrapperComponent, DbxFormlyContext, DbxFormlyFieldsContextDirective, DbxFormlyFormComponent, DbxFormlyModule, DbxMutableForm, DbxPhoneFieldComponent, DbxPickableChipListFieldComponent, DbxPickableListFieldComponent, DbxPickableListFieldItemListComponent, DbxPickableListFieldItemListViewComponent, DbxPickableListFieldItemListViewItemComponent, DbxSearchableChipFieldComponent, DbxSearchableFieldAutocompleteItemComponent, DbxSearchableTextFieldComponent, DbxTextEditorFieldComponent, EXPANDABLE_WRAPPER_KEY, FIELD_VALUES_ARE_EQUAL_VALIDATION_KEY, FIELD_VALUE_IS_AVAILABLE_ERROR_VALIDATION_KEY, FIELD_VALUE_IS_AVAILABLE_VALIDATION_KEY, FLEX_WRAPPER_KEY, INFO_WRAPPER_KEY, INVALID_PHONE_NUMBER_MESSAGE, IS_DIVISIBLE_BY_VALIDATION_KEY, LABEL_STRING_MAX_LENGTH, MAX_LENGTH_VALIDATION_MESSAGE, MAX_VALIDATION_MESSAGE, MIN_LENGTH_VALIDATION_MESSAGE, MIN_VALIDATION_MESSAGE, PHONE_LABEL_MAX_LENGTH, REQUIRED_VALIDATION_MESSAGE, SEARCH_STRING_MAX_LENGTH, SECTION_WRAPPER_KEY, STYLE_WRAPPER_KEY, SUBSECTION_WRAPPER_KEY, TAKE_NEXT_UPCOMING_TIME_CONFIG_OBS, TOGGLE_WRAPPER_KEY, WORKING_WRAPPER_KEY, addWrapperToFormlyFieldConfig, addressField, addressFormlyFields, addressLineField, addressListField, autoTouchWrapper, checkIsFieldFlexLayoutGroupFieldConfig, checkboxField, checklistItemField, chipTextField, cityField, componentField, countryField, dateRangeField, dateTimeField, dbxDateTimeInputValueParseFactory, dbxDateTimeOutputValueFactory, dbxFormSourceObservable, dbxFormSourceObservableFromStream, defaultValidationMessages, disableFormlyFieldAutofillAttributes, emailField, expandWrapper, fieldValueIsAvailableValidator, fieldValuesAreEqualValidator, filterPartialPotentialFieldConfigValuesFromObject, filterPickableItemFieldValuesByLabel, filterPickableItemFieldValuesByLabelFilterFunction, flexLayoutWrapper, formlyField, hiddenField, infoWrapper, isDivisibleBy, isDomain, isInRange, isTruthy, latLngTextField, makeMetaFilterSearchableFieldValueDisplayFn, maxLengthValidationMessage, maxValidationMessage, mergePropsValueObjects, minLengthValidationMessage, minValidationMessage, nameField, numberField, numberFieldTransformParser, partialPotentialFieldConfigKeys, partialPotentialFieldConfigKeysFilter, phoneAndLabelSectionField, phoneField, phoneListField, pickableItemChipField, pickableItemListField, propsAndConfigForFieldConfig, propsForFieldConfig, propsValueForFieldConfig, provideDbxForm, provideDbxMutableForm, provideFormlyContext, repeatArrayField, searchableChipField, searchableStringChipField, searchableTextField, sectionWrapper, sortPickableItemsByLabel, stateField, styleWrapper, subsectionWrapper, syncConfigValueObs, textAreaField, textEditorField, textField, textFieldTransformParser, textIsAvailableField, textPasswordField, textPasswordWithVerifyFieldGroup, textVerifyPasswordField, timeOnlyField, timezoneStringField, timezoneStringSearchFunction, toggleField, toggleWrapper, usernamePasswordLoginFields, validatorsForFieldConfig, valueSelectionField, workingWrapper, wrappedPhoneAndLabelField, zipCodeField };
4241
4436
  //# sourceMappingURL=dereekb-dbx-form.mjs.map