Features
-
๐ก๏ธ Natural language input: Text field accepts natural language input using
Chrono.js
for both single dates and date ranges. Try typing"yesterday"
,"May tenth"
,"in one year"
or"July 8 to 12"
! - ๐งโโ๏ธ Accessibility first: Built to support users of assistive technology. Follows the WAI-ARIA APG Datepicker dialog pattern.
- ๐ผ Framework-agnostic: Standard Web Component that works with any framework โ or no framework at all.
- ๐ Range selection: Allows user to select single dates or date ranges.
-
๐ฆถ Relatively small footprint: The component is ~45KB minified and gzipped with Chrono.js. If you do not
need language parsing, the original
sqrrl/wc-datepicker
calendar is ~8KB -
๐ช Low dependency: External dependencies are limited to Chrono and some accessibility utils (
@react-aria/live-announcer
,@a11y/focus-trap
andaria-hidden
). No date libraries! - ๐ช Strongly typed: Written in TypeScript.
- ๐ช๐บ Localizable: Customizable labels and date formats.
- ๐ Customizable: Semantic markup with no built-in styles. Themes are optional.
- ๐งช Well tested: Quality assured by means of unit tests.
Demo
light.css
Property | Value |
---|---|
value |
|
range Enable range input |
|
id* A page-unique ID used to identify the component. Mandatory for accessibility! |
|
label Label used for the text input field |
|
placeholder Placeholder used for the text input field |
|
locale BCP 47 language tag |
|
min-date Earliest accepted date |
|
max-date Latest accepted date |
|
disabled Disable the datepicker |
|
input-should-format Format valid dates into a more readable date string |
|
first-day-of-week Configure the first week day |
|
show-month-stepper Enable month stepper |
|
show-year-stepper Enable year stepper |
|
show-clear-button Enable clear button |
|
show-keyboard-hint Displays a hint with available keyboard commands |
|
show-today-button Enable today button |
|
start-date Date to show initially |
|
inline Keep the calendar visible; turn off hiding |
Limitations
-
Date parsing
Dates are parsed using the third party library Chrono.js, which comes with some limitations:
-
Only some languages have support for natural language. See this list of currently supported locales. Non-supported languages use ISO-formatted dates as a fallback.
-
Only one language can be used for parsing at a time. I.e. you cannot have support for both English and Japanese date formats.
-
Spelled out numbers are limited to numbers 1-12. "Seventeen", "Twenty-second", "fifty" etc will not be parsed.
-
Install
npm install --save inclusive-dates
# or
yarn add inclusive-dates
Usage
Via script tags
Include the following script tags in your HTML.
<head>
<script
type="module"
src="https://cdn.jsdelivr.net/npm/inclusive-dates/dist/esm/inclusive-dates.js"
/>
<!-- Loading the theme is optional. -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/inclusive-dates/dist/themes/light.css"
/>
</head>
<body>
<inclusive-dates></inclusive-dates>
</body>
Using a bundler
Import the component using a bundler like rollup.js or esbuild.
import { InclusiveDates } from "inclusive-dates/dist/components/inclusive-dates";
// Importing a theme is optional.
import "inclusive-dates/dist/themes/light.css";
customElements.define("inclusive-dates", InclusiveDates);
With a bundler and automatic lazy loading
If you are using a bundler and want to take advantage of automatic
lazy loading, you can call the provided
defineCustomElements
function. This will only load a
small entry file on page load. The component code is loaded only when
the component is actually rendered.
import { defineCustomElements } from "inclusive-dates/dist/loader";
// Importing a theme is optional.
import "inclusive-dates/dist/themes/light.css";
defineCustomElements();
Options
Options with a primitive type can be passed as attributes. Non-primitive options have to be set as properties on the datepicker instance.
Example:<inclusive-dates first-day-of-week="1" id="datepicker"></inclusive-dates>
<script>
const datepicker = document.getElementById('datepicker');
datepicker.disableDate = function(date) {
// disable Sundays
return date.getDay() === 0;
}
</script>
Attribute / Property | Type | Default | Description |
---|---|---|---|
disabled |
boolean |
false |
Disable the datepicker. |
disableDate |
(date: Date) => boolean |
() => false |
Function that gets passed each displayed date. Should return
true to disable it.
|
element-class-name |
string |
inclusive-dates |
Prefix for all element class names. |
first-day-of-week |
number |
0 |
Set first day of a week. 0 for Sunday,
6 for Saturday.
|
range |
boolean |
false |
Enable/disable range selection. |
labels |
WCDatepickerLabels |
See below. | Set label text. |
locale |
string |
navigator?.language || 'en-US' |
BCP 47 locale string used to format dates. |
show-clear-button |
boolean |
false |
Enable/disable the clear button. |
show-month-stepper |
boolean |
true |
Enable/disable the month stepper buttons. |
show-today-button |
boolean |
false |
Enable/disable the today button. |
show-year-stepper |
boolean |
false |
Enable/disable the year stepper buttons. |
start-date |
string |
The current date. |
Date in YYYY-MM-DD format used to determine the
initially displayed month.
|
value |
Date | Date[] | undefined |
The currently selected date. Array of start and end date if range selection is enabled. | |
inline |
boolean |
false |
If true, the calendar will always be visible. |
{
clearButton: 'Clear value',
monthSelect: 'Select month',
nextMonthButton: 'Next month',
nextYearButton: 'Next year',
picker: 'Choose date',
previousMonthButton: 'Previous month',
previousYearButton: 'Previous year',
todayButton: 'Show today',
yearSelect: 'Select year'
}
Events
Name | Type | Description |
---|---|---|
selectDate |
CustomEvent<string | string[] | undefined>
|
Fired when a date is selected. |
changeMonth |
CustomEvent<{ month: number; year: number; }>
|
Fired when the displayed month or year changes. |
componentReady |
CustomEvent<void>
|
Fired when this component is fully loaded at the first render. |
<inclusive-dates id="datepicker"></inclusive-dates>
<script>
const datepicker = document.getElementById('datepicker');
datepicker.addEventListener('selectDate', function(event) {
console.log(event.detail);
});
datepicker.addEventListener('componentReady', function(event) {
console.log(datepicker.startDate);
});
</script>
Styling
Work in progress!
Browser support
Browser | Supported versions |
---|---|
Google Chrome | 61+ |
Apple Safari | 11+ |
Mozilla Firefox | 63+ |
Microsoft Edge | 79+ |
Keyboard controls
Key | Action |
---|---|
Tab | Cycle through the focusable elements. |
Space, Enter | Select current day. |
Arrow left | Move cursor to previous day. |
Arrow right | Move cursor to next day. |
Arrow up | Move cursor to previous week. |
Arrow down | Move cursor to next week. |
Page up | Move cursor to previous month. |
Page down | Move cursor to next month. |
Shift + Page up | Move cursor to previous year. |
Shift + Page down | Move cursor to next year. |
Home | Move cursor to first day of the month. |
End | Move cursor to last day of the month. |
License
Licensed under the MIT license.
About me
I'm Tommy Feldt, an accessibility specialist at Useit based in Stockholm, Sweden
I do inclusive UX design, frontend development, accessibility consulting, WCAG 2.1 audits, talks and more
Check out some of my work on GitHub or send me an e-mail