Skip to content
Lenso UI

NumberInput

Migration guide for NumberInput to NumberField from HeroUI v2 to v3

Refer to the v3 NumberField documentation for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.

Structure Changes

In v2, NumberInput was a single component with props:

import { NumberInput } from "@lenso/ui";
export default function App() {  return <NumberInput label="Amount" defaultValue={1024} />;}

In v3, NumberField requires compound components:

import { NumberField, Label } from "@lenso/ui";
export default function App() {  return (    <NumberField defaultValue={1024}>      <Label>Amount</Label>      <NumberField.Group>        <NumberField.DecrementButton />        <NumberField.Input />        <NumberField.IncrementButton />      </NumberField.Group>    </NumberField>  );}

Key Changes

1. Component Naming

v2: NumberInput
v3: NumberField

2. Component Structure

v2: Single component with props
v3: Compound components: NumberField.Group, NumberField.Input, NumberField.IncrementButton, NumberField.DecrementButton

3. Prop Changes

v2 Propv3 LocationNotes
onValueChangeonChangeRenamed event handler
label—Use Label component
description—Use Description component
errorMessage—Use FieldError component
variantvariant (on NumberField)Simplified to primary | secondary only
color—Removed (use Tailwind CSS)
size—Removed (use Tailwind CSS)
radius—Removed (use Tailwind CSS)
startContent—Place content manually in Group
endContent—Place content manually in Group
labelPlacement—Handle with layout classes
hideStepper—Omit NumberField.IncrementButton and NumberField.DecrementButton
isClearable—Handle clear functionality manually
classNames—Use className props on individual components
isWheelDisabled—Removed

Migration Examples

Form Validation

{/* With description */}<NumberInput  description="Enter the amount"  label="Amount"/>
{/* With error message */}<NumberInput  errorMessage="Please enter a valid number"  isInvalid  label="Amount"/>
{/* Required */}<NumberInput isRequired label="Quantity" />

Controlled

import { useState } from "react";
const [value, setValue] = useState();
<NumberInput  value={value}  onValueChange={setValue}/>

Without Stepper Buttons

<NumberInput hideStepper label="Amount" />

Number Constraints

{/* Min/Max */}<NumberInput  label="Quantity"  maxValue={100}  minValue={0}/>
{/* Step */}<NumberInput label="Percentage" step={0.1} />
{/* Format options */}<NumberInput  formatOptions={{style: "currency", currency: "USD"}}  label="Price"/>

Component Anatomy

The v3 NumberField follows this structure:

NumberField (Root)  ├── Label (optional)  ├── NumberField.Group  │   ├── NumberField.DecrementButton  │   ├── NumberField.Input  │   └── NumberField.IncrementButton  ├── Description (optional)  └── FieldError (optional)

Summary

  1. Component Renamed: NumberInput → NumberField
  2. Component Structure: Must use compound components (NumberField.Group, NumberField.Input, etc.)
  3. Label/Description/Error: Use separate components (Label, Description, FieldError)
  4. Stepper Buttons: Must explicitly include NumberField.IncrementButton and NumberField.DecrementButton
  5. Event Handler: onValueChange → onChange
  6. Variant Simplified: v3 supports only variant="primary" and variant="secondary"; color, size, radius removed — use Tailwind CSS
  7. Content Props Removed: startContent, endContent - place manually
  8. Clear Button Removed: isClearable removed - handle manually
  9. Stepper Control: hideStepper removed - omit buttons instead
  10. Label Placement Removed: labelPlacement removed - handle with layout