Date Time Field
A date field and a time field side by side, both built from the Text Input. The first opens the Date Picker and the second the Time Picker; both accept typed values.
Installation
npx sdaia-ui@latest add date-time-field
Usage
import { DateTimeField } from "@/components/ui/DateTimeField"<DateTimeField legend="Appointment" dateLabel="Date" timeLabel="Time" value={value} onChange={setValue} />Default
A date and a time side by side with one helper message under the pair.
Loading demo: date-time-field-default
Examples
Error
The pair is validated together: a time in the past turns both fields red with one message.
Loading demo: date-time-field-error
24-hour filter
An optional audit filter with 24-hour time.
Loading demo: date-time-field-24-hour
RTL
The fields and labels mirror: the date sits at the start (right).
Loading demo: date-time-field-rtl
Props
Prop | Type | Default | Required |
|---|---|---|---|
value | { date: Date | null; time: TimeValue | null } | — | optional |
defaultValue | DateTimeFieldValue | { date: null, time: null } | optional |
onChange | (value, text: { date; time }) => void | — | optional |
legend | string | — | optional |
dateLabel / timeLabel | string | — | optional |
datePlaceholder / timePlaceholder | string | — | optional |
helperText | string | — | optional |
error | string | — | optional |
timeFormat | "12-hour" | "24-hour" | "12-hour" | optional |
calendar | DatePickerCalendar | "gregorian" | optional |
locale | string | from dir / page | optional |
minDate / maxDate | Date | — | optional |
formatDate / parseDate | (date) => string / (text) => Date | null | — | optional |
timePickerTitle / minuteStep | string / number | — / 5 | optional |
labels | Partial<DateTimeFieldLabels> | — | optional |
required / disabled / size / dir | — | — | optional |
Accessibility
- Two labelled inputs in a <fieldset> with a <legend>; one shared helper / error message is linked to both with aria-describedby, and an error sets aria-invalid on both and is announced.
- Each field is a combobox with aria-haspopup="dialog": click, Enter or Arrow Down open its picker, the keyboard moves focus into it (the selected day or hour), and Escape / Cancel / Submit / Apply return focus to the field.
- Typed values work without the pickers: 2026-10-12, 12/10/2026, 12 Oct 2026 and 12 أكتوبر 2026 for the date; HH:MM (with AM / PM or ص / م) for the time.
- Focus order is date then time in both directions.
Responsive behaviour
- The two fields share the row (16 px gap at desktop). Below about 464 px the time field wraps under the date field, so the shared message still sits under the pair.
- Below 1024 px the date popup uses the Date Picker's mobile layout, sized to the viewport minus 16 px gutters.