You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
RFC / PR Proposal: Composable & Accessible TimePicker for ReUI
Target Repository: keenthemes/reui / ReUI Registry Component Name: time-picker Category: Form / Pickers License: MIT / Free Tier Status: Ready for Upstream Submission
1. Motivation & Problem Statement
ReUI currently provides the powerful date-selector (@reui/date-selector) and event-calendar, but lacks a dedicated Time Picker primitive. While developers frequently need precise time input (e.g. appointment scheduling, business hours, attendance logs, meeting agendas), existing shadcn/community time pickers suffer from significant shortcomings:
Tight coupling to JavaScript Date objects: Most existing solutions force time into full Date objects (requiring arbitrary dates, timezone headaches, and heavy serialization logic) rather than clean "HH:mm" / "HH:mm:ss" string primitives.
Monolithic & Non-composable: Lacking Radix/Base UI-style composable primitives, making it nearly impossible to customize columns, inject custom actions, or render inline without a popover.
Inaccessible keyboard UX: Missing proper WAI-ARIA listbox/option roles and 2D keyboard navigation (jumping between hour/minute columns and navigating items with arrow keys).
Visual jitter & imperfect alignment: Common scroll pickers exhibit clipping numbers, misaligned dividers, or awkward gaps between the columns and action footers.
The ReUI TimePicker solves all of these problems with an enterprise-grade, headless-composable architecture inspired by Base UI and shadcn design standards.
2. Visual Preview (Light & Dark Modes)
Variant
Light Mode
Dark Mode
Standard 24-Hour • 2 columns (Hour / Minute) • Actions: Now / Clear / OK
Composable Raw • Custom trigger styling • Selective footer without Clear
3. Component Highlights
Composable Primitives & Shorthand Support: Use either the one-line <TimePicker value={time} onChange={setTime} /> shorthand or break down into sub-components (TimePickerTrigger, TimePickerContent, TimePickerGroup, TimePickerColumn, TimePickerItem, TimePickerFooter, TimePickerNow, TimePickerClear, TimePickerConfirm).
12/24 Hour Formats: Seamless support for standard 24h mode and 12h mode with AM/PM column.
WAI-ARIA APG Compliant: Full keyboard support (ArrowUp/ArrowDown for list items, ArrowLeft/ArrowRight for column jumping, Home/End, Enter/Space for selection).
When used without children, <TimePicker /> renders a complete out-of-the-box popover trigger and content. When children are provided, it acts as a context provider.
Prop
Type
Default
Description
value
string
undefined
Controlled time string ("HH:mm" or "HH:mm:ss").
defaultValue
string
undefined
Uncontrolled initial value.
onChange
(time: string) => void
undefined
Callback invoked when time changes.
use12Hour
boolean
false
Whether to display 12-hour format with AM/PM column.
showSeconds
boolean
false
Whether to display seconds column.
hourStep
number
1
Interval between selectable hours.
minuteStep
number
1
Interval between selectable minutes (e.g. 5, 15, 30).
secondStep
number
1
Interval between selectable seconds.
minTime
string
undefined
Earliest selectable time ("HH:mm").
maxTime
string
undefined
Latest selectable time ("HH:mm").
disabled
boolean
false
Disables trigger and interaction.
size
"sm" | "default" | "lg"
"default"
Size variant for trigger.
locale
"en" | "zh"
"en"
Language preset for column headers, buttons, and ARIA labels.
i18n
Partial<TimePickerI18nConfig>
undefined
Custom label and ARIA overrides for complete internationalization.
RFC / PR Proposal: Composable & Accessible
TimePickerfor ReUITarget Repository:
keenthemes/reui/ ReUI RegistryComponent Name:
time-pickerCategory: Form / Pickers
License: MIT / Free Tier
Status: Ready for Upstream Submission
1. Motivation & Problem Statement
ReUI currently provides the powerful
date-selector(@reui/date-selector) andevent-calendar, but lacks a dedicated Time Picker primitive. While developers frequently need precise time input (e.g. appointment scheduling, business hours, attendance logs, meeting agendas), existing shadcn/community time pickers suffer from significant shortcomings:Dateobjects: Most existing solutions force time into fullDateobjects (requiring arbitrary dates, timezone headaches, and heavy serialization logic) rather than clean"HH:mm"/"HH:mm:ss"string primitives.The ReUI
TimePickersolves all of these problems with an enterprise-grade, headless-composable architecture inspired by Base UI and shadcn design standards.2. Visual Preview (Light & Dark Modes)
• 2 columns (Hour / Minute)
• Actions:
Now/Clear/OK• 4 columns (Hour / Minute / Sec / AM-PM)
• Second-level precision
• 15-minute intervals (
00,15,30,45)• Operating bounds (08:30–17:30 disabled slots)
• Custom trigger styling
• Selective footer without Clear
3. Component Highlights
<TimePicker value={time} onChange={setTime} />shorthand or break down into sub-components (TimePickerTrigger,TimePickerContent,TimePickerGroup,TimePickerColumn,TimePickerItem,TimePickerFooter,TimePickerNow,TimePickerClear,TimePickerConfirm).minuteStep,hourStep,secondStep, andshowSecondstoggle.ArrowUp/ArrowDownfor list items,ArrowLeft/ArrowRightfor column jumping,Home/End,Enter/Spacefor selection).h-[178px]) with CSS scroll snap (snap-y snap-mandatory).minTime,maxTime, and custom disabling predicates (disabledHours,disabledMinutes,disabledSeconds,disabledTime).4. Primitives & Anatomy
Anatomy Tree
5. API Reference
<TimePicker />(Root)When used without children,
<TimePicker />renders a complete out-of-the-box popover trigger and content. When children are provided, it acts as a context provider.valuestringundefined"HH:mm"or"HH:mm:ss").defaultValuestringundefinedonChange(time: string) => voidundefineduse12HourbooleanfalseshowSecondsbooleanfalsehourStepnumber1minuteStepnumber1secondStepnumber1minTimestringundefined"HH:mm").maxTimestringundefined"HH:mm").disabledbooleanfalsesize"sm" | "default" | "lg""default"locale"en" | "zh""en"i18nPartial<TimePickerI18nConfig>undefinedplaceholderstring"Select time"clearablebooleantrueopenbooleanundefinedonOpenChange(open: boolean) => voidundefinedSub-primitives
<TimePickerTrigger />: Interactive trigger button supporting custom icons, classes, and sizing variants.<TimePickerContent />: Popover content container with normalized border, shadow, and backdrop.<TimePickerGroup />: Container for columns with cohesive vertical border division.<TimePickerColumn />: Column listbox (type="hours" | "minutes" | "seconds" | "period").<TimePickerItem />: Individual selectable time option item.<TimePickerFooter />: Bottom actions container.<TimePickerNow />: Shortcut button to select current local time.<TimePickerClear />: Shortcut button to clear selection.<TimePickerConfirm />: Action button to commit and close popover.6. Worked Examples (
c-time-picker-*)Example 1: Basic 24-Hour Time Picker (
c-time-picker-1)Example 2: 12-Hour Format with Seconds (
c-time-picker-2)Example 3: Stepped Intervals & Operating Hours (
c-time-picker-3)Example 4: Composable Raw Custom Layout (
c-time-picker-4)7. Verification & Quality Gates
role="listbox",role="option",aria-selected,aria-disabled,aria-activedescendant.background,foreground,border,primary,muted-foreground).