Time Field

React Time Field components allow users to select a specific time value using a segment-based input. They are commonly used in booking forms, scheduling flows, reminders, and time-based filters where precise keyboard entry is preferred.

Meeting time
930AM
Choose a start time for the meeting.

Installation

The Time Field relies on the react-aria-components library.

Install the component using the Tailgrids CLI.

npx @tailgrids/cli add time-field

Anatomy

import { Label } from "@/components/tailgrids/core/label";
import { Description } from "@/components/tailgrids/core/description";
import { TimeField } from "@/components/tailgrids/core/time-field";
import { DateInput, DateSegment } from "@/components/tailgrids/core/date-field";

export const TimeFieldExample = () => (
  <TimeField>
    <Label>Meeting time</Label>
    <DateInput>{segment => <DateSegment segment={segment} />}</DateInput>
    <Description>Choose a start time for the meeting.</Description>
  </TimeField>
);

Examples

Basic Usage

A standard time field implementation using segments for precise time entry.

Meeting time
––––AM
Choose a start time for the meeting.

Controlled

Manage the time value externally using the value and onChange props.

Meeting time
530PM

Uncontrolled

An uncontrolled time field with a defaultValue prop.

Meeting time
930AM

With Seconds

Enable second selection by setting the granularity prop to second.

Precise Time
93015AM

With Timezone

Display and manage time zones within the time field.

UTC Event
1430

With Leading Zeros

Use the shouldForceLeadingZeros prop to display leading zeros in time segments.

Meeting time
0930AM
Choose a start time for the meeting.

Validation

Display error messages and validation states when the time value is invalid.

Meeting Time
––––AM
Business hours only

API Reference

TimeField

The segment-based time input component. Wraps React Aria's TimeField and maps boolean props (disabled, readOnly, required, invalid) to their is-* equivalents.

PropTypeDefaultDescription
valueTimeValue | null-The current time value (controlled).
defaultValueTimeValue | null-The default time value (uncontrolled).
onChange(value: TimeValue | null) => void-Handler called when the value changes.
namestring-The name of the input, used when submitting an HTML form.
formstring-The <form> element to associate the input with.
idstring-The element's unique identifier.
autoFocusbooleanfalseWhether the input should receive focus on mount.
hourCycle12 | 24-Whether to use 12-hour or 24-hour format.
granularity'hour' | 'minute' | 'second''minute'The smallest unit of time to display.
hideTimeZonebooleanfalseWhether to hide the time zone abbreviation.
shouldForceLeadingZerosbooleanfalseWhether to always show leading zeros in the hour field.
minValueTimeValue-The minimum allowed time.
maxValueTimeValue-The maximum allowed time.
placeholderValueTimeValue-A placeholder time value when no value is set.
orientation'vertical' | 'horizontal' | 'responsive''vertical'Layout direction of the field container.
disabledbooleanfalseWhether the input is disabled.
readOnlybooleanfalseWhether the input is read only.
requiredbooleanfalseWhether the input is required.
invalidbooleanfalseWhether the input is shown in an invalid state.
validate(value: TimeValue) => ValidationResult | true | null | undefined-Custom validation function for the time value.
validationBehavior'aria' | 'native''native'Whether to use native HTML or ARIA form validation.
aria-labelstring-Defines a string that labels the current element.
aria-labelledbystring-Identifies the element (or elements) that label the element.
aria-describedbystring-Identifies the element that describes the object.
aria-detailsstring-Identifies the element providing extended description.
onBlur(e: FocusEvent) => void-Handler called when the element loses focus.
onFocus(e: FocusEvent) => void-Handler called when the element receives focus.
onFocusChange(isFocused: boolean) => void-Handler called when the element's focus status changes.
onKeyDown(e: KeyboardEvent) => void-Handler called when a key is pressed.
onKeyUp(e: KeyboardEvent) => void-Handler called when a key is released.
classNamestring-Additional CSS classes to apply to the container.

See the React Aria TimeField documentation for more details.

Composition

The Time Field is composed of the root TimeField component plus DateInput and DateSegment from the Date Field package. It can be combined with shared field components (Label, Description, FieldError) for a complete form control.

TimeField                                  — Root container. Manages time state, validation, and ARIA context.
├── Label                                  — Visible label.
├── DateInput (from Date Field)            — Groups editable segments into a styled input area.
│   └── DateSegment (from Date Field)      — Individual editable segment (hour, minute, second, AM/PM).
└── Description                            — Helper text.
  • Use TimeField as the root. It provides the time value, validation state, and keyboard context to all children.
  • Use Label to label the field. It is automatically linked to the input.
  • Use DateInput to render the segment group. It accepts a render function that receives each segment and returns a DateSegment.
  • Use DateSegment inside DateInput to render each editable part of the time. It handles focus, typing, and arrow-key incrementing.
  • Use Description for helper text. It is automatically announced by screen readers.
  • Use FieldError for validation messages. It is linked via aria-errormessage when invalid is set.

Accessibility

  • Keyboard Support: Users can navigate between time segments (hours, minutes, seconds, AM/PM) using Arrow keys and edit values using the number keys.
  • Screen Readers: Each segment is properly labeled and provides live updates to screen readers as values change.
  • Focus Management: Focus is managed automatically between segments for a seamless typing experience.