import { useCalendar } from '@uhg-abyss/web/hooks/useCalendar';import { Calendar } from '@uhg-abyss/web/ui/Calendar';Day.js
Calendar relies on the Day.js library to handle date operations. All date inputs to the Calendar are Dayjs objects and the selectedDates value returned by the useCalendar hook is also a Dayjs object.
Abyss includes a Day.js tool, which includes a number of preset Day.js plugins, but you can also install Day.js separately.
import { dayjs } from '@uhg-abyss/web/tools/dayjs';useCalendar
Using the Calendar requires the useCalendar hook to manage the calendar's date selection logic.
The useCalendar hook accepts two optional parameters:
selectedDates: The initial selected date(s) in the calendar.isDateRange: A boolean that indicates whether the calendar is in date range mode. The default isfalse. See Date range selection for more information.
The useCalendar hook returns an object with the following properties:
selectedDates: The currently selected date(s) in the calendar.onDateClick: A callback function executed when a date is clicked.
Calendar needs both of these values to function correctly, but the returned selectedDates can be used in your own logic as well.
Navigating the calendar
The Calendar header contains buttons to navigate between months and years. The outermost buttons navigate to the same month of the previous/next year, while the inner buttons navigate to the previous/next month.
See the Accessibility tab for more information on keyboard navigation.
Initial active month
By default, when Calendar first renders, it will display the real-world current month. Use the initialActiveMonth prop to override this and display a different month on initial render. This prop accepts a Dayjs object.
Month/year picker
Clicking on the month or year displayed at the top of the calendar will open the respective picker, allowing users to quickly change the displayed month or year.
onMonthChange
Use the onMonthChange prop to provide a callback function that will be executed whenever the active month changes. The callback function receives the new active month as a Dayjs object.
Minimum and maximum dates
Use the minDate and maxDate props to only allow dates within a given range to be selected. Both props accept a Dayjs object. These values are inclusive endpoints, meaning that the date(s) provided can be selected.
When using minDate and/or maxDate, the options in the month or year picker(s) will be restricted to the range provided. If the range is entirely within a single year, the year picker button will be removed. The same is true for the month picker button with a range within a single month.
In the example below, only the dates from one month before today's date to one month after can be selected.
Exclude dates
Use the excludeDate prop to prevent certain dates from being selected. excludeDate accepts a predicate function and checks each date in the current month against it. If the function returns true, the matching date will be disabled.
In the example below, the excludeDate function disables all Sundays and Saturdays.
Footer
Use the footer prop to add a footer to the calendar. The footer prop accepts an object of the following type:
interface CalendarFooter { filledButton?: CalendarFooterButton; outlineButton?: CalendarFooterButton;}CalendarFooterButton is an object that accepts most props of the Button component, with the exception of variant, size, and color, which are set by the Calendar and cannot be altered.
Date range selection
Set the isDateRange parameter of the useCalendar hook to true to enable date range selection. The selectedDates property will return an object with start and end properties, both of which are Dayjs objects.
Note: Ranges consisting of a single date are valid.
ARIA label
Use the ariaLabel prop to provide extra screen reader text for the Calendar.
Calendar Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
ariaLabel | string | - | - | If present, this value will be used as the ARIA label for the Calendar |
className | string | - | - | CSS class name to apply to each element within the component |
css | Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>> | - | - | Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation |
data-testid | string | - | - | Suffix used to create a unique ID used for automated testing |
disableDefaultProviderProps | boolean | false | - | If set to true, the component will not use the DefaultPropsProvider values. If you aren’t using the DefaultPropsProvider, this prop can be ignored. |
excludeDate | (date: Dayjs) => boolean | - | - | Predicate function to exclude matching dates from the Calendar. This applies even to dates within the minDate and maxDate range, if applicable. |
footer | CalendarFooter | - | - | If present, the Calendar will have a footer containing one or two buttons |
initialActiveMonth | Dayjs | - | - | The initial active month to display |
maxDate | Dayjs | - | - | If present, the Calendar will only display dates of this value's month and earlier |
minDate | Dayjs | - | - | If present, the Calendar will only display dates of this value's month and later |
onDateClick | (date: Dayjs) => void | - | Callback function to execute when a date is clicked | |
onMonthChange | (activeMonth: Dayjs) => void | - | - | Callback function executed when the active/displayed month changes |
selectedDates | Dayjs | { start: Dayjs; end?: Dayjs | undefined; } | - | - | The currently selected date(s) |
Calendar Classes
| Class Name | Description |
|---|---|
| .abyss-calendar-root | Calendar root element |
| .abyss-calendar-header-root | Calendar header root element |
| .abyss-calendar-header-month-year-container | Calendar header month/year container |
| .abyss-calendar-header-previous-year-button | Calendar header previous year button |
| .abyss-calendar-header-previous-month-button | Calendar header previous month button |
| .abyss-calendar-header-next-month-button | Calendar header next month button |
| .abyss-calendar-header-next-year-button | Calendar header next year button |
| .abyss-calendar-header-month-button | Calendar header month button |
| .abyss-calendar-header-year-button | Calendar header year button |
| .abyss-calendar-day-grid-root | Calendar table root element |
| .abyss-calendar-day-grid-header | Calendar table header |
| .abyss-calendar-day-grid-header-row | Calendar table header row |
| .abyss-calendar-day-grid-header-cell | Calendar table header cell |
| .abyss-calendar-day-grid-body | Calendar table body |
| .abyss-calendar-day-grid-body-row | Calendar table body row |
| .abyss-calendar-footer | Calendar footer |
| .abyss-calendar-footer-filled-button | Calendar footer filled button |
| .abyss-calendar-footer-outline-button | Calendar footer outline button |
| .abyss-calendar-arrow-button | Arrow button root element |
| .abyss-calendar-arrow-button-icon | Arrow button icon element |
| .abyss-calendar-day-grid-day-cell | Day cell root element |
| .abyss-calendar-day-grid-day-button | Day cell button |
| .abyss-calendar-month-year-picker-header | Month/year picker header |
| .abyss-calendar-month-year-picker-back-button | Month/year picker back button |
| .abyss-calendar-month-year-picker-header-text | Month/year picker header text |
| .abyss-calendar-month-year-list-container | Month/year list container |
| .abyss-calendar-month-year-picker-list-option | Month/year picker list option |
Calendar Keyboard Interactions
| Key | Description |
|---|---|
| Space | Selects the currently focused date |
| Enter | Selects the currently focused date |
| Up Arrow | Moves focus to the same day of the previous week |
| Down Arrow | Moves focus to the same day of the next week |
| Right Arrow | Moves focus to the next day |
| Left Arrow | Moves focus to the previous day |
| Home | Moves focus to first date in the current week |
| End | Moves focus to last date in the current week |
| Page Up | Displays the previous month |
| Page Down | Displays the next month |
| Shift + Page Up | Changes the displayed month to the same month of the previous year |
| Shift + Page Down | Changes the displayed month to the same month of the next year |
Month/Year Picker Keyboard Interactions
| Key | Description |
|---|---|
| Space | Selects the currently focused option, closes the picker, and returns focus to the header button in the calendar |
| Enter | Selects the currently focused option, closes the picker, and returns focus to the header button in the calendar |
| Up Arrow | Moves focus to the previous option in the list. If focus is on the first option, moves focus to the last option in the list |
| Down Arrow | Moves focus to the next option in the list. If focus is on the last option, moves focus to the first option in the list |
Known screen reader issues
- JAWS+Chrome - Works as designed
- NVDA+Chrome - Works "mostly" as designed in pass-through (forms) mode
- Browse mode does not announce all settings
- VO+Safari - Works "partially" as designed
- Does not announce:
- Grouping (ariaLabel)
- Selected dates (single or range)
- Does not announce:
Component Tokens
Note: Click on the token row to copy the token to your clipboard.
Calendar Tokens
| Token Name | Value | |
|---|---|---|
| calendar.color.border.container | #CBCCCD | |
| calendar.color.border.day-button.today | #002677 | |
| calendar.color.icon.utility.active | #00184D | |
| calendar.color.icon.utility.disabled | #7D7F81 | |
| calendar.color.icon.utility.hover | #004BA0 | |
| calendar.color.icon.utility.rest | #002677 | |
| calendar.color.surface.container | #FFFFFF | |
| calendar.color.surface.day-button.default.active | #E5E5E6 | |
| calendar.color.surface.day-button.default.hover | #F3F3F3 | |
| calendar.color.surface.day-button.default.rest | #FFFFFF | |
| calendar.color.surface.day-button.range.active | #D9E9FA | |
| calendar.color.surface.day-button.range.hover | #E3EEFA | |
| calendar.color.surface.day-button.range.rest | #EDF3FB | |
| calendar.color.surface.day-button.range.background | #D9E9FA | |
| calendar.color.surface.day-button.selected.active | #00184D | |
| calendar.color.surface.day-button.selected.hover | #004BA0 | |
| calendar.color.surface.day-button.selected.rest | #002677 | |
| calendar.color.surface.day-button.cell.range | #EDF3FB | |
| calendar.color.text.header | #002677 | |
| calendar.color.text.day-button.disabled | #7D7F81 | |
| calendar.color.text.day-button.default | #002677 | |
| calendar.color.text.day-button.range | #002677 | |
| calendar.color.text.day-button.selected | #FFFFFF | |
| calendar.color.text.week-days | #4B4D4F | |
| month-year-picker.color.border.separator | #CBCCCD | |
| month-year-picker.color.surface.container | #FFFFFF | |
| month-year-picker.color.text.heading | #002677 | |
| calendar.border-radius.all.container | 4px | |
| calendar.border-radius.all.day-button | 500px | |
| calendar.border-width.all.container | 1px | |
| calendar.border-width.all.today | 2px | |
| month-year-picker.border-width.separator | 1px | |
| calendar.sizing.all.icon.utility | 24px | |
| calendar.spacing.gap.horizontal.footer | 8px | |
| calendar.spacing.gap.horizontal.header | 8px | |
| calendar.spacing.gap.horizontal.header-buttons | 8px | |
| calendar.spacing.padding.bottom.container | 8px | |
| calendar.spacing.padding.horizontal.container | 16px | |
| calendar.spacing.padding.vertical.footer | 8px | |
| calendar.spacing.padding.vertical.header | 8px | |
| calendar.spacing.padding.vertical.header-button | 8px | |
| calendar.spacing.padding.vertical.week-days | 4px | |
| calendar.spacing.padding.vertical.week-row | 4px | |
| month-year-picker.spacing.gap.horizontal.header | 8px | |
| month-year-picker.spacing.padding.all.header | 16px | |
| calendar.elevation.container | 0px 2px 4px -2px rgba(0,0,0,0.16) |