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 Prop | v3 Location | Notes |
|---|---|---|
onValueChange | onChange | Renamed event handler |
label | — | Use Label component |
description | — | Use Description component |
errorMessage | — | Use FieldError component |
variant | variant (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
- Component Renamed:
NumberInput→NumberField - Component Structure: Must use compound components (
NumberField.Group,NumberField.Input, etc.) - Label/Description/Error: Use separate components (
Label,Description,FieldError) - Stepper Buttons: Must explicitly include
NumberField.IncrementButtonandNumberField.DecrementButton - Event Handler:
onValueChange→onChange - Variant Simplified: v3 supports only
variant="primary"andvariant="secondary";color,size,radiusremoved — use Tailwind CSS - Content Props Removed:
startContent,endContent- place manually - Clear Button Removed:
isClearableremoved - handle manually - Stepper Control:
hideStepperremoved - omit buttons instead - Label Placement Removed:
labelPlacementremoved - handle with layout