Input DateTime
Date and time input with segmented editing, a hidden field for native forms, and optional calendar selection.
Overview
InputDatetime composes Input Group and, for date / datetime modes, Popover and
Calendar. The visible value is split into focusable segments (one per date/time field in your
format). A hidden <input> mirrors the composed string for native form posts. Use
onValueChange when a full Date is committed: all segments are valid, then Enter, blur
after completion, or a calendar pick.
In date and datetime modes, the trailing button opens a Calendar popover for day selection;
time mode has no calendar.
Key bindings
| Key | Behavior |
|---|---|
| ⌫ | Deletes the last digit in the focused segment. If the segment is empty, focus moves to the previous segment. |
| ⌦ | Clears the focused segment. The next digit typed replaces the whole segment (same as focusing fresh). |
| ←/→ | Move focus to the previous or next segment (at ends of the field, the key has no effect). |
| ↵ | Commits the current composed string: if every segment is filled and the value parses for the format, onValueChange runs with the resulting Date. Works from a segment or from the surrounding control. |
| ⇥ | Moves through segments and the calendar button (in date / datetime modes) in focus order. |
blur | Leaving a segment commits the same way as ↵ (when the value is complete and valid). |
Custom props
| Prop | Type | Description |
|---|---|---|
mode | 'date' | 'time' | 'datetime' | Defaults to 'datetime'. Narrows which field tokens from format are editable (date parts, time parts, or both). |
format | string | Pattern for editable segments (y, M, d, H, m, s runs, as in date-fns) and static text between them (e.g. yyyy/MM/dd - HH:mm). If omitted, defaults are yyyy/MM/dd (date), HH:mm (time), and yyyy/MM/dd HH:mm (datetime). |
value | Date | string | null | Controlled value: a Date or an ISO-like or formatted string parseable with format. |
onValueChange | (date: Date | null) => void | Fires when a committed, valid Date is available (see Overview and Key bindings). |
size | 'xs' | 'sm' | 'default' | 'lg' | Optional. Input Group size: shell height, segment padding/text, and calendar control scale together. This is not the HTML size attribute (that prop is not forwarded to the hidden input). |
Install
Configure your registry in components.json:
{
"registries": {
"@uxio": "https://ui.uxio.dev/r/styles/{style}/{name}.json"
}
}Then run:
npx shadcn@latest add @uxio/input-datetimeThis pulls input-group, calendar, and popover as registry dependencies. The correct variant
(Base UI or Radix) follows your components.json style.
Usage
Controlled datetime
import * as React from "react"
import { InputDatetime } from "@/components/ui/input-datetime"
export function ScheduledAtField() {
const [value, setValue] = React.useState<Date | null>(null)
return (
<InputDatetime mode="datetime" value={value ?? undefined} onValueChange={setValue} />
)
}Date-only with custom format
import * as React from "react"
import { InputDatetime } from "@/components/ui/input-datetime"
export function BirthDateField() {
const [value, setValue] = React.useState<Date | null>(null)
return (
<InputDatetime
mode="date"
format="dd/MM/yyyy"
value={value ?? undefined}
onValueChange={setValue}
/>
)
}Time-only
import * as React from "react"
import { InputDatetime } from "@/components/ui/input-datetime"
export function TimeField() {
const [value, setValue] = React.useState<Date | null>(null)
return (
<InputDatetime mode="time" format="HH:mm" value={value ?? undefined} onValueChange={setValue} />
)
}Examples
Date mode (mode="date")
Committed (onValueChange): —
Hidden string (onChange): —
Time mode (mode="time")
Committed time: Fill HH:mm or pick a day in the calendar (reference date).
Datetime mode (mode="datetime")
Controlled value: —
Size variants
Use size so the field aligns with InputGroup and Input dimensions. Segment padding and text scale with the group.
xs
sm
default
lg