@skyux/datetime 5.6.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/bundles/skyux-datetime.umd.js +488 -162
  2. package/documentation.json +696 -835
  3. package/esm2015/lib/modules/date-pipe/date-format-utility.js +0 -2
  4. package/esm2015/lib/modules/date-pipe/date-format-utility.js.map +1 -1
  5. package/esm2015/lib/modules/date-range-picker/date-range-picker.component.js +47 -58
  6. package/esm2015/lib/modules/date-range-picker/date-range-picker.component.js.map +1 -1
  7. package/esm2015/lib/modules/date-range-picker/types/date-range-relative-value.js +0 -3
  8. package/esm2015/lib/modules/date-range-picker/types/date-range-relative-value.js.map +1 -1
  9. package/esm2015/lib/modules/datepicker/datepicker-calendar-inner.component.js.map +1 -1
  10. package/esm2015/lib/modules/datepicker/datepicker-input-fuzzy.directive.js +60 -50
  11. package/esm2015/lib/modules/datepicker/datepicker-input-fuzzy.directive.js.map +1 -1
  12. package/esm2015/lib/modules/datepicker/datepicker-input.directive.js +51 -40
  13. package/esm2015/lib/modules/datepicker/datepicker-input.directive.js.map +1 -1
  14. package/esm2015/lib/modules/shared/sky-datetime-resources.module.js +1 -1
  15. package/esm2015/lib/modules/shared/sky-datetime-resources.module.js.map +1 -1
  16. package/esm2015/lib/modules/timepicker/timepicker.component.js +6 -6
  17. package/esm2015/lib/modules/timepicker/timepicker.component.js.map +1 -1
  18. package/esm2015/lib/modules/timepicker/timepicker.directive.js +4 -5
  19. package/esm2015/lib/modules/timepicker/timepicker.directive.js.map +1 -1
  20. package/fesm2015/skyux-datetime.js +168 -164
  21. package/fesm2015/skyux-datetime.js.map +1 -1
  22. package/lib/modules/date-pipe/date-format-utility.d.ts +0 -1
  23. package/lib/modules/date-range-picker/date-range-picker.component.d.ts +4 -3
  24. package/lib/modules/date-range-picker/types/date-range-relative-value.d.ts +0 -1
  25. package/lib/modules/datepicker/datepicker-calendar-inner.component.d.ts +16 -13
  26. package/lib/modules/datepicker/datepicker-input-fuzzy.directive.d.ts +6 -1
  27. package/lib/modules/datepicker/datepicker-input.directive.d.ts +6 -2
  28. package/lib/modules/shared/sky-datetime-resources.module.d.ts +1 -1
  29. package/package.json +18 -16
@@ -22,8 +22,6 @@ import { SkyThemeModule } from '@skyux/theme';
22
22
 
23
23
  // This class is mostly ported from the Angular 4.x DatePipe in order to maintain the old
24
24
  class SkyDateFormatUtility {
25
- /* istanbul ignore next */
26
- constructor() { }
27
25
  static format(locale, value, pattern) {
28
26
  let date;
29
27
  if (isBlank(value) || value !== value) {
@@ -124,7 +122,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
124
122
  /**
125
123
  * NOTICE: DO NOT MODIFY THIS FILE!
126
124
  * The contents of this file were automatically generated by
127
- * the 'ng generate @skyux/i18n:lib-resources-module modules/shared/sky-datetime' schematic.
125
+ * the 'ng generate @skyux/i18n:lib-resources-module lib/modules/shared/sky-datetime' schematic.
128
126
  * To update this file, simply rerun the command.
129
127
  */
130
128
  const RESOURCES = {
@@ -2266,14 +2264,15 @@ class SkyFuzzyDatepickerInputDirective {
2266
2264
  */
2267
2265
  this.skyDatepickerNoValidate = false;
2268
2266
  this.dateFormatter = new SkyDateFormatter();
2269
- this.isFirstChange = true;
2270
2267
  this.ngUnsubscribe = new Subject();
2271
2268
  this._futureDisabled = false;
2272
2269
  this._disabled = false;
2273
2270
  this._yearRequired = false;
2271
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2274
2272
  this.onChange = (_) => { };
2275
- /*istanbul ignore next */
2273
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2276
2274
  this.onTouched = () => { };
2275
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2277
2276
  this.onValidatorChange = () => { };
2278
2277
  this.localeProvider
2279
2278
  .getLocaleInfo()
@@ -2363,7 +2362,9 @@ class SkyFuzzyDatepickerInputDirective {
2363
2362
  * through the `ngModel` attribute specified on the `input` element.
2364
2363
  * @required
2365
2364
  */
2366
- set skyFuzzyDatepickerInput(value) { }
2365
+ set skyFuzzyDatepickerInput(value) {
2366
+ // TODO: Remove this property in a future version of SKY UX.
2367
+ }
2367
2368
  /**
2368
2369
  * Specifies the starting day of the week in the calendar, where `0` sets the starting day
2369
2370
  * to Sunday. Place this attribute on the `input` element to override the default
@@ -2393,50 +2394,7 @@ class SkyFuzzyDatepickerInputDirective {
2393
2394
  return this._value;
2394
2395
  }
2395
2396
  set value(value) {
2396
- let fuzzyDate;
2397
- let fuzzyMoment;
2398
- let dateValue;
2399
- let formattedDate;
2400
- if (value instanceof Date) {
2401
- dateValue = value;
2402
- formattedDate = this.dateFormatter.format(value, this.dateFormat);
2403
- fuzzyDate = this.fuzzyDateService.getFuzzyDateFromSelectedDate(value, this.dateFormat);
2404
- }
2405
- else if (typeof value === 'string') {
2406
- fuzzyDate = this.fuzzyDateService.getFuzzyDateFromString(value, this.dateFormat);
2407
- formattedDate = this.fuzzyDateService.format(fuzzyDate, this.dateFormat, this.locale);
2408
- if (!formattedDate) {
2409
- formattedDate = value;
2410
- }
2411
- fuzzyMoment = this.fuzzyDateService.getMomentFromFuzzyDate(fuzzyDate);
2412
- if (fuzzyMoment) {
2413
- dateValue = fuzzyMoment.toDate();
2414
- }
2415
- }
2416
- else {
2417
- fuzzyDate = value;
2418
- formattedDate = this.fuzzyDateService.format(fuzzyDate, this.dateFormat, this.locale);
2419
- fuzzyMoment = this.fuzzyDateService.getMomentFromFuzzyDate(fuzzyDate);
2420
- if (fuzzyMoment) {
2421
- dateValue = fuzzyMoment.toDate();
2422
- }
2423
- }
2424
- const areFuzzyDatesEqual = this.fuzzyDatesEqual(this._value, fuzzyDate);
2425
- const isNewValue = fuzzyDate !== this._value || !areFuzzyDatesEqual;
2426
- this._value = fuzzyDate || value;
2427
- if (isNewValue) {
2428
- this.onChange(this._value);
2429
- // Do not mark the field as "dirty"
2430
- // if the field has been initialized with a value.
2431
- if (this.isFirstChange && this.control) {
2432
- this.control.markAsPristine();
2433
- }
2434
- if (this.isFirstChange && this._value) {
2435
- this.isFirstChange = false;
2436
- }
2437
- this.datepickerComponent.selectedDate = dateValue;
2438
- }
2439
- this.setInputElementValue(formattedDate || '');
2397
+ this.updateValue(value);
2440
2398
  }
2441
2399
  ngOnInit() {
2442
2400
  if (this.yearRequired) {
@@ -2465,7 +2423,6 @@ class SkyFuzzyDatepickerInputDirective {
2465
2423
  this.datepickerComponent.dateChange
2466
2424
  .pipe(distinctUntilChanged(), takeUntil(this.ngUnsubscribe))
2467
2425
  .subscribe((value) => {
2468
- this.isFirstChange = false;
2469
2426
  this.value = value;
2470
2427
  this.onTouched();
2471
2428
  });
@@ -2504,7 +2461,7 @@ class SkyFuzzyDatepickerInputDirective {
2504
2461
  this.control.markAsDirty();
2505
2462
  }
2506
2463
  writeValue(value) {
2507
- this.value = value;
2464
+ this.updateValue(value, false);
2508
2465
  }
2509
2466
  validate(control) {
2510
2467
  if (!this.control) {
@@ -2600,7 +2557,6 @@ class SkyFuzzyDatepickerInputDirective {
2600
2557
  this.onValueChange(this.elementRef.nativeElement.value);
2601
2558
  }
2602
2559
  onValueChange(newValue) {
2603
- this.isFirstChange = false;
2604
2560
  this.value = newValue;
2605
2561
  }
2606
2562
  setInputElementValue(value) {
@@ -2635,6 +2591,58 @@ class SkyFuzzyDatepickerInputDirective {
2635
2591
  ((!dateA.month && !dateB.month) || dateA.month === dateB.month) &&
2636
2592
  ((!dateA.year && !dateB.year) || dateA.year === dateB.year));
2637
2593
  }
2594
+ /**
2595
+ * Update the value of the form control and input element
2596
+ * @param emitEvent Denotes if we emit an event to the consumer's form control. We do not want to do this if the value is being updated via a `setValue` call or a `patchValue` call as this is already handled by Angular.
2597
+ * In these cases we do not want to fire `onChange` as it will cause extra `valueChange` and `statusChange` events and the status of the form should not be affected by these changes.
2598
+ */
2599
+ updateValue(value, emitEvent = true) {
2600
+ var _a;
2601
+ if (this._value === value) {
2602
+ return;
2603
+ }
2604
+ let fuzzyDate;
2605
+ let fuzzyMoment;
2606
+ let dateValue;
2607
+ let formattedDate;
2608
+ if (value instanceof Date) {
2609
+ dateValue = value;
2610
+ formattedDate = this.dateFormatter.format(value, this.dateFormat);
2611
+ fuzzyDate = this.fuzzyDateService.getFuzzyDateFromSelectedDate(value, this.dateFormat);
2612
+ }
2613
+ else if (typeof value === 'string') {
2614
+ fuzzyDate = this.fuzzyDateService.getFuzzyDateFromString(value, this.dateFormat);
2615
+ formattedDate = this.fuzzyDateService.format(fuzzyDate, this.dateFormat, this.locale);
2616
+ if (!formattedDate) {
2617
+ formattedDate = value;
2618
+ }
2619
+ fuzzyMoment = this.fuzzyDateService.getMomentFromFuzzyDate(fuzzyDate);
2620
+ if (fuzzyMoment) {
2621
+ dateValue = fuzzyMoment.toDate();
2622
+ }
2623
+ }
2624
+ else {
2625
+ fuzzyDate = value;
2626
+ formattedDate = this.fuzzyDateService.format(fuzzyDate, this.dateFormat, this.locale);
2627
+ fuzzyMoment = this.fuzzyDateService.getMomentFromFuzzyDate(fuzzyDate);
2628
+ if (fuzzyMoment) {
2629
+ dateValue = fuzzyMoment.toDate();
2630
+ }
2631
+ }
2632
+ const areFuzzyDatesEqual = this.fuzzyDatesEqual(this._value, fuzzyDate);
2633
+ const isNewValue = fuzzyDate !== this._value || !areFuzzyDatesEqual;
2634
+ this._value = fuzzyDate || value;
2635
+ if (isNewValue) {
2636
+ if (emitEvent) {
2637
+ this.onChange(this._value);
2638
+ }
2639
+ else {
2640
+ (_a = this.control) === null || _a === void 0 ? void 0 : _a.setValue(this._value, { emitEvent: false });
2641
+ }
2642
+ this.datepickerComponent.selectedDate = dateValue;
2643
+ }
2644
+ this.setInputElementValue(formattedDate || '');
2645
+ }
2638
2646
  }
2639
2647
  SkyFuzzyDatepickerInputDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFuzzyDatepickerInputDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: SkyDatepickerConfigService }, { token: i0.ElementRef }, { token: SkyFuzzyDateService }, { token: i3.SkyAppLocaleProvider }, { token: i0.Renderer2 }, { token: i3.SkyLibResourcesService }, { token: SkyDatepickerComponent, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
2640
2648
  SkyFuzzyDatepickerInputDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.16", type: SkyFuzzyDatepickerInputDirective, selector: "[skyFuzzyDatepickerInput]", inputs: { dateFormat: "dateFormat", disabled: "disabled", futureDisabled: "futureDisabled", maxDate: "maxDate", minDate: "minDate", skyDatepickerNoValidate: "skyDatepickerNoValidate", skyFuzzyDatepickerInput: "skyFuzzyDatepickerInput", startingDay: "startingDay", yearRequired: "yearRequired" }, host: { listeners: { "change": "onInputChange($event)", "blur": "onInputBlur()", "keyup": "onInputKeyup()" } }, providers: [
@@ -2709,11 +2717,12 @@ class SkyDatepickerInputDirective {
2709
2717
  */
2710
2718
  this.skyDatepickerNoValidate = false;
2711
2719
  this.dateFormatter = new SkyDateFormatter();
2712
- this.isFirstChange = true;
2713
2720
  this.ngUnsubscribe = new Subject();
2721
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2714
2722
  this.onChange = (_) => { };
2715
- /*istanbul ignore next */
2723
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2716
2724
  this.onTouched = () => { };
2725
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
2717
2726
  this.onValidatorChange = () => { };
2718
2727
  this.initialPlaceholder = this.adapter.getPlaceholder(this.elementRef);
2719
2728
  this.updatePlaceholder();
@@ -2834,28 +2843,7 @@ class SkyDatepickerInputDirective {
2834
2843
  return this._value;
2835
2844
  }
2836
2845
  set value(value) {
2837
- const dateValue = this.getDateValue(value);
2838
- const areDatesEqual = this._value instanceof Date &&
2839
- dateValue &&
2840
- dateValue.getTime() === this._value.getTime();
2841
- const isValidDateString = this.isDateStringValid(value);
2842
- // If the string value supplied is malformed, do not set the value to its Date equivalent.
2843
- // (JavaScript's Date parser will convert poorly formatted dates to Date objects, such as "abc 123", which isn't ideal.)
2844
- if (!isValidDateString) {
2845
- this._value = value;
2846
- this.notifyUpdatedValue();
2847
- }
2848
- else if (dateValue !== this._value || !areDatesEqual) {
2849
- this._value = dateValue || value;
2850
- this.notifyUpdatedValue();
2851
- }
2852
- if (dateValue && isValidDateString) {
2853
- const formattedDate = this.dateFormatter.format(dateValue, this.dateFormat);
2854
- this.setInputElementValue(formattedDate);
2855
- }
2856
- else {
2857
- this.setInputElementValue(value || '');
2858
- }
2846
+ this.updateValue(value);
2859
2847
  }
2860
2848
  ngOnInit() {
2861
2849
  if (!this.datepickerComponent) {
@@ -2879,7 +2867,6 @@ class SkyDatepickerInputDirective {
2879
2867
  .pipe(distinctUntilChanged())
2880
2868
  .pipe(takeUntil(this.ngUnsubscribe))
2881
2869
  .subscribe((value) => {
2882
- this.isFirstChange = false;
2883
2870
  this.value = value;
2884
2871
  this.onTouched();
2885
2872
  });
@@ -2931,7 +2918,7 @@ class SkyDatepickerInputDirective {
2931
2918
  this.control.markAsDirty();
2932
2919
  }
2933
2920
  writeValue(value) {
2934
- this.value = value;
2921
+ this.updateValue(value, false);
2935
2922
  }
2936
2923
  validate(control) {
2937
2924
  if (!this.control) {
@@ -3002,7 +2989,6 @@ class SkyDatepickerInputDirective {
3002
2989
  }
3003
2990
  }
3004
2991
  onValueChange(newValue) {
3005
- this.isFirstChange = false;
3006
2992
  this.value = newValue;
3007
2993
  }
3008
2994
  setInputElementValue(value) {
@@ -3029,7 +3015,7 @@ class SkyDatepickerInputDirective {
3029
3015
  return true;
3030
3016
  }
3031
3017
  // Does the value only include digits, dashes, or slashes?
3032
- const regexp = /^[\d\/\-]+$/;
3018
+ const regexp = /^[\d/-]+$/;
3033
3019
  const isValid = regexp.test(value);
3034
3020
  if (isValid) {
3035
3021
  return true;
@@ -3038,23 +3024,56 @@ class SkyDatepickerInputDirective {
3038
3024
  const isValidIso = moment(value, moment.ISO_8601).isValid();
3039
3025
  return isValidIso;
3040
3026
  }
3041
- notifyUpdatedValue() {
3042
- this.onChange(this._value);
3043
- // Do not mark the field as "dirty"
3044
- // if the field has been initialized with a value.
3045
- if (this.isFirstChange && this.control) {
3046
- this.control.markAsPristine();
3047
- }
3048
- if (this.isFirstChange && this._value) {
3049
- this.isFirstChange = false;
3050
- }
3051
- this.datepickerComponent.selectedDate = this._value;
3052
- }
3053
3027
  updatePlaceholder() {
3054
3028
  if (!this.initialPlaceholder) {
3055
3029
  this.adapter.setPlaceholder(this.elementRef, this.dateFormat);
3056
3030
  }
3057
3031
  }
3032
+ /**
3033
+ * Update the value of the form control and input element
3034
+ * @param emitEvent Denotes if we emit an event to the consumer's form control. We do not want to do this if the value is being updated via a `setValue` call or a `patchValue` call as this is already handled by Angular.
3035
+ * In these cases we do not want to fire `onChange` as it will cause extra `valueChange` and `statusChange` events and the status of the form should not be affected by these changes.
3036
+ */
3037
+ updateValue(value, emitEvent = true) {
3038
+ var _a, _b;
3039
+ if (this._value === value) {
3040
+ return;
3041
+ }
3042
+ const dateValue = this.getDateValue(value);
3043
+ const areDatesEqual = this._value instanceof Date &&
3044
+ dateValue &&
3045
+ dateValue.getTime() === this._value.getTime();
3046
+ const isValidDateString = this.isDateStringValid(value);
3047
+ // If the string value supplied is malformed, do not set the value to its Date equivalent.
3048
+ // (JavaScript's Date parser will convert poorly formatted dates to Date objects, such as "abc 123", which isn't ideal.)
3049
+ if (!isValidDateString) {
3050
+ this._value = value;
3051
+ if (emitEvent) {
3052
+ this.onChange(this._value);
3053
+ }
3054
+ else {
3055
+ (_a = this.control) === null || _a === void 0 ? void 0 : _a.setValue(this._value, { emitEvent: false });
3056
+ }
3057
+ this.datepickerComponent.selectedDate = this._value;
3058
+ }
3059
+ else if (dateValue !== this._value || !areDatesEqual) {
3060
+ this._value = dateValue || value;
3061
+ if (emitEvent) {
3062
+ this.onChange(this._value);
3063
+ }
3064
+ else {
3065
+ (_b = this.control) === null || _b === void 0 ? void 0 : _b.setValue(this._value, { emitEvent: false });
3066
+ }
3067
+ this.datepickerComponent.selectedDate = this._value;
3068
+ }
3069
+ if (dateValue && isValidDateString) {
3070
+ const formattedDate = this.dateFormatter.format(dateValue, this.dateFormat);
3071
+ this.setInputElementValue(formattedDate);
3072
+ }
3073
+ else {
3074
+ this.setInputElementValue(value || '');
3075
+ }
3076
+ }
3058
3077
  }
3059
3078
  SkyDatepickerInputDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerInputDirective, deps: [{ token: SkyDatepickerAdapterService }, { token: i0.ChangeDetectorRef }, { token: SkyDatepickerConfigService }, { token: i0.ElementRef }, { token: i3.SkyAppLocaleProvider }, { token: i0.Renderer2 }, { token: i3.SkyLibResourcesService }, { token: SkyDatepickerComponent, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
3060
3079
  SkyDatepickerInputDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.16", type: SkyDatepickerInputDirective, selector: "[skyDatepickerInput]", inputs: { dateFormat: "dateFormat", disabled: "disabled", maxDate: "maxDate", minDate: "minDate", skyDatepickerInput: "skyDatepickerInput", skyDatepickerNoValidate: "skyDatepickerNoValidate", startingDay: "startingDay", strict: "strict" }, host: { listeners: { "change": "onInputChange($event)", "blur": "onInputBlur()", "keyup": "onInputKeyup()" } }, providers: [
@@ -3182,9 +3201,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
3182
3201
  * @dynamic
3183
3202
  */
3184
3203
  class SkyDateRangeRelativeValue {
3185
- // Abstract classes are not covered properly.
3186
- /* istanbul ignore next */
3187
- constructor() { }
3188
3204
  static get today() {
3189
3205
  const today = new Date();
3190
3206
  return {
@@ -3684,12 +3700,13 @@ let uniqueId = 0;
3684
3700
  * ```
3685
3701
  */
3686
3702
  class SkyDateRangePickerComponent {
3687
- constructor(changeDetector, dateRangeService, formBuilder, localeProvider, windowRef, themeSvc) {
3703
+ constructor(changeDetector, dateRangeService, formBuilder, localeProvider, windowRef, ngZone, themeSvc) {
3688
3704
  this.changeDetector = changeDetector;
3689
3705
  this.dateRangeService = dateRangeService;
3690
3706
  this.formBuilder = formBuilder;
3691
3707
  this.localeProvider = localeProvider;
3692
3708
  this.windowRef = windowRef;
3709
+ this.ngZone = ngZone;
3693
3710
  /**
3694
3711
  * Indicates whether to require users to specify a start date.
3695
3712
  * @default false
@@ -3706,11 +3723,11 @@ class SkyDateRangePickerComponent {
3706
3723
  this.showStartDatePicker = false;
3707
3724
  this.ngUnsubscribe = new Subject();
3708
3725
  this._disabled = false;
3709
- /* istanbul ignore next */
3726
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
3710
3727
  this.onChange = (_) => { };
3711
- /* istanbul ignore next */
3728
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
3712
3729
  this.onTouched = () => { };
3713
- /* istanbul ignore next */
3730
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
3714
3731
  this.onValidatorChange = () => { };
3715
3732
  this.localeProvider
3716
3733
  .getLocaleInfo()
@@ -3833,24 +3850,27 @@ class SkyDateRangePickerComponent {
3833
3850
  this.updateCalculators().then(() => {
3834
3851
  this.addEventListeners();
3835
3852
  this.isReady = true;
3836
- this.resetFormGroupValue();
3837
3853
  this.showRelevantFormFields();
3838
- // Fill in any unprovided values after the calculators have been initialized.
3839
- // For example, if the control is initialized with only the `calculatorId`,
3840
- // allow the calculator to fill in the missing start and end dates.
3841
- const { startDate, endDate } = this.value;
3842
- const defaultValue = this.selectedCalculator.getValue(startDate, endDate);
3843
- const newValue = Object.assign({}, defaultValue, this.value);
3844
- this.setValue(newValue, false);
3845
- // This is needed to address a bug in Angular 4.
3846
- // When a control value is set intially, its value is not represented on the view.
3847
- // See: https://github.com/angular/angular/issues/13792
3848
- /* istanbul ignore else */
3849
- if (this.control) {
3850
- this.control.setValue(this.value, {
3851
- emitEvent: false,
3852
- });
3853
- }
3854
+ // We need to let Angular be stable and have rendered the components prior to setting the values and form controls. This ensures all initial validation will be ran correctly.
3855
+ this.ngZone.onStable.pipe(first()).subscribe(() => {
3856
+ // Fill in any unprovided values after the calculators have been initialized.
3857
+ // For example, if the control is initialized with only the `calculatorId`,
3858
+ // allow the calculator to fill in the missing start and end dates.
3859
+ const { startDate, endDate } = this.value;
3860
+ const defaultValue = this.selectedCalculator.getValue(startDate, endDate);
3861
+ const newValue = Object.assign({}, defaultValue, this.value);
3862
+ this.setValue(newValue, false);
3863
+ this.resetFormGroupValue();
3864
+ // This is needed to address a bug in Angular 4.
3865
+ // When a control value is set intially, its value is not represented on the view.
3866
+ // See: https://github.com/angular/angular/issues/13792
3867
+ /* istanbul ignore else */
3868
+ if (this.control) {
3869
+ this.control.setValue(this.value, {
3870
+ emitEvent: false,
3871
+ });
3872
+ }
3873
+ });
3854
3874
  });
3855
3875
  }
3856
3876
  ngOnChanges(changes) {
@@ -3989,46 +4009,26 @@ class SkyDateRangePickerComponent {
3989
4009
  this.changeDetector.markForCheck();
3990
4010
  }
3991
4011
  resetFormGroupValue(value) {
3992
- // Do not emit a value change event on the underlying form group
3993
- // because we're already watching for changes that are triggered by the end user.
3994
- // For example, if we change the value of the form group internally, we don't want the event
3995
- // listeners to be triggered, as those are reserved for user interactions.
3996
- // (See the event listeners listed below.)
3997
- this.formGroup.reset(value || this.value, {
3998
- emitEvent: false,
3999
- });
4012
+ this.formGroup.reset(value || this.value);
4000
4013
  }
4001
4014
  addEventListeners() {
4002
- // Detect errors from the date pickers
4003
- // when control is initialized with a value.
4004
- combineLatest([
4005
- this.startDateControl.statusChanges,
4006
- this.endDateControl.statusChanges,
4007
- ])
4008
- .pipe(first())
4009
- .subscribe((status) => {
4010
- if (status.indexOf('INVALID') > -1) {
4011
- // Wait for initial validation to complete.
4012
- this.windowRef.nativeWindow.setTimeout(() => {
4013
- this.onValidatorChange();
4014
- });
4015
- }
4016
- });
4017
4015
  // Watch for selected calculator change.
4018
4016
  this.calculatorIdControl.valueChanges
4019
4017
  .pipe(takeUntil(this.ngUnsubscribe))
4020
4018
  .subscribe((value) => {
4021
- const id = parseInt(value, 10);
4022
- // if the component is disabled during form creation, null is passed
4023
- // as the value of the calculator id control
4024
- // only handle the value changes if the calculator id is a number
4025
- /* istanbul ignore else */
4026
- if (!isNaN(id)) {
4027
- const calculator = this.getCalculatorById(id);
4028
- const newValue = calculator.getValue();
4029
- this.setValue(newValue);
4030
- this.resetFormGroupValue(newValue);
4031
- this.showRelevantFormFields();
4019
+ if (value !== this.value.calculatorId) {
4020
+ const id = parseInt(value, 10);
4021
+ // if the component is disabled during form creation, null is passed
4022
+ // as the value of the calculator id control
4023
+ // only handle the value changes if the calculator id is a number
4024
+ /* istanbul ignore else */
4025
+ if (!isNaN(id)) {
4026
+ const calculator = this.getCalculatorById(id);
4027
+ const newValue = calculator.getValue();
4028
+ this.setValue(newValue);
4029
+ this.resetFormGroupValue(newValue);
4030
+ this.showRelevantFormFields();
4031
+ }
4032
4032
  }
4033
4033
  });
4034
4034
  // Watch for start date value changes.
@@ -4051,6 +4051,11 @@ class SkyDateRangePickerComponent {
4051
4051
  .pipe(takeUntil(this.ngUnsubscribe))
4052
4052
  .subscribe(() => {
4053
4053
  this.changeDetector.markForCheck();
4054
+ // Wait for initial validation to complete.
4055
+ this.ngZone.onStable.pipe(first()).subscribe(() => {
4056
+ var _a;
4057
+ (_a = this.control) === null || _a === void 0 ? void 0 : _a.updateValueAndValidity({ emitEvent: false });
4058
+ });
4054
4059
  });
4055
4060
  }
4056
4061
  updateCalculators() {
@@ -4070,7 +4075,7 @@ class SkyDateRangePickerComponent {
4070
4075
  return JSON.stringify(rangeA) === JSON.stringify(rangeB);
4071
4076
  }
4072
4077
  }
4073
- SkyDateRangePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDateRangePickerComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: SkyDateRangeService }, { token: i2$2.FormBuilder }, { token: i3.SkyAppLocaleProvider }, { token: i1.SkyAppWindowRef }, { token: i3$2.SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
4078
+ SkyDateRangePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDateRangePickerComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: SkyDateRangeService }, { token: i2$2.FormBuilder }, { token: i3.SkyAppLocaleProvider }, { token: i1.SkyAppWindowRef }, { token: i0.NgZone }, { token: i3$2.SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
4074
4079
  SkyDateRangePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SkyDateRangePickerComponent, selector: "sky-date-range-picker", inputs: { calculatorIds: "calculatorIds", dateFormat: "dateFormat", disabled: "disabled", label: "label", startDateRequired: "startDateRequired", endDateRequired: "endDateRequired" }, providers: [
4075
4080
  SKY_DATE_RANGE_PICKER_VALUE_ACCESSOR,
4076
4081
  SKY_DATE_RANGE_PICKER_VALIDATOR,
@@ -4087,7 +4092,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
4087
4092
  ],
4088
4093
  changeDetection: ChangeDetectionStrategy.OnPush,
4089
4094
  }]
4090
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: SkyDateRangeService }, { type: i2$2.FormBuilder }, { type: i3.SkyAppLocaleProvider }, { type: i1.SkyAppWindowRef }, { type: i3$2.SkyThemeService, decorators: [{
4095
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: SkyDateRangeService }, { type: i2$2.FormBuilder }, { type: i3.SkyAppLocaleProvider }, { type: i1.SkyAppWindowRef }, { type: i0.NgZone }, { type: i3$2.SkyThemeService, decorators: [{
4091
4096
  type: Optional
4092
4097
  }] }]; }, propDecorators: { calculatorIds: [{
4093
4098
  type: Input
@@ -4177,7 +4182,6 @@ class SkyTimepickerComponent {
4177
4182
  return this._disabled;
4178
4183
  }
4179
4184
  set selectedHour(setHour) {
4180
- let hour;
4181
4185
  let hourOffset = 0;
4182
4186
  if (this.selectedMeridies === 'AM' && setHour === 12) {
4183
4187
  hourOffset = -12;
@@ -4188,7 +4192,7 @@ class SkyTimepickerComponent {
4188
4192
  if (this.is8601) {
4189
4193
  hourOffset = 0;
4190
4194
  }
4191
- hour = moment({ hour: setHour }).add(hourOffset, 'hours').hour();
4195
+ const hour = moment({ hour: setHour }).add(hourOffset, 'hours').hour();
4192
4196
  this.activeTime = moment({
4193
4197
  hour: hour,
4194
4198
  minute: moment(this.activeTime).get('minute') + 0,
@@ -4308,9 +4312,9 @@ class SkyTimepickerComponent {
4308
4312
  localeFormat = 'HH:mm';
4309
4313
  this.is8601 = true;
4310
4314
  }
4311
- let data;
4312
- data = {
4313
- hours: Array.apply(undefined, Array(h)).map(function (x, i) {
4315
+ const data = {
4316
+ // Create a sparse array with a length equal to the hour.
4317
+ hours: Array(...Array(h)).map((_, i) => {
4314
4318
  if (format === 'hh') {
4315
4319
  return ++i;
4316
4320
  }
@@ -4322,7 +4326,8 @@ class SkyTimepickerComponent {
4322
4326
  /* sanity check */
4323
4327
  return 0;
4324
4328
  }),
4325
- minutes: Array.apply(undefined, Array(m)).map(function (x, i) {
4329
+ // Create a sparse array with a length equal to the minute.
4330
+ minutes: Array(...Array(m)).map(function (_, i) {
4326
4331
  return i * minuteMultiplier;
4327
4332
  }),
4328
4333
  localeFormat: localeFormat,
@@ -4512,11 +4517,11 @@ class SkyTimepickerInputDirective {
4512
4517
  this.resourcesService = resourcesService;
4513
4518
  this.changeDetector = changeDetector;
4514
4519
  this._timeFormat = 'hh';
4515
- /*istanbul ignore next */
4520
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
4516
4521
  this._onChange = (_) => { };
4517
- /*istanbul ignore next */
4522
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
4518
4523
  this._onTouched = () => { };
4519
- /* istanbul ignore next */
4524
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
4520
4525
  this._validatorChange = () => { };
4521
4526
  }
4522
4527
  /**
@@ -4659,7 +4664,6 @@ class SkyTimepickerInputDirective {
4659
4664
  return '';
4660
4665
  }
4661
4666
  let currentFormat;
4662
- let formatTime;
4663
4667
  if (this.timeFormat === 'hh') {
4664
4668
  currentFormat = 'h:mm A';
4665
4669
  }
@@ -4669,7 +4673,7 @@ class SkyTimepickerInputDirective {
4669
4673
  if (typeof this.returnFormat === 'undefined') {
4670
4674
  this.returnFormat = currentFormat;
4671
4675
  }
4672
- formatTime = {
4676
+ const formatTime = {
4673
4677
  hour: moment(time, currentFormat).hour(),
4674
4678
  minute: moment(time, currentFormat).minute(),
4675
4679
  meridie: moment(time, currentFormat).format('A'),