Date picker
Month-grid date picker for single dates or ranges, with a springing pixel selection block, a dotted range band and a mark on today.
Playground
Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.
<PxDate range defaultValue="2026-10-20/2026-10-24" firstDay={1} />Installation
pnpm dlx shadcn@latest add @lumesec/px-dateFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/px-date.jsonUsage
import { PxDate } from "@/components/lumesec/px-date";
export function Example() {
return <PxDate name="trip" range defaultValue="2026-10-20/2026-10-24" />;
}Behaviour
A month grid with a pixel selection block that springs between days, a dotted band across ranges and a mark on today. Weeks start on Monday; leave out range for a single date.
API reference
Props
Also accepts every prop of <div> (React.ComponentProps<"div">), spread onto the root element.
valueTypestringControlled selection: YYYY-MM-DD, or YYYY-MM-DD/YYYY-MM-DD with range. Use with onValueChange. A new value also shows its month.
defaultValueTypestringDefault""Initial selection when uncontrolled; it also sets the month shown. A form reset restores it.
rangeTypebooleanDefaultfalsePick a start and an end date instead of a single date.
firstDayTypePxDateWeekdayDefault1First day of the week, from 0 (Sunday) to 6. The default is Monday.
nameTypestringForm field name. A range submits as start/end and stays empty until both ends are picked.
disabledTypebooleanDefaultfalseDims the calendar and disables its buttons.
onValueChangeType(value: string) => voidCalled when a date is picked; in range mode only when the end date is picked.
Ref
ref points at the root HTMLDivElement.
Keyboard
| Keys | Action |
|---|---|
| ArrowLeft / ArrowRight | Move to the previous / next day. |
| ArrowUp / ArrowDown | Move to the previous / next week. |
| PageUp / PageDown | Move to the same day in the previous / next month, clamped to its length (31 January moves to 28 February). |
| Enter / Space | Pick the focused day. |
Accessibility
- Days are native buttons with
role="gridcell"inrole="row"weeks inside arole="grid"container. - Each day has an
aria-labelwith the full date ("Saturday, 24 October 2026") andaria-selectedfor the selected start and end; today hasaria-current="date". - Roving tabindex: only the focused day is in the tab order. Moving past the edge of the month shows the next month and keeps focus on the new day.
- The month title is an
aria-live="polite"region; the arrow buttons are labelled "Previous month" and "Next month". - The weekday header and the selection canvas are
aria-hidden. - With
name, a hidden input submitsYYYY-MM-DD, orYYYY-MM-DD/YYYY-MM-DDwithrange, which stays empty until both ends are picked. There is no validation. Form reset restoresdefaultValueand shows its month. - Reduced motion: the month grid swaps without sliding, the selection block jumps instead of springing, and the title and summary swap without rolling.
Theming
Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --foreground, --muted-foreground, --card, --border, --muted, --lumesec and --lumesec-foreground.
Notes
- In range mode, picking a date before the start makes it the new start, and hovering after the start previews the band.
- The Today button shows the current month and picks today. Today is read in the browser, so server markup carries no today mark; without a value the grid fills in after hydration.
- The summary line, for example "20 Oct – Sat, 24 Oct 2026 · 4 nights", and all labels are in English. Dates use local time.
Related
Was this page helpful?