@skyux/datetime 5.5.0 → 5.6.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 (65) hide show
  1. package/bundles/skyux-datetime.umd.js +695 -695
  2. package/documentation.json +187 -187
  3. package/esm2015/lib/modules/date-pipe/date-format-utility.js.map +1 -1
  4. package/esm2015/lib/modules/date-pipe/date-pipe.module.js.map +1 -1
  5. package/esm2015/lib/modules/date-pipe/date.pipe.js.map +1 -1
  6. package/esm2015/lib/modules/date-pipe/fuzzy-date.pipe.js.map +1 -1
  7. package/esm2015/lib/modules/date-range-picker/date-range-picker.component.js +3 -3
  8. package/esm2015/lib/modules/date-range-picker/date-range-picker.component.js.map +1 -1
  9. package/esm2015/lib/modules/date-range-picker/date-range-picker.module.js.map +1 -1
  10. package/esm2015/lib/modules/date-range-picker/date-range.service.js.map +1 -1
  11. package/esm2015/lib/modules/date-range-picker/types/date-range-calculation.js.map +1 -1
  12. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-config.js.map +1 -1
  13. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator.js.map +1 -1
  14. package/esm2015/lib/modules/date-range-picker/types/date-range-default-calculator-config.js.map +1 -1
  15. package/esm2015/lib/modules/date-range-picker/types/date-range-default-calculator-configs.js.map +1 -1
  16. package/esm2015/lib/modules/datepicker/date-formatter.js.map +1 -1
  17. package/esm2015/lib/modules/datepicker/datepicker-calendar-change.js.map +1 -1
  18. package/esm2015/lib/modules/datepicker/datepicker-calendar-inner.component.js +6 -6
  19. package/esm2015/lib/modules/datepicker/datepicker-calendar-inner.component.js.map +1 -1
  20. package/esm2015/lib/modules/datepicker/datepicker-calendar.component.js +1 -1
  21. package/esm2015/lib/modules/datepicker/datepicker-calendar.component.js.map +1 -1
  22. package/esm2015/lib/modules/datepicker/datepicker-input-fuzzy.directive.js +2 -2
  23. package/esm2015/lib/modules/datepicker/datepicker-input-fuzzy.directive.js.map +1 -1
  24. package/esm2015/lib/modules/datepicker/datepicker-input.directive.js +2 -2
  25. package/esm2015/lib/modules/datepicker/datepicker-input.directive.js.map +1 -1
  26. package/esm2015/lib/modules/datepicker/datepicker.component.js +2 -2
  27. package/esm2015/lib/modules/datepicker/datepicker.component.js.map +1 -1
  28. package/esm2015/lib/modules/datepicker/datepicker.module.js +10 -10
  29. package/esm2015/lib/modules/datepicker/datepicker.module.js.map +1 -1
  30. package/esm2015/lib/modules/datepicker/daypicker-button.component.js.map +1 -1
  31. package/esm2015/lib/modules/datepicker/daypicker-cell.component.js +1 -1
  32. package/esm2015/lib/modules/datepicker/daypicker-cell.component.js.map +1 -1
  33. package/esm2015/lib/modules/datepicker/daypicker.component.js +13 -13
  34. package/esm2015/lib/modules/datepicker/daypicker.component.js.map +1 -1
  35. package/esm2015/lib/modules/datepicker/fuzzy-date.service.js +10 -10
  36. package/esm2015/lib/modules/datepicker/fuzzy-date.service.js.map +1 -1
  37. package/esm2015/lib/modules/datepicker/monthpicker.component.js +5 -5
  38. package/esm2015/lib/modules/datepicker/monthpicker.component.js.map +1 -1
  39. package/esm2015/lib/modules/datepicker/yearpicker.component.js +2 -2
  40. package/esm2015/lib/modules/datepicker/yearpicker.component.js.map +1 -1
  41. package/esm2015/lib/modules/shared/sky-datetime-resources.module.js +1 -1
  42. package/esm2015/lib/modules/shared/sky-datetime-resources.module.js.map +1 -1
  43. package/esm2015/lib/modules/timepicker/timepicker.component.js +2 -2
  44. package/esm2015/lib/modules/timepicker/timepicker.component.js.map +1 -1
  45. package/esm2015/lib/modules/timepicker/timepicker.directive.js +3 -3
  46. package/esm2015/lib/modules/timepicker/timepicker.directive.js.map +1 -1
  47. package/esm2015/lib/modules/timepicker/timepicker.module.js +3 -3
  48. package/esm2015/lib/modules/timepicker/timepicker.module.js.map +1 -1
  49. package/esm2015/testing/datepicker-fixture.js.map +1 -1
  50. package/esm2015/testing/timepicker-fixture.js.map +1 -1
  51. package/fesm2015/skyux-datetime-testing.js.map +1 -1
  52. package/fesm2015/skyux-datetime.js +438 -438
  53. package/fesm2015/skyux-datetime.js.map +1 -1
  54. package/lib/modules/date-range-picker/date-range-picker.component.d.ts +2 -2
  55. package/lib/modules/date-range-picker/date-range.service.d.ts +1 -1
  56. package/lib/modules/date-range-picker/types/date-range-calculation.d.ts +1 -1
  57. package/lib/modules/date-range-picker/types/date-range-calculator.d.ts +1 -1
  58. package/lib/modules/datepicker/datepicker-calendar-change.d.ts +1 -1
  59. package/lib/modules/datepicker/datepicker-calendar-inner.component.d.ts +1 -1
  60. package/lib/modules/datepicker/datepicker-calendar.component.d.ts +1 -1
  61. package/lib/modules/datepicker/datepicker-input-fuzzy.directive.d.ts +1 -1
  62. package/lib/modules/datepicker/datepicker-input.directive.d.ts +1 -1
  63. package/lib/modules/datepicker/datepicker.component.d.ts +2 -2
  64. package/lib/modules/datepicker/daypicker.component.d.ts +1 -1
  65. package/package.json +6 -6
@@ -15,10 +15,10 @@ import * as i1 from '@skyux/core';
15
15
  import { SkyAffixAutoFitContext, SkyAffixModule, SkyOverlayModule } from '@skyux/core';
16
16
  import * as i2 from '@skyux/indicators';
17
17
  import { SkyIconModule, SkyWaitModule } from '@skyux/indicators';
18
- import * as i3$2 from '@skyux/theme';
19
- import { SkyThemeModule } from '@skyux/theme';
20
18
  import * as i3$1 from '@skyux/popovers';
21
19
  import { SkyPopoverMessageType, SkyPopoverModule } from '@skyux/popovers';
20
+ import * as i3$2 from '@skyux/theme';
21
+ 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 {
@@ -293,10 +293,10 @@ class SkyFuzzyDateService {
293
293
  return '';
294
294
  }
295
295
  const separator = this.getDateSeparator(format);
296
- let dateParts = [];
297
- let formatTokens = format.split(separator);
296
+ const dateParts = [];
297
+ const formatTokens = format.split(separator);
298
298
  locale = locale || this.currentLocale;
299
- let fuzzyDateMoment = this.getMomentFromFuzzyDate(fuzzyDate).locale(locale);
299
+ const fuzzyDateMoment = this.getMomentFromFuzzyDate(fuzzyDate).locale(locale);
300
300
  for (let index = 0; index < formatTokens.length; index++) {
301
301
  const token = formatTokens[index];
302
302
  /* istanbul ignore else */
@@ -348,7 +348,7 @@ class SkyFuzzyDateService {
348
348
  const dateFormatIndexes = this.getDateFormatIndexes(dateFormat);
349
349
  let dateString = '';
350
350
  // Get the components of the date in the order expected of the local format.
351
- let dateComponents = [
351
+ const dateComponents = [
352
352
  { value: fuzzyDate.year || 0, index: dateFormatIndexes.yearIndex },
353
353
  { value: fuzzyDate.month || 0, index: dateFormatIndexes.monthIndex },
354
354
  { value: fuzzyDate.day || 0, index: dateFormatIndexes.dayIndex },
@@ -368,7 +368,7 @@ class SkyFuzzyDateService {
368
368
  if (!selectedDate || !dateFormat) {
369
369
  return;
370
370
  }
371
- let fuzzyDate = {};
371
+ const fuzzyDate = {};
372
372
  const dateFormatIndexes = this.getDateFormatIndexes(dateFormat);
373
373
  if (dateFormatIndexes.yearIndex > -1) {
374
374
  fuzzyDate.year = selectedDate.getFullYear();
@@ -451,7 +451,7 @@ class SkyFuzzyDateService {
451
451
  // Check if day is valid.
452
452
  if (day) {
453
453
  day = parseInt(day, 10);
454
- let fuzzyMoment = this.getMomentFromFuzzyDate({
454
+ const fuzzyMoment = this.getMomentFromFuzzyDate({
455
455
  month: month,
456
456
  day: day,
457
457
  year: year,
@@ -502,7 +502,7 @@ class SkyFuzzyDateService {
502
502
  };
503
503
  }
504
504
  getCurrentFuzzyDate() {
505
- let currentDate = moment();
505
+ const currentDate = moment();
506
506
  return {
507
507
  day: currentDate.date(),
508
508
  month: currentDate.month() + 1,
@@ -523,7 +523,7 @@ class SkyFuzzyDateService {
523
523
  */
524
524
  getDateSeparator(dateFormat) {
525
525
  let returnValue;
526
- let separators = ['/', '.', '-', ' '];
526
+ const separators = ['/', '.', '-', ' '];
527
527
  separators.forEach((separator) => {
528
528
  if (!returnValue && dateFormat.indexOf(separator) > 0) {
529
529
  returnValue = separator;
@@ -591,7 +591,7 @@ class SkyFuzzyDateService {
591
591
  // Returns the index of each of the date components in the provided string (month, day, year).
592
592
  getDateValueIndexes(date, dateFormat) {
593
593
  const dateFormatIndexes = this.getDateFormatIndexes(dateFormat);
594
- let dateComponentIndexes = [];
594
+ const dateComponentIndexes = [];
595
595
  if (dateFormatIndexes.yearIndex > -1) {
596
596
  dateComponentIndexes.push(dateFormatIndexes.yearIndex);
597
597
  }
@@ -900,37 +900,6 @@ var SkyDateRangeCalculatorType;
900
900
  SkyDateRangeCalculatorType[SkyDateRangeCalculatorType["Relative"] = 3] = "Relative";
901
901
  })(SkyDateRangeCalculatorType || (SkyDateRangeCalculatorType = {}));
902
902
 
903
- /**
904
- * @internal
905
- */
906
- class SkyDatepickerAdapterService {
907
- constructor(renderer) {
908
- this.renderer = renderer;
909
- }
910
- init(elRef) {
911
- this.el = elRef.nativeElement;
912
- }
913
- elementIsFocused() {
914
- const focusedEl = document.activeElement;
915
- return this.el.contains(focusedEl);
916
- }
917
- elementIsVisible() {
918
- const styles = this.el && getComputedStyle(this.el);
919
- return styles && styles.visibility === 'visible';
920
- }
921
- getPlaceholder(elementRef) {
922
- return elementRef.nativeElement.getAttribute('placeholder');
923
- }
924
- setPlaceholder(elementRef, value) {
925
- this.renderer.setAttribute(elementRef.nativeElement, 'placeholder', value);
926
- }
927
- }
928
- SkyDatepickerAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerAdapterService, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable });
929
- SkyDatepickerAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerAdapterService });
930
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerAdapterService, decorators: [{
931
- type: Injectable
932
- }], ctorParameters: function () { return [{ type: i0.Renderer2 }]; } });
933
-
934
903
  class SkyDateFormatter {
935
904
  /**
936
905
  * Sets moment's global locale.
@@ -1114,7 +1083,7 @@ class SkyDatepickerCalendarInnerComponent {
1114
1083
  return false;
1115
1084
  }
1116
1085
  onKeydown(event) {
1117
- let key = this.keys[event.which];
1086
+ const key = this.keys[event.which];
1118
1087
  if (!key || event.shiftKey || event.altKey) {
1119
1088
  return;
1120
1089
  }
@@ -1136,7 +1105,7 @@ class SkyDatepickerCalendarInnerComponent {
1136
1105
  }
1137
1106
  createDateObject(date, format, isSecondary, id) {
1138
1107
  const customDateMatch = this.getCustomDate(date);
1139
- let dateObject = {
1108
+ const dateObject = {
1140
1109
  date: new Date(date.getFullYear(), date.getMonth(), date.getDate()),
1141
1110
  label: this.dateFilter(date, format),
1142
1111
  selected: this.compare(date, this.selectedDate) === 0,
@@ -1150,7 +1119,7 @@ class SkyDatepickerCalendarInnerComponent {
1150
1119
  return dateObject;
1151
1120
  }
1152
1121
  createCalendarRows(dates, size) {
1153
- let rows = [];
1122
+ const rows = [];
1154
1123
  while (dates.length > 0) {
1155
1124
  rows.push(dates.splice(0, size));
1156
1125
  }
@@ -1160,7 +1129,7 @@ class SkyDatepickerCalendarInnerComponent {
1160
1129
  This is ensures that no strangeness happens when converting a date to local time.
1161
1130
  */
1162
1131
  fixTimeZone(date) {
1163
- let newDate = new Date(date);
1132
+ const newDate = new Date(date);
1164
1133
  newDate.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
1165
1134
  return newDate;
1166
1135
  }
@@ -1209,8 +1178,8 @@ class SkyDatepickerCalendarInnerComponent {
1209
1178
  /* istanbul ignore else */
1210
1179
  /* sanity check */
1211
1180
  if (expectedStep) {
1212
- let year = this.activeDate.getFullYear() + direction * (expectedStep.years || 0);
1213
- let month = this.activeDate.getMonth() + direction * (expectedStep.months || 0);
1181
+ const year = this.activeDate.getFullYear() + direction * (expectedStep.years || 0);
1182
+ const month = this.activeDate.getMonth() + direction * (expectedStep.months || 0);
1214
1183
  this.activeDate = new Date(year, month, 1);
1215
1184
  this.refreshView();
1216
1185
  }
@@ -1278,6 +1247,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
1278
1247
  type: Output
1279
1248
  }] } });
1280
1249
 
1250
+ /**
1251
+ * @internal
1252
+ */
1253
+ class SkyDatepickerAdapterService {
1254
+ constructor(renderer) {
1255
+ this.renderer = renderer;
1256
+ }
1257
+ init(elRef) {
1258
+ this.el = elRef.nativeElement;
1259
+ }
1260
+ elementIsFocused() {
1261
+ const focusedEl = document.activeElement;
1262
+ return this.el.contains(focusedEl);
1263
+ }
1264
+ elementIsVisible() {
1265
+ const styles = this.el && getComputedStyle(this.el);
1266
+ return styles && styles.visibility === 'visible';
1267
+ }
1268
+ getPlaceholder(elementRef) {
1269
+ return elementRef.nativeElement.getAttribute('placeholder');
1270
+ }
1271
+ setPlaceholder(elementRef, value) {
1272
+ this.renderer.setAttribute(elementRef.nativeElement, 'placeholder', value);
1273
+ }
1274
+ }
1275
+ SkyDatepickerAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerAdapterService, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable });
1276
+ SkyDatepickerAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerAdapterService });
1277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerAdapterService, decorators: [{
1278
+ type: Injectable
1279
+ }], ctorParameters: function () { return [{ type: i0.Renderer2 }]; } });
1280
+
1281
1281
  class SkyDatepickerConfigService {
1282
1282
  constructor() {
1283
1283
  /**
@@ -1494,7 +1494,7 @@ class SkyDayPickerComponent {
1494
1494
  this.ngUnsubscribe.complete();
1495
1495
  }
1496
1496
  getDates(startDate, n) {
1497
- let dates = new Array(n);
1497
+ const dates = new Array(n);
1498
1498
  let current = new Date(startDate.getTime());
1499
1499
  let i = 0;
1500
1500
  let date;
@@ -1507,17 +1507,17 @@ class SkyDayPickerComponent {
1507
1507
  return dates;
1508
1508
  }
1509
1509
  compareDays(date1, date2) {
1510
- let d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
1511
- let d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
1510
+ const d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
1511
+ const d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
1512
1512
  return d1.getTime() - d2.getTime();
1513
1513
  }
1514
1514
  refreshDayView() {
1515
- let year = this.datepicker.activeDate.getFullYear();
1516
- let month = this.datepicker.activeDate.getMonth();
1517
- let firstDayOfMonth = new Date(year, month, 1);
1518
- let difference = this.datepicker.startingDay - firstDayOfMonth.getDay();
1519
- let numDisplayedFromPreviousMonth = difference > 0 ? 7 - difference : -difference;
1520
- let firstDate = new Date(firstDayOfMonth.getTime());
1515
+ const year = this.datepicker.activeDate.getFullYear();
1516
+ const month = this.datepicker.activeDate.getMonth();
1517
+ const firstDayOfMonth = new Date(year, month, 1);
1518
+ const difference = this.datepicker.startingDay - firstDayOfMonth.getDay();
1519
+ const numDisplayedFromPreviousMonth = difference > 0 ? 7 - difference : -difference;
1520
+ const firstDate = new Date(firstDayOfMonth.getTime());
1521
1521
  if (this.datepicker.activeDate.getDate() !== this.initialDate) {
1522
1522
  this.activeDateHasChanged = true;
1523
1523
  }
@@ -1527,10 +1527,10 @@ class SkyDayPickerComponent {
1527
1527
  firstDate.setDate(-numDisplayedFromPreviousMonth + 1);
1528
1528
  }
1529
1529
  // 42 is the number of days on a six-week calendar
1530
- let days = this.getDates(firstDate, 42);
1531
- let pickerDates = [];
1530
+ const days = this.getDates(firstDate, 42);
1531
+ const pickerDates = [];
1532
1532
  for (let i = 0; i < 42; i++) {
1533
- let _dateObject = this.datepicker.createDateObject(days[i], this.datepicker.formatDay, days[i].getMonth() !== month, this.datepicker.datepickerId + '-' + i);
1533
+ const _dateObject = this.datepicker.createDateObject(days[i], this.datepicker.formatDay, days[i].getMonth() !== month, this.datepicker.datepickerId + '-' + i);
1534
1534
  pickerDates[i] = _dateObject;
1535
1535
  }
1536
1536
  this.labels = [];
@@ -1567,7 +1567,7 @@ class SkyDayPickerComponent {
1567
1567
  date = date + 7;
1568
1568
  }
1569
1569
  else if (key === 'pageup' || key === 'pagedown') {
1570
- let month = this.datepicker.activeDate.getMonth() + (key === 'pageup' ? -1 : 1);
1570
+ const month = this.datepicker.activeDate.getMonth() + (key === 'pageup' ? -1 : 1);
1571
1571
  this.datepicker.activeDate.setMonth(month, 1);
1572
1572
  date = Math.min(this.getDaysInMonth(this.datepicker.activeDate.getFullYear(), this.datepicker.activeDate.getMonth()), date);
1573
1573
  }
@@ -1683,13 +1683,13 @@ class SkyMonthPickerComponent {
1683
1683
  }, 'month');
1684
1684
  }
1685
1685
  compareMonth(date1, date2) {
1686
- let d1 = new Date(date1.getFullYear(), date1.getMonth());
1687
- let d2 = new Date(date2.getFullYear(), date2.getMonth());
1686
+ const d1 = new Date(date1.getFullYear(), date1.getMonth());
1687
+ const d2 = new Date(date2.getFullYear(), date2.getMonth());
1688
1688
  return d1.getTime() - d2.getTime();
1689
1689
  }
1690
1690
  refreshMonthView() {
1691
- let months = new Array(12);
1692
- let year = this.datepicker.activeDate.getFullYear();
1691
+ const months = new Array(12);
1692
+ const year = this.datepicker.activeDate.getFullYear();
1693
1693
  let date;
1694
1694
  for (let i = 0; i < 12; i++) {
1695
1695
  date = new Date(year, i, 1);
@@ -1716,7 +1716,7 @@ class SkyMonthPickerComponent {
1716
1716
  date = date + this.datepicker.monthColLimit;
1717
1717
  }
1718
1718
  else if (key === 'pageup' || key === 'pagedown') {
1719
- let year = this.datepicker.activeDate.getFullYear() + (key === 'pageup' ? -1 : 1);
1719
+ const year = this.datepicker.activeDate.getFullYear() + (key === 'pageup' ? -1 : 1);
1720
1720
  this.datepicker.activeDate.setFullYear(year);
1721
1721
  }
1722
1722
  else if (key === 'home') {
@@ -1767,9 +1767,9 @@ class SkyYearPickerComponent {
1767
1767
  return date1.getFullYear() - date2.getFullYear();
1768
1768
  }
1769
1769
  refreshYearView() {
1770
- let years = new Array(this.datepicker.yearRange);
1770
+ const years = new Array(this.datepicker.yearRange);
1771
1771
  let date;
1772
- let start = this.getStartingYear(this.datepicker.activeDate.getFullYear());
1772
+ const start = this.getStartingYear(this.datepicker.activeDate.getFullYear());
1773
1773
  for (let i = 0; i < this.datepicker.yearRange; i++) {
1774
1774
  date = new Date(this.datepicker.activeDate);
1775
1775
  date.setFullYear(start + i, 0, 1);
@@ -2239,61 +2239,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
2239
2239
  }] } });
2240
2240
 
2241
2241
  // tslint:disable:no-forward-ref no-use-before-declare
2242
- const SKY_DATEPICKER_VALUE_ACCESSOR = {
2242
+ const SKY_FUZZY_DATEPICKER_VALUE_ACCESSOR = {
2243
2243
  provide: NG_VALUE_ACCESSOR,
2244
- useExisting: forwardRef(() => SkyDatepickerInputDirective),
2244
+ useExisting: forwardRef(() => SkyFuzzyDatepickerInputDirective),
2245
2245
  multi: true,
2246
2246
  };
2247
- const SKY_DATEPICKER_VALIDATOR = {
2247
+ const SKY_FUZZY_DATEPICKER_VALIDATOR = {
2248
2248
  provide: NG_VALIDATORS,
2249
- useExisting: forwardRef(() => SkyDatepickerInputDirective),
2249
+ useExisting: forwardRef(() => SkyFuzzyDatepickerInputDirective),
2250
2250
  multi: true,
2251
2251
  };
2252
2252
  // tslint:enable
2253
- class SkyDatepickerInputDirective {
2254
- constructor(adapter, changeDetector, configService, elementRef, localeProvider, renderer, resourcesService, datepickerComponent) {
2255
- this.adapter = adapter;
2253
+ class SkyFuzzyDatepickerInputDirective {
2254
+ constructor(changeDetector, configService, elementRef, fuzzyDateService, localeProvider, renderer, resourcesService, datepickerComponent) {
2256
2255
  this.changeDetector = changeDetector;
2257
2256
  this.configService = configService;
2258
2257
  this.elementRef = elementRef;
2258
+ this.fuzzyDateService = fuzzyDateService;
2259
2259
  this.localeProvider = localeProvider;
2260
2260
  this.renderer = renderer;
2261
2261
  this.resourcesService = resourcesService;
2262
2262
  this.datepickerComponent = datepickerComponent;
2263
2263
  /**
2264
- * Indicates whether to disable date validation on the datepicker input.
2264
+ * Indicates whether to disable date validation on the fuzzy datepicker input.
2265
2265
  * @default false
2266
2266
  */
2267
2267
  this.skyDatepickerNoValidate = false;
2268
2268
  this.dateFormatter = new SkyDateFormatter();
2269
2269
  this.isFirstChange = true;
2270
2270
  this.ngUnsubscribe = new Subject();
2271
+ this._futureDisabled = false;
2272
+ this._disabled = false;
2273
+ this._yearRequired = false;
2271
2274
  this.onChange = (_) => { };
2272
2275
  /*istanbul ignore next */
2273
2276
  this.onTouched = () => { };
2274
2277
  this.onValidatorChange = () => { };
2275
- this.initialPlaceholder = this.adapter.getPlaceholder(this.elementRef);
2276
- this.updatePlaceholder();
2277
2278
  this.localeProvider
2278
2279
  .getLocaleInfo()
2279
2280
  .pipe(takeUntil(this.ngUnsubscribe))
2280
2281
  .subscribe((localeInfo) => {
2281
- SkyDateFormatter.setLocale(localeInfo.locale);
2282
+ this.locale = localeInfo.locale;
2283
+ SkyDateFormatter.setLocale(this.locale);
2282
2284
  this.preferredShortDateFormat =
2283
2285
  SkyDateFormatter.getPreferredShortDateFormat();
2284
- this.applyDateFormat();
2285
2286
  });
2286
2287
  }
2287
2288
  /**
2288
2289
  * Specifies the date format for the input. Place this attribute on the `input` element
2289
- * to override the default in the `SkyDatepickerConfigService`.
2290
+ * to override the default in `SkyDatepickerConfigService`.
2290
2291
  * @default "MM/DD/YYYY"
2291
2292
  */
2292
2293
  set dateFormat(value) {
2293
- /* istanbul ignore else */
2294
- if (value !== this._dateFormat) {
2295
- this._dateFormat = value;
2296
- this.applyDateFormat();
2294
+ this._dateFormat = value;
2295
+ if (this.value) {
2296
+ const formattedDate = this.fuzzyDateService.format(this.value, this.dateFormat, this.locale);
2297
+ this.setInputElementValue(formattedDate);
2298
+ this.changeDetector.markForCheck();
2297
2299
  }
2298
2300
  }
2299
2301
  get dateFormat() {
@@ -2311,54 +2313,57 @@ class SkyDatepickerInputDirective {
2311
2313
  this.renderer.setProperty(this.elementRef.nativeElement, 'disabled', value);
2312
2314
  }
2313
2315
  get disabled() {
2314
- return this._disabled || false;
2316
+ return this._disabled;
2315
2317
  }
2316
2318
  /**
2317
- * @internal
2318
- * Indicates if the input element or any of its children have focus.
2319
+ * Indicates whether to prevent users from specifying dates that are in the future.
2320
+ * Place this attribute on the `input` element.
2321
+ * @default false
2319
2322
  */
2320
- get inputIsFocused() {
2321
- return this.adapter.elementIsFocused();
2323
+ set futureDisabled(value) {
2324
+ this._futureDisabled = value;
2325
+ this.onValidatorChange();
2326
+ }
2327
+ get futureDisabled() {
2328
+ return this._futureDisabled;
2322
2329
  }
2323
2330
  /**
2324
- * Specifies the latest date that is available in the calendar. Place this attribute on
2325
- * the `input` element to override the default in `SkyDatepickerConfigService`.
2331
+ * Specifies the latest fuzzy date allowed. Place this attribute on the `input` element
2332
+ * to prevent fuzzy dates after a specified date. This property accepts
2333
+ * a `SkyFuzzyDate` value that includes numeric month, day, and year values.
2334
+ * For example: `{ month: 1, day: 1, year: 2027 }`.
2326
2335
  */
2327
2336
  set maxDate(value) {
2328
2337
  this._maxDate = value;
2329
- this.datepickerComponent.maxDate = this.maxDate;
2338
+ this.datepickerComponent.maxDate = this.getMaxDate();
2330
2339
  this.onValidatorChange();
2331
2340
  }
2332
2341
  get maxDate() {
2333
- return this._maxDate || this.configService.maxDate;
2342
+ return this._maxDate;
2334
2343
  }
2335
2344
  /**
2336
- * Specifies the earliest date that is available in the calendar. Place this attribute on
2337
- * the `input` element to override the default in `SkyDatepickerConfigService`.
2345
+ * Specifies the earliest fuzzy date allowed. Place this attribute on the `input` element
2346
+ * to prevent fuzzy dates before a specified date. This property accepts a `SkyFuzzyDate` value
2347
+ * that includes numeric month, day, and year values.
2348
+ * For example: `{ month: 1, day: 1, year: 2007 }`.
2338
2349
  */
2339
2350
  set minDate(value) {
2340
2351
  this._minDate = value;
2341
- this.datepickerComponent.minDate = this.minDate;
2352
+ this.datepickerComponent.minDate = this.getMinDate();
2342
2353
  this.onValidatorChange();
2343
2354
  }
2344
2355
  get minDate() {
2345
- return this._minDate || this.configService.minDate;
2356
+ return this._minDate;
2346
2357
  }
2347
2358
  /**
2348
- * Creates the datepicker input and calendar. Place this directive on an `input` element,
2349
- * and wrap the input in a `sky-datepicker` component. The value that users select is driven
2359
+ * Creates the fuzzy datepicker input and calendar to let users specify dates that are
2360
+ * not complete. For example, if users know the year but not the month or day, they can
2361
+ * enter just the year. Place this directive on an `input` element, and wrap the `input`
2362
+ * in a `sky-datepicker` component. The value that users select is driven
2350
2363
  * through the `ngModel` attribute specified on the `input` element.
2351
2364
  * @required
2352
2365
  */
2353
- set skyDatepickerInput(value) {
2354
- if (value) {
2355
- console.warn('[Deprecation warning] You no longer need to provide a template reference variable ' +
2356
- 'to the `skyDatepickerInput` attribute (this will be a breaking change in the next ' +
2357
- 'major version release).\n' +
2358
- 'Do this instead:\n' +
2359
- '<sky-datepicker>\n <input skyDatepickerInput />\n</sky-datepicker>');
2360
- }
2361
- }
2366
+ set skyFuzzyDatepickerInput(value) { }
2362
2367
  /**
2363
2368
  * Specifies the starting day of the week in the calendar, where `0` sets the starting day
2364
2369
  * to Sunday. Place this attribute on the `input` element to override the default
@@ -2374,54 +2379,79 @@ class SkyDatepickerInputDirective {
2374
2379
  return this._startingDay || this.configService.startingDay;
2375
2380
  }
2376
2381
  /**
2377
- * Indicates whether the format of the date value must match the format from the `dateFormat` value.
2378
- * If this property is `true` and the datepicker input directive cannot find an exact match, then
2379
- * the input is marked as invalid.
2380
- * If this property is `false` and the datepicker input directive cannot find an exact match, then
2381
- * it attempts to format the string based on the [ISO 8601 standard format](https://www.iso.org/iso-8601-date-and-time-format.html).
2382
+ * Indicates whether to require the year in fuzzy dates.
2382
2383
  * @default false
2383
2384
  */
2384
- set strict(value) {
2385
- this._strict = value;
2385
+ set yearRequired(value) {
2386
+ this._yearRequired = value;
2387
+ this.onValidatorChange();
2386
2388
  }
2387
- get strict() {
2388
- return this._strict || false;
2389
+ get yearRequired() {
2390
+ return this._yearRequired;
2389
2391
  }
2390
2392
  get value() {
2391
2393
  return this._value;
2392
2394
  }
2393
2395
  set value(value) {
2394
- const dateValue = this.getDateValue(value);
2395
- const areDatesEqual = this._value instanceof Date &&
2396
- dateValue &&
2397
- dateValue.getTime() === this._value.getTime();
2398
- const isValidDateString = this.isDateStringValid(value);
2399
- // If the string value supplied is malformed, do not set the value to its Date equivalent.
2400
- // (JavaScript's Date parser will convert poorly formatted dates to Date objects, such as "abc 123", which isn't ideal.)
2401
- if (!isValidDateString) {
2402
- this._value = value;
2403
- this.notifyUpdatedValue();
2404
- }
2405
- else if (dateValue !== this._value || !areDatesEqual) {
2406
- this._value = dateValue || value;
2407
- this.notifyUpdatedValue();
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);
2408
2404
  }
2409
- if (dateValue && isValidDateString) {
2410
- const formattedDate = this.dateFormatter.format(dateValue, this.dateFormat);
2411
- this.setInputElementValue(formattedDate);
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
+ }
2412
2415
  }
2413
2416
  else {
2414
- this.setInputElementValue(value || '');
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;
2415
2438
  }
2439
+ this.setInputElementValue(formattedDate || '');
2416
2440
  }
2417
2441
  ngOnInit() {
2442
+ if (this.yearRequired) {
2443
+ if (this.dateFormat.toLowerCase().indexOf('y') === -1) {
2444
+ throw new Error('You have configured conflicting settings. Year is required and dateFormat does not include year.');
2445
+ }
2446
+ }
2418
2447
  if (!this.datepickerComponent) {
2419
- throw new Error('You must wrap the `skyDatepickerInput` directive within a ' +
2448
+ throw new Error('You must wrap the `skyFuzzyDatepickerInput` directive within a ' +
2420
2449
  '`<sky-datepicker>` component!');
2421
2450
  }
2422
2451
  const element = this.elementRef.nativeElement;
2423
2452
  this.renderer.addClass(element, 'sky-form-control');
2424
2453
  const hasAriaLabel = element.getAttribute('aria-label');
2454
+ /* istanbul ignore else */
2425
2455
  if (!hasAriaLabel) {
2426
2456
  this.resourcesService
2427
2457
  .getString('skyux_date_field_default_label')
@@ -2433,8 +2463,7 @@ class SkyDatepickerInputDirective {
2433
2463
  }
2434
2464
  ngAfterContentInit() {
2435
2465
  this.datepickerComponent.dateChange
2436
- .pipe(distinctUntilChanged())
2437
- .pipe(takeUntil(this.ngUnsubscribe))
2466
+ .pipe(distinctUntilChanged(), takeUntil(this.ngUnsubscribe))
2438
2467
  .subscribe((value) => {
2439
2468
  this.isFirstChange = false;
2440
2469
  this.value = value;
@@ -2456,33 +2485,20 @@ class SkyDatepickerInputDirective {
2456
2485
  this.changeDetector.markForCheck();
2457
2486
  });
2458
2487
  }
2459
- this.adapter.init(this.elementRef);
2460
2488
  }
2461
2489
  ngOnDestroy() {
2462
2490
  this.ngUnsubscribe.next();
2463
2491
  this.ngUnsubscribe.complete();
2464
2492
  }
2465
2493
  onInputChange(event) {
2466
- const value = event.target.value;
2467
- if (this.skyDatepickerNoValidate) {
2468
- this.onValueChange(value);
2469
- return;
2470
- }
2471
- // Don't try to parse the string value into a Date value if it is malformed.
2472
- if (this.isDateStringValid(value)) {
2473
- this.onValueChange(value);
2474
- return;
2475
- }
2476
- this._value = value;
2477
- this.onChange(value);
2478
- this.control.setErrors({
2479
- skyDate: {
2480
- invalid: true,
2481
- },
2482
- });
2494
+ this.onValueChange(event.target.value);
2483
2495
  }
2484
2496
  onInputBlur() {
2485
2497
  this.onTouched();
2498
+ const formattedDate = this.fuzzyDateService.format(this.value, this.dateFormat, this.locale);
2499
+ if (this.control.valid) {
2500
+ this.setInputElementValue(formattedDate);
2501
+ }
2486
2502
  }
2487
2503
  onInputKeyup() {
2488
2504
  this.control.markAsDirty();
@@ -2497,38 +2513,71 @@ class SkyDatepickerInputDirective {
2497
2513
  if (this.skyDatepickerNoValidate) {
2498
2514
  return;
2499
2515
  }
2500
- const value = control.value;
2501
- if (!value) {
2516
+ if (!this.control.value) {
2502
2517
  return;
2503
2518
  }
2504
- const dateValue = this.getDateValue(value);
2505
- const isDateValid = dateValue && this.dateFormatter.dateIsValid(dateValue);
2506
- if (!isDateValid || !this.isDateStringValid(value)) {
2507
- // Mark the invalid control as touched so that the input's invalid CSS styles appear.
2508
- // (This is only required when the invalid value is set by the FormControl constructor.)
2509
- this.control.markAsTouched();
2510
- return {
2511
- skyDate: {
2519
+ const value = control.value;
2520
+ let fuzzyDate;
2521
+ let validationError;
2522
+ if (typeof value === 'string') {
2523
+ fuzzyDate = this.fuzzyDateService.getFuzzyDateFromString(value, this.dateFormat);
2524
+ }
2525
+ else {
2526
+ fuzzyDate = value;
2527
+ }
2528
+ if (!fuzzyDate) {
2529
+ validationError = {
2530
+ skyFuzzyDate: {
2512
2531
  invalid: value,
2513
2532
  },
2514
2533
  };
2515
2534
  }
2516
- const minDate = this.minDate;
2517
- if (minDate && this.dateFormatter.dateIsValid(minDate) && value < minDate) {
2518
- return {
2519
- skyDate: {
2520
- minDate,
2535
+ if (!validationError && !fuzzyDate.year && this.yearRequired) {
2536
+ validationError = {
2537
+ skyFuzzyDate: {
2538
+ yearRequired: value,
2521
2539
  },
2522
2540
  };
2523
2541
  }
2524
- const maxDate = this.maxDate;
2525
- if (maxDate && this.dateFormatter.dateIsValid(maxDate) && value > maxDate) {
2526
- return {
2527
- skyDate: {
2528
- maxDate,
2529
- },
2530
- };
2542
+ if (!validationError && fuzzyDate.year) {
2543
+ let fuzzyDateRange;
2544
+ if (this.maxDate) {
2545
+ fuzzyDateRange = this.fuzzyDateService.getFuzzyDateRange(fuzzyDate, this.maxDate);
2546
+ if (!fuzzyDateRange.valid) {
2547
+ validationError = {
2548
+ skyFuzzyDate: {
2549
+ maxDate: value,
2550
+ },
2551
+ };
2552
+ }
2553
+ }
2554
+ if (!validationError && this.minDate) {
2555
+ fuzzyDateRange = this.fuzzyDateService.getFuzzyDateRange(this.minDate, fuzzyDate);
2556
+ if (!fuzzyDateRange.valid) {
2557
+ validationError = {
2558
+ skyFuzzyDate: {
2559
+ minDate: value,
2560
+ },
2561
+ };
2562
+ }
2563
+ }
2564
+ if (!validationError && this.futureDisabled) {
2565
+ fuzzyDateRange = this.fuzzyDateService.getFuzzyDateRange(fuzzyDate, this.fuzzyDateService.getCurrentFuzzyDate());
2566
+ if (!fuzzyDateRange.valid) {
2567
+ validationError = {
2568
+ skyFuzzyDate: {
2569
+ futureDisabled: value,
2570
+ },
2571
+ };
2572
+ }
2573
+ }
2574
+ }
2575
+ if (validationError) {
2576
+ // Mark the invalid control as touched so that the input's invalid CSS styles appear.
2577
+ // (This is only required when the invalid value is set by the FormControl constructor.)
2578
+ this.control.markAsTouched();
2531
2579
  }
2580
+ return validationError;
2532
2581
  }
2533
2582
  registerOnChange(fn) {
2534
2583
  this.onChange = fn;
@@ -2550,14 +2599,6 @@ class SkyDatepickerInputDirective {
2550
2599
  detectInputValueChange() {
2551
2600
  this.onValueChange(this.elementRef.nativeElement.value);
2552
2601
  }
2553
- applyDateFormat() {
2554
- this.updatePlaceholder();
2555
- if (this.value) {
2556
- const formattedDate = this.dateFormatter.format(this.value, this.dateFormat);
2557
- this.setInputElementValue(formattedDate);
2558
- this.changeDetector.markForCheck();
2559
- }
2560
- }
2561
2602
  onValueChange(newValue) {
2562
2603
  this.isFirstChange = false;
2563
2604
  this.value = newValue;
@@ -2565,87 +2606,69 @@ class SkyDatepickerInputDirective {
2565
2606
  setInputElementValue(value) {
2566
2607
  this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
2567
2608
  }
2568
- getDateValue(value) {
2569
- let dateValue;
2570
- if (value instanceof Date) {
2571
- dateValue = value;
2572
- }
2573
- else if (typeof value === 'string') {
2574
- const date = this.dateFormatter.getDateFromString(value, this.dateFormat, this.strict);
2575
- if (this.dateFormatter.dateIsValid(date)) {
2576
- dateValue = date;
2609
+ getMaxDate() {
2610
+ if (this.maxDate) {
2611
+ const maxDate = this.fuzzyDateService.getMomentFromFuzzyDate(this.maxDate);
2612
+ if (maxDate.isValid()) {
2613
+ return maxDate.toDate();
2577
2614
  }
2578
2615
  }
2579
- return dateValue;
2580
- }
2581
- /**
2582
- * Validates the input value to ensure it is formatted correctly.
2583
- */
2584
- isDateStringValid(value) {
2585
- if (!value || typeof value !== 'string') {
2586
- return true;
2587
- }
2588
- // Does the value only include digits, dashes, or slashes?
2589
- const regexp = /^[\d\/\-]+$/;
2590
- const isValid = regexp.test(value);
2591
- if (isValid) {
2592
- return true;
2616
+ else if (this.futureDisabled) {
2617
+ return new Date();
2593
2618
  }
2594
- // If not, does it conform to the standard ISO format?
2595
- const isValidIso = moment(value, moment.ISO_8601).isValid();
2596
- return isValidIso;
2619
+ return this.configService.maxDate;
2597
2620
  }
2598
- notifyUpdatedValue() {
2599
- this.onChange(this._value);
2600
- // Do not mark the field as "dirty"
2601
- // if the field has been initialized with a value.
2602
- if (this.isFirstChange && this.control) {
2603
- this.control.markAsPristine();
2604
- }
2605
- if (this.isFirstChange && this._value) {
2606
- this.isFirstChange = false;
2621
+ getMinDate() {
2622
+ if (this.minDate) {
2623
+ const minDate = this.fuzzyDateService.getMomentFromFuzzyDate(this.minDate);
2624
+ if (minDate.isValid()) {
2625
+ return minDate.toDate();
2626
+ }
2607
2627
  }
2608
- this.datepickerComponent.selectedDate = this._value;
2628
+ return this.configService.minDate;
2609
2629
  }
2610
- updatePlaceholder() {
2611
- if (!this.initialPlaceholder) {
2612
- this.adapter.setPlaceholder(this.elementRef, this.dateFormat);
2613
- }
2630
+ /* istanbul ignore next */
2631
+ fuzzyDatesEqual(dateA, dateB) {
2632
+ return (dateA &&
2633
+ dateB &&
2634
+ ((!dateA.day && !dateB.day) || dateA.day === dateB.day) &&
2635
+ ((!dateA.month && !dateB.month) || dateA.month === dateB.month) &&
2636
+ ((!dateA.year && !dateB.year) || dateA.year === dateB.year));
2614
2637
  }
2615
2638
  }
2616
- 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 });
2617
- 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: [
2618
- SKY_DATEPICKER_VALUE_ACCESSOR,
2619
- SKY_DATEPICKER_VALIDATOR,
2620
- SkyDatepickerAdapterService,
2639
+ 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
+ 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: [
2641
+ SKY_FUZZY_DATEPICKER_VALUE_ACCESSOR,
2642
+ SKY_FUZZY_DATEPICKER_VALIDATOR,
2621
2643
  ], ngImport: i0 });
2622
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerInputDirective, decorators: [{
2644
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFuzzyDatepickerInputDirective, decorators: [{
2623
2645
  type: Directive,
2624
2646
  args: [{
2625
- selector: '[skyDatepickerInput]',
2647
+ selector: '[skyFuzzyDatepickerInput]',
2626
2648
  providers: [
2627
- SKY_DATEPICKER_VALUE_ACCESSOR,
2628
- SKY_DATEPICKER_VALIDATOR,
2629
- SkyDatepickerAdapterService,
2649
+ SKY_FUZZY_DATEPICKER_VALUE_ACCESSOR,
2650
+ SKY_FUZZY_DATEPICKER_VALIDATOR,
2630
2651
  ],
2631
2652
  }]
2632
- }], ctorParameters: function () { return [{ type: SkyDatepickerAdapterService }, { type: i0.ChangeDetectorRef }, { type: SkyDatepickerConfigService }, { type: i0.ElementRef }, { type: i3.SkyAppLocaleProvider }, { type: i0.Renderer2 }, { type: i3.SkyLibResourcesService }, { type: SkyDatepickerComponent, decorators: [{
2653
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: SkyDatepickerConfigService }, { type: i0.ElementRef }, { type: SkyFuzzyDateService }, { type: i3.SkyAppLocaleProvider }, { type: i0.Renderer2 }, { type: i3.SkyLibResourcesService }, { type: SkyDatepickerComponent, decorators: [{
2633
2654
  type: Optional
2634
2655
  }] }]; }, propDecorators: { dateFormat: [{
2635
2656
  type: Input
2636
2657
  }], disabled: [{
2637
2658
  type: Input
2659
+ }], futureDisabled: [{
2660
+ type: Input
2638
2661
  }], maxDate: [{
2639
2662
  type: Input
2640
2663
  }], minDate: [{
2641
2664
  type: Input
2642
- }], skyDatepickerInput: [{
2643
- type: Input
2644
2665
  }], skyDatepickerNoValidate: [{
2645
2666
  type: Input
2667
+ }], skyFuzzyDatepickerInput: [{
2668
+ type: Input
2646
2669
  }], startingDay: [{
2647
2670
  type: Input
2648
- }], strict: [{
2671
+ }], yearRequired: [{
2649
2672
  type: Input
2650
2673
  }], onInputChange: [{
2651
2674
  type: HostListener,
@@ -2659,63 +2682,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
2659
2682
  }] } });
2660
2683
 
2661
2684
  // tslint:disable:no-forward-ref no-use-before-declare
2662
- const SKY_FUZZY_DATEPICKER_VALUE_ACCESSOR = {
2685
+ const SKY_DATEPICKER_VALUE_ACCESSOR = {
2663
2686
  provide: NG_VALUE_ACCESSOR,
2664
- useExisting: forwardRef(() => SkyFuzzyDatepickerInputDirective),
2687
+ useExisting: forwardRef(() => SkyDatepickerInputDirective),
2665
2688
  multi: true,
2666
2689
  };
2667
- const SKY_FUZZY_DATEPICKER_VALIDATOR = {
2690
+ const SKY_DATEPICKER_VALIDATOR = {
2668
2691
  provide: NG_VALIDATORS,
2669
- useExisting: forwardRef(() => SkyFuzzyDatepickerInputDirective),
2692
+ useExisting: forwardRef(() => SkyDatepickerInputDirective),
2670
2693
  multi: true,
2671
2694
  };
2672
2695
  // tslint:enable
2673
- class SkyFuzzyDatepickerInputDirective {
2674
- constructor(changeDetector, configService, elementRef, fuzzyDateService, localeProvider, renderer, resourcesService, datepickerComponent) {
2696
+ class SkyDatepickerInputDirective {
2697
+ constructor(adapter, changeDetector, configService, elementRef, localeProvider, renderer, resourcesService, datepickerComponent) {
2698
+ this.adapter = adapter;
2675
2699
  this.changeDetector = changeDetector;
2676
2700
  this.configService = configService;
2677
2701
  this.elementRef = elementRef;
2678
- this.fuzzyDateService = fuzzyDateService;
2679
2702
  this.localeProvider = localeProvider;
2680
2703
  this.renderer = renderer;
2681
2704
  this.resourcesService = resourcesService;
2682
2705
  this.datepickerComponent = datepickerComponent;
2683
2706
  /**
2684
- * Indicates whether to disable date validation on the fuzzy datepicker input.
2707
+ * Indicates whether to disable date validation on the datepicker input.
2685
2708
  * @default false
2686
2709
  */
2687
2710
  this.skyDatepickerNoValidate = false;
2688
2711
  this.dateFormatter = new SkyDateFormatter();
2689
2712
  this.isFirstChange = true;
2690
2713
  this.ngUnsubscribe = new Subject();
2691
- this._futureDisabled = false;
2692
- this._disabled = false;
2693
- this._yearRequired = false;
2694
2714
  this.onChange = (_) => { };
2695
2715
  /*istanbul ignore next */
2696
2716
  this.onTouched = () => { };
2697
2717
  this.onValidatorChange = () => { };
2718
+ this.initialPlaceholder = this.adapter.getPlaceholder(this.elementRef);
2719
+ this.updatePlaceholder();
2698
2720
  this.localeProvider
2699
2721
  .getLocaleInfo()
2700
2722
  .pipe(takeUntil(this.ngUnsubscribe))
2701
2723
  .subscribe((localeInfo) => {
2702
- this.locale = localeInfo.locale;
2703
- SkyDateFormatter.setLocale(this.locale);
2724
+ SkyDateFormatter.setLocale(localeInfo.locale);
2704
2725
  this.preferredShortDateFormat =
2705
2726
  SkyDateFormatter.getPreferredShortDateFormat();
2727
+ this.applyDateFormat();
2706
2728
  });
2707
2729
  }
2708
2730
  /**
2709
2731
  * Specifies the date format for the input. Place this attribute on the `input` element
2710
- * to override the default in `SkyDatepickerConfigService`.
2732
+ * to override the default in the `SkyDatepickerConfigService`.
2711
2733
  * @default "MM/DD/YYYY"
2712
2734
  */
2713
2735
  set dateFormat(value) {
2714
- this._dateFormat = value;
2715
- if (this.value) {
2716
- const formattedDate = this.fuzzyDateService.format(this.value, this.dateFormat, this.locale);
2717
- this.setInputElementValue(formattedDate);
2718
- this.changeDetector.markForCheck();
2736
+ /* istanbul ignore else */
2737
+ if (value !== this._dateFormat) {
2738
+ this._dateFormat = value;
2739
+ this.applyDateFormat();
2719
2740
  }
2720
2741
  }
2721
2742
  get dateFormat() {
@@ -2733,57 +2754,54 @@ class SkyFuzzyDatepickerInputDirective {
2733
2754
  this.renderer.setProperty(this.elementRef.nativeElement, 'disabled', value);
2734
2755
  }
2735
2756
  get disabled() {
2736
- return this._disabled;
2757
+ return this._disabled || false;
2737
2758
  }
2738
2759
  /**
2739
- * Indicates whether to prevent users from specifying dates that are in the future.
2740
- * Place this attribute on the `input` element.
2741
- * @default false
2760
+ * @internal
2761
+ * Indicates if the input element or any of its children have focus.
2742
2762
  */
2743
- set futureDisabled(value) {
2744
- this._futureDisabled = value;
2745
- this.onValidatorChange();
2746
- }
2747
- get futureDisabled() {
2748
- return this._futureDisabled;
2763
+ get inputIsFocused() {
2764
+ return this.adapter.elementIsFocused();
2749
2765
  }
2750
2766
  /**
2751
- * Specifies the latest fuzzy date allowed. Place this attribute on the `input` element
2752
- * to prevent fuzzy dates after a specified date. This property accepts
2753
- * a `SkyFuzzyDate` value that includes numeric month, day, and year values.
2754
- * For example: `{ month: 1, day: 1, year: 2027 }`.
2767
+ * Specifies the latest date that is available in the calendar. Place this attribute on
2768
+ * the `input` element to override the default in `SkyDatepickerConfigService`.
2755
2769
  */
2756
2770
  set maxDate(value) {
2757
2771
  this._maxDate = value;
2758
- this.datepickerComponent.maxDate = this.getMaxDate();
2772
+ this.datepickerComponent.maxDate = this.maxDate;
2759
2773
  this.onValidatorChange();
2760
2774
  }
2761
2775
  get maxDate() {
2762
- return this._maxDate;
2776
+ return this._maxDate || this.configService.maxDate;
2763
2777
  }
2764
2778
  /**
2765
- * Specifies the earliest fuzzy date allowed. Place this attribute on the `input` element
2766
- * to prevent fuzzy dates before a specified date. This property accepts a `SkyFuzzyDate` value
2767
- * that includes numeric month, day, and year values.
2768
- * For example: `{ month: 1, day: 1, year: 2007 }`.
2779
+ * Specifies the earliest date that is available in the calendar. Place this attribute on
2780
+ * the `input` element to override the default in `SkyDatepickerConfigService`.
2769
2781
  */
2770
2782
  set minDate(value) {
2771
2783
  this._minDate = value;
2772
- this.datepickerComponent.minDate = this.getMinDate();
2784
+ this.datepickerComponent.minDate = this.minDate;
2773
2785
  this.onValidatorChange();
2774
2786
  }
2775
2787
  get minDate() {
2776
- return this._minDate;
2788
+ return this._minDate || this.configService.minDate;
2777
2789
  }
2778
2790
  /**
2779
- * Creates the fuzzy datepicker input and calendar to let users specify dates that are
2780
- * not complete. For example, if users know the year but not the month or day, they can
2781
- * enter just the year. Place this directive on an `input` element, and wrap the `input`
2782
- * in a `sky-datepicker` component. The value that users select is driven
2791
+ * Creates the datepicker input and calendar. Place this directive on an `input` element,
2792
+ * and wrap the input in a `sky-datepicker` component. The value that users select is driven
2783
2793
  * through the `ngModel` attribute specified on the `input` element.
2784
2794
  * @required
2785
2795
  */
2786
- set skyFuzzyDatepickerInput(value) { }
2796
+ set skyDatepickerInput(value) {
2797
+ if (value) {
2798
+ console.warn('[Deprecation warning] You no longer need to provide a template reference variable ' +
2799
+ 'to the `skyDatepickerInput` attribute (this will be a breaking change in the next ' +
2800
+ 'major version release).\n' +
2801
+ 'Do this instead:\n' +
2802
+ '<sky-datepicker>\n <input skyDatepickerInput />\n</sky-datepicker>');
2803
+ }
2804
+ }
2787
2805
  /**
2788
2806
  * Specifies the starting day of the week in the calendar, where `0` sets the starting day
2789
2807
  * to Sunday. Place this attribute on the `input` element to override the default
@@ -2799,79 +2817,54 @@ class SkyFuzzyDatepickerInputDirective {
2799
2817
  return this._startingDay || this.configService.startingDay;
2800
2818
  }
2801
2819
  /**
2802
- * Indicates whether to require the year in fuzzy dates.
2820
+ * Indicates whether the format of the date value must match the format from the `dateFormat` value.
2821
+ * If this property is `true` and the datepicker input directive cannot find an exact match, then
2822
+ * the input is marked as invalid.
2823
+ * If this property is `false` and the datepicker input directive cannot find an exact match, then
2824
+ * it attempts to format the string based on the [ISO 8601 standard format](https://www.iso.org/iso-8601-date-and-time-format.html).
2803
2825
  * @default false
2804
2826
  */
2805
- set yearRequired(value) {
2806
- this._yearRequired = value;
2807
- this.onValidatorChange();
2827
+ set strict(value) {
2828
+ this._strict = value;
2808
2829
  }
2809
- get yearRequired() {
2810
- return this._yearRequired;
2830
+ get strict() {
2831
+ return this._strict || false;
2811
2832
  }
2812
2833
  get value() {
2813
2834
  return this._value;
2814
2835
  }
2815
2836
  set value(value) {
2816
- let fuzzyDate;
2817
- let fuzzyMoment;
2818
- let dateValue;
2819
- let formattedDate;
2820
- if (value instanceof Date) {
2821
- dateValue = value;
2822
- formattedDate = this.dateFormatter.format(value, this.dateFormat);
2823
- fuzzyDate = this.fuzzyDateService.getFuzzyDateFromSelectedDate(value, this.dateFormat);
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();
2824
2847
  }
2825
- else if (typeof value === 'string') {
2826
- fuzzyDate = this.fuzzyDateService.getFuzzyDateFromString(value, this.dateFormat);
2827
- formattedDate = this.fuzzyDateService.format(fuzzyDate, this.dateFormat, this.locale);
2828
- if (!formattedDate) {
2829
- formattedDate = value;
2830
- }
2831
- fuzzyMoment = this.fuzzyDateService.getMomentFromFuzzyDate(fuzzyDate);
2832
- if (fuzzyMoment) {
2833
- dateValue = fuzzyMoment.toDate();
2834
- }
2848
+ else if (dateValue !== this._value || !areDatesEqual) {
2849
+ this._value = dateValue || value;
2850
+ this.notifyUpdatedValue();
2835
2851
  }
2836
- else {
2837
- fuzzyDate = value;
2838
- formattedDate = this.fuzzyDateService.format(fuzzyDate, this.dateFormat, this.locale);
2839
- fuzzyMoment = this.fuzzyDateService.getMomentFromFuzzyDate(fuzzyDate);
2840
- if (fuzzyMoment) {
2841
- dateValue = fuzzyMoment.toDate();
2842
- }
2852
+ if (dateValue && isValidDateString) {
2853
+ const formattedDate = this.dateFormatter.format(dateValue, this.dateFormat);
2854
+ this.setInputElementValue(formattedDate);
2843
2855
  }
2844
- const areFuzzyDatesEqual = this.fuzzyDatesEqual(this._value, fuzzyDate);
2845
- const isNewValue = fuzzyDate !== this._value || !areFuzzyDatesEqual;
2846
- this._value = fuzzyDate || value;
2847
- if (isNewValue) {
2848
- this.onChange(this._value);
2849
- // Do not mark the field as "dirty"
2850
- // if the field has been initialized with a value.
2851
- if (this.isFirstChange && this.control) {
2852
- this.control.markAsPristine();
2853
- }
2854
- if (this.isFirstChange && this._value) {
2855
- this.isFirstChange = false;
2856
- }
2857
- this.datepickerComponent.selectedDate = dateValue;
2856
+ else {
2857
+ this.setInputElementValue(value || '');
2858
2858
  }
2859
- this.setInputElementValue(formattedDate || '');
2860
2859
  }
2861
2860
  ngOnInit() {
2862
- if (this.yearRequired) {
2863
- if (this.dateFormat.toLowerCase().indexOf('y') === -1) {
2864
- throw new Error('You have configured conflicting settings. Year is required and dateFormat does not include year.');
2865
- }
2866
- }
2867
2861
  if (!this.datepickerComponent) {
2868
- throw new Error('You must wrap the `skyFuzzyDatepickerInput` directive within a ' +
2862
+ throw new Error('You must wrap the `skyDatepickerInput` directive within a ' +
2869
2863
  '`<sky-datepicker>` component!');
2870
2864
  }
2871
2865
  const element = this.elementRef.nativeElement;
2872
2866
  this.renderer.addClass(element, 'sky-form-control');
2873
2867
  const hasAriaLabel = element.getAttribute('aria-label');
2874
- /* istanbul ignore else */
2875
2868
  if (!hasAriaLabel) {
2876
2869
  this.resourcesService
2877
2870
  .getString('skyux_date_field_default_label')
@@ -2883,7 +2876,8 @@ class SkyFuzzyDatepickerInputDirective {
2883
2876
  }
2884
2877
  ngAfterContentInit() {
2885
2878
  this.datepickerComponent.dateChange
2886
- .pipe(distinctUntilChanged(), takeUntil(this.ngUnsubscribe))
2879
+ .pipe(distinctUntilChanged())
2880
+ .pipe(takeUntil(this.ngUnsubscribe))
2887
2881
  .subscribe((value) => {
2888
2882
  this.isFirstChange = false;
2889
2883
  this.value = value;
@@ -2905,20 +2899,33 @@ class SkyFuzzyDatepickerInputDirective {
2905
2899
  this.changeDetector.markForCheck();
2906
2900
  });
2907
2901
  }
2902
+ this.adapter.init(this.elementRef);
2908
2903
  }
2909
2904
  ngOnDestroy() {
2910
2905
  this.ngUnsubscribe.next();
2911
2906
  this.ngUnsubscribe.complete();
2912
2907
  }
2913
2908
  onInputChange(event) {
2914
- this.onValueChange(event.target.value);
2909
+ const value = event.target.value;
2910
+ if (this.skyDatepickerNoValidate) {
2911
+ this.onValueChange(value);
2912
+ return;
2913
+ }
2914
+ // Don't try to parse the string value into a Date value if it is malformed.
2915
+ if (this.isDateStringValid(value)) {
2916
+ this.onValueChange(value);
2917
+ return;
2918
+ }
2919
+ this._value = value;
2920
+ this.onChange(value);
2921
+ this.control.setErrors({
2922
+ skyDate: {
2923
+ invalid: true,
2924
+ },
2925
+ });
2915
2926
  }
2916
2927
  onInputBlur() {
2917
2928
  this.onTouched();
2918
- let formattedDate = this.fuzzyDateService.format(this.value, this.dateFormat, this.locale);
2919
- if (this.control.valid) {
2920
- this.setInputElementValue(formattedDate);
2921
- }
2922
2929
  }
2923
2930
  onInputKeyup() {
2924
2931
  this.control.markAsDirty();
@@ -2933,71 +2940,38 @@ class SkyFuzzyDatepickerInputDirective {
2933
2940
  if (this.skyDatepickerNoValidate) {
2934
2941
  return;
2935
2942
  }
2936
- if (!this.control.value) {
2937
- return;
2938
- }
2939
2943
  const value = control.value;
2940
- let fuzzyDate;
2941
- let validationError;
2942
- if (typeof value === 'string') {
2943
- fuzzyDate = this.fuzzyDateService.getFuzzyDateFromString(value, this.dateFormat);
2944
- }
2945
- else {
2946
- fuzzyDate = value;
2944
+ if (!value) {
2945
+ return;
2947
2946
  }
2948
- if (!fuzzyDate) {
2949
- validationError = {
2950
- skyFuzzyDate: {
2947
+ const dateValue = this.getDateValue(value);
2948
+ const isDateValid = dateValue && this.dateFormatter.dateIsValid(dateValue);
2949
+ if (!isDateValid || !this.isDateStringValid(value)) {
2950
+ // Mark the invalid control as touched so that the input's invalid CSS styles appear.
2951
+ // (This is only required when the invalid value is set by the FormControl constructor.)
2952
+ this.control.markAsTouched();
2953
+ return {
2954
+ skyDate: {
2951
2955
  invalid: value,
2952
2956
  },
2953
2957
  };
2954
2958
  }
2955
- if (!validationError && !fuzzyDate.year && this.yearRequired) {
2956
- validationError = {
2957
- skyFuzzyDate: {
2958
- yearRequired: value,
2959
+ const minDate = this.minDate;
2960
+ if (minDate && this.dateFormatter.dateIsValid(minDate) && value < minDate) {
2961
+ return {
2962
+ skyDate: {
2963
+ minDate,
2959
2964
  },
2960
2965
  };
2961
2966
  }
2962
- if (!validationError && fuzzyDate.year) {
2963
- let fuzzyDateRange;
2964
- if (this.maxDate) {
2965
- fuzzyDateRange = this.fuzzyDateService.getFuzzyDateRange(fuzzyDate, this.maxDate);
2966
- if (!fuzzyDateRange.valid) {
2967
- validationError = {
2968
- skyFuzzyDate: {
2969
- maxDate: value,
2970
- },
2971
- };
2972
- }
2973
- }
2974
- if (!validationError && this.minDate) {
2975
- fuzzyDateRange = this.fuzzyDateService.getFuzzyDateRange(this.minDate, fuzzyDate);
2976
- if (!fuzzyDateRange.valid) {
2977
- validationError = {
2978
- skyFuzzyDate: {
2979
- minDate: value,
2980
- },
2981
- };
2982
- }
2983
- }
2984
- if (!validationError && this.futureDisabled) {
2985
- fuzzyDateRange = this.fuzzyDateService.getFuzzyDateRange(fuzzyDate, this.fuzzyDateService.getCurrentFuzzyDate());
2986
- if (!fuzzyDateRange.valid) {
2987
- validationError = {
2988
- skyFuzzyDate: {
2989
- futureDisabled: value,
2990
- },
2991
- };
2992
- }
2993
- }
2994
- }
2995
- if (validationError) {
2996
- // Mark the invalid control as touched so that the input's invalid CSS styles appear.
2997
- // (This is only required when the invalid value is set by the FormControl constructor.)
2998
- this.control.markAsTouched();
2967
+ const maxDate = this.maxDate;
2968
+ if (maxDate && this.dateFormatter.dateIsValid(maxDate) && value > maxDate) {
2969
+ return {
2970
+ skyDate: {
2971
+ maxDate,
2972
+ },
2973
+ };
2999
2974
  }
3000
- return validationError;
3001
2975
  }
3002
2976
  registerOnChange(fn) {
3003
2977
  this.onChange = fn;
@@ -3019,6 +2993,14 @@ class SkyFuzzyDatepickerInputDirective {
3019
2993
  detectInputValueChange() {
3020
2994
  this.onValueChange(this.elementRef.nativeElement.value);
3021
2995
  }
2996
+ applyDateFormat() {
2997
+ this.updatePlaceholder();
2998
+ if (this.value) {
2999
+ const formattedDate = this.dateFormatter.format(this.value, this.dateFormat);
3000
+ this.setInputElementValue(formattedDate);
3001
+ this.changeDetector.markForCheck();
3002
+ }
3003
+ }
3022
3004
  onValueChange(newValue) {
3023
3005
  this.isFirstChange = false;
3024
3006
  this.value = newValue;
@@ -3026,69 +3008,87 @@ class SkyFuzzyDatepickerInputDirective {
3026
3008
  setInputElementValue(value) {
3027
3009
  this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
3028
3010
  }
3029
- getMaxDate() {
3030
- if (this.maxDate) {
3031
- const maxDate = this.fuzzyDateService.getMomentFromFuzzyDate(this.maxDate);
3032
- if (maxDate.isValid()) {
3033
- return maxDate.toDate();
3011
+ getDateValue(value) {
3012
+ let dateValue;
3013
+ if (value instanceof Date) {
3014
+ dateValue = value;
3015
+ }
3016
+ else if (typeof value === 'string') {
3017
+ const date = this.dateFormatter.getDateFromString(value, this.dateFormat, this.strict);
3018
+ if (this.dateFormatter.dateIsValid(date)) {
3019
+ dateValue = date;
3034
3020
  }
3035
3021
  }
3036
- else if (this.futureDisabled) {
3037
- return new Date();
3022
+ return dateValue;
3023
+ }
3024
+ /**
3025
+ * Validates the input value to ensure it is formatted correctly.
3026
+ */
3027
+ isDateStringValid(value) {
3028
+ if (!value || typeof value !== 'string') {
3029
+ return true;
3038
3030
  }
3039
- return this.configService.maxDate;
3031
+ // Does the value only include digits, dashes, or slashes?
3032
+ const regexp = /^[\d\/\-]+$/;
3033
+ const isValid = regexp.test(value);
3034
+ if (isValid) {
3035
+ return true;
3036
+ }
3037
+ // If not, does it conform to the standard ISO format?
3038
+ const isValidIso = moment(value, moment.ISO_8601).isValid();
3039
+ return isValidIso;
3040
3040
  }
3041
- getMinDate() {
3042
- if (this.minDate) {
3043
- const minDate = this.fuzzyDateService.getMomentFromFuzzyDate(this.minDate);
3044
- if (minDate.isValid()) {
3045
- return minDate.toDate();
3046
- }
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
3047
  }
3048
- return this.configService.minDate;
3048
+ if (this.isFirstChange && this._value) {
3049
+ this.isFirstChange = false;
3050
+ }
3051
+ this.datepickerComponent.selectedDate = this._value;
3049
3052
  }
3050
- /* istanbul ignore next */
3051
- fuzzyDatesEqual(dateA, dateB) {
3052
- return (dateA &&
3053
- dateB &&
3054
- ((!dateA.day && !dateB.day) || dateA.day === dateB.day) &&
3055
- ((!dateA.month && !dateB.month) || dateA.month === dateB.month) &&
3056
- ((!dateA.year && !dateB.year) || dateA.year === dateB.year));
3053
+ updatePlaceholder() {
3054
+ if (!this.initialPlaceholder) {
3055
+ this.adapter.setPlaceholder(this.elementRef, this.dateFormat);
3056
+ }
3057
3057
  }
3058
3058
  }
3059
- 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 });
3060
- 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: [
3061
- SKY_FUZZY_DATEPICKER_VALUE_ACCESSOR,
3062
- SKY_FUZZY_DATEPICKER_VALIDATOR,
3059
+ 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
+ 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: [
3061
+ SKY_DATEPICKER_VALUE_ACCESSOR,
3062
+ SKY_DATEPICKER_VALIDATOR,
3063
+ SkyDatepickerAdapterService,
3063
3064
  ], ngImport: i0 });
3064
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFuzzyDatepickerInputDirective, decorators: [{
3065
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyDatepickerInputDirective, decorators: [{
3065
3066
  type: Directive,
3066
3067
  args: [{
3067
- selector: '[skyFuzzyDatepickerInput]',
3068
+ selector: '[skyDatepickerInput]',
3068
3069
  providers: [
3069
- SKY_FUZZY_DATEPICKER_VALUE_ACCESSOR,
3070
- SKY_FUZZY_DATEPICKER_VALIDATOR,
3070
+ SKY_DATEPICKER_VALUE_ACCESSOR,
3071
+ SKY_DATEPICKER_VALIDATOR,
3072
+ SkyDatepickerAdapterService,
3071
3073
  ],
3072
3074
  }]
3073
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: SkyDatepickerConfigService }, { type: i0.ElementRef }, { type: SkyFuzzyDateService }, { type: i3.SkyAppLocaleProvider }, { type: i0.Renderer2 }, { type: i3.SkyLibResourcesService }, { type: SkyDatepickerComponent, decorators: [{
3075
+ }], ctorParameters: function () { return [{ type: SkyDatepickerAdapterService }, { type: i0.ChangeDetectorRef }, { type: SkyDatepickerConfigService }, { type: i0.ElementRef }, { type: i3.SkyAppLocaleProvider }, { type: i0.Renderer2 }, { type: i3.SkyLibResourcesService }, { type: SkyDatepickerComponent, decorators: [{
3074
3076
  type: Optional
3075
3077
  }] }]; }, propDecorators: { dateFormat: [{
3076
3078
  type: Input
3077
3079
  }], disabled: [{
3078
3080
  type: Input
3079
- }], futureDisabled: [{
3080
- type: Input
3081
3081
  }], maxDate: [{
3082
3082
  type: Input
3083
3083
  }], minDate: [{
3084
3084
  type: Input
3085
- }], skyDatepickerNoValidate: [{
3085
+ }], skyDatepickerInput: [{
3086
3086
  type: Input
3087
- }], skyFuzzyDatepickerInput: [{
3087
+ }], skyDatepickerNoValidate: [{
3088
3088
  type: Input
3089
3089
  }], startingDay: [{
3090
3090
  type: Input
3091
- }], yearRequired: [{
3091
+ }], strict: [{
3092
3092
  type: Input
3093
3093
  }], onInputChange: [{
3094
3094
  type: HostListener,
@@ -4625,7 +4625,7 @@ class SkyTimepickerInputDirective {
4625
4625
  if (!this.control) {
4626
4626
  this.control = control;
4627
4627
  }
4628
- let value = control.value;
4628
+ const value = control.value;
4629
4629
  if (!value) {
4630
4630
  return undefined;
4631
4631
  }