Skip to content
  1. Keyline UI
  2. Time field
Keyline UIComponents
  • Get started
    • Installation
    • Theming
    • Modes
    • Configuration
    • Composition
  • Actions
    • Button
    • Button group
    • Split button
    • Toggle
    • Toggle group
    • Toolbar
    • Menu
    • Menubar
    • Context menu
  • Inputs
    • Field and form
    • Checkbox
    • Checkbox group
    • Radio group
    • Switch
    • Slider
    • Segmented
    • Select
    • Native select
    • Combobox
    • Multiselect
    • Number field
    • OTP field
    • Time field
    • Date picker and calendar
    • Date range
  • Data
    • Table
    • Chart
    • Stat and meter
    • Status and badge
    • Progress
    • Skeleton
    • Empty
    • Avatar
    • Kbd
    • Marker
  • Navigation
    • Tabs
    • Breadcrumb
    • Pagination
    • Nav
    • Navigation menu
    • Command menu
  • Overlays
    • Dialog
    • Alert dialog
    • Drawer
    • Sheet
    • Popover
    • Hover card
    • Tooltip
    • Toast
    • Notice
  • Layout
    • App shell
    • Sidebar
    • Panel
    • Resizable
    • Scroll area
    • Accordion
    • Collapsible
    • Carousel
    • Inspector
    • Item
    • Direction
  • Conversation
    • Message
    • Bubble
    • Message scroller
    • Attachment
    • Questionnaire
  • Blocks
    • Shipments

Time field

A time of day typed in parts: hours, minutes and, on a 12-hour clock, AM or PM. Type digits and it moves on by itself; arrow keys step each part and stay inside the hours you allow.

Loading the live example…

"use client"

import { useState } from "react"
import { TimeField } from "@/components/keyline/ui/time-field"

const show = (t: string) => new Date(`2026-01-01T${t}`).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })

export function DockTime() {
  const [time, setTime] = useState<string | null>("10:30")

  return (
    <div className="grid max-w-[320px] gap-3">
      <TimeField
        label="Truck arrives at"
        hourCycle={12}
        locale="en-US"
        minuteStep={15}
        min="07:00"
        max="16:00"
        zone="EST"
        value={time}
        onValueChange={setTime}
        description="The dock is open 7 AM to 4 PM. Arrow keys move by 15 minutes."
      />
      <p role="status" className="text-[14px] text-kl-ink-2">
        {time ? `Darryl will have the dock clear at ${show(time)}.` : "No arrival time yet."}
      </p>
    </div>
  )
}

Installation

npx shadcn@latest add @keyline-ui/time-field

Run it where your components.json is. The first time, map the @keyline-ui registry: one command, in Installation.

Usage

import { TimeField } from "@/components/keyline/ui/time-field"
<TimeField label="Truck arrives at" hourCycle={12} min="07:00" max="16:00" value={time} onValueChange={setTime} />

Props

PropTypeDefaultDescription
labelReactNodeDefault —Names the field; each part is named too. Required.
valuestring | nullDefault —Always 24-hour "HH:MM", whichever clock is shown. onValueChange gets null while a part is missing.
hourCycle12 | 24Default 2412 adds an AM/PM part, named by the locale.
min / max"HH:MM"Default —Arrow keys stay inside; a typed time outside is invalid with rangeMessage.
minuteStepnumberDefault 1Arrow keys move the minutes by this much.
zoneReactNodeDefault —A cell after the time, such as EST.
namestringDefault —Submits "HH:MM" with a form. required asks for a time.
errorReactNodeDefault —The message when a check fails. With invalid it always shows.
descriptionReactNodeDefault —A line under the field, read out with it.
layout"control" | "cell"Default "control"cell drops the frame and hides the label, to sit inside another frame.

Backspace in an empty part goes back to the one before; leaving a part pads it (“7” becomes “07”). In a right-to-left page the time keeps clock order.

Sheet 29 of 73PreviousOTP fieldNextDate picker and calendar
On this page