Skip to main content

Calendar

Displays a calendar for users to select a date or date range.

Submit feedback
github
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 is false. 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.

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.

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

NameTypeDefaultRequiredDescription
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

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
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)

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

Calendar Classes

Class NameDescription
.abyss-calendar-rootCalendar root element
.abyss-calendar-header-rootCalendar header root element
.abyss-calendar-header-month-year-containerCalendar header month/year container
.abyss-calendar-header-previous-year-buttonCalendar header previous year button
.abyss-calendar-header-previous-month-buttonCalendar header previous month button
.abyss-calendar-header-next-month-buttonCalendar header next month button
.abyss-calendar-header-next-year-buttonCalendar header next year button
.abyss-calendar-header-month-buttonCalendar header month button
.abyss-calendar-header-year-buttonCalendar header year button
.abyss-calendar-day-grid-rootCalendar table root element
.abyss-calendar-day-grid-headerCalendar table header
.abyss-calendar-day-grid-header-rowCalendar table header row
.abyss-calendar-day-grid-header-cellCalendar table header cell
.abyss-calendar-day-grid-bodyCalendar table body
.abyss-calendar-day-grid-body-rowCalendar table body row
.abyss-calendar-footerCalendar footer
.abyss-calendar-footer-filled-buttonCalendar footer filled button
.abyss-calendar-footer-outline-buttonCalendar footer outline button
.abyss-calendar-arrow-buttonArrow button root element
.abyss-calendar-arrow-button-iconArrow button icon element
.abyss-calendar-day-grid-day-cellDay cell root element
.abyss-calendar-day-grid-day-buttonDay cell button
.abyss-calendar-month-year-picker-headerMonth/year picker header
.abyss-calendar-month-year-picker-back-buttonMonth/year picker back button
.abyss-calendar-month-year-picker-header-textMonth/year picker header text
.abyss-calendar-month-year-list-containerMonth/year list container
.abyss-calendar-month-year-picker-list-optionMonth/year picker list option

Calendar Keyboard Interactions

KeyDescription
SpaceSelects the currently focused date
EnterSelects the currently focused date
Up ArrowMoves focus to the same day of the previous week
Down ArrowMoves focus to the same day of the next week
Right ArrowMoves focus to the next day
Left ArrowMoves focus to the previous day
HomeMoves focus to first date in the current week
EndMoves focus to last date in the current week
Page UpDisplays the previous month
Page DownDisplays the next month
Shift + Page UpChanges the displayed month to the same month of the previous year
Shift + Page DownChanges the displayed month to the same month of the next year

Month/Year Picker Keyboard Interactions

KeyDescription
SpaceSelects the currently focused option, closes the picker, and returns focus to the header button in the calendar
EnterSelects the currently focused option, closes the picker, and returns focus to the header button in the calendar
Up ArrowMoves 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 ArrowMoves 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)

Component Tokens

Note: Click on the token row to copy the token to your clipboard.

Calendar Tokens

Token NameValue
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)
Table of Contents