Date picker
A date picker is a form field for one date. People type the date or pick it from a calendar; the form gets an ISO date such as 2026-03-17.
<tk-field label="Departure date" helper="For example, 27 3 2026"> <tk-date-picker name="departure" min="2026-03-05" max="2026-09-30"></tk-date-picker> </tk-field>
Put the date picker in a aria-label. Inside a Field, set required and disabled on the
Field.
Anatomy
| Part | What it is |
|---|---|
tk-date-picker |
the element; two Tab stops |
field part |
the bordered box; fills its container |
input part |
the native text input; always typable |
| calendar button | at the end of the box; opens the calendar; the second Tab stop |
popover part |
the panel with the |
The label, helper, and error come from a
Sizes
<tk-date-picker aria-label="Start date" value="2026-03-17"></tk-date-picker> <tk-date-picker size="large" aria-label="End date" value="2026-03-24"></tk-date-picker>
size |
Height | Padding-inline | Value text |
|---|---|---|---|
medium (default) |
32px | space-8 / space-4 |
Body Small (14/20) |
large |
36px | space-10 / space-4 |
Body Medium (16/24) |
The end padding is smaller so the 24px calendar button sits evenly in the box. The heights match Input and Button.
States
<tk-date-picker aria-label="Joined" value="2024-11-02" readonly></tk-date-picker> <tk-date-picker aria-label="Renewal date" value="2026-11-02" disabled></tk-date-picker>
<tk-field label="Arrival date" error="Arrival date must be a real date"> <tk-date-picker name="arrival"></tk-date-picker> </tk-field>
The box doesn't change on hover. On focus, its border takes the focus color and grows thicker inward. While the calendar is open and focus is in it, the box shows no focus.
readonly: people can focus and copy the date; the calendar button doesn't work.disabled: nothing works, and the date is left out of the form.- Error: set
erroron the Field. The border turns red and the message shows under the box.
Typing a date
The text is read when people press Enter or leave the field, never while they type. These all work:
2026-03-2727 mar 2026,March 27, 2026, or27 March(this year)27 3 2026,27/3/2026, or27.3.2026: day, month, year
Years need four digits. After a date is read, the field shows it as "27 Mar 2026".
If the text isn't a real date, the field keeps it, clears the value, and blocks the form
from submitting. Show a message with the Field's error; see
Opening the calendar
- The calendar button, or
Downin the field, opens the calendar. Focusing, clicking, or typing in the field never opens it. - Focus moves to the selected day, or today, or the first day people can pick.
- Picking a day sets the value, closes the calendar, and returns focus to the field. There is no OK button.
Esc, a click outside, orTabcloses it without changing anything.Escdoesn't close a dialog around it.- People can click back into the field and type while the calendar stays open.
Memorable dates
For a date people know by heart, use
<tk-field label="Day"><tk-input inputmode="numeric" autocomplete="bday-day"></tk-input></tk-field> <tk-field label="Month"><tk-input inputmode="numeric" autocomplete="bday-month"></tk-input></tk-field> <tk-field label="Year"><tk-input inputmode="numeric" autocomplete="bday-year"></tk-input></tk-field>
- Use one field each for day, month, and year, under a group label such as "Date of birth" and one hint: "For example, 27 3 2007". Or use one field where space is tight.
- Ask for the month as a number, not a select.
- Don't move focus to the next field automatically.
- Set
autocompleteon birth dates:bday-day,bday-month,bday-year, orbdayon one field.
When to use
Ask whether people already know the date.
- Use a date picker for a near date where the weekday or distance matters: an appointment, a booking, a deadline.
- Use typed fields for a date people know by heart, such as a birth date or an expiry
date. See
Memorable dates . - Use a
Date range picker for a period. Don't pair two date pickers. - Use a
Time picker for the time, next to the date picker. - Use a
Calendar when the grid should stay visible on the page.
Content
- Name the date's role in the label: "Departure date", not "Date".
- Put the format in the helper with an example: "For example, 27 3 2026". Never only in the placeholder; it disappears when people start typing.
- Pick the first error that applies, and reuse the label's words:
| Problem | Error message |
|---|---|
| empty and required | "Enter your departure date" |
| year missing or short | "Departure date must include a full year" |
| not a real date | "Departure date must be a real date" |
| outside the allowed dates | "Departure date must be in the future", or "… must be between 5 March and 30 September 2026" |
Don't write "Invalid date" or "Please". More in
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
| Label the date's role: "Departure date" | Label it "Date" |
| Put "For example, 27 3 2026" in the helper | Put the format only in the placeholder |
| Let people type a birth date in plain fields | Use a date picker for a birth date |
Set min and max |
Let people pick any date in any year |
| Use a Date range picker for a period | Put two date pickers side by side as a range |
| Put a Time picker next to it for a time | Ask for the time inside the date field |
Related
Field : the label, helper, and error around a date picker.Calendar : the grid inside, its keys, and range mode.Date range picker : a start and end date.Time picker : the time next to a date.Input : the box this field shares, and the base for memorable dates.
API
Attributes
| Attribute | Type | Default | What it does |
|---|---|---|---|
value |
ISO date (yyyy-mm-dd) |
'' |
the date; submits under name |
name |
string | — | the form field name |
min / max |
ISO date | — | the allowed dates; earlier or later dates block submission |
week-start |
1–7 |
1 |
the calendar's first day of the week, Monday to Sunday |
required |
boolean | false |
an empty field blocks submission; no visible mark (the Field adds the asterisk) |
readonly |
boolean | false |
focusable and copyable; the calendar button doesn't work |
disabled |
boolean | false |
not focusable, left out of the form |
autocomplete |
string | — | the autofill purpose, such as bday |
placeholder |
string | — | text shown while empty; avoid it |
size |
medium | large |
medium |
height 32 / 36px |
Events
change fires when the date changes: after typing a date that reads, or after picking a
day. input fires on every keystroke. Setting value in code fires nothing. Resetting
the form restores the first value.
CSS
::part(field): the bordered box.::part(input): the native text input.::part(popover): the calendar panel.
Tokens
The box uses the
| Part | Tokens |
|---|---|
| calendar button | 24×24px, radius-full; icon icon/default, icon-size-16; disabled icon/disabled |
| calendar button, hover / press | state/hover / state/press |
| calendar button, focus | border/accent/focus ring inside the button |
| popover | surface/raised + shadow-2, radius-16, 4px from the box |
In high contrast, the popover also gets a 1px border/default. Values per theme:
Accessibility
Built in:
- A native text input that announces as a combobox with a calendar popup, open or closed.
- The calendar button says "Choose date", or "Change date, 17 Mar 2026" once there is a value.
- Every open moves focus into the calendar, and every close puts focus somewhere sensible.
- A date that can't be read, a missing required date, or a date out of bounds blocks submission and moves focus to the field.
- The calendar button is 24px, the minimum target size.
Your part:
- Name every date picker: a Field label with the date's role, or
aria-label. - Put the format example in the helper.
- Set
minandmaxto the dates that make sense. - Write errors on the Field, as
Content says.
| Key | Action |
|---|---|
Tab |
field, then calendar button, then on |
Down / Alt + Down |
opens the calendar and moves focus into it |
Enter |
reads the typed date; if the calendar is closed, submits the form |
Esc |
closes the calendar |
Keys inside the calendar:
Contrast limits
- Field border: 1.33:1 in light and 2.00:1 in dark, under the 3:1 minimum; 4.22:1 in high contrast. Always show a label.