IndiaCN UI

Time Picker

Hour, minute and second columns.

Introduction

Three scrolling columns. Hover fills primary-50 and the current value fills primary-100, with a neutral-100 rule between the columns — measured from the UX4G kit.

Each column is a listbox where selection follows focus, so and change the value directly. That is the right pattern for a spinner, and it keeps each column to one tab stop rather than sixty.

For a time behind a trigger, use TimePickerField from Date Picker.

Installation

npx shadcn@latest add https://indiacn.in/r/time-picker.json
import { TimeColumns, TimePicker } from '@/components/ui/time-picker';

Usage

const [time, setTime] = useState<ITimeValue>({ hours: 9, minutes: 30, seconds: 0 });

return <TimePicker value={time} onValueChange={setTime} showHeader />;

Examples

Default

09:30:00

Chosen: 09:30:00

TimePickerDefault
'use client';

import { useState } from 'react';

import { ITimeValue, TimePicker } from '@/components/ui/time-picker';

export default function Component() {
  const [time, setTime] = useState<ITimeValue>({ hours: 9, minutes: 30, seconds: 0 });

  return <TimePicker value={time} onValueChange={setTime} showHeader />;
}

Without seconds

14:00
TimePickerNoSeconds
'use client';

import { useState } from 'react';

import { ITimeValue, TimePicker, formatTime } from '@/components/ui/time-picker';
import { Body3 } from '@/components/ui/typography';

export function TimePickerDefault() {
  const [time, setTime] = useState<ITimeValue>({ hours: 9, minutes: 30, seconds: 0 });

  return (
    <div className='flex flex-col gap-4'>
      <TimePicker value={time} onValueChange={setTime} showHeader />
      <Body3 className='text-neutral-600'>Chosen: {formatTime(time, true)}</Body3>
    </div>
  );
}

export function TimePickerNoSeconds() {
  const [time, setTime] = useState<ITimeValue>({ hours: 14, minutes: 0, seconds: 0 });

  return <TimePicker value={time} onValueChange={setTime} showSeconds={false} showHeader />;
}

Accessibility

KeyMoves
One step, wrapping
PageUp PageDownTen steps
Home EndFirst and last value
  • Each column is a listbox labelled Hour, Minute or Second, and every option carries aria-selected.
  • Only the current value is tabbable, so three columns are three tab stops.
  • The selected fill is primary-100 with neutral text, which holds well past 4.5:1 in both themes.
  • Values are zero-padded and rendered with tabular-nums, so the columns do not jitter as they scroll.

API Reference

TimePicker

PropTypeDefaultDescription
valueITimeValueCurrent time
onValueChange(value: ITimeValue) => voidFires on every change
showSecondsbooleantrueRenders the third column
showHeaderbooleanfalseEchoes the value above the columns
onConfirm() => voidOmit it and the Ok button is not rendered

TimeColumns

The three columns with no card, header or footer, for composing into a larger surface. Takes value, onValueChange and showSeconds.

ITimeValue is { hours: number; minutes: number; seconds: number }. The module also exports formatTime(value, showSeconds) and toTimeValue(date).

On this page