Time Picker
An accessible time picker component with inline editing and dropdown selection. Automatically adapts to 12-hour or 24-hour format based on user locale.
Installation
pnpm dlx shadcn@latest add @diceui/time-pickerLayout
Import the parts, and compose them together.
import {
TimePicker,
TimePickerLabel,
TimePickerInputGroup,
TimePickerInput,
TimePickerSeparator,
TimePickerTrigger,
TimePickerContent,
TimePickerHour,
TimePickerMinute,
TimePickerClear,
} from "@/components/ui/time-picker";
return (
<TimePicker>
<TimePickerLabel />
<TimePickerInputGroup>
<TimePickerInput segment="hour" />
<TimePickerSeparator />
<TimePickerInput segment="minute" />
<TimePickerInput segment="period" />
<TimePickerTrigger />
</TimePickerInputGroup>
<TimePickerContent>
<TimePickerHour />
<TimePickerMinute />
<TimePickerClear />
</TimePickerContent>
</TimePicker>
)Examples
With Step
Use the hourStep, minuteStep, and secondStep props to set custom intervals for hour, minute, and second selection respectively.
With Seconds
Include seconds in time selection.
Custom Placeholders
Customize empty segment placeholders for different display formats.
Open on Focus
Use the openOnFocus prop to open the content when the input is focused.
Input Group Click Action
Configure what happens when clicking on empty space in the input group. By default, it focuses the first input for inline editing, but you can set it to open the popover instead.
Controlled State
Control the time picker value programmatically.
With Form
Use the time picker in a form with validation.
API Reference
TimePicker
The main container component for time picker functionality.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-disabled] | Present when the time picker is disabled |
[data-invalid] | Present when the time picker is invalid |
[data-readonly] | Present when the time picker is read-only |
TimePickerLabel
The label component for the time picker field.
Prop
Type
TimePickerInputGroup
The container for input segments that sets up CSS variables for dynamic segment widths.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-disabled] | Present when the time picker is disabled |
[data-invalid] | Present when the time picker is invalid |
| CSS Variable | Description | Default |
|---|---|---|
--time-picker-hour-input-width | The width of the hour input segment, dynamically calculated based on the hour placeholder length. | 2ch (for '--' placeholder) |
--time-picker-minute-input-width | The width of the minute input segment, dynamically calculated based on the minute placeholder length. | 2ch (for '--' placeholder) |
--time-picker-second-input-width | The width of the second input segment, dynamically calculated based on the second placeholder length. | 2ch (for '--' placeholder) |
--time-picker-period-input-width | The width of the period (AM/PM) input segment, dynamically calculated based on the period placeholder length. | 2ch (for '--' placeholder) |
Must use style prop to override the css variables of the input segment, because the width is dynamically calculated based on the placeholder length.
TimePickerTrigger
Button to open the time picker content.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-state] | 'open' | 'closed' |
[data-disabled] | Present when the time picker is disabled |
[data-readonly] | Present when the time picker is read-only |
[data-invalid] | Present when the time picker is invalid |
TimePickerContent
Container for the time selection interface.
Prop
Type
| Data Attribute | Value |
|---|---|
[data-state] | 'open' | 'closed' |
[data-side] | The side where the content is positioned |
[data-align] | The alignment of the content |
TimePickerHour
Component for selecting hours.
Prop
Type
TimePickerMinute
Component for selecting minutes.
Prop
Type
TimePickerSecond
Component for selecting seconds.
Prop
Type
TimePickerPeriod
Component for selecting AM/PM in 12-hour format.
Prop
Type
TimePickerSeparator
Visual separator between time units.
Prop
Type
TimePickerClear
Button to clear the selected time.
Prop
Type
TimePickerInput
Inline editable input field for time segments (hour, minute, second, period).
Prop
Type
| CSS Variable | Description |
|---|---|
--time-picker-hour-input-width | Can be set directly on the hour segment input to override the width for that specific input. |
--time-picker-minute-input-width | Can be set directly on the minute segment input to override the width for that specific input. |
--time-picker-second-input-width | Can be set directly on the second segment input to override the width for that specific input. |
--time-picker-period-input-width | Can be set directly on the period segment input to override the width for that specific input. |
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| 0-9 | Type digits to enter time values in input segments. Auto-pads single digits (1 → 01) and auto-advances to next segment after two digits or when first digit exceeds maximum |
| A1 | Sets period to AM when period input is focused |
| P2 | Sets period to PM when period input is focused |
| Tab | When the input is focused, moves to next segment (hour → minute → second → period). When the content is open, moves to next column with wrapping |
| ShiftTab | When the input is focused, moves to previous segment. When the content is open, moves to previous column with wrapping |
| ArrowRight | When the input is focused, moves to next segment. When the content is open, moves to next column with wrapping |
| ArrowLeft | When the input is focused, moves to previous segment. When the content is open, moves to previous column with wrapping |
| ArrowUp | When the input is focused, increments value with wrapping, selection preserved. When the content is open, navigates to previous value in column |
| ArrowDown | When the input is focused, decrements value with wrapping, selection preserved. When the content is open, navigates to next value in column |
| Enter | When the input is focused, confirms and removes focus. When the content is open, selects highlighted value. When the trigger is focused, opens/closes the content |
| Escape | When the input is focused, cancels editing and restores previous value. When the content is open, closes without changing value |
| Space | When the trigger is focused, opens/closes the content |
| BackspaceDelete | Clears focused segment back to placeholder (--) when entire segment is selected |
Notes
Behavior
- Native HTML time input behavior: Replicates the exact behavior of
<input type="time">for maximum familiarity- Auto-pads single digits instantly (typing "1" shows "01")
- Smart auto-advance after two digits or when digit exceeds maximum first digit
- Partial time values supported (e.g., "10:--" instead of "10:00")
- Selection preserved after actions for seamless typing
- Inline editing: All time segments are always visible and editable, no need to open the content
- Content for convenience: The clock icon trigger opens the content for easier selection with mouse/touch
- Keyboard-first design: Full keyboard navigation between segments using arrow keys or tab
- Clear segments: Press Backspace or Delete on a selected segment to clear it back to "--"
Format & Locale
- Automatic format detection: Display format (12-hour vs 24-hour) is automatically detected from user's locale settings
- Consistent value format: The time value is always stored in 24-hour format ("HH:mm" or "HH:mm:ss"), regardless of display format
- Locale override: Use the
localeprop to explicitly set a locale (e.g., "en-US" for 12-hour, "en-GB" for 24-hour) - Period shortcuts: In 12-hour format, use A/P or 1/2 keys to quickly set AM/PM