Web component
<p-datetime>
Date, time and date range picker with a calendar dialog
- Import
@parallelogram-js/core/components/PDatetime- Tag
p-datetime
Playground
<form class="form" action="#chosen">
<div class="form__group">
<label class="form__label" for="visit-date">Date</label>
<div class="form__control">
<p-datetime id="visit-date" name="date" mode="date" show-quick-dates required></p-datetime>
</div>
</div>
<div class="form__actions">
<button type="submit">Continue</button>
</div>
</form>
Use the example to see the events it sends.
Submits the local date and time chosen, such as 2024-01-15T14:30, as <input type="datetime-local"> does. In time mode it submits hh:mm, and format changes what is sent.
<form class="form" action="#chosen">
<div class="form__group">
<label class="form__label" for="appointment">Appointment</label>
<div class="form__control">
<p-datetime id="appointment" name="appointment" mode="datetime" value="2024-01-15T14:30"></p-datetime>
</div>
</div>
<div class="form__actions">
<button type="submit">Book</button>
</div>
</form>
Use the example to see the events it sends.
<form class="form" action="#chosen">
<div class="form__group">
<span class="form__label">Stay</span>
<div class="form__control">
<p-datetime name="check-in" range range-to="check-out" from-label="Check in" to-label="Check out"></p-datetime>
</div>
</div>
<div class="form__actions">
<button type="submit">Search rooms</button>
</div>
</form>
Use the example to see the events it sends.
About
The value fields and the calendar button open a dialog with a day grid and, in datetime and time modes, time selects. Values are local and follow the native inputs: yyyy-mm-dd in date mode, yyyy-mm-ddThh:mm in datetime mode like datetime-local, and hh:mm in time mode, with :ss when the seconds are set. An ISO instant with Z or an offset is read as the local date and time it stands for. The element is form-associated: it submits its value, and in range mode the end of the range under range-to, in that format or the one format names.
min and max disable days outside them, and min-from-field and max-from-field follow another field, such as a check-in date limiting check-out.
Accessibility
In the day grid the arrow keys move by day and week, Home and End go to the start and end of the week, Page Up and Page Down change month (with Shift, year), Enter or Space picks the focused day, and Escape closes the dialog and returns focus. In the month and year views the arrow keys move between months or years, and Home and End go to the start and end of the row. Moving focus outside the picker closes the dialog.
Without JavaScript
Until the module loads this element is empty markup with no field and no calendar in it, and the package stylesheet hides it while scripts are running. It is the form field, so a form submitted before it upgrades carries no date and required cannot hold the form back. Where that matters, render a native <input type="date"> on the server and replace it once the module is in.
Usage
Register the component and the framework loads it the first time a page contains p-datetime.
import { Parallelogram } from '@parallelogram-js/core';
const app = Parallelogram.create();
app.components.add('p-datetime', () => import('@parallelogram-js/core/components/PDatetime'));
app.run();
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
mode | date | datetime | time | date | What the picker chooses Property mode. |
value | string | none | The value, or the start of the range, in local time: yyyy-mm-dd in date mode, yyyy-mm-ddThh:mm in datetime mode and hh:mm in time mode. An ISO instant with Z or an offset is read as the local date and time Property value. |
name | string | none | The form field name Property name. |
time-format | 12 | 24 | 24 | Hour format of the time selects Property timeFormat. |
show-quick-dates | flag | none | Show quick date buttons Property showQuickDates. |
quick-dates | string | yesterday,today,tomorrow | Comma-separated quick dates Property quickDates. |
range | flag | none | Choose a start and end Property range. |
range-to | string | none | Form field name for the end of the range Property rangeTo. |
range-to-value | string | none | The end of the range, in the same format as value Property rangeToValue. |
date-noun | string | date | The word for a date inside the sentences below, where {what} stands For every instance, PDatetime.defaults.dateNoun. |
datetime-noun | string | date and time | The same for a date and time For every instance, PDatetime.defaults.datetimeNoun. |
time-noun | string | time | The same for a time For every instance, PDatetime.defaults.timeNoun. |
placeholder | string | Select {what}... | Shown in an empty field For every instance, PDatetime.defaults.placeholder. |
from-placeholder | string | Start {what}... | Shown in an empty start field of a range For every instance, PDatetime.defaults.fromPlaceholder. |
to-placeholder | string | End {what}... | Shown in an empty end field of a range For every instance, PDatetime.defaults.toPlaceholder. |
choose-label | string | Choose {what} | The accessible name of the calendar button and the panel For every instance, PDatetime.defaults.chooseLabel. |
choose-range-label | string | Choose {what} range | The accessible name of the panel while choosing a range For every instance, PDatetime.defaults.chooseRangeLabel. |
value-label | string | {label}: {value} | The accessible name of a field: its form label, or the mode's noun, and its value For every instance, PDatetime.defaults.valueLabel. |
empty-value | string | not set | The {value} in that name while the field is empty For every instance, PDatetime.defaults.emptyValue. |
from-label | string | From | Label for the start of the range Property fromLabel. For every instance, PDatetime.defaults.fromLabel. |
to-label | string | To | Label for the end of the range Property toLabel. For every instance, PDatetime.defaults.toLabel. |
prev-month-label | string | Previous month | The accessible name of the previous button over the days For every instance, PDatetime.defaults.prevMonthLabel. |
next-month-label | string | Next month | The same for the next button For every instance, PDatetime.defaults.nextMonthLabel. |
prev-year-label | string | Previous year | The previous button over the months For every instance, PDatetime.defaults.prevYearLabel. |
next-year-label | string | Next year | The next button over the months For every instance, PDatetime.defaults.nextYearLabel. |
prev-years-label | string | Previous years | The previous button over the years For every instance, PDatetime.defaults.prevYearsLabel. |
next-years-label | string | Next years | The next button over the years For every instance, PDatetime.defaults.nextYearsLabel. |
hour-label | string | Hour | The accessible name of the hour select For every instance, PDatetime.defaults.hourLabel. |
minute-label | string | Minute | The accessible name of the minute select For every instance, PDatetime.defaults.minuteLabel. |
ampm-label | string | AM or PM | The accessible name of the AM/PM select For every instance, PDatetime.defaults.ampmLabel. |
clear-label | string | Clear | The clear button For every instance, PDatetime.defaults.clearLabel. |
apply-label | string | Apply | The apply button For every instance, PDatetime.defaults.applyLabel. |
range-start-hint | string | Click to select start date | Announced while choosing a range, before a start is chosen For every instance, PDatetime.defaults.rangeStartHint. |
range-end-hint | string | Start date selected. Now select end date | Announced once the start is chosen For every instance, PDatetime.defaults.rangeEndHint. |
range-done-hint | string | Range selected. Click dates to modify. | Announced once both ends are chosen For every instance, PDatetime.defaults.rangeDoneHint. |
yesterday-label | string | Yesterday | The quick date for yesterday For every instance, PDatetime.defaults.yesterdayLabel. |
today-label | string | Today | The quick date for today For every instance, PDatetime.defaults.todayLabel. |
tomorrow-label | string | Tomorrow | The quick date for tomorrow For every instance, PDatetime.defaults.tomorrowLabel. |
required-message | string | Please choose a {what}. | The form's validity message while a required field is empty For every instance, PDatetime.defaults.requiredMessage. |
required-range-message | string | Please choose a start and end {what}. | The same for a required range For every instance, PDatetime.defaults.requiredRangeMessage. |
min-message | string | Please choose a date on or after {date}. | The validity message for a date before min, with {date} formatted in the page's language For every instance, PDatetime.defaults.minMessage. |
max-message | string | Please choose a date on or before {date}. | The same for a date after max For every instance, PDatetime.defaults.maxMessage. |
lang | string | none | The language for month and weekday names and every formatted date, taken from the nearest ancestor's lang when the picker has none, and from the browser when the page has none either. A language without a region keeps the visitor's own: lang="en" shows an Australian visitor 15 Jan 2024, lang="en-US" shows everyone Jan 15. Changing it on the picker re-renders; changing an ancestor's does not |
min | string | none | Earliest selectable date, as yyyy-mm-dd, a local date and time, or ISO Property min. |
max | string | none | Latest selectable date, as yyyy-mm-dd, a local date and time, or ISO Property max. |
min-from-field | string | none | Name of a field whose value also sets the earliest date Property minFromField. |
max-from-field | string | none | Name of a field whose value also sets the latest date Property maxFromField. |
format | string | none | Format of the submitted value: iso, iso-tz, iso-datetime, iso-datetime-tz, us-date, us-datetime, eu-date, eu-datetime, mysql, or tokens yyyy mm dd hh ii ss tz tzz Property format. |
required | flag | none | The value, both ends in range mode, must be set for the form to submit Property required. |
disabled | flag | none | Disables the picker; a disabled fieldset does the same Property disabled. |
Properties
| Name | Type | Description |
|---|---|---|
value | string | The value, or the start of the range, as a local string in the format of the mode |
rangeToValue | string | The end of the range, in the same format as value |
range | boolean | Reflects the range attribute |
formread only | HTMLFormElement | null | The owning form |
validityread only | ValidityState | The validity state |
Methods
| Name | Signature | Description |
|---|---|---|
open | () => void | Open the calendar dialog |
close | (options?: { returnFocus?: boolean }) => void | Close the dialog, optionally returning focus to the control that opened it |
toggle | () => void | Open or close the dialog |
checkValidity | () => boolean | Check the value |
reportValidity | () => boolean | Check the value and show the browser message |
Events
| Name | Detail | Description |
|---|---|---|
change | { value: string; complete: boolean; toValue?: string; from?: string; to?: string } | The value changed; complete is true once both ends of a range are set. Bubbles out of shadow roots DOM event |
p-datetime:open | { value: string; toValue?: string } | The dialog opened DOM event |
p-datetime:close | { changed: boolean; value: string; toValue?: string } | The dialog closed; changed says whether the value differs from when it opened DOM event |
Shadow parts
| Name | Description |
|---|---|
field | The row holding the value buttons and the calendar button |
input | Each value button, which shows the date and opens the panel |
trigger | The calendar button at the end of the field |
panel | The dialog holding the calendar, the time and the actions |
nav | The month navigation row |
month-year | The month and year button in that row |
grid | The day grid |
day | Each day button in the grid |
time-select | Each time select: the hour, the minute and AM/PM |
ampm | The AM/PM select, which also carries time-select |
action | Each button in the actions row |
primary | The Apply button, which also carries action |
CSS custom properties
| Name | Default | Description |
|---|---|---|
--datetime-shadow-color | var(--color-shadow) | Colour the panel shadow is built from |
--datetime-btn-hover-bg | var(--color-hover) | Background of a hovered navigation button |
--datetime-placeholder-opacity | 0.6 | Opacity of the placeholder in an empty field |
--datetime-icon-opacity | 0.7 | Opacity of the calendar and chevron icons |
--datetime-disabled-opacity | var(--form-control-disabled-opacity) | Opacity of a disabled field; follows the form control family |
--datetime-padding-x | 0.75em | Horizontal padding of the value buttons |
--datetime-padding-y | 0.375em | Vertical padding of the value buttons |
--datetime-gap | 0.5em | Space between the parts of the field and the panel |
--datetime-radius-lg | var(--panel-border-radius) | The panel's corner radius; follows the panel family |
--datetime-border-width | 1px | Width of the field and panel borders |
--datetime-focus-ring-width | 2px | Width of the focus ring on days and controls |
--datetime-today-border-width | 2px | Width of the ring marking today's date |
--datetime-transition | 0.15s ease | Length and easing of hover and focus changes |
--datetime-panel-padding | var(--panel-padding) | Padding inside the panel; follows the panel family |
--datetime-preset-bg | var(--color-surface-muted) | Background of a quick-date pill; follows the muted surface |
--datetime-preset-color | var(--color-text) | Text of a quick-date pill; follows the text colour |
--datetime-preset-hover-bg | var(--color-accent) | Background of a quick-date pill under the pointer; follows the accent |
--datetime-preset-hover-color | var(--color-accent-contrast) | Text of a quick-date pill under the pointer; follows the accent contrast |
--datetime-action-btn-bg | var(--button-secondary-bg) | Background of an action button; follows the secondary button |
--datetime-action-btn-color | var(--button-secondary-color) | Text of an action button |
--datetime-action-btn-border | var(--button-secondary-border) | Border of an action button |
--datetime-action-btn-hover-bg | var(--button-secondary-hover-bg) | Background of a hovered action button |
--datetime-action-btn-hover-border | var(--button-secondary-hover-border) | Border of a hovered action button |
--datetime-action-btn-primary-bg | var(--button-primary-bg) | Background of the Apply button; set the button token to change every component, or this one for the picker alone |
--datetime-action-btn-primary-color | var(--button-primary-color) | Text of the Apply button |
--datetime-action-btn-primary-hover-bg | none | Background of the hovered Apply button |
--datetime-action-btn-radius | var(--button-border-radius) | Corner radius of an action button |
--datetime-action-btn-padding | var(--button-padding-y) var(--button-padding-x) | Padding of an action button |
--datetime-action-btn-min-height | var(--button-min-height) | Least height of an action button |
--datetime-action-btn-font-size | var(--button-font-size) | Font size of an action button |
--datetime-action-btn-font-weight | var(--button-font-weight) | Font weight of an action button |
--datetime-action-btn-text-transform | none | Text transform of an action button |
--datetime-action-btn-letter-spacing | normal | Letter spacing of an action button |
--datetime-accent | var(--color-accent) | Focus rings, today, hovered buttons and the tint behind days in a range |
--datetime-accent-strong | var(--color-accent-hover) | Selected days and primary buttons, which carry text |
--datetime-bg | var(--surface-dropdown-color-bg) | Field and panel background |
--datetime-text | currentColor | Text colour |
--datetime-muted | var(--color-text-muted) | Muted text |
--datetime-border | var(--color-border) | Panel border and dividers |
--datetime-control-border | var(--surface-control-border-color) | Border of the field and the time selects |
--datetime-radius | none | Corner radius |
--datetime-shadow | 0 4px 6px var(--color-shadow) | Panel shadow |
--datetime-hover | var(--color-hover) | Background of hovered days and buttons |
--datetime-cell-size | none | Size of each day in the grid |
--datetime-panel-min-width | none | Narrowest the panel gets |
--datetime-animation-duration | none | Length of the panel animation |