Timepicker
A flexible time picker with 12/24 hour formats, time range selection, and disabled time constraints.
Installation
npx vayu-ui-cli@latest add time-pickerUsage
Basic (12h format)
:
24-Hour Format
:
Time Range
Select time range
With Constraints (9AM - 5PM)
:
Anatomy
import { Timepicker } from 'vayu-ui';
<Timepicker.Root value={time} onValueChange={setTime} format="12h" label="Start time">
<Timepicker.Trigger />
<Timepicker.Content>
<Timepicker.TimeGrid />
<Timepicker.Footer />
</Timepicker.Content>
</Timepicker.Root>;
{
/* Custom column layout */
}
<Timepicker.Root format="24h">
<Timepicker.Trigger />
<Timepicker.Content>
<Timepicker.HourColumn />
<Timepicker.MinuteColumn />
<Timepicker.Error />
<Timepicker.Footer />
</Timepicker.Content>
</Timepicker.Root>;- Timepicker.Root — Root container. Manages time state, format, mode, and provides context to children.
- Timepicker.Trigger — Button with inline editing. Displays the selected time and opens the dropdown.
- Timepicker.Content — Portal-based dropdown with focus trap and auto-positioning.
- Timepicker.TimeGrid — Pre-configured layout of hour, minute, and period columns.
- Timepicker.HourColumn — Individual hour selection column with scroll and keyboard navigation.
- Timepicker.MinuteColumn — Individual minute selection column, respects
minuteStep. - Timepicker.PeriodColumn — AM/PM toggle column, only rendered in 12h format.
- Timepicker.Footer — Action buttons for clearing and applying selection.
- Timepicker.Error — Error message display within the dropdown.
Accessibility
- Keyboard Support:
Enter/Space— Select the focused time item or open the dropdown.ArrowDown/ArrowUp— Navigate within a time column (wraps circularly).ArrowLeft/ArrowRight— Navigate between columns (hour, minute, period).Home/End— Jump to first / last item in the current column.Escape— Close the dropdown and return focus to the trigger.Tab— Move focus through the dropdown content (trapped while open).Shift+Tabreverses.Backspace— In trigger inline mode, decrement the focused field value.
- ARIA Attributes:
role="combobox"andaria-expandedonTimepicker.Trigger.role="dialog"andaria-modal="true"onTimepicker.Content.role="listbox"on each time column witharia-label("Hour", "Minute", "Period").role="option"witharia-selectedandaria-disabledon each time item.aria-labelledbylinks the label to the trigger for identification.
- Focus Behavior:
- Opening the dropdown focuses the first selected option, or the first enabled item.
- Closing via Escape returns focus to the trigger.
- Focus is trapped within the dropdown while open.
- Selected items auto-scroll into view when the dropdown opens.
Screen reader behavior
When a user focuses the trigger, the screen reader announces the label, the currently selected time or placeholder, and the expanded state via aria-expanded. When the dropdown opens, the dialog role is announced along with the column listboxes. Each time option is announced with its value, selected state via aria-selected, and disabled state via aria-disabled. Navigating between columns with arrow keys announces the column label. In range mode, the current phase (start or end) is announced when switching. Closing the dropdown returns focus to the trigger, which announces the updated time value.
Component Folder Structure
TimePicker/
├── TimePicker.tsx # Root component with context provider and state management
├── TimePickerTrigger.tsx # Trigger with inline editing and keyboard navigation
├── TimePickerContent.tsx # Portal-based dropdown with focus trap and positioning
├── TimePickerColumns.tsx # Hour, Minute, Period columns with grid layout
├── TimePickerFooter.tsx # Footer actions (Clear, Apply) and error display
├── utils.ts # Time parsing, formatting, validation utilities
├── types.ts # TypeScript type definitions
├── index.ts # Re-exports all components and types
└── README.md # Component usage referenceProps
Timepicker.Root
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Timepicker subcomponents. |
value | TimeValue | TimeRange | null | — | Controlled value. |
defaultValue | TimeValue | TimeRange | null | — | Uncontrolled initial value. |
onValueChange | (value: TimeValue | TimeRange | null) => void | — | Callback when value changes. |
format | '12h' | '24h' | '12h' | Time display format. |
mode | 'single' | 'range' | 'single' | Single time or time range selection. |
label | string | — | Accessible label for the timepicker. |
error | string | — | Error message to display. |
disabled | boolean | false | Disable the timepicker. |
placeholder | string | 'Select time' | Placeholder text in the trigger. |
minuteStep | number | 5 | Minute increment step. |
clearable | boolean | true | Show clear button in footer. |
showApplyButton | boolean | false | Show Apply button in footer. |
minTime | string | — | Minimum selectable time in HH:MM format. |
maxTime | string | — | Maximum selectable time in HH:MM format. |
disabledTimes | string[] | — | Array of disabled times in HH:MM format. |
disabledHours | number[] | — | Array of disabled hours (0-23). |
className | string | — | Additional CSS classes. |
Timepicker.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes. |
Timepicker.Content
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Dropdown content subcomponents. |
className | string | — | Additional CSS classes. |
Timepicker.TimeGrid
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes. |
Timepicker.HourColumn
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes. |
Timepicker.MinuteColumn
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes. |
Timepicker.PeriodColumn
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes. |
Timepicker.Footer
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Custom footer content. |
className | string | — | Additional CSS classes. |
Timepicker.Error
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Custom error content. |
className | string | — | Additional CSS classes. |