Time Picker
Enter a time using your locale’s clock format.
import { TimePicker } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Use a time picker for a time of day: a standup, a maintenance window, a reminder. It works like the platform's own time field, with hours, minutes and, on a 12-hour clock, AM or PM, but it's styled and stepped like the rest of the kit. Pair it with a Date Picker when the moment needs a day too. For a duration, use a Number Input. Where a time is spun rather than typed (a touch-first form, an alarm), a Wheel Picker with hour and minute columns is the alternative.
import { Field, FieldLabel, TimePicker } from '@youj/react'
export function Standup() {
const [time, setTime] = useState<string | null>('09:30')
return (
<Field>
<FieldLabel>Daily standup</FieldLabel>
<TimePicker value={time} onValueChange={setTime} step={15} />
</Field>
)
}The value is a 24-hour "HH:mm" string, like <input type="time">, once both hours and minutes are set, and null otherwise. Each segment is a spinbutton in one Input Group frame.
Description
A daily standup time on a 12-hour clock, in 15-minute steps.
Type digits and the picker moves on by itself once a segment can't take another: "7" in the hours means 07, while "1" waits for a second digit. A colon or ArrowRight moves on too, so "245p" types 2:45 PM. ArrowUp and ArrowDown step, wrapping around, and minutes step by step. Home and End jump to a segment's ends, Backspace clears it, and A or P sets the period. A typed minute that falls between steps snaps to the nearest step when you leave the field.
Clocks that follow the locale.
The clock follows the locale: locale="de-DE" gives a 24-hour clock, en-US a 12-hour one with its own AM and PM words. hourCycle overrides the locale when a time is always shown one way, such as UTC maintenance windows on a 24-hour clock.
Default: the YoujProvider's locale (en-US without one), never the runtime's, so the server and the browser render the same clock and AM/PM words.
Code
time-picker-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propsvalue, defaultValue, onValueChange… (13)
Props
| Prop | Type | |
|---|---|---|
value | string | null"HH:mm", 24-hour. | – |
defaultValue | string | nulldefault null | null |
onValueChange | (value: string | null) => void | – |
hourCycle | 12 | 2412 or 24. Default: the locale's. | – |
locale | stringA BCP 47 locale for the clock and the AM/PM words. Default: the YoujProvider locale. | – |
step | numberMinutes per ArrowUp/Down, and the grid a typed minute snaps to. default 1 | 1 |
disabled | boolean | – |
name | stringAlso submits "HH:mm" with a native form. | – |
id | string | – |
ref | Ref<HTMLInputElement> | – |
onBlur | () => void | – |
className | string | – |
aria-label | string | – |
MotionSegment focus · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Segment focusthe focused segment takes a soft accent tint | duration.fastease.standard140ms · cubic-bezier(0.2, 0, 0, 1) | 140mscubic-bezier(0.2, 0, 0, 1) |
Reduced motion
Nothing else moves, so reduced motion changes nothing: the tint still marks the focused segment.
Reduced motion
The only motion is the focused segment's tint, which stays, because it shows where you're typing.
AccessibilityKeyboard, ARIA
Accessibility
- The segments sit in a group named by the Field's label, or by
aria-label. Each is aspinbuttonnamed "Hours", "Minutes" or "AM/PM", with its range and a value text that reads "Empty" while it's unset. - The Field's description and error describe every segment, and
aria-invalidandaria-requiredfollow the Field. - Tab moves between segments like any other field. The arrows, digits, Home, End, Backspace, A and P work as described above.
- With
name, a hidden input submits the"HH:mm"value with a native form.