@hmcts/rpx-xui-common-lib 1.4.30-date-component-common-validation → 1.4.31-date-component-validation-fixes

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.
@@ -11,7 +11,9 @@ import { Component, Input } from '@angular/core';
11
11
  * displaying errorMessage messages
12
12
  * */
13
13
  export class GovUkDateComponent {
14
- constructor() { }
14
+ constructor() {
15
+ this.isOptional = false;
16
+ }
15
17
  /**
16
18
  * @return {?}
17
19
  */
@@ -27,21 +29,39 @@ export class GovUkDateComponent {
27
29
  * @private
28
30
  * @param {?} d
29
31
  * @param {?} month
32
+ * @param {?} year
30
33
  * @return {?}
31
34
  */
32
- isValidDate(d, month) {
35
+ isValidDate(d, month, year) {
36
+ /** @type {?} */
37
+ const dateCheck = !isNaN(d.getTime());
38
+ // Month mismatch occurs if the provided day or month are invalid, or either is omitted. **Note:** This is insufficient for
39
+ // checking date validity when the year is omitted because it defaults to 1900 - an extra check is required
33
40
  /** @type {?} */
34
- const dateCheck = d instanceof Date && !isNaN(d.getTime());
41
+ const monthMatch = d.getMonth() === month;
35
42
  /** @type {?} */
36
- const leapYearCheck = d.getMonth() === month;
37
- return dateCheck && leapYearCheck;
43
+ const yearMatch = d.getFullYear() === year;
44
+ return dateCheck && monthMatch && yearMatch;
45
+ }
46
+ /**
47
+ * @private
48
+ * @param {?} value
49
+ * @return {?}
50
+ */
51
+ isEmpty(value) {
52
+ // Note: Intentional use of == to check for null or undefined
53
+ /* eslint-disable eqeqeq */
54
+ /* tslint:disable:triple-equals */
55
+ // NaN and < 0 checks required for month field
56
+ return value == null || value === '' || isNaN(value) || value < 0;
57
+ /* eslint-enable eqeqeq */
58
+ /* tslint:enable:triple-equals */
38
59
  }
39
60
  /**
40
61
  * @return {?}
41
62
  */
42
63
  DateValidator() {
43
- /** @type {?} */
44
- const res = (/**
64
+ return (/**
45
65
  * @return {?}
46
66
  */
47
67
  () => {
@@ -51,11 +71,13 @@ export class GovUkDateComponent {
51
71
  const month = this.formGroup.get(this.month).value - 1;
52
72
  /** @type {?} */
53
73
  const year = this.formGroup.get(this.year).value;
54
- /** @type {?} */
55
- const isValid = this.isValidDate(new Date(year, month, day), month);
56
- return !isValid ? { dateComponent: true } : null;
74
+ // Validation should pass if the date field is optional and day, month, and year are all empty
75
+ if (this.isOptional && this.isEmpty(day) && this.isEmpty(month) && this.isEmpty(year)) {
76
+ return null;
77
+ }
78
+ // + to coerce year to a number
79
+ return !this.isValidDate(new Date(year, month, day), month, +year) ? { dateComponent: true } : null;
57
80
  });
58
- return res;
59
81
  }
60
82
  }
61
83
  GovUkDateComponent.decorators = [
@@ -70,7 +92,8 @@ GovUkDateComponent.ctorParameters = () => [];
70
92
  GovUkDateComponent.propDecorators = {
71
93
  config: [{ type: Input }],
72
94
  errorMessage: [{ type: Input }],
73
- formGroup: [{ type: Input }]
95
+ formGroup: [{ type: Input }],
96
+ isOptional: [{ type: Input }]
74
97
  };
75
98
  if (false) {
76
99
  /** @type {?} */
@@ -80,10 +103,12 @@ if (false) {
80
103
  /** @type {?} */
81
104
  GovUkDateComponent.prototype.formGroup;
82
105
  /** @type {?} */
106
+ GovUkDateComponent.prototype.isOptional;
107
+ /** @type {?} */
83
108
  GovUkDateComponent.prototype.month;
84
109
  /** @type {?} */
85
110
  GovUkDateComponent.prototype.day;
86
111
  /** @type {?} */
87
112
  GovUkDateComponent.prototype.year;
88
113
  }
89
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ292LXVrLWRhdGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGhtY3RzL3JweC14dWktY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9nb3YtdWkvY29tcG9uZW50cy9nb3YtdWstZGF0ZS9nb3YtdWstZGF0ZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFFTixNQUFNLGVBQWUsQ0FBQzs7Ozs7OztBQWV2QixNQUFNLE9BQU8sa0JBQWtCO0lBQzdCLGdCQUFlLENBQUM7Ozs7SUFTVCxRQUFRO1FBQ2IsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDbkMsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxRQUFRLENBQUM7UUFDdkMsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLENBQUM7O2NBQy9CLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFO1FBQzFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDNUQsQ0FBQzs7Ozs7OztJQUVPLFdBQVcsQ0FBQyxDQUFNLEVBQUUsS0FBYTs7Y0FDakMsU0FBUyxHQUFHLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDOztjQUNwRCxhQUFhLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLEtBQUs7UUFDNUMsT0FBTyxTQUFTLElBQUksYUFBYSxDQUFDO0lBQ3BDLENBQUM7Ozs7SUFFTSxhQUFhOztjQUNaLEdBQUc7OztRQUFHLEdBQTRCLEVBQUU7O2tCQUNsQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUs7O2tCQUN4QyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDOztrQkFDaEQsSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLOztrQkFDMUMsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUM7WUFDbkUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNuRCxDQUFDLENBQUE7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7OztZQXRDRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLG9CQUFvQjtnQkFDOUIsbTJGQUEyQzs7YUFFNUM7Ozs7O3FCQUdFLEtBQUs7MkJBQ0wsS0FBSzt3QkFDTCxLQUFLOzs7O0lBRk4sb0NBQXlDOztJQUN6QywwQ0FBaUQ7O0lBQ2pELHVDQUErQjs7SUFFL0IsbUNBQWtCOztJQUNsQixpQ0FBZ0I7O0lBQ2hCLGtDQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uSW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvcnMsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlc01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Vycm9yLW1lc3NhZ2VzLW1vZGVsJztcbmltcG9ydCB7IEdvdlVpQ29uZmlnTW9kZWwgfSBmcm9tICcuLi8uLi9tb2RlbHMvZ292LXVpLWNvbmZpZy1tb2RlbCc7XG4vKlxuICogR292IFVLIERhdGUgQ29tcG9uZW50XG4gKiBSZXNwb25zaWJsZSBmb3IgZGlzcGxheWluZyAzIGlucHV0IGZpZWxkczpcbiAqIGRheSAvIG1vbnRoIC8geWVhclxuICogZGlzcGxheWluZyBlcnJvck1lc3NhZ2UgbWVzc2FnZXNcbiAqICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd4dWlsaWItZ292LXVrLWRhdGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vZ292LXVrLWRhdGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9nb3YtdWstZGF0ZS5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIEdvdlVrRGF0ZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIGNvbnN0cnVjdG9yKCkge31cbiAgQElucHV0KCkgcHVibGljIGNvbmZpZzogR292VWlDb25maWdNb2RlbDtcbiAgQElucHV0KCkgcHVibGljIGVycm9yTWVzc2FnZTogRXJyb3JNZXNzYWdlc01vZGVsO1xuICBASW5wdXQoKSBwdWJsaWMgZm9ybUdyb3VwOiBhbnk7XG5cbiAgcHVibGljIG1vbnRoOiBhbnk7XG4gIHB1YmxpYyBkYXk6IGFueTtcbiAgcHVibGljIHllYXI6IGFueTtcblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5kYXkgPSBgJHt0aGlzLmNvbmZpZy5pZH1fZGF5YDtcbiAgICB0aGlzLm1vbnRoID0gYCR7dGhpcy5jb25maWcuaWR9X21vbnRoYDtcbiAgICB0aGlzLnllYXIgPSBgJHt0aGlzLmNvbmZpZy5pZH1feWVhcmA7XG4gICAgY29uc3QgZGF0ZVZhbGlkYXRvciA9IHRoaXMuRGF0ZVZhbGlkYXRvcigpO1xuICAgIHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLmRheSkuc2V0VmFsaWRhdG9ycyhkYXRlVmFsaWRhdG9yKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNWYWxpZERhdGUoZDogYW55LCBtb250aDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGF0ZUNoZWNrID0gZCBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKGQuZ2V0VGltZSgpKTtcbiAgICBjb25zdCBsZWFwWWVhckNoZWNrID0gZC5nZXRNb250aCgpID09PSBtb250aDtcbiAgICByZXR1cm4gZGF0ZUNoZWNrICYmIGxlYXBZZWFyQ2hlY2s7XG4gIH1cblxuICBwdWJsaWMgRGF0ZVZhbGlkYXRvcigpOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgcmVzID0gKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IGRheSA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLmRheSkudmFsdWU7XG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLm1vbnRoKS52YWx1ZSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gdGhpcy5mb3JtR3JvdXAuZ2V0KHRoaXMueWVhcikudmFsdWU7XG4gICAgICBjb25zdCBpc1ZhbGlkID0gdGhpcy5pc1ZhbGlkRGF0ZShuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KSwgbW9udGgpO1xuICAgICAgcmV0dXJuICFpc1ZhbGlkID8geyBkYXRlQ29tcG9uZW50OiB0cnVlIH0gOiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIHJlcztcbiAgfVxufVxuIl19
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ292LXVrLWRhdGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGhtY3RzL3JweC14dWktY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9nb3YtdWkvY29tcG9uZW50cy9nb3YtdWstZGF0ZS9nb3YtdWstZGF0ZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFFTixNQUFNLGVBQWUsQ0FBQzs7Ozs7OztBQWV2QixNQUFNLE9BQU8sa0JBQWtCO0lBQzdCO1FBSWdCLGVBQVUsR0FBWSxLQUFLLENBQUM7SUFKN0IsQ0FBQzs7OztJQVVULFFBQVE7UUFDYixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFFBQVEsQ0FBQztRQUN2QyxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sQ0FBQzs7Y0FDL0IsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUU7UUFDMUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM1RCxDQUFDOzs7Ozs7OztJQUVPLFdBQVcsQ0FBQyxDQUFPLEVBQUUsS0FBYSxFQUFFLElBQVk7O2NBQ2hELFNBQVMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Ozs7Y0FHL0IsVUFBVSxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxLQUFLOztjQUNuQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUk7UUFDMUMsT0FBTyxTQUFTLElBQUksVUFBVSxJQUFJLFNBQVMsQ0FBQztJQUM5QyxDQUFDOzs7Ozs7SUFFTyxPQUFPLENBQUMsS0FBVTtRQUN4Qiw2REFBNkQ7UUFDN0QsMkJBQTJCO1FBQzNCLGtDQUFrQztRQUNsQyw4Q0FBOEM7UUFDOUMsT0FBTyxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDbEUsMEJBQTBCO1FBQzFCLGlDQUFpQztJQUNuQyxDQUFDOzs7O0lBRU0sYUFBYTtRQUNsQjs7O1FBQU8sR0FBNEIsRUFBRTs7a0JBQzdCLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSzs7a0JBQ3hDLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUM7O2tCQUNoRCxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUs7WUFDaEQsOEZBQThGO1lBQzlGLElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDckYsT0FBTyxJQUFJLENBQUM7YUFDYjtZQUNELCtCQUErQjtZQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3RHLENBQUMsRUFBQztJQUNKLENBQUM7OztZQXZERixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLG9CQUFvQjtnQkFDOUIsbTJGQUEyQzs7YUFFNUM7Ozs7O3FCQUdFLEtBQUs7MkJBQ0wsS0FBSzt3QkFDTCxLQUFLO3lCQUNMLEtBQUs7Ozs7SUFITixvQ0FBeUM7O0lBQ3pDLDBDQUFpRDs7SUFDakQsdUNBQStCOztJQUMvQix3Q0FBNEM7O0lBRTVDLG1DQUFrQjs7SUFDbEIsaUNBQWdCOztJQUNoQixrQ0FBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkluaXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uRXJyb3JzLCBWYWxpZGF0b3JGbiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZXNNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9lcnJvci1tZXNzYWdlcy1tb2RlbCc7XG5pbXBvcnQgeyBHb3ZVaUNvbmZpZ01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2dvdi11aS1jb25maWctbW9kZWwnO1xuLypcbiAqIEdvdiBVSyBEYXRlIENvbXBvbmVudFxuICogUmVzcG9uc2libGUgZm9yIGRpc3BsYXlpbmcgMyBpbnB1dCBmaWVsZHM6XG4gKiBkYXkgLyBtb250aCAvIHllYXJcbiAqIGRpc3BsYXlpbmcgZXJyb3JNZXNzYWdlIG1lc3NhZ2VzXG4gKiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAneHVpbGliLWdvdi11ay1kYXRlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dvdi11ay1kYXRlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZ292LXVrLWRhdGUuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBHb3ZVa0RhdGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBjb25zdHJ1Y3RvcigpIHt9XG4gIEBJbnB1dCgpIHB1YmxpYyBjb25maWc6IEdvdlVpQ29uZmlnTW9kZWw7XG4gIEBJbnB1dCgpIHB1YmxpYyBlcnJvck1lc3NhZ2U6IEVycm9yTWVzc2FnZXNNb2RlbDtcbiAgQElucHV0KCkgcHVibGljIGZvcm1Hcm91cDogYW55O1xuICBASW5wdXQoKSBwdWJsaWMgaXNPcHRpb25hbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHB1YmxpYyBtb250aDogYW55O1xuICBwdWJsaWMgZGF5OiBhbnk7XG4gIHB1YmxpYyB5ZWFyOiBhbnk7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZGF5ID0gYCR7dGhpcy5jb25maWcuaWR9X2RheWA7XG4gICAgdGhpcy5tb250aCA9IGAke3RoaXMuY29uZmlnLmlkfV9tb250aGA7XG4gICAgdGhpcy55ZWFyID0gYCR7dGhpcy5jb25maWcuaWR9X3llYXJgO1xuICAgIGNvbnN0IGRhdGVWYWxpZGF0b3IgPSB0aGlzLkRhdGVWYWxpZGF0b3IoKTtcbiAgICB0aGlzLmZvcm1Hcm91cC5nZXQodGhpcy5kYXkpLnNldFZhbGlkYXRvcnMoZGF0ZVZhbGlkYXRvcik7XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWREYXRlKGQ6IERhdGUsIG1vbnRoOiBudW1iZXIsIHllYXI6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRhdGVDaGVjayA9ICFpc05hTihkLmdldFRpbWUoKSk7XG4gICAgLy8gTW9udGggbWlzbWF0Y2ggb2NjdXJzIGlmIHRoZSBwcm92aWRlZCBkYXkgb3IgbW9udGggYXJlIGludmFsaWQsIG9yIGVpdGhlciBpcyBvbWl0dGVkLiAqKk5vdGU6KiogVGhpcyBpcyBpbnN1ZmZpY2llbnQgZm9yXG4gICAgLy8gY2hlY2tpbmcgZGF0ZSB2YWxpZGl0eSB3aGVuIHRoZSB5ZWFyIGlzIG9taXR0ZWQgYmVjYXVzZSBpdCBkZWZhdWx0cyB0byAxOTAwIC0gYW4gZXh0cmEgY2hlY2sgaXMgcmVxdWlyZWRcbiAgICBjb25zdCBtb250aE1hdGNoID0gZC5nZXRNb250aCgpID09PSBtb250aDtcbiAgICBjb25zdCB5ZWFyTWF0Y2ggPSBkLmdldEZ1bGxZZWFyKCkgPT09IHllYXI7XG4gICAgcmV0dXJuIGRhdGVDaGVjayAmJiBtb250aE1hdGNoICYmIHllYXJNYXRjaDtcbiAgfVxuXG4gIHByaXZhdGUgaXNFbXB0eSh2YWx1ZTogYW55KSB7XG4gICAgLy8gTm90ZTogSW50ZW50aW9uYWwgdXNlIG9mID09IHRvIGNoZWNrIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgIC8qIGVzbGludC1kaXNhYmxlIGVxZXFlcSAqL1xuICAgIC8qIHRzbGludDpkaXNhYmxlOnRyaXBsZS1lcXVhbHMgKi9cbiAgICAvLyBOYU4gYW5kIDwgMCBjaGVja3MgcmVxdWlyZWQgZm9yIG1vbnRoIGZpZWxkXG4gICAgcmV0dXJuIHZhbHVlID09IG51bGwgfHwgdmFsdWUgPT09ICcnIHx8IGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA8IDA7XG4gICAgLyogZXNsaW50LWVuYWJsZSBlcWVxZXEgKi9cbiAgICAvKiB0c2xpbnQ6ZW5hYmxlOnRyaXBsZS1lcXVhbHMgKi9cbiAgfVxuXG4gIHB1YmxpYyBEYXRlVmFsaWRhdG9yKCk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IGRheSA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLmRheSkudmFsdWU7XG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLm1vbnRoKS52YWx1ZSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gdGhpcy5mb3JtR3JvdXAuZ2V0KHRoaXMueWVhcikudmFsdWU7XG4gICAgICAvLyBWYWxpZGF0aW9uIHNob3VsZCBwYXNzIGlmIHRoZSBkYXRlIGZpZWxkIGlzIG9wdGlvbmFsIGFuZCBkYXksIG1vbnRoLCBhbmQgeWVhciBhcmUgYWxsIGVtcHR5XG4gICAgICBpZiAodGhpcy5pc09wdGlvbmFsICYmIHRoaXMuaXNFbXB0eShkYXkpICYmIHRoaXMuaXNFbXB0eShtb250aCkgJiYgdGhpcy5pc0VtcHR5KHllYXIpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gKyB0byBjb2VyY2UgeWVhciB0byBhIG51bWJlclxuICAgICAgcmV0dXJuICF0aGlzLmlzVmFsaWREYXRlKG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpLCBtb250aCwgK3llYXIpID8geyBkYXRlQ29tcG9uZW50OiB0cnVlIH0gOiBudWxsO1xuICAgIH07XG4gIH1cbn1cbiJdfQ==
@@ -12,6 +12,7 @@ import { Component, Input } from '@angular/core';
12
12
  * */
13
13
  var GovUkDateComponent = /** @class */ (function () {
14
14
  function GovUkDateComponent() {
15
+ this.isOptional = false;
15
16
  }
16
17
  /**
17
18
  * @return {?}
@@ -31,20 +32,45 @@ var GovUkDateComponent = /** @class */ (function () {
31
32
  * @private
32
33
  * @param {?} d
33
34
  * @param {?} month
35
+ * @param {?} year
34
36
  * @return {?}
35
37
  */
36
38
  GovUkDateComponent.prototype.isValidDate = /**
37
39
  * @private
38
40
  * @param {?} d
39
41
  * @param {?} month
42
+ * @param {?} year
40
43
  * @return {?}
41
44
  */
42
- function (d, month) {
45
+ function (d, month, year) {
43
46
  /** @type {?} */
44
- var dateCheck = d instanceof Date && !isNaN(d.getTime());
47
+ var dateCheck = !isNaN(d.getTime());
48
+ // Month mismatch occurs if the provided day or month are invalid, or either is omitted. **Note:** This is insufficient for
49
+ // checking date validity when the year is omitted because it defaults to 1900 - an extra check is required
45
50
  /** @type {?} */
46
- var leapYearCheck = d.getMonth() === month;
47
- return dateCheck && leapYearCheck;
51
+ var monthMatch = d.getMonth() === month;
52
+ /** @type {?} */
53
+ var yearMatch = d.getFullYear() === year;
54
+ return dateCheck && monthMatch && yearMatch;
55
+ };
56
+ /**
57
+ * @private
58
+ * @param {?} value
59
+ * @return {?}
60
+ */
61
+ GovUkDateComponent.prototype.isEmpty = /**
62
+ * @private
63
+ * @param {?} value
64
+ * @return {?}
65
+ */
66
+ function (value) {
67
+ // Note: Intentional use of == to check for null or undefined
68
+ /* eslint-disable eqeqeq */
69
+ /* tslint:disable:triple-equals */
70
+ // NaN and < 0 checks required for month field
71
+ return value == null || value === '' || isNaN(value) || value < 0;
72
+ /* eslint-enable eqeqeq */
73
+ /* tslint:enable:triple-equals */
48
74
  };
49
75
  /**
50
76
  * @return {?}
@@ -54,8 +80,7 @@ var GovUkDateComponent = /** @class */ (function () {
54
80
  */
55
81
  function () {
56
82
  var _this = this;
57
- /** @type {?} */
58
- var res = (/**
83
+ return (/**
59
84
  * @return {?}
60
85
  */
61
86
  function () {
@@ -65,11 +90,13 @@ var GovUkDateComponent = /** @class */ (function () {
65
90
  var month = _this.formGroup.get(_this.month).value - 1;
66
91
  /** @type {?} */
67
92
  var year = _this.formGroup.get(_this.year).value;
68
- /** @type {?} */
69
- var isValid = _this.isValidDate(new Date(year, month, day), month);
70
- return !isValid ? { dateComponent: true } : null;
93
+ // Validation should pass if the date field is optional and day, month, and year are all empty
94
+ if (_this.isOptional && _this.isEmpty(day) && _this.isEmpty(month) && _this.isEmpty(year)) {
95
+ return null;
96
+ }
97
+ // + to coerce year to a number
98
+ return !_this.isValidDate(new Date(year, month, day), month, +year) ? { dateComponent: true } : null;
71
99
  });
72
- return res;
73
100
  };
74
101
  GovUkDateComponent.decorators = [
75
102
  { type: Component, args: [{
@@ -83,7 +110,8 @@ var GovUkDateComponent = /** @class */ (function () {
83
110
  GovUkDateComponent.propDecorators = {
84
111
  config: [{ type: Input }],
85
112
  errorMessage: [{ type: Input }],
86
- formGroup: [{ type: Input }]
113
+ formGroup: [{ type: Input }],
114
+ isOptional: [{ type: Input }]
87
115
  };
88
116
  return GovUkDateComponent;
89
117
  }());
@@ -96,10 +124,12 @@ if (false) {
96
124
  /** @type {?} */
97
125
  GovUkDateComponent.prototype.formGroup;
98
126
  /** @type {?} */
127
+ GovUkDateComponent.prototype.isOptional;
128
+ /** @type {?} */
99
129
  GovUkDateComponent.prototype.month;
100
130
  /** @type {?} */
101
131
  GovUkDateComponent.prototype.day;
102
132
  /** @type {?} */
103
133
  GovUkDateComponent.prototype.year;
104
134
  }
105
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ292LXVrLWRhdGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGhtY3RzL3JweC14dWktY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9nb3YtdWkvY29tcG9uZW50cy9nb3YtdWstZGF0ZS9nb3YtdWstZGF0ZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFFTixNQUFNLGVBQWUsQ0FBQzs7Ozs7OztBQVV2QjtJQU1FO0lBQWUsQ0FBQzs7OztJQVNULHFDQUFROzs7SUFBZjtRQUNFLElBQUksQ0FBQyxHQUFHLEdBQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFNBQU0sQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxHQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxXQUFRLENBQUM7UUFDdkMsSUFBSSxDQUFDLElBQUksR0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsVUFBTyxDQUFDOztZQUMvQixhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRTtRQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVELENBQUM7Ozs7Ozs7SUFFTyx3Q0FBVzs7Ozs7O0lBQW5CLFVBQW9CLENBQU0sRUFBRSxLQUFhOztZQUNqQyxTQUFTLEdBQUcsQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7O1lBQ3BELGFBQWEsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssS0FBSztRQUM1QyxPQUFPLFNBQVMsSUFBSSxhQUFhLENBQUM7SUFDcEMsQ0FBQzs7OztJQUVNLDBDQUFhOzs7SUFBcEI7UUFBQSxpQkFTQzs7WUFSTyxHQUFHOzs7UUFBRzs7Z0JBQ0osR0FBRyxHQUFHLEtBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLOztnQkFDeEMsS0FBSyxHQUFHLEtBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQzs7Z0JBQ2hELElBQUksR0FBRyxLQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSzs7Z0JBQzFDLE9BQU8sR0FBRyxLQUFJLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDO1lBQ25FLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbkQsQ0FBQyxDQUFBO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDOztnQkF0Q0YsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLG0yRkFBMkM7O2lCQUU1Qzs7Ozs7eUJBR0UsS0FBSzsrQkFDTCxLQUFLOzRCQUNMLEtBQUs7O0lBOEJSLHlCQUFDO0NBQUEsQUF2Q0QsSUF1Q0M7U0FsQ1ksa0JBQWtCOzs7SUFFN0Isb0NBQXlDOztJQUN6QywwQ0FBaUQ7O0lBQ2pELHVDQUErQjs7SUFFL0IsbUNBQWtCOztJQUNsQixpQ0FBZ0I7O0lBQ2hCLGtDQUFpQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uSW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvcnMsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlc01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Vycm9yLW1lc3NhZ2VzLW1vZGVsJztcbmltcG9ydCB7IEdvdlVpQ29uZmlnTW9kZWwgfSBmcm9tICcuLi8uLi9tb2RlbHMvZ292LXVpLWNvbmZpZy1tb2RlbCc7XG4vKlxuICogR292IFVLIERhdGUgQ29tcG9uZW50XG4gKiBSZXNwb25zaWJsZSBmb3IgZGlzcGxheWluZyAzIGlucHV0IGZpZWxkczpcbiAqIGRheSAvIG1vbnRoIC8geWVhclxuICogZGlzcGxheWluZyBlcnJvck1lc3NhZ2UgbWVzc2FnZXNcbiAqICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd4dWlsaWItZ292LXVrLWRhdGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vZ292LXVrLWRhdGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9nb3YtdWstZGF0ZS5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIEdvdlVrRGF0ZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIGNvbnN0cnVjdG9yKCkge31cbiAgQElucHV0KCkgcHVibGljIGNvbmZpZzogR292VWlDb25maWdNb2RlbDtcbiAgQElucHV0KCkgcHVibGljIGVycm9yTWVzc2FnZTogRXJyb3JNZXNzYWdlc01vZGVsO1xuICBASW5wdXQoKSBwdWJsaWMgZm9ybUdyb3VwOiBhbnk7XG5cbiAgcHVibGljIG1vbnRoOiBhbnk7XG4gIHB1YmxpYyBkYXk6IGFueTtcbiAgcHVibGljIHllYXI6IGFueTtcblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5kYXkgPSBgJHt0aGlzLmNvbmZpZy5pZH1fZGF5YDtcbiAgICB0aGlzLm1vbnRoID0gYCR7dGhpcy5jb25maWcuaWR9X21vbnRoYDtcbiAgICB0aGlzLnllYXIgPSBgJHt0aGlzLmNvbmZpZy5pZH1feWVhcmA7XG4gICAgY29uc3QgZGF0ZVZhbGlkYXRvciA9IHRoaXMuRGF0ZVZhbGlkYXRvcigpO1xuICAgIHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLmRheSkuc2V0VmFsaWRhdG9ycyhkYXRlVmFsaWRhdG9yKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNWYWxpZERhdGUoZDogYW55LCBtb250aDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGF0ZUNoZWNrID0gZCBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKGQuZ2V0VGltZSgpKTtcbiAgICBjb25zdCBsZWFwWWVhckNoZWNrID0gZC5nZXRNb250aCgpID09PSBtb250aDtcbiAgICByZXR1cm4gZGF0ZUNoZWNrICYmIGxlYXBZZWFyQ2hlY2s7XG4gIH1cblxuICBwdWJsaWMgRGF0ZVZhbGlkYXRvcigpOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgcmVzID0gKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IGRheSA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLmRheSkudmFsdWU7XG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLm1vbnRoKS52YWx1ZSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gdGhpcy5mb3JtR3JvdXAuZ2V0KHRoaXMueWVhcikudmFsdWU7XG4gICAgICBjb25zdCBpc1ZhbGlkID0gdGhpcy5pc1ZhbGlkRGF0ZShuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KSwgbW9udGgpO1xuICAgICAgcmV0dXJuICFpc1ZhbGlkID8geyBkYXRlQ29tcG9uZW50OiB0cnVlIH0gOiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIHJlcztcbiAgfVxufVxuIl19
135
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ292LXVrLWRhdGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGhtY3RzL3JweC14dWktY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9nb3YtdWkvY29tcG9uZW50cy9nb3YtdWstZGF0ZS9nb3YtdWstZGF0ZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFFTixNQUFNLGVBQWUsQ0FBQzs7Ozs7OztBQVV2QjtJQU1FO1FBSWdCLGVBQVUsR0FBWSxLQUFLLENBQUM7SUFKN0IsQ0FBQzs7OztJQVVULHFDQUFROzs7SUFBZjtRQUNFLElBQUksQ0FBQyxHQUFHLEdBQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFNBQU0sQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxHQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxXQUFRLENBQUM7UUFDdkMsSUFBSSxDQUFDLElBQUksR0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsVUFBTyxDQUFDOztZQUMvQixhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRTtRQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVELENBQUM7Ozs7Ozs7O0lBRU8sd0NBQVc7Ozs7Ozs7SUFBbkIsVUFBb0IsQ0FBTyxFQUFFLEtBQWEsRUFBRSxJQUFZOztZQUNoRCxTQUFTLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDOzs7O1lBRy9CLFVBQVUsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssS0FBSzs7WUFDbkMsU0FBUyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJO1FBQzFDLE9BQU8sU0FBUyxJQUFJLFVBQVUsSUFBSSxTQUFTLENBQUM7SUFDOUMsQ0FBQzs7Ozs7O0lBRU8sb0NBQU87Ozs7O0lBQWYsVUFBZ0IsS0FBVTtRQUN4Qiw2REFBNkQ7UUFDN0QsMkJBQTJCO1FBQzNCLGtDQUFrQztRQUNsQyw4Q0FBOEM7UUFDOUMsT0FBTyxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSyxFQUFFLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDbEUsMEJBQTBCO1FBQzFCLGlDQUFpQztJQUNuQyxDQUFDOzs7O0lBRU0sMENBQWE7OztJQUFwQjtRQUFBLGlCQVlDO1FBWEM7OztRQUFPOztnQkFDQyxHQUFHLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUs7O2dCQUN4QyxLQUFLLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDOztnQkFDaEQsSUFBSSxHQUFHLEtBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLO1lBQ2hELDhGQUE4RjtZQUM5RixJQUFJLEtBQUksQ0FBQyxVQUFVLElBQUksS0FBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3JGLE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFDRCwrQkFBK0I7WUFDL0IsT0FBTyxDQUFDLEtBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN0RyxDQUFDLEVBQUM7SUFDSixDQUFDOztnQkF2REYsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLG0yRkFBMkM7O2lCQUU1Qzs7Ozs7eUJBR0UsS0FBSzsrQkFDTCxLQUFLOzRCQUNMLEtBQUs7NkJBQ0wsS0FBSzs7SUE4Q1IseUJBQUM7Q0FBQSxBQXhERCxJQXdEQztTQW5EWSxrQkFBa0I7OztJQUU3QixvQ0FBeUM7O0lBQ3pDLDBDQUFpRDs7SUFDakQsdUNBQStCOztJQUMvQix3Q0FBNEM7O0lBRTVDLG1DQUFrQjs7SUFDbEIsaUNBQWdCOztJQUNoQixrQ0FBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkluaXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uRXJyb3JzLCBWYWxpZGF0b3JGbiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZXNNb2RlbCB9IGZyb20gJy4uLy4uL21vZGVscy9lcnJvci1tZXNzYWdlcy1tb2RlbCc7XG5pbXBvcnQgeyBHb3ZVaUNvbmZpZ01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2dvdi11aS1jb25maWctbW9kZWwnO1xuLypcbiAqIEdvdiBVSyBEYXRlIENvbXBvbmVudFxuICogUmVzcG9uc2libGUgZm9yIGRpc3BsYXlpbmcgMyBpbnB1dCBmaWVsZHM6XG4gKiBkYXkgLyBtb250aCAvIHllYXJcbiAqIGRpc3BsYXlpbmcgZXJyb3JNZXNzYWdlIG1lc3NhZ2VzXG4gKiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAneHVpbGliLWdvdi11ay1kYXRlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dvdi11ay1kYXRlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZ292LXVrLWRhdGUuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBHb3ZVa0RhdGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBjb25zdHJ1Y3RvcigpIHt9XG4gIEBJbnB1dCgpIHB1YmxpYyBjb25maWc6IEdvdlVpQ29uZmlnTW9kZWw7XG4gIEBJbnB1dCgpIHB1YmxpYyBlcnJvck1lc3NhZ2U6IEVycm9yTWVzc2FnZXNNb2RlbDtcbiAgQElucHV0KCkgcHVibGljIGZvcm1Hcm91cDogYW55O1xuICBASW5wdXQoKSBwdWJsaWMgaXNPcHRpb25hbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHB1YmxpYyBtb250aDogYW55O1xuICBwdWJsaWMgZGF5OiBhbnk7XG4gIHB1YmxpYyB5ZWFyOiBhbnk7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZGF5ID0gYCR7dGhpcy5jb25maWcuaWR9X2RheWA7XG4gICAgdGhpcy5tb250aCA9IGAke3RoaXMuY29uZmlnLmlkfV9tb250aGA7XG4gICAgdGhpcy55ZWFyID0gYCR7dGhpcy5jb25maWcuaWR9X3llYXJgO1xuICAgIGNvbnN0IGRhdGVWYWxpZGF0b3IgPSB0aGlzLkRhdGVWYWxpZGF0b3IoKTtcbiAgICB0aGlzLmZvcm1Hcm91cC5nZXQodGhpcy5kYXkpLnNldFZhbGlkYXRvcnMoZGF0ZVZhbGlkYXRvcik7XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWREYXRlKGQ6IERhdGUsIG1vbnRoOiBudW1iZXIsIHllYXI6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRhdGVDaGVjayA9ICFpc05hTihkLmdldFRpbWUoKSk7XG4gICAgLy8gTW9udGggbWlzbWF0Y2ggb2NjdXJzIGlmIHRoZSBwcm92aWRlZCBkYXkgb3IgbW9udGggYXJlIGludmFsaWQsIG9yIGVpdGhlciBpcyBvbWl0dGVkLiAqKk5vdGU6KiogVGhpcyBpcyBpbnN1ZmZpY2llbnQgZm9yXG4gICAgLy8gY2hlY2tpbmcgZGF0ZSB2YWxpZGl0eSB3aGVuIHRoZSB5ZWFyIGlzIG9taXR0ZWQgYmVjYXVzZSBpdCBkZWZhdWx0cyB0byAxOTAwIC0gYW4gZXh0cmEgY2hlY2sgaXMgcmVxdWlyZWRcbiAgICBjb25zdCBtb250aE1hdGNoID0gZC5nZXRNb250aCgpID09PSBtb250aDtcbiAgICBjb25zdCB5ZWFyTWF0Y2ggPSBkLmdldEZ1bGxZZWFyKCkgPT09IHllYXI7XG4gICAgcmV0dXJuIGRhdGVDaGVjayAmJiBtb250aE1hdGNoICYmIHllYXJNYXRjaDtcbiAgfVxuXG4gIHByaXZhdGUgaXNFbXB0eSh2YWx1ZTogYW55KSB7XG4gICAgLy8gTm90ZTogSW50ZW50aW9uYWwgdXNlIG9mID09IHRvIGNoZWNrIGZvciBudWxsIG9yIHVuZGVmaW5lZFxuICAgIC8qIGVzbGludC1kaXNhYmxlIGVxZXFlcSAqL1xuICAgIC8qIHRzbGludDpkaXNhYmxlOnRyaXBsZS1lcXVhbHMgKi9cbiAgICAvLyBOYU4gYW5kIDwgMCBjaGVja3MgcmVxdWlyZWQgZm9yIG1vbnRoIGZpZWxkXG4gICAgcmV0dXJuIHZhbHVlID09IG51bGwgfHwgdmFsdWUgPT09ICcnIHx8IGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA8IDA7XG4gICAgLyogZXNsaW50LWVuYWJsZSBlcWVxZXEgKi9cbiAgICAvKiB0c2xpbnQ6ZW5hYmxlOnRyaXBsZS1lcXVhbHMgKi9cbiAgfVxuXG4gIHB1YmxpYyBEYXRlVmFsaWRhdG9yKCk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IGRheSA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLmRheSkudmFsdWU7XG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuZm9ybUdyb3VwLmdldCh0aGlzLm1vbnRoKS52YWx1ZSAtIDE7XG4gICAgICBjb25zdCB5ZWFyID0gdGhpcy5mb3JtR3JvdXAuZ2V0KHRoaXMueWVhcikudmFsdWU7XG4gICAgICAvLyBWYWxpZGF0aW9uIHNob3VsZCBwYXNzIGlmIHRoZSBkYXRlIGZpZWxkIGlzIG9wdGlvbmFsIGFuZCBkYXksIG1vbnRoLCBhbmQgeWVhciBhcmUgYWxsIGVtcHR5XG4gICAgICBpZiAodGhpcy5pc09wdGlvbmFsICYmIHRoaXMuaXNFbXB0eShkYXkpICYmIHRoaXMuaXNFbXB0eShtb250aCkgJiYgdGhpcy5pc0VtcHR5KHllYXIpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gKyB0byBjb2VyY2UgeWVhciB0byBhIG51bWJlclxuICAgICAgcmV0dXJuICF0aGlzLmlzVmFsaWREYXRlKG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpLCBtb250aCwgK3llYXIpID8geyBkYXRlQ29tcG9uZW50OiB0cnVlIH0gOiBudWxsO1xuICAgIH07XG4gIH1cbn1cbiJdfQ==
@@ -3588,7 +3588,9 @@ GovUkCheckboxesComponent.propDecorators = {
3588
3588
  * displaying errorMessage messages
3589
3589
  * */
3590
3590
  class GovUkDateComponent {
3591
- constructor() { }
3591
+ constructor() {
3592
+ this.isOptional = false;
3593
+ }
3592
3594
  /**
3593
3595
  * @return {?}
3594
3596
  */
@@ -3604,21 +3606,39 @@ class GovUkDateComponent {
3604
3606
  * @private
3605
3607
  * @param {?} d
3606
3608
  * @param {?} month
3609
+ * @param {?} year
3607
3610
  * @return {?}
3608
3611
  */
3609
- isValidDate(d, month) {
3612
+ isValidDate(d, month, year) {
3613
+ /** @type {?} */
3614
+ const dateCheck = !isNaN(d.getTime());
3615
+ // Month mismatch occurs if the provided day or month are invalid, or either is omitted. **Note:** This is insufficient for
3616
+ // checking date validity when the year is omitted because it defaults to 1900 - an extra check is required
3610
3617
  /** @type {?} */
3611
- const dateCheck = d instanceof Date && !isNaN(d.getTime());
3618
+ const monthMatch = d.getMonth() === month;
3612
3619
  /** @type {?} */
3613
- const leapYearCheck = d.getMonth() === month;
3614
- return dateCheck && leapYearCheck;
3620
+ const yearMatch = d.getFullYear() === year;
3621
+ return dateCheck && monthMatch && yearMatch;
3622
+ }
3623
+ /**
3624
+ * @private
3625
+ * @param {?} value
3626
+ * @return {?}
3627
+ */
3628
+ isEmpty(value) {
3629
+ // Note: Intentional use of == to check for null or undefined
3630
+ /* eslint-disable eqeqeq */
3631
+ /* tslint:disable:triple-equals */
3632
+ // NaN and < 0 checks required for month field
3633
+ return value == null || value === '' || isNaN(value) || value < 0;
3634
+ /* eslint-enable eqeqeq */
3635
+ /* tslint:enable:triple-equals */
3615
3636
  }
3616
3637
  /**
3617
3638
  * @return {?}
3618
3639
  */
3619
3640
  DateValidator() {
3620
- /** @type {?} */
3621
- const res = (/**
3641
+ return (/**
3622
3642
  * @return {?}
3623
3643
  */
3624
3644
  () => {
@@ -3628,11 +3648,13 @@ class GovUkDateComponent {
3628
3648
  const month = this.formGroup.get(this.month).value - 1;
3629
3649
  /** @type {?} */
3630
3650
  const year = this.formGroup.get(this.year).value;
3631
- /** @type {?} */
3632
- const isValid = this.isValidDate(new Date(year, month, day), month);
3633
- return !isValid ? { dateComponent: true } : null;
3651
+ // Validation should pass if the date field is optional and day, month, and year are all empty
3652
+ if (this.isOptional && this.isEmpty(day) && this.isEmpty(month) && this.isEmpty(year)) {
3653
+ return null;
3654
+ }
3655
+ // + to coerce year to a number
3656
+ return !this.isValidDate(new Date(year, month, day), month, +year) ? { dateComponent: true } : null;
3634
3657
  });
3635
- return res;
3636
3658
  }
3637
3659
  }
3638
3660
  GovUkDateComponent.decorators = [
@@ -3647,7 +3669,8 @@ GovUkDateComponent.ctorParameters = () => [];
3647
3669
  GovUkDateComponent.propDecorators = {
3648
3670
  config: [{ type: Input }],
3649
3671
  errorMessage: [{ type: Input }],
3650
- formGroup: [{ type: Input }]
3672
+ formGroup: [{ type: Input }],
3673
+ isOptional: [{ type: Input }]
3651
3674
  };
3652
3675
 
3653
3676
  /**