Skip to content

Time Picker

TimePicker pairs an embedded, segmented Time Input for keyboard entry with a popover holding one scrollable listbox column per unit (hours, minutes, optional seconds, optional AM/PM). It reuses the Popover engine for anchoring and the dismissable layer, so the root owns a single open state; each column auto-generates its options for its unit, roves with a single tabindex, and commits the chosen unit while preserving the others. It owns a TimeOnly? value and an open flag: controlled via @bind-Value / @bind-Open, uncontrolled via DefaultValue / DefaultOpen. Keyboard entry through the Input works whether or not the popup is open.

@using Navius.Primitives.Components.TimePicker
<NaviusTimePicker>
<NaviusTimePickerInput />
<NaviusTimePickerTrigger />
<NaviusTimePickerContent>
<NaviusTimePickerColumn Unit="hour" />
<NaviusTimePickerColumn Unit="minute" />
<NaviusTimePickerColumn Unit="dayPeriod" />
</NaviusTimePickerContent>
</NaviusTimePicker>

Owns the value and open state and cascades them to the input, trigger, and columns. Renders no DOM of its own (wraps a Popover). Value and Open are two-way bindable.

Prop Type Default Description
Value TimeOnly? - Controlled value. Pair with ValueChanged (@bind-Value).
ValueChanged EventCallback<TimeOnly?> - Fires when the controlled Value should change.
DefaultValue TimeOnly? - Initial value when used uncontrolled.
Open bool false Controlled open state. Pair with OpenChanged (@bind-Open).
OpenChanged EventCallback<bool> - Fires when the controlled Open value should change.
DefaultOpen bool false Initial open state when used uncontrolled.
Granularity string "minute" Coarsest unit shown: "hour", "minute", or "second".
HourCycle int? current culture 12 or 24. Unset resolves from the current culture’s short time pattern.
MinuteStep int 1 Step between minute options in the Minute column.
SecondStep int 1 Step between second options in the Second column.
Disabled bool false Disables the input and the trigger.
ChildContent RenderFragment? - The Input, Trigger, and Content parts.

The typed, segmented surface: an embedded Time Input bound to the picker’s shared value. Keyboard entry here works whether or not the popup is open. Renders the Time Input group.

Prop Type Default Description
Attributes IDictionary<string, object>? - Forwarded to the underlying Time Input.

The clock button that toggles the popup. Delegates to the Popover trigger. Renders a button.

Prop Type Default Description
ChildContent RenderFragment? - Trigger content.
Attributes IDictionary<string, object>? - Forwarded to the rendered button.

Portals and anchors the popup (Popover Portal > Positioner > Popup) and hosts the columns. Renders the popover popup, role="dialog".

Prop Type Default Description
Side string "bottom" Preferred side, forwarded to the Popover Positioner.
Align string "start" Alignment along the side, forwarded to the Popover Positioner.
SideOffset double 4 Distance in px from the trigger, forwarded to the Popover Positioner.
ChildContent RenderFragment? - The Column parts.
Attributes IDictionary<string, object>? - Forwarded to the rendered popup.

One scrollable listbox for a single unit; auto-generates its options and commits through the shared context. Renders a div with role="listbox".

Prop Type Default Description
Unit string "hour" Which unit this column edits: "hour", "minute", "second", or "dayPeriod".
Class string? - Class applied to the listbox container.
OptionClass string? - Class applied to each option button.
Part Attribute Description
Input data-navius-time-picker-input Present on the embedded time input.
Trigger data-popup-open Present while the popup is open (from the Popover trigger).
Content data-open Present while open (from the Popover engine).
Content data-closed Present while closing, through the exit transition (from the Popover engine).
Content data-starting-style Present at the start of the open transition (from the Popover engine).
Content data-ending-style Present at the start of the close transition (from the Popover engine).
Column data-unit "hour" | "minute" | "second" | "dayPeriod".
Column data-selected Present on the option matching the current unit value.
Column data-highlighted Present on the roving-active option.
Key Behavior
Arrow Up / Arrow Down Moves the roving highlight within the column.
Home / End Moves to the first / last option.
0-9 Type-ahead: jumps to the option whose value starts with the typed digits.
Enter / Space Commits the highlighted option (via its native button activation).

The Trigger delegates to the Popover trigger, so it carries aria-haspopup="dialog" and aria-expanded. The Content is the Popover popup, role="dialog". Each Column renders role="listbox" with an aria-label naming its unit, holding role="option" buttons with aria-selected and a roving tabindex so only one option per column is Tab-reachable at a time. The Input keeps its own spinbutton semantics (see Date Input). This mechanism is covered by the Playwright browser test suite and gated by axe-core in CI.