InputsReact
A date and a time typed in one row of segments: the date segments of DateField and the time segments of TimeField, in the locale's order.
Rendered by React 19.3.1
Loading React…Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<DateTimeField.Root>
<DateTimeField.Input>
<DateTimeField.Segment />
</DateTimeField.Input>
<DateTimeField.Clear />
</DateTimeField.Root>Examples
The demo at the top is the one example this component has so far.
API reference
27 props across 4 parts, in React syntax. className, style, render are listed once, under Shared props.
ClearDateTimeField.Clear
Clears the whole value, including a partly typed one. It is out of the tab order: Backspace clears a segment from the keyboard. Renders a <button>.
InputDateTimeField.Input
The visual control: it wraps the segments. Its children are a function of the segments, since their order depends on the locale; without children it renders every segment. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
childrenThe segments, or a function of them: ({ segments }) => .... | React.ReactNode | ((context: { segments: FieldSegment[]; }) => React.ReactNode) | — |
RootDateTimeField.Root
Groups all parts of a field that edits a date and a time in segments. Values are strings such as '2026-11-07T14:30'; HTML's space instead of T is accepted. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
onIncompleteChangeEvent handler called when the segments change while no complete value exists, with the | ((parts: FieldParts, eventDetails: DateFieldRootChangeEventDetails) => void) | — |
localeThe BCP 47 locale of the segment order, literals, digits and day periods. | string | 'en-US' |
forceLeadingZerosWhether the day, month and hour show a leading zero. | boolean | — |
placeholderValueThe value an empty segment takes on its first Up or Down press. | string | — |
todayThe date of today ('2026-11-07'), for the starting point of an empty date segment. | `${number}-${number}-${number}` | — |
timeZoneThe time zone that decides what today is, when today is not given. | string | — |
autoAdvanceWhether focus moves to the next segment when the typed number cannot get another digit. | boolean | true |
segmentRoleThe role of the segments. | DateFieldSegmentRole | 'spinbutton' |
labelsThe texts the field adds: the segment names, the text of an empty segment, the Clear label. | Partial<DateFieldLabels> | — |
disabledWhether the component should ignore user interaction. | boolean | false |
readOnlyWhether the user should be unable to change the value. | boolean | false |
requiredWhether the user must fill in the field before submitting a form. | boolean | false |
invalidWhether the field is invalid. | boolean | false |
nameIdentifies the field when a form is submitted. | string | — |
formIdentifies the form that owns the hidden input. | string | — |
inputRefA ref to access the first segment. | React.Ref<HTMLInputElement> | — |
valueThe value, null for none. | `${number}-${number}-${number}T${number}:${number}${string}` | null | — |
defaultValueThe value when initially rendered. | `${number}-${number}-${number}T${number}:${number}${string}` | null | — |
onValueChangeEvent handler called when the value changes: a complete value, or null when a complete | ((value: `${number}-${number}-${number}T${number}:${number}${string}` | null, eventDetails: DateFieldRootChangeEventDetails) => void) | — |
minThe earliest valid value. | `${number}-${number}-${number}T${number}:${number}${string}` | — |
maxThe latest valid value. | `${number}-${number}-${number}T${number}:${number}${string}` | — |
hourCycleThe hour cycle, 12 (with a day period segment) or 24. | 12 | 24 | — |
granularityThe finest segment shown. | TimeGranularity | — |
stepThe native step in seconds. | number | — |
isDateUnavailableWhether a date cannot be chosen. | ((date: `${number}-${number}-${number}`) => boolean) | — |
| Data attribute | Description |
|---|---|
data-disabled | Present when the field is disabled. |
data-readonly | Present when the field does not allow changing the value. |
data-required | Present when the field is required. |
data-empty | Present when no segment has a value. |
data-filled | Present when every segment has a value. |
data-incomplete | Present when some segments have a value and others do not. |
data-focused | Present when focus is inside the field. |
data-invalid | Present when the field is invalid. |
SegmentDateTimeField.Segment
One segment of the value. An editable segment (year, month, day, hour, minute, second, millisecond, day period) is a real <input> with the spinbutton role; a literal (/, :) is a <span> hidden from assistive technology., or a <span> for a literal. Renders an <input>.
| Prop | Type | Default |
|---|---|---|
segmentrequiredThe segment to render, one of the segments the Input gives its children. | FieldSegment | — |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS class applied to the element, or a function that
returns a class based on the component's state. | string | ((state: State) => string | undefined) |
styleStyle applied to the element, or a function that
returns a style object based on the component's state. | React.CSSProperties | ((state: State) => React.CSSProperties | undefined) |
renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component. | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State> |
Keyboard and accessibility
Keyboard
| Keys | Does | Part |
|---|---|---|
| Type into the segment and move on when it is full, from the year into the hour | Segment | |
| ArrowUpArrowDown | Step the segment by one and wrap, without carrying into the next | Segment |
| PageUpPageDown | Step by the segment's page amount: day 7, month 3, year 10, hour 6, minute and second 15 | Segment |
| ArrowLeftArrowRight | Move to the previous or next segment, swapped in right to left | Segment |
| Backspace | Deletes the last digit; on an empty segment, moves to the previous one | Segment |
| EnterEscape | Not captured | Segment |
| ControlMetaAlt | Untouched | Segment |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Root | role="group", aria-labelledby the Field label and a visually hidden text of the full date and time | tabbing in reads "Meeting, Thursday, November 12, 2026 at 2:30 PM" once |
| Segment | role="spinbutton" with its name, range and value, as in DateField and TimeField | each part is read on its own, and an empty one says "Empty" |
| Segment | aria-invalid and aria-errormessage when the value is invalid | the error is on the element that has focus |
| Clear | aria-label "Clear" (from labels), tabindex="-1" | the button is named and adds no tab stop |
Focus order
- Each editable segment is a tab stop, the date first and then the time in
en-US. - A full segment moves focus on unless
autoAdvanceisfalse; the year moves on to the hour. - Clear is out of the tab order.