ProComponents, templates & AI tooling
HeroUI
27.7k

NumberInput

NumberInput → NumberField 从 HeroUI v2 到 v3 的迁移指南。

完整的 API 参考、样式指南与高级示例请参阅 v3 NumberField 文档。本指南只关注从 HeroUI v2 的迁移。

结构变化

在 v2 中,NumberInput 是单个组件,通过 prop 配置:

import { NumberInput } from "@heroui/react";

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

在 v3 中,NumberField 改为复合组件:

import { NumberField, Label } from "@heroui/react";

export default function App() {
  return (
    <NumberField defaultValue={1024}>
      <Label>Amount</Label>
      <NumberField.Group>
        <NumberField.DecrementButton />
        <NumberField.Input />
        <NumberField.IncrementButton />
      </NumberField.Group>
    </NumberField>
  );
}

主要变化

1. 组件命名

v2: NumberInput
v3: NumberField

2. 组件结构

v2: 单个组件,通过 prop 配置
v3: 复合组件:NumberField.GroupNumberField.InputNumberField.IncrementButtonNumberField.DecrementButton

3. Prop 变更

v2 propv3 位置说明
onValueChangeonChange事件处理函数已重命名
label改用 Label 组件
description改用 Description 组件
errorMessage改用 FieldError 组件
variantvariant(在 NumberField 上)简化为仅 primary | secondary
color已移除(请改用 Tailwind CSS)
size已移除(请改用 Tailwind CSS)
radius已移除(请改用 Tailwind CSS)
startContent手动将内容放入 Group 中
endContent手动将内容放入 Group 中
labelPlacement通过布局类自行处理
hideStepper省略 NumberField.IncrementButtonNumberField.DecrementButton
isClearable请手动实现清除功能
classNames改在各子组件上使用 className prop
isWheelDisabled已移除

迁移示例

表单校验

{/* 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" />
import { Description, FieldError, Label } from "@heroui/react";

{/* With description */}
<NumberField>
  <Label>Amount</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
  <Description>Enter the amount</Description>
</NumberField>

{/* With error message */}
<NumberField isInvalid>
  <Label>Amount</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
  <FieldError>Please enter a valid number</FieldError>
</NumberField>

{/* Required */}
<NumberField isRequired>
  <Label>Quantity</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
</NumberField>

受控

import { useState } from "react";

const [value, setValue] = useState();

<NumberInput
  value={value}
  onValueChange={setValue}
/>
import { useState } from "react";

const [value, setValue] = useState<number | undefined>();

<NumberField value={value} onChange={setValue}>
  <Label>Amount</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
</NumberField>

不带步进按钮

<NumberInput hideStepper label="Amount" />
<NumberField>
  <Label>Amount</Label>
  <NumberField.Group>
    <NumberField.Input />
  </NumberField.Group>
</NumberField>

数值约束

{/* 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"
/>
{/* Min/Max */}
<NumberField maxValue={100} minValue={0}>
  <Label>Quantity</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
</NumberField>

{/* Step */}
<NumberField step={0.1}>
  <Label>Percentage</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
</NumberField>

{/* Format options */}
<NumberField formatOptions={{style: "currency", currency: "USD"}}>
  <Label>Price</Label>
  <NumberField.Group>
    <NumberField.DecrementButton />
    <NumberField.Input />
    <NumberField.IncrementButton />
  </NumberField.Group>
</NumberField>

组件结构

v3 NumberField 遵循以下结构:

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

总结

  1. 组件重命名NumberInputNumberField
  2. 组件结构:必须使用复合组件(NumberField.GroupNumberField.Input 等)
  3. 标签 / 描述 / 错误:改用独立组件(LabelDescriptionFieldError
  4. 步进按钮:必须显式包含 NumberField.IncrementButtonNumberField.DecrementButton
  5. 事件处理函数onValueChangeonChange
  6. 简化变体:v3 仅支持 variant="primary"variant="secondary"colorsizeradius 已移除——请改用 Tailwind CSS
  7. 移除 content propstartContentendContent —— 请手动放置
  8. 移除清除按钮isClearable 已移除——请自行实现
  9. 步进控件hideStepper 已移除——通过省略相应按钮实现
  10. 移除 labelPlacementlabelPlacement 已移除——请通过布局自行实现

本页目录