Skip to main content

TimePicker

A popover-based time selection component supporting 12/24-hour clocks, minute stepping, controlled/uncontrolled usage, collision-aware positioning, and scrollable column selection UI. Designed for scheduling, booking flows, and enterprise form workflows.


Usage

Basic usage

import { TimePicker } from '@nofinite/nui';

<TimePicker />

Controlled usage

const [time, setTime] = useState("13:30");

<TimePicker value={time} onChange={setTime} />

24-hour clock

<TimePicker clockType={24} />

Minute stepping

<TimePicker minuteStep={15} />

Form integration

<TimePicker name="appointmentTime" />

Disabled state

<TimePicker disabled />

Props

PropTypeDefaultDescription
valuestringControlled value (HH:mm)
defaultValuestringInitial uncontrolled value
onChange(v:string) => voidChange callback
clockType12 | 2412Clock format
minuteStepnumber1Minute increment
placeholderstringSelect timeTrigger placeholder
namestringHidden input name for forms
idstringTrigger id
classNamestringStyling override
disabledbooleanfalseDisabled state

Variants

Clock variants

<TimePicker clockType={12} />
<TimePicker clockType={24} />

Minute precision variants

<TimePicker minuteStep={5} />
<TimePicker minuteStep={30} />

Control mode variants

<TimePicker defaultValue="09:00" />
<TimePicker value="10:30" />

Available variants

  • 12-hour timepicker
  • 24-hour timepicker
  • Stepped minute picker
  • Full precision minute picker
  • Controlled timepicker
  • Uncontrolled timepicker
  • Disabled timepicker
  • Form-integrated timepicker

Guidelines

  • Use minuteStep ≥ 5 for booking interfaces
  • Prefer 24h clock in enterprise or international contexts
  • Use 12h clock for consumer scheduling UX
  • Keep placeholder visible until selection
  • Avoid extremely fine minuteStep with mobile touch targets

States

  • Closed trigger
  • Open popover
  • Selected item
  • Hover item
  • Disabled
  • Placeholder state
  • Focus-visible trigger

Keyboard Interaction

  • Trigger opens popover via Enter / Space
  • Tab navigates interactive elements
  • Arrow navigation handled by scroll columns
  • Escape closes popover via outside click handling
  • Focus restored to trigger on close

Accessibility

  • Trigger uses aria-haspopup="dialog"
  • aria-expanded reflects popover state
  • Hidden input enables native form submission
  • Focus restoration improves keyboard continuity
  • Scroll columns keep selected item centered
  • Visual selection conveys active value
  • Placeholder styling distinguishes empty state

Design Tokens

TokenUsage
--nui-bg-surfacePanel background
--nui-bg-mutedDisabled trigger
--nui-bg-subtleHover item
--nui-fg-defaultText
--nui-fg-subtlePlaceholder
--nui-fg-disabledDisabled text
--nui-border-defaultBorders
--nui-border-hoverHover border
--nui-color-primarySelected item
--nui-color-primary-fgSelected text
--nui-brand-100Focus ring
--nui-radius-md/lgRadius
--nui-space-*Spacing
--nui-z-dropdownPopover layering

Best Practices

Do

  • Use stepped minutes for faster selection
  • Maintain focus restoration for accessibility
  • Use hidden input for non-JS form compatibility
  • Prefer 24h clock for timezone-heavy apps
  • Combine with date picker for scheduling workflows

Don’t

  • Allow minuteStep values that break UX consistency
  • Disable collision positioning for overlays
  • Use extremely narrow triggers with long formatted values
  • Hide popover without restoring focus
  • Use timepicker for duration selection