From ade32c60ec0c47daa7f93101dde071ee7971f2da Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 31 Oct 2024 11:09:15 +0100 Subject: [PATCH] docs(material/timepicker): add timepicker documentation and live examples Populates the timepicker's guide and add live examples. --- .../material/timepicker/BUILD.bazel | 7 + .../material/timepicker/index.ts | 6 + .../timepicker-custom-icon-example.html | 8 + .../timepicker-custom-icon-example.ts | 16 + ...epicker-datepicker-integration-example.css | 3 + ...picker-datepicker-integration-example.html | 18 + ...mepicker-datepicker-integration-example.ts | 26 ++ .../timepicker-forms-example.html | 10 + .../timepicker-forms-example.ts | 24 ++ .../timepicker-locale-example.html | 8 + .../timepicker-locale-example.ts | 24 ++ .../timepicker-options-example.html | 30 ++ .../timepicker-options-example.ts | 21 ++ .../timepicker-overview-example.html | 2 + .../timepicker-validation-example.css | 3 + .../timepicker-validation-example.html | 26 ++ .../timepicker-validation-example.ts | 20 ++ src/material/timepicker/timepicker.md | 314 +++++++++++++++++- 18 files changed, 565 insertions(+), 1 deletion(-) create mode 100644 src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html create mode 100644 src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts create mode 100644 src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css create mode 100644 src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html create mode 100644 src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts create mode 100644 src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html create mode 100644 src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts create mode 100644 src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html create mode 100644 src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts create mode 100644 src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html create mode 100644 src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts create mode 100644 src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css create mode 100644 src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html create mode 100644 src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts diff --git a/src/components-examples/material/timepicker/BUILD.bazel b/src/components-examples/material/timepicker/BUILD.bazel index 6743551b16cf..09a215458152 100644 --- a/src/components-examples/material/timepicker/BUILD.bazel +++ b/src/components-examples/material/timepicker/BUILD.bazel @@ -15,8 +15,15 @@ ng_module( deps = [ "//src/cdk/testing", "//src/cdk/testing/testbed", + "//src/material/button", + "//src/material/datepicker", + "//src/material/form-field", + "//src/material/icon", + "//src/material/input", "//src/material/timepicker", "//src/material/timepicker/testing", + "@npm//@angular/common", + "@npm//@angular/forms", "@npm//@angular/platform-browser", "@npm//@types/jasmine", ], diff --git a/src/components-examples/material/timepicker/index.ts b/src/components-examples/material/timepicker/index.ts index f9d81a9e356d..196ce4b3ca88 100644 --- a/src/components-examples/material/timepicker/index.ts +++ b/src/components-examples/material/timepicker/index.ts @@ -1,2 +1,8 @@ export {TimepickerOverviewExample} from './timepicker-overview/timepicker-overview-example'; +export {TimepickerFormsExample} from './timepicker-forms/timepicker-forms-example'; +export {TimepickerDatepickerIntegrationExample} from './timepicker-datepicker-integration/timepicker-datepicker-integration-example'; +export {TimepickerValidationExample} from './timepicker-validation/timepicker-validation-example'; +export {TimepickerOptionsExample} from './timepicker-options/timepicker-options-example'; +export {TimepickerCustomIconExample} from './timepicker-custom-icon/timepicker-custom-icon-example'; +export {TimepickerLocaleExample} from './timepicker-locale/timepicker-locale-example'; export {TimepickerHarnessExample} from './timepicker-harness/timepicker-harness-example'; diff --git a/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html new file mode 100644 index 000000000000..00ca86bf4a87 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.html @@ -0,0 +1,8 @@ + + Pick a time + + + globe + + + diff --git a/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts new file mode 100644 index 000000000000..4f356aade0c0 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-custom-icon/timepicker-custom-icon-example.ts @@ -0,0 +1,16 @@ +import {ChangeDetectionStrategy, Component} from '@angular/core'; +import {MatTimepickerModule} from '@angular/material/timepicker'; +import {MatIcon} from '@angular/material/icon'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {provideNativeDateAdapter} from '@angular/material/core'; + +/** @title Timepicker with custom toggle icon */ +@Component({ + selector: 'timepicker-custom-icon-example', + templateUrl: 'timepicker-custom-icon-example.html', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, MatIcon], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TimepickerCustomIconExample {} diff --git a/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css new file mode 100644 index 000000000000..ea720f56d371 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.css @@ -0,0 +1,3 @@ +mat-form-field { + margin-right: 16px; +} diff --git a/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html new file mode 100644 index 000000000000..b33725aa847a --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.html @@ -0,0 +1,18 @@ + + Meeting date + + + + + + + Meeting time + + + + + +

Value: {{value}}

diff --git a/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts new file mode 100644 index 000000000000..9583814a648c --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-datepicker-integration/timepicker-datepicker-integration-example.ts @@ -0,0 +1,26 @@ +import {ChangeDetectionStrategy, Component} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {MatTimepickerModule} from '@angular/material/timepicker'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {provideNativeDateAdapter} from '@angular/material/core'; +import {MatDatepickerModule} from '@angular/material/datepicker'; + +/** @title Timepicker integration with datepicker */ +@Component({ + selector: 'timepicker-datepicker-integration-example', + templateUrl: 'timepicker-datepicker-integration-example.html', + styleUrl: './timepicker-datepicker-integration-example.css', + providers: [provideNativeDateAdapter()], + imports: [ + MatFormFieldModule, + MatInputModule, + MatTimepickerModule, + MatDatepickerModule, + FormsModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TimepickerDatepickerIntegrationExample { + value: Date; +} diff --git a/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html new file mode 100644 index 000000000000..cb110ede3ffd --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.html @@ -0,0 +1,10 @@ + + Pick a time + + + + + +

Value: {{formControl.value}}

+

Touched: {{formControl.touched}}

+

Dirty: {{formControl.dirty}}

diff --git a/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts new file mode 100644 index 000000000000..60ce8d3a6aec --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-forms/timepicker-forms-example.ts @@ -0,0 +1,24 @@ +import {ChangeDetectionStrategy, Component} from '@angular/core'; +import {FormControl, ReactiveFormsModule} from '@angular/forms'; +import {MatTimepickerModule} from '@angular/material/timepicker'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {provideNativeDateAdapter} from '@angular/material/core'; + +/** @title Timepicker forms integration */ +@Component({ + selector: 'timepicker-forms-example', + templateUrl: 'timepicker-forms-example.html', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, ReactiveFormsModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TimepickerFormsExample { + formControl: FormControl; + + constructor() { + const initialValue = new Date(); + initialValue.setHours(12, 30, 0); + this.formControl = new FormControl(initialValue); + } +} diff --git a/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html new file mode 100644 index 000000000000..fae0e9b34de8 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.html @@ -0,0 +1,8 @@ + + Pick a time + + + + + + diff --git a/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts new file mode 100644 index 000000000000..18217aebaada --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-locale/timepicker-locale-example.ts @@ -0,0 +1,24 @@ +import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {MatTimepickerModule} from '@angular/material/timepicker'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {DateAdapter, provideNativeDateAdapter} from '@angular/material/core'; +import {MatButtonModule} from '@angular/material/button'; + +/** @title Timepicker with different locale */ +@Component({ + selector: 'timepicker-locale-example', + templateUrl: 'timepicker-locale-example.html', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, FormsModule, MatButtonModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TimepickerLocaleExample { + private readonly _adapter = inject>(DateAdapter); + value = new Date(2024, 0, 1, 13, 45, 0); + + protected switchLocale() { + this._adapter.setLocale('bg-BG'); + } +} diff --git a/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html new file mode 100644 index 000000000000..3641f89734e4 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.html @@ -0,0 +1,30 @@ +

Interval examples

+ +
+ + Every 45 minutes + + + + +
+ +
+ + Every 3.5 hours + + + + +
+ +

Custom list of options

+ +
+ + Pick a time of day + + + + +
diff --git a/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts new file mode 100644 index 000000000000..ae75213b1b55 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-options/timepicker-options-example.ts @@ -0,0 +1,21 @@ +import {ChangeDetectionStrategy, Component} from '@angular/core'; +import {MatTimepickerModule, MatTimepickerOption} from '@angular/material/timepicker'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {provideNativeDateAdapter} from '@angular/material/core'; + +/** @title Timepicker options customization */ +@Component({ + selector: 'timepicker-options-example', + templateUrl: 'timepicker-options-example.html', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TimepickerOptionsExample { + customOptions: MatTimepickerOption[] = [ + {label: 'Morning', value: new Date(2024, 0, 1, 9, 0, 0)}, + {label: 'Noon', value: new Date(2024, 0, 1, 12, 0, 0)}, + {label: 'Evening', value: new Date(2024, 0, 1, 22, 0, 0)}, + ]; +} diff --git a/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html b/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html index 9c7394525960..a8c3fb17bae9 100644 --- a/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html +++ b/src/components-examples/material/timepicker/timepicker-overview/timepicker-overview-example.html @@ -1,6 +1,8 @@ Pick a time + + diff --git a/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css new file mode 100644 index 000000000000..55f74ff0a83f --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.css @@ -0,0 +1,3 @@ +mat-form-field { + margin-bottom: 30px; +} diff --git a/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html new file mode 100644 index 000000000000..d1ed42c97a47 --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.html @@ -0,0 +1,26 @@ + + Pick a time + + + + + @if (formControl.errors?.['matTimepickerParse']) { + Value isn't a valid time + } + + @if (formControl.errors?.['matTimepickerMin']) { + Value is too early + } + + @if (formControl.errors?.['matTimepickerMax']) { + Value is too late + } + + +

Enter a value before 12:30 PM or after 5:30 PM to see the errors

+

Errors: {{formControl.errors | json}}

diff --git a/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts new file mode 100644 index 000000000000..9702b1be034f --- /dev/null +++ b/src/components-examples/material/timepicker/timepicker-validation/timepicker-validation-example.ts @@ -0,0 +1,20 @@ +import {ChangeDetectionStrategy, Component} from '@angular/core'; +import {JsonPipe} from '@angular/common'; +import {FormControl, ReactiveFormsModule} from '@angular/forms'; +import {MatTimepickerModule} from '@angular/material/timepicker'; +import {MatInputModule} from '@angular/material/input'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {provideNativeDateAdapter} from '@angular/material/core'; + +/** @title Timepicker validation */ +@Component({ + selector: 'timepicker-validation-example', + templateUrl: 'timepicker-validation-example.html', + styleUrl: './timepicker-validation-example.css', + providers: [provideNativeDateAdapter()], + imports: [MatFormFieldModule, MatInputModule, MatTimepickerModule, ReactiveFormsModule, JsonPipe], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TimepickerValidationExample { + formControl = new FormControl(null); +} diff --git a/src/material/timepicker/timepicker.md b/src/material/timepicker/timepicker.md index 1333ed77b7e1..820e5aff6722 100644 --- a/src/material/timepicker/timepicker.md +++ b/src/material/timepicker/timepicker.md @@ -1 +1,313 @@ -TODO +The Angular Material Timepicker allows users to set the time portion of a date object either by +typing it in or by selecting it from a list of pre-defined options. + + + +### Connecting a timepicker to an input + +A timepicker is composed of a text input and a dropdown menu, connected through the `matTimepicker` +binding on the input. + +There is also an optional timepicker toggle button that gives the user an easy way to open the dropdown. + + + +The timepicker input and toggle can be used either on their own or as a part of a `mat-form-field`: + + + +### Timepicker forms integration + +The timepicker input integrates with the `@angular/forms` module by providing itself as a +`ControlValueAccessor` and a `Validator` (see [Input validation](#input-validation) below for more +information). When the user types in a new time or selects one from the dropdown, the +time will be set on the date object which is the current value of the form control. If the form +control doesn't have a value, the timepicker will create one with today's date and the selected +time. + + + + +### Integration with `MatDatepicker` + +Material's datepicker and timepicker components can operate over the same value, allowing for a +combined datetime picker to be implemented. When binding the two components to the same value, the +datepicker will set the entire date object while the timepicker will only modify the time portion +of it. + + + +### Input validation + +The timepicker input checks that the value typed in by the user is a valid time string and +whether it fits into the specified bounds. + +If the user types in an invalid time string (for example `abc` or `24:67`), the timepicker input +will report the `matTimepickerParse` error. The string is parsed using the `parseTime` method of +the [the current date implementation](#choosing-a-date-implementation-and-format-settings). + +The timepicker input also checks that the value typed in by the user fits within the minimum and +maximum bounds set through the `matTimepickerMin` and `matTimepickerMax` inputs. They accept either +a date object with a specific time or a time string. The inputs also control which times will be +shown inside of the dropdown menu. For example, setting `matTimepickerMin="12:30"` and +`matTimepickerMax="21:25"` will allow the user to only select a time between 12:30 in the afternoon +and 9:25 in the evening. If the value is outside of those bounds, either a `maxTimepickerMin` or +`matTimepickerMax` error will be reported to the value accessor. + + + + +### Customizing the dropdown options + +By default the `mat-timepicker` dropdown shows options at 30 minute intervals. You can customize the +list of options either by setting an interval or providing a custom set of options. + +The easiest way is to change the options is to pass the `interval` input to `mat-timepicker` with +an interval string which will be used when generating the options. For example, +`` will show the options at 90 minute intervals, starting from the +minimum time and ending at the maximum. Valid interval strings include: +* A number which will be interpreted as minutes, e.g. `interval="50"` represents 50 minutes. +* A number with short units, for example `30m` represents 30 minutes while `5h` is 5 hours. +Supported short units include `h` or `H` for hours, `m` or `M` for minutes and `s` or `S` for seconds. +* A number with long units, for example `75 min` represents 75 minutes while `1.5 hours` is an hour +and a half. Supported long units include `min` or `minute` or `minutes` for minutes, `hour` or `hours` for +hours and `second` or `seconds` for seconds. + +Furthermore, the default interval can be controlled for the entire application using the +`MAT_TIMEPICKER_CONFIG` injection token. For example, adding the following to your `providers` will +default all timepickers to a 90 minute interval: + +```ts +import {MAT_TIMEPICKER_CONFIG} from '@angular/material/timepicker'; + +{ + provide: MAT_TIMEPICKER_CONFIG, + useValue: {interval: '90 minutes'}, +} +``` + +If your app requires more fine-grained control over the options, you can pass in an array of +options into `mat-timepicker` instead. Note that the options need to match the `MatTimepickerOption` +interface. + + + + +### Customizing the toggle icon + +`mat-timepicker-toggle` renders a clock icon by default. You can customize it by projecting in an +element with the `matTimepickerToggleIcon` attribute into the toggle: + + + +### Internationalization + +Internationalization of the timepicker uses the same date adapter as `mat-datepicker`. It is +configured via three aspects: + +1. The date locale. +2. The date implementation that the timepicker accepts. +3. The display and parse formats used by the timepicker. + +#### Setting the locale code + +By default, the `MAT_DATE_LOCALE` injection token will use the existing `LOCALE_ID` locale code +from `@angular/core`. If you want to override it, you can provide a new value for the +`MAT_DATE_LOCALE` token: + +```ts +bootstapApplication(MyApp, { + providers: [{provide: MAT_DATE_LOCALE, useValue: 'en-GB'}], +}); +``` + +It's also possible to set the locale at runtime using the `setLocale` method of the `DateAdapter`. + +**Note:** if you're using the `provideDateFnsAdapter`, you have to provide the data object for your +locale to `MAT_DATE_LOCALE` instead of the locale code, in addition to providing a configuration +compatible with `date-fns` to `MAT_DATE_FORMATS`. Locale data for `date-fns` can be imported +from `date-fns/locale`. + + + +#### Choosing a date implementation and format settings + +The timepicker is built to be implementation-agnostic and to be interoperable with +`mat-datepicker`. This means that it can be made to work with a variety of different date +implementations. However it also means that developers need to make sure to provide the +appropriate pieces for the timepicker to work with their chosen implementation. + +The easiest way to ensure this is to import one of the provided date adapters: + +`provideNativeDateAdapter` or `MatNativeDateModule` + + + + + + + + + + + + + + + + + + + + +
Date typeDate
Supported localesLocales using either AM/PM or 24-hour formatting
DependenciesNone
Import from@angular/material/core
+ +`provideDateFnsAdapter` or `MatDateFnsModule` (installed via `ng add @angular/material-date-fns-adapter`) + + + + + + + + + + + + + + + + + + + + +
Date typeDate
Supported localesSee project for details
Dependenciesdate-fns
Import from@angular/material-date-fns-adapter
+ +`provideLuxonDateAdapter` or `MatLuxonDateModule` (installed via `ng add @angular/material-luxon-adapter`) + + + + + + + + + + + + + + + + + + + + +
Date typeDateTime
Supported localesSee project for details
DependenciesLuxon
Import from@angular/material-luxon-adapter
+ +`provideMomentDateAdapter` or `MatMomentDateModule` (installed via `ng add @angular/material-moment-adapter`) + + + + + + + + + + + + + + + + + + + + +
Date typeMoment
Supported localesSee project for details
DependenciesMoment.js
Import from@angular/material-moment-adapter
+ +**Note**: `provideNativeDateAdapter` implements time parsing using a regex which means that it +only supports AM/PM time (e.g. `1:45 PM`) or 24-hour time (e.g. `22:45` or `22.45`). As such +it won't work on locales with different formatting. We recommend using one of the provided date +adapters mentioned above or creating your own adapter by extending the `DateAdapter` class from +`@angular/material/core`. For example, if you want to use the `date-fns` adapter, you can update +your `bootstrapApplication` format to the following: + +```ts +import {provideDateFnsAdapter} from '@angular/material-date-fns-adapter'; + +bootstrapApplication(MyApp, { + providers: [provideDateFnsAdapter()] +}); +``` + +#### Customizing the parse and display formats + +The `MAT_DATE_FORMATS` object is a collection of formats that the timepicker uses when parsing +and displaying date objects. These formats are passed through to the `DateAdapter` so you will want +to make sure that the format objects you're providing are compatible with the `DateAdapter` used in +your app. + +`MAT_DATE_FORMATS` is the same object used by `mat-datepicker` so it's likely already +configured if your app is using the datepicker, but for the timepicker you need to ensure that the +`display.timeInput`, `display.timeOptionLabel` and `parse.timeInput` properties are set as well. + +If you want use one of the `DateAdapters` that ships with Angular Material, but use your own +`MAT_DATE_FORMATS`, you can either pass the formats into the providers function, or provide the +`MAT_DATE_FORMATS` token yourself. For example: + +```ts +bootstrapApplication(MyApp, { + providers: [provideNativeDateAdapter(MY_NATIVE_DATE_FORMATS)], +}); +``` + +### Accessibility + +The timepicker implements the [ARIA combobox interaction pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/). +The timepicker input specifies `role="combobox"` while the content of the dropdown applies +`role="listbox"` and the options within the dropdown apply `role="option"`. By default the listbox +is labelled from the `mat-form-field` it is placed in, but if you aren't using a form field or if +you want to customize the label, you can do so through the `ariaLabel` or `ariaLabelledby` inputs +on `mat-timepicker`. + +### Troubleshooting + +#### Error: MatTimepicker: No provider found for DateAdapter/MAT_DATE_FORMATS + +This error is thrown if you haven't provided all of the injectables the timepicker needs in order to +work correctly. The easiest way to resolve this is to add `provideNativeDateAdapter` or +`provideMomentDateAdapter` to your app config. See +[_Choosing a date implementation_](#choosing-a-date-implementation-and-format-settings) for +more information. + +#### Error: MatTimepicker: Incomplete `MAT_DATE_FORMATS` has been provided + +The timepicker needs the `display.timeInput`, `display.timeOptionLabel` and `parse.timeInput` fields +in `MAT_DATE_FORMATS` in order to work correctly. You should update your date formats object to +include include these fields. See [_Customizing the parse and display formats_](#customizing-the-parse-and-display-formats) +for more information. + +#### Error: Cannot specify both the `options` and `interval` inputs at the same time + +A `mat-timepicker` cannot specifify both the `options` and `interval` inputs at the same time. +The template should be updated to remove one of them. + +#### Error: Value of `options` input cannot be an empty array + +The array passed into the `options` input of `mat-timepicker` cannot be empty, because the user +won't have any options to choose from. + +#### Error: A MatTimepicker can only be associated with a single input + +This error is thrown if more than one `` tries to claim ownership over the same +`` (via the `matTimepicker` attribute on the input). A timepicker can only be +associated with a single input.