Browse docs
Browse docs
TimePicker is a form-connected time-of-day field: an editable text input
paired with a dropdown of time options. Type a time freely — it is normalized
on blur — or pick a slot from the list. It integrates with DashForm, RBAC,
and the Dashforge field layout automatically. The name prop connects the
field to the form schema.
The stored value is a canonical 24-hour "HH:mm" string, or null. 12-hour
notation is a display concern (hour12) — never the storage format. The field
carries no date and no time zone.
import { DashForm } from '@dashforge/forms';
import { TimePicker } from '@dashforge/ui';
<DashForm onSubmit={(data) => console.log(data)}>
<TimePicker
name="meetingTime"
label="Meeting time"
rules={{ required: 'Please pick a time' }}
/>
</DashForm>A basic field — type a time (2:30 pm, 14:30, 230pm all parse) or pick
one from the dropdown.
<TimePicker name="meetingTime" label="Meeting time" />minTime / maxTime bound the selectable range; stepMinutes sets the
dropdown granularity.
09:00–17:00, 15-minute steps
<TimePicker
name="slot"
label="Appointment slot"
minTime="09:00"
maxTime="17:00"
stepMinutes={15}
helperText="09:00–17:00, 15-minute steps"
/>hour12 renders the input and dropdown in 12-hour notation. The stored value
stays the canonical 24-hour "HH:mm".
<TimePicker name="alarm" label="Alarm" hour12 defaultValue="14:30" />| Prop | Type | Default | Description |
|---|---|---|---|
name | string | — | Field name — the bridge registration key. Required. |
label | ReactNode | — | Field label. |
helperText | ReactNode | — | Hint text below the control. |
rules | RegisterOptions | — | Validation rules forwarded to the form bridge. |
required | boolean | false | Adds the label asterisk. |
error | boolean | — | Explicit error state (overrides the bridge's auto error). |
disabled | boolean | false | Disables the field. |
placeholder | string | — | Shown when no time is selected. |
layout | 'stacked' | 'inline' | 'floating' | 'stacked' | Label / control layout. floating is downgraded to stacked. |
value | string | null | — | Controlled value ("HH:mm"). |
defaultValue | string | null | — | Uncontrolled initial value. |
onChange | (value: string | null) => void | — | Fired with the new time. |
minTime / maxTime | string | "00:00" / "23:59" | Selectable bounds, "HH:mm". |
stepMinutes | number | 30 | Step between dropdown options, in minutes. |
hour12 | boolean | false | Render the input + dropdown in 12-hour notation. |
visibleWhen | (engine: Engine) => boolean | — | Reactive visibility predicate. |
access | AccessRequirement | — | RBAC access requirement. |
fullWidth | boolean | false | Stretches the field to its container width. |
testId | string | — | Test id applied to the field root. |
"HH:mm" storage. The bridge value is always the canonical
24-hour form, even when hour12 is set — hour12 only changes the display.2:30 pm, 14.30, 230pm) is normalized via
parseTimeString on blur / Enter. Unparseable input reverts to the last
committed value; an empty input commits null.DatePicker; for date + time
in one control, use DateTimePicker.<TimePicker value={time} onChange={(v) => setTime(v)} label="Meeting time" />Inside DashForm the field registers automatically — validation, error
gating, and touch tracking flow through the bridge.
The access prop maps an RBAC decision to one of three field states:
<TimePicker
name="cutoffTime"
label="Cut-off time"
access={{ resource: 'schedule', action: 'update', onUnauthorized: 'disable' }}
/>