# 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.
- React: `import { PxDate } from "@/components/lumesec/px-date"`
- Collection: Pixel UI (https://elements.lumesec.ai/components/pixel-ui)
- Registry item: https://elements.lumesec.ai/r/px-date.json
- Page: https://elements.lumesec.ai/components/pixel-ui/date



Live preview: https://elements.lumesec.ai/view/px-date

Demo source:

```tsx
import { PxDate } from "@/components/lumesec/px-date";

export default function PxDateDemo() {
  return (
    <div className="w-full max-w-[400px] rounded-[14px] border border-border bg-card px-5 py-[18px] shadow-[0_14px_34px_-20px_rgb(0_0_0/0.4)]">
      <PxDate name="trip" range defaultValue="2026-10-20/2026-10-24" />
    </div>
  );
}
```

## Playground

Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.

## Installation

```bash
npx shadcn@latest add @lumesec/px-date
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/px-date.json
```

## Usage

React:

```tsx
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.

| Prop            | Type                      | Default | Description                                                                                                                              |
| --------------- | ------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `value`         | `string`                  | —       | Controlled selection: `YYYY-MM-DD`, or `YYYY-MM-DD/YYYY-MM-DD` with `range`. Use with `onValueChange`. A new value also shows its month. |
| `defaultValue`  | `string`                  | `""`    | Initial selection when uncontrolled; it also sets the month shown. A form reset restores it.                                             |
| `range`         | `boolean`                 | `false` | Pick a start and an end date instead of a single date.                                                                                   |
| `firstDay`      | `PxDateWeekday`           | `1`     | First day of the week, from `0` (Sunday) to `6`. The default is Monday.                                                                  |
| `name`          | `string`                  | —       | Form field name. A range submits as `start/end` and stays empty until both ends are picked.                                              |
| `disabled`      | `boolean`                 | `false` | Dims the calendar and disables its buttons.                                                                                              |
| `onValueChange` | `(value: string) => void` | —       | Called 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"` in `role="row"` weeks inside a `role="grid"` container.
* Each day has an `aria-label` with the full date ("Saturday, 24 October 2026") and `aria-selected` for the selected start and end; today has `aria-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 submits `YYYY-MM-DD`, or `YYYY-MM-DD/YYYY-MM-DD` with `range`, which stays empty until both ends are picked. There is no validation. Form reset restores `defaultValue` and 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](/docs/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.


