314 lines
13 KiB
Markdown
314 lines
13 KiB
Markdown
|
|
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.
|
||
|
|
|
||
|
|
<!-- example(timepicker-overview) -->
|
||
|
|
|
||
|
|
### 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.
|
||
|
|
|
||
|
|
<!-- example({"example":"timepicker-overview",
|
||
|
|
"file":"timepicker-overview-example.html",
|
||
|
|
"region":"minimum-setup"}) -->
|
||
|
|
|
||
|
|
The timepicker input and toggle can be used either on their own or as a part of a `mat-form-field`:
|
||
|
|
|
||
|
|
<!-- example({"example":"timepicker-overview",
|
||
|
|
"file":"timepicker-overview-example.html"}) -->
|
||
|
|
|
||
|
|
### 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.
|
||
|
|
|
||
|
|
<!-- example(timepicker-forms) -->
|
||
|
|
|
||
|
|
|
||
|
|
### 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.
|
||
|
|
|
||
|
|
<!-- example(timepicker-datepicker-integration) -->
|
||
|
|
|
||
|
|
### 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.
|
||
|
|
|
||
|
|
<!-- example(timepicker-validation) -->
|
||
|
|
|
||
|
|
|
||
|
|
### 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,
|
||
|
|
`<mat-timepicker interval="90m"/>` 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.
|
||
|
|
|
||
|
|
<!-- example(timepicker-options) -->
|
||
|
|
|
||
|
|
|
||
|
|
### 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:
|
||
|
|
|
||
|
|
<!-- example(timepicker-custom-icon) -->
|
||
|
|
|
||
|
|
### 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`.
|
||
|
|
|
||
|
|
<!-- example(timepicker-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`
|
||
|
|
|
||
|
|
<table>
|
||
|
|
<tbody>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Date type</th>
|
||
|
|
<td><code>Date</code></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Supported locales</th>
|
||
|
|
<td>Locales using either AM/PM or 24-hour formatting</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Dependencies</th>
|
||
|
|
<td>None</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Import from</th>
|
||
|
|
<td><code>@angular/material/core</code></td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
`provideDateFnsAdapter` or `MatDateFnsModule` (installed via `ng add @angular/material-date-fns-adapter`)
|
||
|
|
|
||
|
|
<table>
|
||
|
|
<tbody>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Date type</th>
|
||
|
|
<td><code>Date</code></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Supported locales</th>
|
||
|
|
<td><a href="https://github.com/date-fns/date-fns/tree/master/src/locale/">See project for details</a></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Dependencies</th>
|
||
|
|
<td><a href="https://date-fns.org/">date-fns</a></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Import from</th>
|
||
|
|
<td><code>@angular/material-date-fns-adapter</code></td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
`provideLuxonDateAdapter` or `MatLuxonDateModule` (installed via `ng add @angular/material-luxon-adapter`)
|
||
|
|
|
||
|
|
<table>
|
||
|
|
<tbody>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Date type</th>
|
||
|
|
<td><code>DateTime</code></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Supported locales</th>
|
||
|
|
<td><a href="https://moment.github.io/luxon/">See project for details</a></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Dependencies</th>
|
||
|
|
<td><a href="https://moment.github.io/luxon/">Luxon</a></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Import from</th>
|
||
|
|
<td><code>@angular/material-luxon-adapter</code></td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
`provideMomentDateAdapter` or `MatMomentDateModule` (installed via `ng add @angular/material-moment-adapter`)
|
||
|
|
|
||
|
|
<table>
|
||
|
|
<tbody>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Date type</th>
|
||
|
|
<td><code>Moment</code></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Supported locales</th>
|
||
|
|
<td><a href="https://github.com/moment/moment/tree/develop/src/locale">See project for details</a></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Dependencies</th>
|
||
|
|
<td><a href="https://momentjs.com/">Moment.js</a></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<th align="left" scope="row">Import from</th>
|
||
|
|
<td><code>@angular/material-moment-adapter</code></td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
**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 `<input>` tries to claim ownership over the same
|
||
|
|
`<mat-timepicker>` (via the `matTimepicker` attribute on the input). A timepicker can only be
|
||
|
|
associated with a single input.
|