The datepicker is one of the newest components in Angular Material (added in May 2017). Our goal in creating the Angular Material datepicker is to create a datepicker that adheres to Material Design principles and is flexible enough to work across different applications and in different locales. The datepicker is still a relatively new component and there is plenty more work to be done, but we believe that the current design is a solid foundation to build on.

Overview

The datepicker consists of three main parts.

The input The popup trigger The calendar popup

This is reflected in the API:

The md-datepicker component is the core of the datepicker, we then connect an Input to it using the [mdDatepicker] directive. The md-datepicker-toggle is completely optional. It’s an easy way to create a md-icon-button and automatically hook it up to the datepicker, but you can always create a custom toggle by connecting the (click) event on any element to call picker.toggle() .

The datepicker input supports the usual min , max , and required attributes to add validation as well as an additional mdDatepickerFilter attribute which allows for finer grained control of what’s considered a valid date. Adding validation to the input also automatically disabled invalid dates on the calendar.

The md-datepicker element has a startDate attribute to set the date the calendar starts at and a startView attribute that can be used to set the initial calendar view to either month or year mode.

To improve usability on mobile devices where screen real estate is limited there is a boolean attribute, touchUi , that can be used to enable or disable a touch UI mode. Currently the only difference is that the touch UI mode opens in a fullscreen dialog whereas the normal mode opens in a popup attached to the input. In the future we expect these UIs to diverge further as we continue to optimize each mode for its respective use case. Rather than prescribing what counts as a touch device, the datepicker leaves this decision up the developer. We recommend setting up a dynamic binding: [touchUi]="isTouch" .

i18n

One of the most challenging aspects of designing a datepicker is making sure that it works in all locales. This is difficult because different locales may have different date formats, calendar conventions (e.g. which day is the first day of the week), or even completely different calendars.

Because of the differences in date format across locales, even choosing a date representation is difficult. The native JavaScript Date object offers very limited parsing capabilities. For example, regardless of your locale, 1/2/2017 will always be parsed as January 2nd, 2017 , even though in many locales it actually means February 1st, 2017 .

Because of these limitations we can’t always rely on the native Date object. Maintaining our own date parsing and formatting logic is outside the scope of Angular Material. At the same time we don’t want to introduce a dependency on a third party date library, this could bloat people’s apps, and they may already have a date solution they’re happy with.

The DateAdapter

Our solution to this problem was to allow developers to choose the date representation that works best for them. We accomplished this by removing all knowledge of how dates actually work from the datepicker and moving it instead into a DateAdapter class. DateAdapter is an abstract class that requires a concrete subclass to actually fill in the details of to work with dates. Angular Material includes one such subclass NativeDateAdapter . By providing the NativeDateAdapter as the application’s DateAdapter the datepicker can be made to work with the native JavaScript Date . However this means that your application will have the date parsing limitations discussed above. If your application needs to work with locales other than en-US , we recommend creating your own adapter instead, by extending either DateAdapter or NativeDateAdapter .

One of the coolest things about the DateAdapter design is that it allows the entire datepicker to be generic and work with any kind of date object you like. For example, say you’re already using Moment.js throughout your app, you can create a MomentDateAdapter :

Specify the formats to use for various pieces of the datepicker (e.g. the month header that normally says something like “Jul 2017” and the parsing format for the input):

And finally provide both of these things in your application module:

Now when you go to use the datepicker, instead of passing it Date objects you just directly pass it Moment objects:

Future work

As the datepicker has only just been released there are still a number of features we want to add:

Additional pre-made date adapters for libraries like Moment.js, date-fns #5972

Infinite scrolling through months/years #5973

Ability to select a month rather than a specific date #4853

Ability to select a date & time #5648

Ability to select a range of dates #4763

Support for non-Gregorian calendars #2519

General UX enhancements #5974

Conclusion