Textarea
textarea收多行文本输入,高度随内容自增
用法
基础用法
多行输入,rows 控制初始可见行数(默认 3)。
tsx
<Textarea placeholder="写点什么…" className="w-64" />尺寸
size 提供 sm / md(默认)/ lg 三档。
tsx
<>
<Textarea size="sm" placeholder="sm" className="w-64" />
<Textarea size="md" placeholder="md" className="w-64" />
<Textarea size="lg" placeholder="lg" className="w-64" />
</>自适应高度
autoResize 随内容自动长高,rows 作下限。
tsx
<Textarea autoResize defaultValue={"随内容长高\n第二行\n第三行"} className="w-64" />单元格内联编辑
variant="cell" 卸掉外壳,高度交给 CSS field-sizing: content 跟随内容(rows 下限默认 1,无需每格再传)。焦点态是浅底 + 内嵌下划线,不会像焦点环那样溢出到相邻格。
tsx
<Textarea variant="cell" defaultValue="就地编辑,输入换行会自己长高" aria-label="备注" />无效态
invalid 标红边框与焦点环(独立使用时手动传)。
tsx
<Textarea invalid defaultValue="错的内容" className="w-64" />禁用态
disabled 降透明度并屏蔽交互。
tsx
<Textarea disabled defaultValue="禁用态" className="w-64" />何时用
多行文本输入(备注、描述、留言)。单行输入用 Input;从固定选项选一项用 Select。开 autoResize 让高度随内容增长,rows 作为下限。放进 hulian Field 内会自动接管 label/error/aria 关联。
导入
ts
import { Textarea, textareaVariants } from "@hulianui/ui"Props
继承原生 <textarea> 属性(除 size 被覆盖外,如 value/onChange/rows/placeholder/disabled…)。
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| size | "xs" | "sm" | "md" | "lg" | "md" | 尺寸(CVA 变体,覆盖原生 size)。xs 与 Input / SelectTrigger 的 xs 等高,用于密集数据表。variant="cell" 下只影响字号,不再有内距 |
| ref | Ref<HTMLTextAreaElement> | - | 转发到内层原生 `<textarea>`。focus() / select() / 取 .value / react-hook-form 的 register() 都靠它;与内部 autoResize 用的 ref 自动并存 |
| variant | "default" | "cell" | "default" | 外壳形态。cell = 表格单元格里的就地编辑器:无边框、透明底、零内距,高度由 CSS field-sizing: content 跟随内容,焦点态用浅底 + 内嵌下划线代替焦点环 |
| value | string | number | readonly string[] | null | - | 受控值。除原生类型外还收 `null`,按空串渲染(#220,同 Input):`useForm` 的 register().value 会把「显式清空」的 null 原样给出来。不传(undefined)仍是非受控 |
| invalid | boolean | false | 独立使用时标红;在 hulian Field 内由 Field.Root invalid 自动驱动 |
| autoResize | boolean | false | 随内容自适应高度(JS scrollHeight,rows 为下限) |
| rows | number | 3(variant="cell" 时 1) | 初始/最小行高 |
| disabled | boolean | false | 禁用 |
Events
| 事件 | 类型 | 说明 |
|---|---|---|
| onChange | (e: ChangeEvent<HTMLTextAreaElement>) => void | 透传原生输入回调(受控时配合 value 使用) |
禁忌 / 坑
variant="cell"与autoResize是同一件事的两条路:前者交给 CSSfield-sizing: content(浏览器原生,无 JS 往返),后者是 JS 读scrollHeight。默认只需要 `cell`;field-sizing是较新的 CSS 特性,不支持的浏览器会退回按rows的固定高度(不破版,只是不自增),需要覆盖到那些浏览器时把autoResize一起传上——autoResize写的是内联style.height,优先级高于field-sizing的固有尺寸,叠加不冲突。- 表格里就地编辑用
variant="cell",不要在调用处写className="border-0 bg-transparent p-0 resize-none field-sizing-content …"覆盖默认外壳;同时rows的下限在cell下已默认为1,不必每格再传rows={1}。 variant="cell"/autoResize这一档不接受resize-*覆盖,而且覆盖只会成功一半:这一档发出的是resize-none overflow-hidden,两者在 tailwind-merge 里分属不同组,className="resize-y"只顶得掉resize-none,overflow-hidden原样留下——手柄能拖,但往小拖时内容直接被裁且不出滚动条(同时field-sizing-content还在按内容算高度,跟手柄写出的内联 height 抢)。组件会在开发期console.warn点名(每档只喊一次)。要一个可拖的框请改用variant="default"且不传autoResize。- 实现/扩展 field-aware Textarea 时见 [[base-ui-field-control-render-textarea-type-safe]]:Base UI Field 无 Textarea 原语,textarea 专属 props(ref/rows/onInput)要放在
render元素上而非Field.Control,否则 TS 报 ref 类型错或静默丢 Field a11y 接线。 - 在 hulian Field 内不要重复传
invalid,由 Field.Root 自动驱动。
相关
Playground
<Textarea size="md" placeholder="写点什么…" rows={3} />