Date Picker
Date pickers display a month grid for selecting a single date or a date range inline. Use them when dates need to remain visible, such as in scheduling interfaces or embedded inside another form control.
-
Pro Components -
Responsive Layout Tools -
Ever-Growing Pattern Library -
Unlimited Hosted Projects -
Pre-Built Pro Themes -
Pro Theme Builder -
Pro Color Tools -
Official Figma Design Kit Newer additions to Web Awesome, like <wa-toast>, aren't included in the currently available kit, but a new version is in the works.
Track its progress on GitHub. -
WA Pro Perpetual License -
Actual Human™ Support
Already have Pro? Log in
Date pickers display an inline calendar that lets users choose a single date or a date range. They follow the WAI-ARIA Date Picker pattern and use Intl.DateTimeFormat for localization.
<wa-date-picker> is the inline calendar grid. It is not form-associated and does not submit with forms. For an input that opens a calendar in a popover and participates in forms, use <wa-date-input>.
Examples
Initial Value
By default, the calendar is in single-date mode. Set the value attribute to an ISO date string (YYYY-MM-DD) to preselect a date.
The value attribute always uses ISO 8601 date-only strings: YYYY-MM-DD for single dates and YYYY-MM-DD/YYYY-MM-DD for ranges. The JavaScript setter also accepts Date objects and { from, to } shapes for ergonomic use in code.
<script type="module"> const picker = document.querySelector('wa-date-picker'); // Strings picker.value = '2026-05-11'; picker.value = '2026-05-11/2026-05-18'; // Date objects (single mode) picker.value = new Date(2026, 4, 11); // Range objects picker.value = { from: '2026-05-11', to: '2026-05-18' }; picker.value = { from: new Date(2026, 4, 11), to: new Date(2026, 4, 18) }; </script>
Read the value back with the read-only valueAsDate and valueAsRange properties for typed access.
<script type="module"> const picker = document.querySelector('wa-date-picker'); // mode="single" const date = picker.valueAsDate; // Date | null // mode="range" const { from, to } = picker.valueAsRange; // { from: Date | null; to: Date | null } </script>
Min & Max
Use min and max to bound the selectable range. Days outside the bounds are disabled and not focusable.
Disabling Past & Future
Use disable-past or disable-future to disable all dates before or after today. These are convenience shortcuts that don't require knowing today's date in advance.
Date Range
Use mode="range" to let users pick a start and end date. In range mode, the value is two ISO dates separated by a forward slash, e.g. 2026-05-11/2026-05-18.
It's a good practice to set months="2" in range mode so users can see both ends of the range at once.
Two-Month Display
Set months="2" to render two months side-by-side. This is especially useful in range mode so users can see both ends of a long range at once.
By default, the previous/next buttons advance the visible range by two months. Set page-by="single" to advance one month at a time instead.
Size
Use the size attribute to set the calendar's size.
Disabled
Use the disabled attribute to disable the entire calendar.
Readonly
Use the readonly attribute to display the current value without allowing changes. Cells remain focusable so users can still navigate the grid with the keyboard.
Disabling Specific Dates
Use disabled-dates with a whitespace-separated list of ISO dates to disable individual days. This is useful for holidays or blackout dates. Whitespace around each date is trimmed, so you can put dates on separate lines for readability.
Disabling Days of the Week
Use disabled-days-of-week to disable specific weekdays. The attribute accepts a space-separated list of three-letter weekday names (sun, mon, tue, wed, thu, fri, sat), in any order.
Range Length Constraints
Use min-range and max-range to enforce a minimum or maximum range length in days. If the user's second click violates the constraint, the range is not committed.
Localization
Set the locale attribute to a BCP-47 language tag. When omitted, the calendar uses the inherited lang attribute. Month and weekday names, the first day of the week, and weekend designations are all locale-aware.
First Day of the Week
By default, the first day of the week is determined by the locale. Set first-day-of-week to a three-letter weekday name (sun, mon, tue, wed, thu, fri, or sat) to override.
Weekday Format
Use weekday-format to control how weekday headers are rendered.
Week Numbers
Use with-week-numbers to display ISO 8601 week numbers in a column on the left.
Outside Days
Use with-outside-days to render the trailing days of the previous month and the leading days of the next month inside the grid.
Initial View
Use the view attribute to set the initial view. Accepted values are days (default), months, and years.
Conditionally Disabling Dates
For complex rules (e.g. holidays loaded from an API, weekday + odd-week conditions), set the isDateDisabled JavaScript property to a function that receives a Date and returns true to disable it. This runs in addition to the declarative disabled-* attributes — a date is disabled if any rule matches it.
Custom Day Content
To render custom content inside a specific day cell, provide a slot named day-YYYY-MM-DD. The slotted content replaces the day's label but the button chrome (data attributes, ARIA, click handling) is preserved. This is useful for badges, dots, or holiday labels.
Dynamic Day Content
For content that follows a rule across many dates (e.g. paydays, recurring events, moving holidays), set the dayContent JavaScript property to a function that receives a Date and returns a string of HTML, a Lit TemplateResult, or null to use the default label. This runs for every rendered day cell, so it scales to any year the user navigates to.
If both a day-YYYY-MM-DD slot and dayContent apply to the same date, the slot wins.
Custom Footer
Add buttons or other content below the calendar using the footer slot. The picker exposes goToToday() and clear() methods for common shortcut buttons.
Custom Navigation Icons
Replace the default chevrons by slotting your own icons into previous-icon and next-icon.
Listening for Changes
The change event fires when the user commits a new value. In range mode, input also fires after the first click of a new range, before commit.
API
Importing
If you're using the autoloader or a hosted project, components load on demand — no manual import needed. To cherry-pick a component manually, use one of the following snippets.
Import this component directly from the CDN:
import 'https://ka-f.webawesome.com/[email protected]/components/date-picker/date-picker.js';
After installing Web Awesome via npm, import this component:
import '@awesome.me/webawesome/dist/components/date-picker/date-picker.js';
If you're self-hosting Web Awesome, import this component from your server:
import './webawesome/dist/components/date-picker/date-picker.js';
To import this component for React 18 or below, use the following code:
import WaDatePicker from '@awesome.me/webawesome/dist/react/date-picker/index.js';
Slots
Learn more about using slots.
| Name | Description |
|---|---|
footer
|
Optional content rendered below the calendar grid. Empty by default. |
header
|
Replaces the entire header row including title and navigation buttons. Advanced use only. |
next-icon
|
Icon shown inside the next-page button. Defaults to a right chevron. |
previous-icon
|
Icon shown inside the previous-page button. Defaults to a left chevron. |
Attributes & Properties
Learn more about attributes and properties.
| Name | Description | Reflects |
|---|---|---|
dayContent |
Author-supplied function that returns custom content for a day cell. Receives a
Date and returns a string of
HTML, a Lit TemplateResult, or null to use the default day number. Runs for every rendered day cell (including
outside days). A day-YYYY-MM-DD slot, when provided for the same date, wins over this function. Property only.
Type
WaDatePickerDayContent | undefined
|
|
disableddisabled |
Disables the entire picker.
Type
boolean
Default
false
|
|
disabledDatesdisabled-dates |
A list of whitespace-separated ISO dates that should be disabled. The property accepts an array.
Type
string | string[] | Date[]
|
|
disabledDaysOfWeekdisabled-days-of-week |
Weekdays to disable. Accepts a space-separated list of three-letter weekday names:
sun, mon, tue, wed,
thu, fri, sat
Type
string
Default
''
|
|
disableFuturedisable-future |
Disable all dates strictly after
today.
Type
boolean
Default
false
|
|
disablePastdisable-past |
Disable all dates strictly before
today.
Type
boolean
Default
false
|
|
firstDayOfWeekfirst-day-of-week |
The first day of the week. The default
auto uses the current locale's week info. To set a specific day, pass a
three-letter weekday name: sun, mon, tue, wed, thu, fri, or sat.
Type
WaDatePickerFirstDayOfWeek
Default
'auto'
|
|
focusedDatefocused-date |
The currently focused date as
YYYY-MM-DD. Drives roving tabindex and the visible month.
Type
string
Default
''
|
|
isDateDisabled |
Author-supplied predicate that returns
true when a date should be disabled. Runs in addition to declarative
min / max / disabled-* rules. JavaScript-only — set via property, not attribute.
Type
(date: Date) => boolean | undefined
|
|
localelocale |
BCP-47 locale override. When empty, the inherited
lang attribute is used.
Type
string
Default
''
|
|
maxmax |
The latest selectable date as
YYYY-MM-DD.
Type
string
Default
''
|
|
maxRangemax-range |
Maximum range length in days (
mode="range" only). 0 disables the check.
Type
number
Default
0
|
|
minmin |
The earliest selectable date as
YYYY-MM-DD.
Type
string
Default
''
|
|
minRangemin-range |
Minimum range length in days (
mode="range" only). 0 disables the check.
Type
number
Default
0
|
|
modemode |
The selection mode.
Type
WaDatePickerMode
Default
'single'
|
|
monthsmonths |
Number of months rendered side-by-side. Either
1 or 2. Set to 2 to see both ends of a range at once.
Type
1 | 2
Default
1
|
|
pageBypage-by |
Whether prev/next advances by the visible range (
months) or one month at a time (single).
Type
WaDatePickerPageBy
Default
'months'
|
|
readonlyreadonly |
Displays the current value without allowing changes. Cells remain focusable.
Type
boolean
Default
false
|
|
sizesize |
Visual size.
Type
WaDatePickerSize | 'small' | 'medium' | 'large'
Default
'm'
|
|
todaytoday |
Overrides the date considered "today".
Type
string
Default
''
|
|
valuevalue |
The selected date(s). For
mode="single", an ISO date string (YYYY-MM-DD) or empty. For mode="range", two ISO
dates separated by / (YYYY-MM-DD/YYYY-MM-DD). The property setter also accepts Date objects and
{ from, to } objects for ranges.
Type
string
|
|
valueAsDate |
Read-only convenience getter: returns the selected date in
mode="single".
Type
Date | null
|
|
valueAsRange |
Read-only convenience getter: returns the selected range in
mode="range".
Type
WaDatePickerRange
|
|
viewview |
The current view.
Type
WaDatePickerView
Default
'days'
|
|
weekdayFormatweekday-format |
The weekday header format.
Type
WaDatePickerWeekdayFormat
Default
'short'
|
|
withOutsideDayswith-outside-days |
Shows leading and trailing days from adjacent months.
Type
boolean
Default
false
|
|
withWeekNumberswith-week-numbers |
Shows an ISO week-number column.
Type
boolean
Default
false
|
|
Methods
Learn more about methods.
| Name | Description | Arguments |
|---|---|---|
clear() |
Clears the current selection and emits input then change. |
|
focus() |
Focuses the calendar at the currently focused day. |
options: FocusOptions
|
goToDate() |
Scrolls the view to show the given date and sets the focused day. |
date: string | Date
|
goToToday() |
Equivalent to goToDate(today). |
Events
Learn more about events.
| Name | Description |
|---|---|
change |
Emitted when the user commits a new value. Read the current value from event.target.value. |
input |
Emitted when the value changes during interaction. In range mode, this fires after the first click of a new range. |
wa-focus-day |
Emitted when the focused day changes via keyboard navigation, paging, or pointer hover. event.detail is { date: Date }. |
wa-view-change |
Emitted when the date picker switches between day, month, and year views. event.detail is { view, date }. |
Custom States
Learn more about custom states.
| Name | Description | CSS selector |
|---|---|---|
disabled |
The date picker is disabled. |
:state(disabled)
|
range |
The date picker is in range mode. |
:state(range)
|
readonly |
The date picker is readonly. |
:state(readonly)
|
CSS Parts
Learn more about CSS parts.
| Name | Description | CSS selector |
|---|---|---|
base |
The component's outer wrapper. |
::part(base)
|
day |
A day cell button. State-specific parts are added in addition to day so you can target them with ::part(day-...). |
::part(day)
|
day-disabled |
Added when the day is disabled. |
::part(day-disabled)
|
day-label |
The label text inside a day button. |
::part(day-label)
|
day-outside |
Added when the day belongs to an adjacent month (requires with-outside-days). |
::part(day-outside)
|
day-placeholder |
An empty cell rendered in trailing rows when with-outside-days is off, so the grid is always 6 rows tall and the calendar's height doesn't shift between months. |
::part(day-placeholder)
|
day-range-end |
Added to the second endpoint of a range. |
::part(day-range-end)
|
day-range-inner |
Added to days that fall between the two endpoints of a committed range. |
::part(day-range-inner)
|
day-range-preview |
Added to days inside the hover preview span during an in-progress range. |
::part(day-range-preview)
|
day-range-start |
Added to the first endpoint of a range. |
::part(day-range-start)
|
day-selected |
Added when the day is selected (single mode or a range endpoint). |
::part(day-selected)
|
day-today |
Added to the day cell that represents today. |
::part(day-today)
|
day-weekend |
Added when the day falls on a weekend per the locale's week info. |
::part(day-weekend)
|
footer |
The container wrapping the footer slot. |
::part(footer)
|
grid |
The day grid <table> for a month. |
::part(grid)
|
header |
The header row containing the title and navigation buttons. |
::part(header)
|
month |
A single rendered month. |
::part(month)
|
month-label |
The label rendered above each month when months is greater than 1. |
::part(month-label)
|
months |
The container that holds the rendered month(s). |
::part(months)
|
nav |
The container around the previous and next buttons. |
::part(nav)
|
next |
The next-page button. |
::part(next)
|
previous |
The previous-page button. |
::part(previous)
|
title |
The clickable month/year title button that steps the view up (days → months → years). |
::part(title)
|
view-cell |
The gridcell wrapper around a single view item. Transparent to layout (display: contents). |
::part(view-cell)
|
view-grid |
The grid used when the picker is in month-select or year-select view. |
::part(view-grid)
|
view-item |
A single month or year button inside the view grid. State-specific parts are added as siblings. |
::part(view-item)
|
view-item-disabled |
Added when every day in the month/year is disabled. |
::part(view-item-disabled)
|
view-item-selected |
Added to the month/year that matches the current selection. |
::part(view-item-selected)
|
view-item-today |
Added to the month/year representing today. |
::part(view-item-today)
|
view-row |
A row of three items inside the view grid. Transparent to layout (display: contents). |
::part(view-row)
|
weekday |
A single weekday label cell. |
::part(weekday)
|
weekdays |
The row of weekday labels above each month grid. |
::part(weekdays)
|
weeknumber |
A single week-number cell. |
::part(weeknumber)
|
weeknumbers |
The week-number column header cell. |
::part(weeknumbers)
|
Dependencies
This component automatically imports the following elements. Sub-dependencies, if any exist, will also be included in this list.