Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsForm Blocks

Time Picker

Three time-picker variants — a drum-roll wheel, a typed HH:MM input field, and a button-triggered popover. Supports 12h/24h formats, seconds, configurable minute steps, all intent colours, RTL, and keyboard navigation.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import { TimePicker } from "@tessinaui/ui";
{/* Inline wheel (default) */}
<TimePicker defaultValue="10:30" />

{/* Typed input field */}
<TimePicker variant="input" defaultValue="10:30" />

{/* Button trigger + popover wheel */}
<TimePicker variant="popover" defaultValue="10:30" />

{/* 24-hour format */}
<TimePicker format="24h" defaultValue="14:00" />

{/* With seconds */}
<TimePicker showSeconds defaultValue="10:30:00" />

{/* 15-minute step (wheel & popover only) */}
<TimePicker step={15} defaultValue="10:30" />

{/* Controlled */}
<TimePicker value={time} onChange={setTime} />

Showcase

Variants

VariantBehaviour
wheelInline drum-roll columns — always visible on the page
inputTyped input field with editable HH / MM (/ SS) segments and an AM/PM toggle for 12h. Type digits to set the value; auto-advances to the next segment after 2 digits.
popoverClock-icon trigger button that opens a popover containing the wheel

API Reference

PropTypeDefaultDescription
variant"wheel" | "input" | "popover""wheel"Display mode
valuestring | null—Controlled value in "HH:mm" or "HH:mm:ss" 24h format
defaultValuestring | nullnullUncontrolled initial value
onChange(value: string) => void—Called when the time changes; receives "HH:mm" or "HH:mm:ss"
format"12h" | "24h""12h"Hour column format — "12h" shows an AM/PM column, "24h" shows 00–23
showSecondsbooleanfalseAdd a seconds column
step1 | 5 | 10 | 15 | 301Minute and second interval; only values divisible by this step appear in the column
size"xs" | "sm" | "md" | "lg" | "xl""md"Size token — controls item height, text size, and column width
intent"none" | "primary" | "error" | "warning" | "success" | "info""none"Colour intent applied to the selection band and selected text
rounded"none" | "sm" | "md" | "lg" | "full""md"Corner radius of the wheel container and input trigger
disabledbooleanfalsePrevent interaction and reduce opacity
readOnlybooleanfalseDisplay value without allowing interaction
dir"ltr" | "rtl""ltr"Text direction — reverses column order for RTL locales
placeholderstring"--:-- --" / "--:--"Shown in the input trigger when no value is set; auto-adjusts for 24h format
skeletonbooleanfalseReplace the component with a pulsing placeholder sized to match the variant
showLabelsbooleanfalseRender hours, min, sec labels next to the selected numbers (wheel & popover variants) — columns widen to fit the labels
classNamestring—Additional classes on the root element

Notes

  • Value format — Values are always stored and emitted in 24h "HH:mm" (or "HH:mm:ss" when showSeconds is true). The format prop only controls the display columns; you never need to parse AM/PM from the emitted value.
  • Controlled vs uncontrolled — Pass value + onChange for controlled, or defaultValue alone for uncontrolled. Once value is defined the component is fully controlled.
  • Step alignment — When step > 1, an incoming value whose minute (or second) doesn't appear in the step list is snapped to the nearest step value automatically.
  • Wheel keyboard navigation — Each column is focusable (tabIndex={0}) and responds to ArrowUp / ArrowDown (step ±1), Home (first item), End (last item). Columns announce their role and selection via role="listbox" / role="option" / aria-selected.
  • Wheel and drag — Scroll the mouse wheel over a column to cycle values. Click-and-drag vertically to scroll multiple steps at once. Pointer capture ensures drag tracking works even when the pointer leaves the column bounds.
  • Typed input — variant="input" renders editable HH / MM (/ SS) segments and an AM/PM toggle for 12h. Each segment accepts up to 2 digits and auto-advances to the next. ArrowUp / ArrowDown step the focused segment by ±1 and wrap at min/max. Enter blurs the segment, committing the typed buffer. The step prop has no effect here — the user can land on any minute or second.
  • RTL — dir="rtl" reverses the column order inside the wheel and flips the input/popover layout via the CSS dir attribute on the container.
  • Popover trigger — The variant="popover" trigger shows a formatted display value with a Clock icon and a rotating ChevronDown indicator. The popover is positioned below-start and animates in/out via Base UI's data-[starting-style] / data-[ending-style] attributes.
  • Selected number visibility — The selection band renders behind the column list so the active number stays readable on every intent (including the solid bg-secondary used by the none intent).

Date Picker

A button-triggered date picker popover built on Calendar and Base UI Popover. Supports single, range, and multiple selection, preset shortcuts, stacked or sidebar preset layouts, footer slot, and min/max constraints.

OTP Input

One-time password input with individual digit cells. Supports three visual variants, five sizes, five intents, masking, separator groups, numeric/alphanumeric/alphabetic input types, and full RTL/LTR support.

On this page

PlaygroundInstallationUsageShowcaseVariantsAPI ReferenceNotes