Input
Input 从 HeroUI v2 到 v3 的迁移指南。
完整的 API 参考、样式指南与高级示例请参阅 v3 Input 文档。本指南只关注从 HeroUI v2 的迁移。
关键变化:Input → TextField
v2: Input 是功能完备的组件,内置标签、描述、错误信息、校验、变体、颜色、尺寸等。
v3: Input 现在只是一个原语组件(仅是输入元素本身)。对于表单字段,请使用 TextField,它由 Input 与 Label、Description、FieldError 等子组件组成。在 v2 中并没有独立的 TextField 或 InputGroup;单一的 Input 组件就负责标签、描述、起止内容与校验等所有职责。
何时使用 Input vs TextField
使用 TextField(大多数场景)
当你需要以下能力时,请使用 TextField:
- 标签
- 描述
- 错误信息
- 校验
- 表单集成
使用 Input(仅原语)
当你需要以下能力时,请使用 Input:
- 仅一个基础的 input 元素
- 自定义的标签 / 错误处理
- 与自定义表单组件集成
结构变化
在 v2 中,Input 是功能完备的组件,通过 prop 接收标签、描述、占位符等:
import { Input } from "@lenso/ui";
export default function App() { return ( <Input label="Email" placeholder="Enter your email" type="email" /> );}在 v3 中,Input 是原语组件。对于带标签与校验的表单字段,请使用 TextField,将 Input 与 Label、Description、FieldError 组合在一起:
import { TextField, Label, Input, FieldError } from "@lenso/ui";
export default function App() { return ( <TextField name="email" type="email"> <Label>Email</Label> <Input placeholder="Enter your email" /> <FieldError /> </TextField> );}主要变化
1. 组件拆分
v2: 单一 Input 组件,承担所有职责
v3: 拆分为 Input(原语)与 TextField(复合组件)
2. Prop 变更
| v2 prop | v3 位置 | 说明 |
|---|---|---|
label | Label | 在 TextField 内使用 Label 组件 |
description | Description | 在 TextField 内使用 Description 组件 |
errorMessage | FieldError | 在 TextField 内使用 FieldError 组件 |
variant | Input | 从多种变体(flat、bordered、underlined、faded)改为 "primary"(默认,带阴影)与 "secondary"(弱化、无阴影,适合 Surface 场景) |
color、size、radius | - | 已移除(请改用 Tailwind CSS) |
fullWidth | Input 或 TextField | Input 与 TextField 上均仍支持 fullWidth 布尔属性 |
labelPlacement | - | 通过 Label 的布局自行处理 |
startContent | InputGroup.Prefix | 在 TextField 内使用 InputGroup 与 InputGroup.Prefix |
endContent | InputGroup.Suffix | 在 TextField 内使用 InputGroup 与 InputGroup.Suffix |
isClearable | - | 请通过按钮手动实现 |
isRequired、isInvalid | TextField | 请设置在 TextField 上 |
validate | TextField | 在 TextField 上使用 validate |
classNames | - | 改在各子组件上使用 className |
onValueChange | Input | 改用 onChange 事件处理函数 |
迁移示例
表单校验
{/* With description */}<Input description="We'll never share your email" label="Email" type="email"/>
{/* With error message */}<Input errorMessage="Please enter a valid email" isInvalid label="Email" type="email"/>
{/* Required */}<Input isRequired label="Email" type="email" />Input 起止内容
对于带前缀或后缀内容的输入,请使用 InputGroup 复合组件:
<Input label="Price" startContent={<span>$</span>} type="number"/>InputGroup 为前缀 / 后缀内容提供合适的样式与布局。其中:
InputGroup.Prefix表示位于输入之前的内容(取代startContent)InputGroup.Suffix表示位于输入之后的内容(取代endContent)InputGroup.Input表示输入元素本身
带清除按钮的 Input
<Input isClearable label="Email" onClear={() => console.log("cleared")} type="email"/>受控 Input
import { useState } from "react";
const [value, setValue] = useState("");
<Input label="Email" onValueChange={setValue} type="email" value={value}/>总结
- 组件拆分:表单字段使用
TextField,仅原语输入使用Input - 标签必须显式声明:必须使用
Label组件而不是labelprop - 错误展示:必须使用
FieldError组件而不是errorMessageprop - 描述:必须使用
Description组件而不是descriptionprop - 校验:将
validate函数从Input移到TextField上 - 起止内容:在
TextField内使用InputGroup与InputGroup.Prefix/InputGroup.Suffix - 清除按钮:请手动实现
CloseButton - 简化变体:v2 提供多种变体(flat、bordered、underlined、faded);v3 提供
"primary"(默认)与"secondary"(适合 Surface) - fullWidth:
fullWidthprop 在Input与TextField上均可用 - 移除 color:请改用 Tailwind CSS 类
- 移除 size:请改用 Tailwind CSS 类
- 移除 radius:请改用 Tailwind CSS 类
- 移除 onValueChange:改用
onChange事件处理函数 - 移除 classNames:改在各子组件上使用
classNameprop