DateTimePicker
A date chip and a time beside it, editable in place. It puts
DatePicker and TimePicker together
and adds the AM/PM control the latter lacks.
Use this when / not when
- Use for a single moment — an expiry, a scheduled send, a reminder — where both halves matter.
- Not when only the day matters;
DatePickeris smaller and has no time to leave at midnight. - Not when only the time matters —
TimePickeron its own, though you then own the AM/PM control. - Not for a range, and not for a disabled or read-only display: neither is a prop.
Import
import { DateTimePicker } from "@onlyoffice/apps-ui-kit/components/date-time-picker";
Also exported from the root barrel @onlyoffice/apps-ui-kit.
Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme.
Dates are Luxon DateTime objects. translations is required and is not filled in for you:
without it the AM/PM drop-down has blank options.
Stories
Default
The picker as a form shows it before anything is chosen: only the "Select date" button. Pick a day to see the time appear beside it, click the time to edit it, and change any other prop live in the Controls panel below.
With Error
Use it when the chosen moment fails validation: the time turns red and the control is marked invalid for screen readers (hasError). A day is picked here because the time, the only part drawn in the error colour, shows only once there is one.
With Initial Date
Use it to edit a moment that already exists, such as a saved deadline: the day chip and the time show it from the first render (initialDate). The English locale gives a 12-hour clock; click the time to see the AM/PM drop-down beside the editor.
Hidden Cross
Use it for a field that must always hold a moment: the day chip has no cross, so the day can be changed in the calendar but never cleared (hideCross).
Twenty Four Hour Clock
Any locale that is not English switches the clock to 24 hours (locale): the time reads "14:30" rather than "02:30 PM", and the editor opened by a click on it has no AM/PM drop-down. The calendar is written in the same locale.
Css Customization
Every overridable variable set on one wrapper -- the variables are listed under CSS variables on this page. Click the time to see the time editor and the day chip to see the calendar; the day chip, the "select date" button and the AM/PM drop-down keep their own variables, listed in the SelectedItem, AddButton and ComboBox stories.
Minimal example
className, id, selectDateText, hasError, locale, openDate, onChange and
translations are all required by the type.
import { useState } from "react";
import { DateTime } from "luxon";
import { DateTimePicker } from "@onlyoffice/apps-ui-kit/components/date-time-picker";
export function ExpiresAt() {
const [at, setAt] = useState<DateTime | null>(null);
return (
<DateTimePicker
id="expires-at"
className=""
locale="en"
selectDateText="Set an expiry"
hasError={false}
openDate={DateTime.now()}
onChange={setAt}
translations={{ AM: "AM", PM: "PM" }}
/>
);
}
Props
Recipes
Error
hasError is required. It draws the shown time in red and sets aria-invalid on the wrapper;
the date chip and the open time editor keep their usual colours, and no message is printed.
import { useState } from "react";
import { DateTime } from "luxon";
import { DateTimePicker } from "@onlyoffice/apps-ui-kit/components/date-time-picker";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
export function ScheduledSend() {
const [at, setAt] = useState<DateTime | null>(null);
const isPast = Boolean(at && at < DateTime.now());
return (
<div>
<DateTimePicker
id="send-at"
className=""
locale="en"
selectDateText="Schedule"
hasError={isPast}
minDate={DateTime.now()}
openDate={DateTime.now()}
onChange={setAt}
translations={{ AM: "AM", PM: "PM" }}
/>
{isPast ? <Text fontSize="12px">Choose a time in the future</Text> : null}
</div>
);
}
Behaviour the types don't state
- The time only appears once a date is chosen. Until then the control is just the date button; there is no way to set a time first.
- The time is a display until it is clicked. Clicking the clock swaps it for
TimePickerplus the meridiem drop-down; an outside click, Enter or Tab swaps it back. The editor takes focus as soon as it opens. - Clearing the date hides the time. The chip's cross (unless
hideCross) empties the day, removes the time beside it and reportsnulltoonChange. - 12-hour or 24-hour is decided by
locale, not by a prop. The component treats anything startingen, plusen-GBexplicitly, as 12-hour — so a British locale gets AM/PM, and every other locale gets a 24-hour clock with no meridiem control. - Choosing a meridiem shifts the time by twelve hours rather than setting it. Picking AM subtracts twelve and picking PM adds twelve, whichever half the value was already in.
translationsis required but was missing from the exported props type until now; it is read while rendering, so an object withAMandPMhas to be passed.className,id,selectDateTextandhasErrorare required by the type even though empty values are perfectly ordinary. Pass""andfalse.- The date half is a
DatePickerdriven through itsouterDate, so all of that component's behaviour applies — including the fixeddd MMM yyyyformat and the calendar closing on every pick. - Outside clicks and keys are listened for on the document in the capture phase, so they act before anything in your own tree.
CSS variables
Set these on an ancestor to retheme the time display. Everything else the stylesheet defines is private to it.
The parts it is built from keep their own variables, which reach them from the same ancestor:
--time-input-* for the time editor (see TimePicker),
--calendar-* for the calendar (see Calendar), and those of
SelectedItem, AddButton and
ComboBox for the day chip, the button and the AM/PM drop-down.
Accessibility
- The time display is a
<span role="button">withtabIndex={0}and anaria-labelgiving the current time, but no key handler — Enter and Space do not open the editor. - That
aria-labelalways writes the time on a 24-hour clock (Current time: 14:30), even when the display shows02:30 PM. - The time editor takes focus when it opens; Enter or Tab closes it again.
- The "select date" button is a
role="button"named byselectDateTextand reportsaria-expandedwhile the calendar is open. - The date half inherits
DatePicker's limits: the calendar cannot be operated from the keyboard. aria-invalidis set on the wrapper fromhasError, but no message is tied to it.aria-labelon the wrapper isselectDateText, which describes the button rather than the whole control.- The meridiem drop-down is a
ComboBox, with that component's limitations.
Test ids
| Element | data-testid |
|---|---|
| The wrapper | date-time-picker, or dataTestId |
| The time area | date-time-picker-time-wrapper |
| The time display | date-time-picker-time-display |
| The clock glyph | date-time-picker-clock-icon |
Related
DatePicker— the date half.TimePicker— the time half.Calendar— the grid behind the date.