Date input
FreeA date field you type into, with the reading shown live and a month that carries data marks.
pnpm dlx shadcn@latest add https://caliperui.site/r/date-input.jsonTry “next fri”, “14 oct” or “in 2 weeks”.
Payout lands by 17:00 on 2026-10-16.
When to use #
Use it for
- Scheduling where typing “next fri” beats clicking through months.
- Dates where some days carry data (invoices due) or are unavailable for a reason.
Skip it when
- People mostly browse a month; use the date picker or calendar.
Decisions #
Why it is built this way, so you know what to keep when you change your copy.
Behaviour
- It shows what it read before it commits
- Typed text such as “next fri” or “in 2 weeks” is read back in mono under the field, and Enter commits it, so a misread date is caught before it is saved.
Usage
- Let people type
- Most dates are faster to type than to pick. Keep the calendar for browsing and the field for knowing.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/date-input.json
Adds its 6 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above. It is built from DateInput and parseNaturalDate.
import { useState } from "react" import { DateInput } from "@/components/ui/date-input" export function PayoutDate() { const [date, setDate] = useState<string | null>("2026-10-16"); const due: Record<string, string> = { "2026-10-14": "1 invoice due", "2026-10-18": "1 invoice due", "2026-10-21": "2 invoices due" }; const weekend = (iso: string) => [0, 6].includes(new Date(`${iso}T12:00:00`).getDay()); return ( <div className="grid w-full max-w-xs gap-2 pb-80"> <DateInput label="Schedule payout" value={date} onValueChange={setDate} today={new Date(2026, 9, 9)} marks={(iso) => due[iso]} disabledDates={weekend} disabledReason={(iso) => (weekend(iso) ? "banks are closed at weekends" : undefined)} /> <p role="status" className="text-sm text-muted-foreground">{date ? `Payout lands by 17:00 on ${date}.` : "No date yet."}</p> </div> ); }
API reference #
DateInput
component
parseNaturalDate
component
No props of its own; it accepts the native props of its root element.
Accessibility #
It is built on native elements and keeps aria-invalid, aria-describedby, aria-label, aria-hidden and aria-live in step with state. Changes that matter are announced through a live region.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.