Calendar

The month grid for picking a day, used inside the date picker and on its own.

Refined portVue source: WildCalendar.vueStorybook story: Forms/Calendar

Try it

Click a day, or tab into the grid and use the arrow keys. The arrows carry on into the next month.

October 2026

Su
Mo
Tu
We
Th
Fr
Sa
Friday, October 9, 2026
Min / max
<WildCalendar
  v-model="date"
/>

When to use

  • Use it on its own where the month should stay open, such as in a schedule editor.
  • Set bounds when only some days are valid. Days outside keep their place, so the columns still line up with the weekdays.
Don’t use it

Anatomy

Three bands on a 340px surface. Every month shows six weeks, so the calendar never changes height.

  • Header: previous year, previous month, the month label, next month, next year.
  • Weekday row, starting on Sunday.
  • Six weeks of days, including days from the months either side.

Day states

default
today
selected
selected + today
other month
out of bounds
keyboard focus
Today keeps its dot when it’s selected, so the grid always shows which day is today.

Accessibility

The grid is one tab stop, on the chosen day or today. The month label is announced each time it changes.

KeyWhat it does
TabMoves through the header buttons, then onto one day in the grid.
Arrow keysMove a day or a week, into the next or previous month.
Home / EndMove to the start or end of the week.
Page Up / Page DownMove a month. With Shift, a year.
Enter / SpacePicks the focused day.

Props

PropTypeDefaultDescription
value / defaultValueDate | nullnullThe chosen day, controlled or uncontrolled.
onChange(day: Date) => void—Fires with the picked day.
minDate / maxDateDate | string | nullnullThe first and last days that can be picked.
autoFocusbooleanfalseFocuses the grid on mount.
footerReactNode—Actions under the grid, inside the surface.

Tokens

TokenValueWhere it lands
--global-blue-1000#1877F2The selected day. White on it is 4.23:1.
--global-blue-1100#0C296ASelected day on hover (white 13.63:1), and today’s number, 12.75:1 on its tint.
--global-blue-1000#1877F2The focus ring.
--global-blue-100#EBFAFFToday’s ground.
--global-blue-1000#1877F2Today’s dot. Blue-1000 is only 3.96:1 on the tint, so the number takes blue-1100.
--global-neutral-grey-200 / -1200#F5F5F5 / #1D1C20A hovered day and its number.
--global-neutral-grey-1100#2D2B32An ordinary day.
--global-neutral-grey-700#C9C9CCDays from the months either side.
(no token)#4F4D55Weekday headers.
--font-size-sm12pxDay numbers.
--font-weight-medium475Day numbers.
--radius-lg / -md8px / 6pxDay cells; header buttons.
--shadow-lg0 10px 15px -3px …The surface.