Skip to content
  1. Keyline UI
  2. Number 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

Number field

A number in a field frame, with − and + cells and a unit. The input is the one Tab stop; the arrow keys do the stepping.

Loading the live example…

"use client"

import { useState } from "react"
import { NumberField } from "@/components/keyline/ui/number-field"

const IN_STOCK = 480

export function Reorder() {
  const [cases, setCases] = useState<number | null>(24)
  const over = cases != null && cases > IN_STOCK

  return (
    <div className="grid max-w-[320px] gap-3">
      <NumberField
        label="Reorder for Blue Cross"
        unit="cases"
        min={1}
        largeStep={10}
        value={cases}
        onValueChange={setCases}
        invalid={over}
        error={`The warehouse has ${IN_STOCK}. Split it into two deliveries.`}
        description="Shift + arrow keys step by 10."
      />
      <p role="status" className="text-[14px] text-kl-ink-2">
        {cases == null ? "Enter a quantity." : over ? "Not sent." : `${cases * 10} reams, on Thursday's truck.`}
      </p>
    </div>
  )
}

Installation

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

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

Usage

import { NumberField } from "@/components/keyline/ui/number-field"
<NumberField label="Reorder" unit="cases" min={1} value={cases} onValueChange={setCases} />

Examples

Currency

format takes Intl.NumberFormat options, so the field shows dollars while value stays a plain number. With steppers off, it is a typed amount.

Loading the live example…

"use client"

import { useState } from "react"
import { NumberField } from "@/components/keyline/ui/number-field"

export function UnitPrice() {
  const [price, setPrice] = useState<number | null>(42)

  return (
    <div className="grid max-w-[320px] gap-3">
      <NumberField
        label="Price per case"
        locale="en-US"
        format={{ style: "currency", currency: "USD" }}
        min={0}
        step={0.5}
        steppers={false}
        value={price}
        onValueChange={setPrice}
      />
      <p role="status" className="text-[14px] text-kl-ink-2">
        {price == null ? "No price yet." : price < 38 ? "Below the floor corporate set. Jan will call." : "Within the price list."}
      </p>
    </div>
  )
}

Props

PropTypeDefaultDescription
labelReactNodeDefault —Names the field. Required.
valuenumber | nullDefault —With onValueChange, or start with defaultValue. Typing commits on blur or Enter.
min / maxnumberDefault —The stepper that would leave the range is disabled.
step / largeStepnumberDefault 1 / 10Arrow keys take step; Shift with an arrow, or Page Up and Down, take largeStep.
unitReactNodeDefault —A cell after the number. It labels the value and is not part of it.
formatIntl.NumberFormatOptionsDefault —Formats the number, such as currency or percent. Pair it with locale.
steppersbooleanDefault trueTurn the − and + cells off where stepping makes no sense.
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.

Home and End jump to min and max. Holding a stepper repeats. Built on Base UI Number Field; its other props pass through.

Sheet 27 of 73PreviousMultiselectNextOTP field
On this page