Time pickers

Time pickers (COMPONENT_SPEC §28) are Compose's TimePicker (a clock dial), TimeInput (two text fields) and the expressive TimeScroll (two infinite wheels), with TimePickerDialog and VibrantTimePickerDialog around them. The dial and AM/PM toggle buttons follow Compose's isUpdatedTimepickerToggleEnabled design at the pinned version: the period is a pair of toggle buttons in primary container, bold when selected. The vibrant variants are the expressive overloads (larger, rounder fields; a filled field in place of the outlined one).

The dial is a radio group of hours or minutes: arrow keys move the selection around the dial, a tap or drag picks a value and, for hours, moves on to the minutes after a short delay, as Compose. The selector rotates on the default spatial spring and the faces crossfade on the default effects spring. The time input runs every edit through a port of Compose's TimeInputTransformation (two digits at most, the hour read in the current period, invalid values kept and shown in the error colors) and its fields are spin buttons (Up / Down step and wrap). The wheels are spin buttons too; they settle on Compose's ScrollField springs.

Dial (element)

<m3e-time-picker hour minute hour-cycle="12 | 24" selection="hour | minute" vibrant layout="auto | vertical | horizontal"> fires change (detail: { hour, minute }; the inputs' native input / change do not reach the host) and selection-change (detail: { value }, 'hour' | 'minute'; its selection key is deprecated since 1.8, removed in 2.0). layout="auto" lays the picker out horizontally in a landscape window, as Compose.

selection-change bubbles in 1.x, like every state event: a listener on an element also hears the same event from an element nested inside it, such as a tooltip in a dialog or a time picker in a tab panel. Check the target first: if (e.target !== host) return;. DECISIONS D25 proposes that 2.0 stop bubbling state events; item events such as action keep bubbling.

12-hour
24-hour, minutes, vibrant
Horizontal (landscape)

Time input (element)

<m3e-time-input> takes the same attributes as the dial; vibrant fills the fields, uncontained is Compose's time input with a side column (AM, PM and a mode toggle that fires mode-toggle).

12-hour
24-hour, vibrant
Uncontained, side column

Scroll wheels (element)

<m3e-time-scroll>: drag, scroll or use the arrow keys on a wheel; a click on a row scrolls to it. uncontained adds the side column, whose toggle switches to the keyboard input.

12-hour
24-hour, uncontained

Dialog (element)

Put a picker in a .m3e-time-picker-dialog surface (__title, __content, __actions with a __spacer after the mode toggle) inside <m3e-dialog variant="custom">; --vibrant is the vibrant dialog, with no title.

Picked: none

Select Time

React

<TimePicker value defaultValue onChange is24Hour selection onSelectionChange vibrant layout locale labels>, <TimeInput vibrant uncontained onModeToggle> and <TimeScroll uncontained onModeToggle> render the same DOM as the elements (onModeToggle(next) gets the mode the toggle asks for: 'scroll' from the input, 'input' from the wheels). <TimePickerDialog title modeToggleButton dismissButton confirmButton> and <VibrantTimePickerDialog> wrap a picker in <BasicAlertDialog>; <TimePickerModeToggle displayMode scroll onDisplayModeChange> (onDisplayModeChange(next) gets the mode to show) is the icon button with its tooltip that switches between the picker and the input (Compose's switchable sample).

Sources

androidx Compose Material3 1.5.0-beta01 (19991f2c): TimePickerTokens.kt and TimeInputTokens.kt as read by TimePicker.kt (the vibrant fields, the dial radii and MaxDistance, AnalogTimePickerState's spring), TimePickerDialog.kt, ScrollField.kt, TimeFormat.android.kt / TimePicker.android.kt, ComposeMaterial3Flags.kt (isUpdatedTimepickerToggleEnabled, L117–127) and foundation gestures/snapping/SnapFlingBehavior.kt (MinFlingVelocityDp, L432–433); values in components/time-picker-defaults.css (lines in PARITY.md). The math is checked against a JVM run of the vendored Kotlin.

m3.material.io Time pickers (page ec8e6da4…: the baseline dial and input) and its token DB (TOKEN_TABLE.39f4b152dd9bd292, md.comp.time-picker and md.comp.time-input), which agrees with every token both define. SOURCES register #45.