NUIv3.0.7

Time Range Picker

A composable, accessible TimeRangePicker component for modern React applications.

tsx
import { TimeRangePicker } from '@nofinite/nui';

Interactive Preview

Loading preview...

A popover-based time range selector supporting 12/24-hour clocks, minute stepping, controlled/uncontrolled mode, scrollable hour/minute/AM-PM columns, and start/end part switching. Ideal for booking forms, scheduling interfaces, and time window selection in dashboards.


Usage

Basic usage

tsx
import { TimeRangePicker } from '@nofinite/nui';

<TimeRangePicker />;

Controlled usage

tsx
const [range, setRange] = useState({ from: '09:00', to: '17:00' });

<TimeRangePicker value={range} onChange={setRange} />;

24-hour clock

tsx
<TimeRangePicker clockType={24} />

Minute stepping

tsx
<TimeRangePicker minuteStep={15} />

Form integration

tsx
<TimeRangePicker nameFrom="startTime" nameTo="endTime" />

Disabled state

tsx
<TimeRangePicker disabled />


Variants

Clock variants

tsx
<TimeRangePicker clockType={12} />
<TimeRangePicker clockType={24} />

Minute precision variants

tsx
<TimeRangePicker minuteStep={5} />
<TimeRangePicker minuteStep={30} />

Control mode variants

tsx
<TimeRangePicker defaultValue={{ from: "09:00", to: "17:00" }} />
<TimeRangePicker value={{ from: "10:30", to: "18:00" }} />

Available variants

  • 12-hour range picker
  • 24-hour range picker
  • Stepped minute range picker
  • Full precision minute range picker
  • Controlled/uncontrolled range picker
  • Disabled range picker
  • Form-integrated range picker
  • Start/End toggle UI

Guidelines

  • Default minuteStep ≥ 5 for faster selection
  • Use 24-hour clock for international or enterprise apps
  • Use 12-hour clock for consumer-friendly booking UX
  • Always show placeholder until user selects both times
  • Ensure popover width fits both from → to labels

States

  • Closed trigger
  • Open popover
  • Active part (Start/End)
  • Selected hour/minute/AM-PM
  • Hover item
  • Disabled
  • Placeholder
  • Focus-visible trigger

Keyboard Interaction

  • Trigger opens popover via Enter / Space
  • Tab navigates start/end buttons and scroll columns
  • Arrow navigation scrolls hour/minute/AM-PM items
  • Escape closes popover
  • Focus restores to trigger on close
  • Footer buttons are accessible via Tab/Enter

Accessibility

  • Trigger uses aria-haspopup="dialog"
  • aria-expanded reflects popover state
  • Hidden inputs enable form submission
  • Focus restoration ensures keyboard continuity
  • Selected items are visually highlighted
  • Start/End part toggle is keyboard accessible
  • Placeholder indicates empty range

z-dropdown | Popover layering |


Best Practices

Do

  • Use stepped minutes for faster selection
  • Switch activePart for proper Start/End selection
  • Maintain focus restoration
  • Use hidden inputs for form integration
  • Use 24h clock in global apps
  • Combine with date picker for scheduling workflows

Don’t

  • Allow very small minuteStep values that break UX
  • Disable collision positioning
  • Use extremely narrow triggers with long from → to labels
  • Hide popover without focus restoration
  • Mix uncontrolled and controlled values inconsistently

API Reference

PropTypeDefaultDescription
valueTimeRangeControlled time range object
defaultValueTimeRangeUncontrolled default time range object
onChange((v: TimeRange) => void)Callback fired when either the start or end time changes
clockTypeenum12Uses 12-hour or 24-hour clock formatting. Defaults to 12.
minuteStepnumber1Step interval for the minute column. Defaults to 1.
placeholderstringSelect time rangePlaceholder text displayed when no range is selected
nameFromstringName attribute applied to the "from" hidden input for native forms
nameTostringName attribute applied to the "to" hidden input for native forms
disabledbooleanfalseDisables the picker entirely