Text input with a calendar trigger button that opens a DatetimePicker in a popover. Accepts both typed and picked datetime values, held as an ISO 8601 string.
Use @uxf/ui/datetime-picker-input for a standalone, controlled datetime field — you own the value/onChange state.
Inside a @uxf/form form, use the twin @uxf/form/datetime-picker-input instead: it wires the field into react-hook-form (useController), adds required/format/min-max validation, and reads the disabled/read-only flags from the form context. This ui component is the underlying controlled primitive it renders.
import { DatetimePickerInput } from "@uxf/ui/datetime-picker-input";
import { useState } from "react";
function Example() {
const [value, setValue] = useState<string | null>(null);
return (
<DatetimePickerInput
isClearable
label="Date and time"
name="datetime"
onChange={setValue}
placeholder="Enter date…"
value={value}
/>
);
}
Extends InputWithPopoverProps<string | null> (from @uxf/ui/_input-with-popover), so it accepts the standard field props: label, helperText, hiddenLabel, isClearable, isDisabled, isReadOnly, isInvalid, isRequired, size, variant, leftAddon/rightAddon, leftElement/rightElement, popoverPlacement, popoverStrategy, onBlur/onFocus, autoFocus, form, id, className. children is omitted; placeholder and triggerElement are re-declared as optional.
Component-specific and notable props:
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string | null |
— (required) | Current value. The picker emits an ISO 8601 datetime string. |
onChange |
(value: string | null, event?) => void |
— (required) | Called with the new value: an ISO string for a valid entry, the raw text when unparseable, or null when empty. |
name |
string |
— (required) | Field name. |
placeholder |
string |
— | Input placeholder. |
triggerElement |
ReactNode |
<Icon name="calendar" size={20} /> |
Element rendered as the popover trigger. |
minDate |
string |
— | Earliest selectable date, formatted YYYY-MM-DD. |
maxDate |
string |
— | Latest selectable date, formatted YYYY-MM-DD. |
unavailableDates |
Date[] |
— | Dates that cannot be selected. |
bottomContent |
ReactNode |
— | Extra content rendered below the calendar. |
CustomDatetimePicker |
(props: { value: DatetimeString | null; onChange; onClose: () => void }) => ReactNode |
— | Render a custom picker body in the popover instead of the default DatetimePicker. |
D. M. YYYY H:mm (DISPLAY_DATETIME_FORMAT).ALLOWED_DATETIME_FORMAT (e.g. D. M. YYYY H:mm, DD.MM.YYYY HH:mm). A valid entry becomes an ISO 8601 string; empty becomes null; anything else is passed through as raw text.Both ALLOWED_DATETIME_FORMAT (string[]) and DISPLAY_DATETIME_FORMAT (string) are exported from @uxf/ui/datetime-picker-input.
isClearable, a clear button appears while the field has a value and is interactive; clearing sets the value to null.isDisabled / isReadOnly block interaction and prevent the popover from opening.isInvalid applies the error styling; pass helperText for the message.Client component ("use client").
This component ships no stylesheet of its own; import the styles of the parts it composes once in your global CSS:
@import url("@uxf/ui/css/input-with-popover.css");
@import url("@uxf/ui/css/datetime-picker.css");
@import url("@uxf/ui/css/tabs.css");
@import url("@uxf/ui/css/date-picker.css");
@import url("@uxf/ui/css/calendar.css");
@import url("@uxf/ui/css/time-picker.css");
@import url("@uxf/ui/css/button.css");
@import url("@uxf/ui/css/icon.css");
Also requires the global @uxf/ui token layer, set up once per app — see @uxf/ui setup.