@@ -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
@@ -134,17 +150,25 @@ export class MatYearView<D> implements AfterContentInit {
134150 this . _dateAdapter . createDate ( this . _dateAdapter . getYear ( this . activeDate ) , month , 1 ) ,
135151 this . _dateFormats . display . monthYearA11yLabel ) ;
136152 return new MatCalendarCell (
137- month , monthName . toLocaleUpperCase ( ) , ariaLabel , this . _isMonthEnabled ( month ) ) ;
153+ month , monthName . toLocaleUpperCase ( ) , ariaLabel , this . _shouldEnableMonth ( month ) ) ;
138154 }
139155
140156 /** Whether the given month is enabled. */
141- private _isMonthEnabled ( month : number ) {
157+ private _shouldEnableMonth ( month : number ) {
158+
159+ const activeYear = this . _dateAdapter . getYear ( this . activeDate ) ;
160+
161+ if ( month === undefined || month === null ||
162+ this . _isYearAndMonthAfterMaxDate ( activeYear , month ) ||
163+ this . _isYearAndMonthBeforeMinDate ( activeYear , month ) ) {
164+ return false ;
165+ }
166+
142167 if ( ! this . dateFilter ) {
143168 return true ;
144169 }
145170
146- let firstOfMonth = this . _dateAdapter . createDate (
147- this . _dateAdapter . getYear ( this . activeDate ) , month , 1 ) ;
171+ const firstOfMonth = this . _dateAdapter . createDate ( activeYear , month , 1 ) ;
148172
149173 // If any date in the month is enabled count the month as enabled.
150174 for ( let date = firstOfMonth ; this . _dateAdapter . getMonth ( date ) == month ;
@@ -157,6 +181,36 @@ export class MatYearView<D> implements AfterContentInit {
157181 return false ;
158182 }
159183
184+ /**
185+ * Tests whether the combination month/year is after this.maxDate, considering
186+ * just the month and year of this.maxDate
187+ */
188+ private _isYearAndMonthAfterMaxDate ( year : number , month : number ) {
189+ if ( this . maxDate ) {
190+ const maxYear = this . _dateAdapter . getYear ( this . maxDate ) ;
191+ const maxMonth = this . _dateAdapter . getMonth ( this . maxDate ) ;
192+
193+ return year > maxYear || ( year === maxYear && month > maxMonth ) ;
194+ }
195+
196+ return false ;
197+ }
198+
199+ /**
200+ * Tests whether the combination month/year is before this.minDate, considering
201+ * just the month and year of this.minDate
202+ */
203+ private _isYearAndMonthBeforeMinDate ( year : number , month : number ) {
204+ if ( this . minDate ) {
205+ const minYear = this . _dateAdapter . getYear ( this . minDate ) ;
206+ const minMonth = this . _dateAdapter . getMonth ( this . minDate ) ;
207+
208+ return year < minYear || ( year === minYear && month < minMonth ) ;
209+ }
210+
211+ return false ;
212+ }
213+
160214 /**
161215 * @param obj The object to check.
162216 * @returns The given object if it is both a date instance and valid, otherwise null.
0 commit comments