@asphalt-react/date-picker
v2.0.0-rc.4
Published
DatePicker
Downloads
669
Readme
DatePicker
DatePicker is a controlled component that lets a user pick a single date or a range of dates via a popover calendar. DatePicker also has an Datefield for users type in a date value. The format — which is also the placeholder - should be ISO-8601 YYYY-MM-DD
for single date selection and YYYY-MM-DD to YYYY-MM-DD
for range. Clicking the button in the date field toggles the calendar.
The calendar contains 2 sections:
The top section contains buttons to navigate to adjacent months and toggle the year panel. The user can choose a year from the year panel.
The bottom section displays the dates. You can configure the first day of the week and the non working days. DatePicker also supports a
dual
mode that renders two calendars simultaneously making it easier to select a range of dates. DatePicker supports i18n via thelocale
prop. To restrict the selectable dates, use theminDate
&maxDate
props.
DatePicker has 3 variants offering different date ranges:
- pro: Default variant which shows dates from 10 years before the current year or the initial selected date's year to 10 years ahead
- dob: Shows dates in the past from 85 years to 13 years prior to current year. Additionally, the non-working days are not highlighted.
- event: Shows dates from today's date or initial selected date to 6 months ahead
In touch supported devices the DatePicker has the ability to render native date-picker. If the browser doesn't support <input type="date" />
, or range
selection is enabled, then it does not render the native date-picker.
Usage
import { DatePicker } from "@asphalt-react/date-picker";
function App() {
const [date, setDate] = React.useState(null);
return (
<DatePicker value={date} onChange={(date, { event }) => setDate(date)} />
)
}
Errors
Dates are complex objects to deal with and can easily cause issues. DatePicker checks for various issues which may arise during interaction. It detects & notifies these errors:
InvalidDate
: When an invalid date is passed. Use the new Date() constructor to create date objects.InvalidRange
: When theminDate
is ahead ofmaxDate
.RangeBreach
: When the date falls outside of the selectable range.UserInvalidDate
: When the user types an invalid date or the date does not match the required format. For example:2020-12-25
✅2019-2-10
✅2019-2-10 to 2019-03-23
✅lorem ipsum
❌ - invalid date2019-12-45
❌ - invalid date25/12/2020
❌ - incorrect format
UserRangeBreach
: When the user enters a date which falls outside of the selectable rangeUserInvalidRange
: When the user enters a date range, where the start date falls after the end date range. For example:2023-10-12 to 2020-02-12
❌
Accessibility
DatePicker works well with assistive technologies. You can enable certain features via props.
The default focus lands on the date tile containing the selected date (if provided) or today's date. DatePicker traps & rotates focus among actionable elements.
Keyboard shortcuts
You can navigate & select using these keyboard shortcuts:
- Use ←, →, ↑ and ↓ to navigate among the dates
- Use space or enter to select a date
- Use option ( alt for windows ) + ← or → to navigate to the same date of the adjacent month
- Use meta + ← or → to navigate to the same month of the adjacent year
- Use tab or shift + tab to rotate focus in the calendar and in the year panel
- Use esc to close the year panel
- Use esc to close the calendar
Data attributes
DatePicker accepts data-* attributes and passes it to the date field.
Props
value
An array of Date object(s). Accepts an instance of Date for the selected date. In case of range, the Date instance in the first index maps to the start date of the range, and the second index maps to the end date of range.
const value = [new Date()] // single date selection
const rangedValue = [new Date(), new Date()] // range selection
| type | required | default | | ------- | -------- | ------- | | arrayOf | false | N/A |
onChange
A callback to handle date change event. The callback has the following signature:
// date is an array of Date instance(s)
onChange = (date, {event}) => {}
| type | required | default | | ---- | -------- | ------- | | func | false | N/A |
onError
A callback to handle errors. The DatePicker has a few pre-defined errors. The callback has the following signature:
onError = (error) => {}
| type | required | default | | ---- | -------- | ------- | | func | false | N/A |
minDate
Restricts the minimum selectable date.
| type | required | default | | ---------- | -------- | ------- | | instanceOf | false | N/A |
maxDate
Resricts the maximum selectable date.
| type | required | default | | ---------- | -------- | ------- | | instanceOf | false | N/A |
range
Allows selection of a range of dates.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
dual
Renders the calendars of two successive months simultaneously.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
locale
Use locale
for internationalization. It formats the day and month names based on the locale and sets the
starting day of the week.
DatePicker supports a set of pre-defined locale strings: "en-US" - English (United States) "en-IN" - English (India) "id" - Bahasa (Indonesia) "vi" - Vietnamese
If you need other locales, pass the locale objects from date-fns/locale
| type | required | default | | ----- | -------- | ------- | | union | false | "en-US" |
weekStartsOn
Configure the starting day of the week. Accepts one integer from 0 - 6, where 0 stands for Sunday.
| type | required | default | | ---- | -------- | ------- | | enum | false | N/A |
nonWorkingDays
Configure the non-working days (or weekend) for the week. Accepts an array of integers from 0 - 6, where 0 stands for Sunday.
| type | required | default | | ------- | -------- | ------- | | arrayOf | false | [0, 6] |
markNonWorkingDates
Highlights the non-working days so that they stand apart from the normal days.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
size
Controls the size of the DatePicker. Accepts one of "s", "m" or "l".
| type | required | default | | ---- | -------- | ------- | | enum | false | "m" |
native
DatePicker can render the web's native date-picker in touch-enabled devices, if the device's operating system supports
input fields of type "date". This behavior is overriden if range
is set to true
as native date-pickers don't support range
selection.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
pro
Renders "pro" variant.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
dob
Renders "dob" variant.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
event
Renders "event" variant.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
invalid
Highlights the DatePicker's field to show an error state.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
placeholder
Placeholder of the field. Overrides the default placeholder which displays the format of date selection.
| type | required | default | | ------ | -------- | ------- | | string | false | N/A |
stretch
Stretches the date field to take container's width.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
disabled
Disables the DatePicker.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
calendarId
A unique identifier for the Calendar.
| type | required | default | | ------ | -------- | ------- | | string | false | N/A |
calendarLabel
Set as the "aria-label" for the button that toggles the picker. The label should cover 2 cases:
- If no date selected the label should ask the user to select a date
- If a date is selected - the label should mention the selected date along with case 1
| type | required | default | | ------ | -------- | ------- | | string | false | N/A |
nextMonthLabel
Set as the "aria-label" for the next month navigation button.
| type | required | default | | ------ | -------- | ------- | | string | false | N/A |
previousMonthLabel
Set as the "aria-label" for the previous month navigation button.
| type | required | default | | ------ | -------- | ------- | | string | false | N/A |
Calendar
Calendar renders the dates of a given month and year, allowing the user to select a date or a range of dates from that month.
Props
selected
An array of Date object(s). Accepts an instance of Date for the selected date. In case of range, the Date instance in the first index maps to the start date of the range, and the second index maps to the end date of range.
const value = [new Date()] // single date selection
const rangedValue = [new Date(), new Date()] // range selection
| type | required | default | | ------- | -------- | ------- | | arrayOf | false | null |
onSelect
A callback to handle date change event. The callback has the following signature:
// date is an array of Date instance(s)
onSelect = (date, {event}) => {}
| type | required | default | | ---- | -------- | ------- | | func | false | N/A |
onError
A callback to handle errors. The DatePicker has a few pre-defined errors. The callback has the following signature:
onError = (error) => {}
| type | required | default | | ---- | -------- | ------- | | func | false | N/A |
month
A zero-based value for the month, where "0" indicates the first month of the year.
| type | required | default | | ---- | -------- | ------- | | enum | true | N/A |
year
A 4-digit value for the year number, for instance: 2024.
| type | required | default | | ------ | -------- | ------- | | number | true | N/A |
minDate
Restricts the minimum selectable date.
| type | required | default | | ---------- | -------- | ------- | | instanceOf | false | null |
maxDate
Resricts the maximum selectable date.
| type | required | default | | ---------- | -------- | ------- | | instanceOf | false | null |
range
Allows selection of a range of dates.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
locale
Use locale
for internationalization. It formats the day and month names based on the locale and sets the
starting day of the week.
DatePicker supports a set of pre-defined locale strings: "en-US" - English (United States) "en-IN" - English (India) "id" - Bahasa (Indonesia) "vi" - Vietnamese
If you need other locales, pass the locale objects from date-fns/locale
| type | required | default | | ----- | -------- | ------- | | union | false | "en-US" |
weekStartsOn
Configure the starting day of the week. Accepts one integer from 0 - 6, where 0 stands for Sunday.
| type | required | default | | ---- | -------- | ------- | | enum | false | N/A |
nonWorkingDays
Configure the non-working days (or weekend) for the week. Accepts an array of integers from 0 - 6, where 0 stands for Sunday.
| type | required | default | | ------- | -------- | ------- | | arrayOf | false | [0, 6] |
highlightNonWorkingDays
Highlights the non-working days so that they stand apart from the normal days.
| type | required | default | | ---- | -------- | ------- | | bool | false | true |
size
Controls the size of the DatePicker. Accepts one of "s", "m" or "l".
| type | required | default | | ---- | -------- | ------- | | enum | false | "m" |
label
Accepts a node for the Calendar's label. Defaults to month and year of the Calendar. For instance: "September 2023".
You can set the prop to false
to not render a label.
| type | required | default | | ----- | -------- | ------- | | union | false | null |
onNavigation
A callback to handle keyboard navigation among the DateTiles in Calendar.
| type | required | default | | ---- | -------- | ------- | | func | false | N/A |
hidePrevious
Hides the previous month dates.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
hideNext
Hides the next month dates.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
focused
The date currently in focus. Accepts an instance of the Date class.
| type | required | default | | ---------- | -------- | ------- | | instanceOf | false | N/A |
navigable
A React ref to control whether the DateTiles should be focusable. The ref's value should be either "true" or "false".
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
DateTile
Renders dates.
Props
children
Date to display
| type | required | default | | ---- | -------- | ------- | | node | true | N/A |
peripheral
Controls whether the Date falls in current month or one of adjacent months.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
today
Adds styles to distinguish the current date with rest of the dates.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
nonWorking
Adds styles to distinguish dates that fall on non-working days or weekend.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
selected
Adds selected styles.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
selectionEdge
Adds styles to the start and end dates or range selection.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
restricted
Dates not allowed for selection.
Use this to let users know the minimum and maximum selectable dates.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
stickStart
Removes border radius from the start edge of DateTiles.
Use it along with stickEnd
to create a range selection.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
stickEnd
Removes border radius from the end edge of DateTiles.
Use it along with stickStart
to create a range selection.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
interactive
Controls interactivity of a DateTile.
Use it to allow/disallow selection of holidays or dates of adjacent months.
| type | required | default | | ---- | -------- | ------- | | bool | false | true |
size
Size of DateTile. Accepts one of "m" or "l".
| type | required | default | | ---- | -------- | ------- | | enum | false | "m" |
focused
Makes DateTile focusable through Tab key.
| type | required | default | | ---- | -------- | ------- | | bool | false | N/A |
DayTile
Renders the Day Tile.
Props
children
Day to display.
Use a 3 letter notation for the day names. For example, "Mon" for Monday.
| type | required | default | | ---- | -------- | ------- | | node | true | N/A |
nonWorking
Adds styles to denote a day falls on weekend.
| type | required | default | | ---- | -------- | ------- | | bool | false | false |
size
Size of DayTile. Accepts one of "m" & "l".
| type | required | default | | ---- | -------- | ------- | | enum | false | "m" |
Hooks
The DatePicker component exposes two immensly powerful hooks - useNavigation()
and useCalendar()
that let you create a custom solution for date selection.
useNavigation
The useNavigation
hook help you to use the Calendar unit component and integrate with the keyboard accessibility automagically. It returns the following values:
- focused - The focused date
- onNavigation - The function to handle keyboard navigation.
- navigable - Let's the Calendar determine how to handle the focus state.
- previousMonth - a function that takes a positive integer as the argument and shifts back the current view by the same value. Use this for implementing the previous month selector.
// shifts back the view by 3 months
previousMonth(3)
- nextMonth - a function that takes a positive integer as the argument and shifts forward the current view by the same value. Use this for implementing the next month selector.
// shifts forward the view by 3 months
nextMonth(3)
- changeYear - a function that takes the full year and sets it as the view's year.
Pass these in the Calendar component and you are done.
Props
The hook accepts a few props:
- base - a date of the month and year to show
- selected - An array of selected date or a start date and end date for range selection.
- minDate - Restricts the date selection before it
- maxDate - Restricts the date selection after it
- onViewChange - The callback to change the view
- views = 1 - Allows the hook to handle multiple calendars simultaneously
- edges = false - Allows the hook to move focus between different views.
Usage
const [base, setBase] = useState(null)
const onViewChange = (date) => {
setBase(date)
}
const {focused, onNavigation, navigable} = useNavigation({
base: new Date(2023, 4, 1)
onViewChange
})
<Calendar
month={base.getMonth()}
year={base.getFullYear()}
focused={focused}
onNavigation={onNavigation}
navigable={navigable}
/>
useCalendar
The useCalendar
hook allows you to create your own Calendar. It returns the following:
- dates - An array of stateful objects for each date in the view. Each object has keys mapped to the props in DateTile unit component.
- days - An array of statuful objects for each day in the week. Each object has keys mapped to the DayTile unit component.
- label - The label to show for each Calendar. Defaults to "MMMM YYYY", for eg, "September 2023".
- startIndex - The starting day of the month. Has a value from 0 - 6, mapped to each day of the week.
Props
The useCalendar
hooks accepts the following props:
- month - The month of the Calendar to show
- year - The year of the Calendar to show
- selected - An array of selected date or a start date and end date for range selection.
- minDate - Restricts the date selection before it
- maxDate - Restricts the date selection after it
- nonWorkingDays - The non working days for the week. Similar to the
nonWorkingDays
prop in DatePicker - weekStartsOn - The starting day of the week. Similar to the
weekStartsOn
prop in DatePicker. - locale - The locale object. Get the locale objects from
date-fns/locale
- range - Modifies the date objects to adapt to range selection.
- previous - If true, prepends the previous month's date to the current month's dates.
- next - If true, appends the next month's date to the current month's dates.
Usage
const {
dates,
startIndex,
days,
label: monthLabel,
} = useCalendar({
month: 3,
year: 2024,
});
const CustomCalendar = () => {
return (
<div>
<span>{label}</span>
<div>
{days.map((day) => (
<DayTile {...props} />
))}
</div>
<div>
{dates.map((date) => (
<DateTile {...props} />
))}
</div>
</div>
);
};