Forms
Time picker
A time field made of spinbutton segments — hours, minutes, optional seconds, optional AM/PM — rather than a free-text box or a scrolling list of every quarter hour.
Import
import { TimePicker } from '@the_viveksingh/vivek-ui'Office hours
Hours and minutes as spinbutton segments. Typed digits accumulate and focus advances, arrows step and wrap, and a committed value is clamped into min/max rather than refused - refusing makes typing 9 impossible when the minimum is 09:30. A half-entered time is null, never a guess.
Office hours only — a typed 08:00 clamps to 09:00 on commit.
The form receives start=09:30.
const [start, setStart] = useState<string | null>('09:30')
<Field label="Start" help="Office hours only">
<TimePicker name="start" min="09:00" max="17:30" value={start} onValueChange={setStart} />
</Field>
// The form receives start=09:30. The value is always 24-hour 'HH:mm'.12-hour display, 24-hour value
hourCycle changes what is shown and how AM/PM is entered; onValueChange still receives 14:30. Chosen explicitly rather than from Intl, because a field that renders 24-hour on the server and 12-hour in the browser is a hydration mismatch.
Shown as 12-hour with AM/PM, reported as 24-hour: the display is presentation, the value is data.
Type digits to fill a segment, arrows to step, A or P for the period. Home and End jump to the first and last segment.
<TimePicker defaultValue="14:30" hourCycle={12} withSeconds name="kickoff" />
// Displays 02 : 30 : 00 PM. Type A or P on the period segment to switch.
// onValueChange -> '14:30:00'Props
Generated from the package's own type declarations, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | null | — | Controlled value, always in 24-hour form: `'HH:mm'`, or `'HH:mm:ss'` with `withSeconds`. `null` while any required segment is empty. The 12-hour display never leaks into the value — `hourCycle` is presentation, the canonical string is the data. |
defaultValue | string | null | — | — |
onValueChange | (value: string | null) => void | — | — |
withSeconds | boolean | — | Add a seconds segment. Default `false`. |
hourCycle | 12 | 24 | — | `24` (default) or `12` with an AM/PM segment. Deterministic on purpose: `Intl` would pick per machine, and a field that shows 24-hour to the server and 12-hour to the browser is a hydration mismatch waiting to happen. Choose it for your audience. |
min | string | — | Inclusive bounds in the same canonical form. A committed value is clamped into them. |
max | string | — | — |
size | 'sm' | 'md' | 'lg' | — | — |
disabled | boolean | — | — |
readOnly | boolean | — | — |
invalid | boolean | — | — |
required | boolean | — | — |
name | string | — | One hidden field carrying the canonical value, so a form never sees the segments. |
Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.
Rendering
TimePicker declares 'use client' because it needs state, effects or event handlers. Importing it into a Server Component creates a client boundary at this component — everything above it stays on the server.