@@ -59,6 +59,22 @@ export class MatYearView<D> implements AfterContentInit {
5959 }
6060 private _selected : D | null ;
6161
62+ /** The minimum selectable date. */
63+ @Input ( )
64+ get minDate ( ) : D | null { return this . _minDate ; }
65+ set minDate ( value : D | null ) {
66+ this . _minDate = this . _getValidDateOrNull ( this . _dateAdapter . deserialize ( value ) ) ;
67+ }
68+ private _minDate : D | null ;
69+
70+ /** The maximum selectable date. */
71+ @Input ( )
72+ get maxDate ( ) : D | null { return this . _maxDate ; }
73+ set maxDate ( value : D | null ) {
74+ this . _maxDate = this . _getValidDateOrNull ( this . _dateAdapter . deserialize ( value ) ) ;
75+ }
76+ private _maxDate : D | null ;
77+
6278 /** A function used to filter which dates are selectable. */
6379 @Input ( ) dateFilter : ( date : D ) => boolean ;
6480
@@ -142,17 +158,25 @@ export class MatYearView<D> implements AfterContentInit {
142158 this . _dateAdapter . createDate ( this . _dateAdapter . getYear ( this . activeDate ) , month , 1 ) ,
143159 this . _dateFormats . display . monthYearA11yLabel ) ;
144160 return new MatCalendarCell (
145- month , monthName . toLocaleUpperCase ( ) , ariaLabel , this . _isMonthEnabled ( month ) ) ;
161+ month , monthName . toLocaleUpperCase ( ) , ariaLabel , this . _shouldEnableMonth ( month ) ) ;
146162 }
147163
148164 /** Whether the given month is enabled. */
149- private _isMonthEnabled ( month : number ) {
165+ private _shouldEnableMonth ( month : number ) {
166+
167+ const activeYear = this . _dateAdapter . getYear ( this . activeDate ) ;
168+
169+ if ( month === undefined || month === null ||
170+ this . _isYearAndMonthAfterMaxDate ( activeYear , month ) ||
171+ this . _isYearAndMonthBeforeMinDate ( activeYear , month ) ) {
172+ return false ;
173+ }
174+
150175 if ( ! this . dateFilter ) {
151176 return true ;
152177 }
153178
154- let firstOfMonth = this . _dateAdapter . createDate (
155- this . _dateAdapter . getYear ( this . activeDate ) , month , 1 ) ;
179+ const firstOfMonth = this . _dateAdapter . createDate ( activeYear , month , 1 ) ;
156180
157181 // If any date in the month is enabled count the month as enabled.
158182 for ( let date = firstOfMonth ; this . _dateAdapter . getMonth ( date ) == month ;
@@ -165,6 +189,36 @@ export class MatYearView<D> implements AfterContentInit {
165189 return false ;
166190 }
167191
192+ /**
193+ * Tests whether the combination month/year is after this.maxDate, considering
194+ * just the month and year of this.maxDate
195+ */
196+ private _isYearAndMonthAfterMaxDate ( year : number , month : number ) {
197+ if ( this . maxDate ) {
198+ const maxYear = this . _dateAdapter . getYear ( this . maxDate ) ;
199+ const maxMonth = this . _dateAdapter . getMonth ( this . maxDate ) ;
200+
201+ return year > maxYear || ( year === maxYear && month > maxMonth ) ;
202+ }
203+
204+ return false ;
205+ }
206+
207+ /**
208+ * Tests whether the combination month/year is before this.minDate, considering
209+ * just the month and year of this.minDate
210+ */
211+ private _isYearAndMonthBeforeMinDate ( year : number , month : number ) {
212+ if ( this . minDate ) {
213+ const minYear = this . _dateAdapter . getYear ( this . minDate ) ;
214+ const minMonth = this . _dateAdapter . getMonth ( this . minDate ) ;
215+
216+ return year < minYear || ( year === minYear && month < minMonth ) ;
217+ }
218+
219+ return false ;
220+ }
221+
168222 /**
169223 * @param obj The object to check.
170224 * @returns The given object if it is both a date instance and valid, otherwise null.
0 commit comments