Calendar popover

Types or picks a date and optional local time. A 1px field opens a calendar in the native top layer.

Schedule

Print run

Type a date or open the calendar. The review also includes a local time.

Local date and time, without a time zone.

Use it for

  • Form dates that can be typed or chosen from a month grid.
  • type="datetime-local" for a date with hour and minute controls; the value has no time zone.
  • String values such as 2026-07-24 or 2026-07-24T10:30; min and max use the same format.

Not for

  • A permanently visible month grid; use Calendar.
  • Date ranges; use DateRangePicker.
  • An absolute timestamp shared across time zones; resolve the local value and its time zone in the application.

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 { CalendarPopover } from "@noorddev/vlak-react";

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

2. Vendor the source

npx @noorddev/vlak-cli add calendar-popover

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-popover.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 { CalendarPopover } from "@noorddev/vlak-react";

const [date, setDate] = useState("2026-07-24");
const [review, setReview] = useState("2026-07-23T10:30");

<CalendarPopover label="Print date" name="printDate" value={date} onValueChange={setDate} required />
<CalendarPopover
  label="Proof review"
  name="review"
  type="datetime-local"
  value={review}
  onValueChange={setReview}
  hint="Local date and time, without a time zone."
/>

CalendarPopover

Editable civil dates with native form validation and a top-layer calendar.

PropTypeDefaultDescription
type"date" | "datetime-local""date"
valuestringLocal canonical value. Typed partial drafts are emitted too.
defaultValuestring""
onValueChange(value: string) => void
minstring
maxstring
weekStart0 | 11
localestring"en"
triggerLabelstring"Open calendar"
dialogLabelstring
labelReactNodeLabel rendered above the field at 12px.
okbooleanMarks the field as validated: ink border and ink feedback text.
feedbackReactNodeQuiet feedback line under the field.
hintReactNodeHint under the field; it describes the control.
errorReactNodeError under the field; it describes the control and marks it invalid.

Also accepts InputHTMLAttributes<HTMLInputElement>.

KeysDoes
TabMoves through the date field, calendar trigger, and open panel controls; leaving closes the panel
Enter, Space on the triggerOpens the calendar
Arrow down in the field or on the triggerOpens the calendar and focuses the selected day
Arrow keys, Home, EndMoves between calendar days or to the ends of the week
Page up, Page downMoves by month; hold Shift to move by year
Enter, Space on a daySelects the date; local date and time fields wait for Done
EscapeCloses the panel and discards unconfirmed date and time changes
<div class="rs-calendar-popover"><label class="rs-calendar-popover-label" for="deadline">Deadline</label><div class="rs-calendar-popover-control"><input id="deadline" class="rs-input rs-input-grouped rs-calendar-popover-input" type="text" value="2026-07-24" /><button class="rs-btn-ghost rs-calendar-popover-trigger" type="button" aria-label="Open calendar" aria-haspopup="dialog" aria-expanded="false"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" aria-hidden="true"><path d="M3 3.5h10v10H3zM3 6.5h10M5.5 1.5v4M10.5 1.5v4" /></svg></button></div><input type="hidden" name="deadline" value="2026-07-24" /></div>
.rs-calendar-popover.rs-calendar-popover-label.rs-calendar-popover-control.rs-calendar-popover-input.rs-calendar-popover-trigger.rs-calendar-popover-panel.rs-calendar-popover-grid.rs-calendar-popover-time.rs-calendar-popover-actions.rs-calendar-popover-action.rs-calendar-popover-done.rs-calendar-popover-feedback.rs-calendar-popover-error