Skip to content
NewService Map: 30 components for hosts, ports and routes
<hf-wheel>Custom elementInputsForm controlFree

Time picker wheel

Two-column time picker wheel: rows curve on a cylinder, flings carry inertia and snap to a value that submits as HH:MM.

View as Markdown
<hf-wheel>

Trydrag or scroll a column, or use the arrow keys.

Playground

Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.

Loading <hf-wheel>
Props
valuelive
stepremounts
labelremounts
nameremounts
<HfWheel value="09:30" step={5} label="Remind me at" name="remind" />

Installation

pnpm dlx shadcn@latest add @lumesec/hf-wheel
First timeRegister the @lumesec registry once, or install by URL+

Adds @lumesec to your components.json:

pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/hf-wheel.json

Usage

import { HfWheel } from "@/components/lumesec/hf-wheel";

export function Example() {
  return (
    <HfWheel name="remind" label="Remind me at" value="09:30" step={5} />
  );
}

Behaviour

A picker wheel like the one in the effort slider’s name, turned into a full control. Rows curve away on a cylinder, the selection band magnifies, and it flings with inertia before snapping to a value.

API reference

Attributes

valueReact propvalueTypestringDefault09:30

Selected time as HH:MM (24-hour). Hours clamp to 0–23 and minutes round to the nearest step. Observed: a change animates both columns to the new time. Reflects the current selection.

stepReact propstepTypenumberDefault5

Minute increment, rounded and clamped to 1–30. The minute column shows multiples of step below 60. Read once when the element connects.

labelReact proplabelTypestringDefaultRemind me at

Text above the wheel. Read once on connect.

nameReact propnameTypestring

Form field name used when the element is inside a form.

Events

Events bubble and cross the shadow boundary unless the description says otherwise.

changeReact proponChangeDetail{ value: string }

Fires once, after both columns have stopped, when the wheel settles on a new value after a drag, fling, wheel scroll, key press or a change to the value attribute. value is HH:MM.

Properties

valueTypestring

The selected time as HH:MM, including a time the columns are still moving to. Setting it updates the getter and the value attribute at once, then animates the columns.

step (read-only)Typenumber

The effective minute step, 1 to 30.

form (read-only)TypeHTMLFormElement | null

The owning form, from ElementInternals.

name (read-only)Typestring | null

The name attribute. There is no setter; set the attribute instead.

Keyboard

KeysAction
ArrowUp / ArrowDownSelect the previous or next value in the focused column. Values wrap around.
PageUp / PageDownMove three values back or forward in the focused column.

Accessibility

  • Each column is focusable with role="spinbutton" and aria-label Hours or Minutes.
  • Columns expose aria-valuenow and an aria-valuetext such as 9 hours or 30 minutes; there is no aria-valuemin or aria-valuemax.
  • The visible label is plain text and is not associated with the columns.
  • The digits are text in an aria-hidden layer over the canvas, so the ARIA values on the columns are the text alternative.
  • Form-associated through ElementInternals.
  • Submits the time as HH:MM under name. There is no validation, and form reset and disabled are not handled.
  • Reduced motion: flings stop without inertia, columns jump to the target value instead of springing, and the value label changes without the roll.

Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from --lumesec. See Theming.

This component reads --foreground, --lumesec and --muted-foreground.

To restyle only LumeSec elements, set the matching --ui-* overrides: --ui-accent, --ui-fg, --ui-mono and --ui-muted.

Notes

  • Fixed size: the wheel is 236px wide and 188px tall, and the host is inline-block.
  • The digits are set in the mono font with tabular figures; the selection band behind them is a dotted field.
  • Clicking a row without dragging snaps to that row; a mouse wheel or trackpad scrolls the column under the pointer.
  • After value is set, change fires once with the new time when both columns have settled. After a key press or a click on a row, the getter reports the target at once, while the attribute and aria-valuenow update when the column settles.

Was this page helpful?