Calendar

Selects a date from a month grid. Selected day fills with ink; today has a 1px outline.

July 2026
MoTuWeThFrSaSu

Day

The run

Today is a hairline. The selected day is ink. Arrow keys move the cursor.

July 2026
MoTuWeThFrSaSu

Use it for

  • Picking one day when the month context matters: bookings, deadlines, schedules.
  • Inline on the page; DatePicker wraps it in a trigger.

Not for

  • Typing a known date; use Input type="date".
  • Ranges; the grid selects one day.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { Calendar } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/calendar.

2. Vendor the source

npx @noorddev/vlak-cli add calendar

The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/calendar.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { useState } from "react";
import { Calendar } from "@noorddev/vlak-react";

const [date, setDate] = useState<Date>();

<Calendar value={date} onValueChange={setDate} weekStart={1} />

Calendar

Month grid with one roving tab stop. Arrows move by day and week, Home/End to the week's ends, PageUp/PageDown by month (Shift: year). Selected is ink; today is a hairline.

PropTypeDefaultDescription
valueDate
defaultValueDate
onValueChange(date: Date) => void
onSelect(date: Date) => voidDeprecated. Use `onValueChange`.
defaultMonthDate
weekStart0 | 110 = Sunday, 1 = Monday.
autoFocusbooleanMove focus to the roving day on mount (a date picker opening).

Also accepts Omit<HTMLAttributes<HTMLDivElement>, "onSelect" | "defaultValue">.

KeysDoes
TabFocuses the month buttons, then the roving day
Arrow left, Arrow rightPrevious or next day
Arrow up, Arrow downSame day the week before or after
Home, EndFirst or last day of the week
Page up, Page downSame day the month before or after
Shift + Page up, Shift + Page downSame day the year before or after
Enter, SpaceSelects the focused day
<div class="rs-cal"><div class="rs-cal-head"><span class="rs-cal-title">July 2026</span><span class="rs-cal-nav"><button class="rs-page"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M10.5 3.75 L5.5 8.25 L10.5 12.75" vector-effect="non-scaling-stroke"/></svg></button><button class="rs-page"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M5.5 3.75 L10.5 8.25 L5.5 12.75" vector-effect="non-scaling-stroke"/></svg></button></span></div><div class="rs-cal-grid" role="grid"><div class="rs-cal-row" role="row"><span class="rs-cal-dow" role="columnheader">Mo</span><span class="rs-cal-dow" role="columnheader">Tu</span><span class="rs-cal-dow" role="columnheader">We</span><span class="rs-cal-dow" role="columnheader">Th</span><span class="rs-cal-dow" role="columnheader">Fr</span><span class="rs-cal-dow" role="columnheader">Sa</span><span class="rs-cal-dow" role="columnheader">Su</span></div><div class="rs-cal-row" role="row"><button class="rs-cal-day" role="gridcell" tabindex="-1">20</button><button class="rs-cal-day" role="gridcell" tabindex="-1">21</button><button class="rs-cal-day" role="gridcell" tabindex="-1">22</button><button class="rs-cal-day" role="gridcell" tabindex="-1">23</button><button class="rs-cal-day rs-cal-day-selected" role="gridcell" tabindex="0" aria-selected="true">24</button><button class="rs-cal-day rs-cal-day-today" role="gridcell" tabindex="-1" aria-current="date">25</button><button class="rs-cal-day" role="gridcell" tabindex="-1">26</button></div></div></div>
.rs-cal.rs-cal-head.rs-cal-title.rs-cal-nav.rs-cal-grid.rs-cal-row.rs-cal-dow.rs-cal-day.rs-cal-day-out.rs-cal-day-today.rs-cal-day-selected.rs-cal-icon.rs-cal-page