We'll never share your email
import { Input } from "@cloudflare/kumo";
export function InputBasicDemo() {
return (
<Input
label="Email"
placeholder="you@example.com"
description="We'll never share your email"
/>
);
}安装
批量导入
import { Input } from "@cloudflare/kumo";细粒度导入
import { Input } from "@cloudflare/kumo/components/input";用法
使用内置 Field(推荐)
使用 label 属性即可启用内置的 Field 包装,获得标签、说明与错误提示支持。
import { Input } from "@cloudflare/kumo";
export default function Example() {
return (
<Input
label="Email"
placeholder="you@example.com"
description="We'll never share your email"
/>
);
}裸 Input(自定义布局)
自定义表单布局时,可不使用 label 直接使用 Input。此时必须提供 aria-label
或 aria-labelledby 以保证无障碍。
import { Input } from "@cloudflare/kumo";
export default function Example() {
return <Input placeholder="Search..." aria-label="Search products" />;
}示例
带标签与说明
label 属性会启用内置的 Field 包装,并自动采用垂直布局 (标签位于输入框上方)。
3-20 characters, alphanumeric only
import { Input } from "@cloudflare/kumo";
export function InputWithLabelDemo() {
return (
<Input
label="Username"
placeholder="Choose a username"
description="3-20 characters, alphanumeric only"
/>
);
}错误提示 (字符串)
将 error 作为字符串传入即可显示简单的错误消息。当 error 属性为真值时,
会自动应用错误样式。
import { Input } from "@cloudflare/kumo";
export function InputErrorStringDemo() {
return (
<Input
label="Email"
placeholder="you@example.com"
value="invalid-email"
error="Please enter a valid email address"
/>
);
}错误提示 (校验对象)
将 error 作为包含 message 和 match 的对象传入,可用于 HTML5 校验。
当字段的有效性与 match 匹配时显示错误。
import { Input } from "@cloudflare/kumo";
export function InputErrorObjectDemo() {
return (
<Input
label="Password"
type="password"
value="short"
error={{
message: "Password must be at least 8 characters",
match: "tooShort",
}}
minLength={8}
/>
);
}Input 尺寸
提供四种尺寸:xs、sm、base(默认)、lg。
import { Input } from "@cloudflare/kumo";
export function InputSizesDemo() {
return (
<div className="flex flex-col gap-4">
<Input size="xs" label="Extra Small" placeholder="Extra small input" />
<Input size="sm" label="Small" placeholder="Small input" />
<Input label="Base" placeholder="Base input (default)" />
<Input size="lg" label="Large" placeholder="Large input" />
</div>
);
}禁用
import { Input } from "@cloudflare/kumo";
export function InputDisabledDemo() {
return <Input label="Disabled field" placeholder="Cannot edit" disabled />;
}可选字段
设置 required={false} 可在标签后显示「(选填)」文本。
import { Input } from "@cloudflare/kumo";
export function InputOptionalFieldDemo() {
return (
<Input
label="Phone Number"
required={false}
placeholder="+1 (555) 000-0000"
/>
);
}带标签提示框
使用 labelTooltip 可添加一个信息图标,悬停时显示补充说明。
import { Input } from "@cloudflare/kumo";
export function InputLabelTooltipDemo() {
return (
<Input
label="API Key"
labelTooltip="Find this in your dashboard under Settings > API Keys"
placeholder="sk_live_..."
/>
);
}ReactNode 标签
label 属性接受 ReactNode,可实现富文本格式的标签。
import { Input } from "@cloudflare/kumo";
export function InputReactNodeLabelDemo() {
return (
<Input
label={
<span>
Email for <strong>billing</strong>
</span>
}
required
placeholder="billing@company.com"
type="email"
/>
);
}通过 onChange 受控
标准的 React onChange 处理函数接收完整的事件对象,使用 e.target.value
获取值。
Uses e.target.value
import { useState } from "react";
import { Input } from "@cloudflare/kumo";
/** Controlled input using `onChange` (native React event). */
export function InputControlledOnChangeDemo() {
const [value, setValue] = useState("");
return (
<Input
label="With onChange"
placeholder="Type something..."
description={value ? `Value: ${value}` : "Uses e.target.value"}
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
}通过 onValueChange 受控
onValueChange 是 Base UI 提供的便捷处理函数,直接给出字符串值——无需再从事件中
解包。Select、Combobox 和 Radio.Group 采用的也是这一模式。
Receives the value directly
import { useState } from "react";
import { Input } from "@cloudflare/kumo";
/** Controlled input using `onValueChange` (Base UI convenience — gives you the string directly). */
export function InputControlledOnValueChangeDemo() {
const [value, setValue] = useState("");
return (
<Input
label="With onValueChange"
placeholder="Type something..."
description={value ? `Value: ${value}` : "Receives the value directly"}
value={value}
onValueChange={(v) => setValue(v)}
/>
);
}裸 Input(无标签)
不带 label 的 Input 会渲染为裸输入框。必须提供 aria-label 以保证无障碍。
import { Input } from "@cloudflare/kumo";
export function InputBareDemo() {
return <Input placeholder="Search..." aria-label="Search products" />;
}无标签时的错误提示
即使没有可见的 label,错误消息和说明仍会渲染——使用 aria-label
保证输入框的无障碍可用性。
import { Input } from "@cloudflare/kumo";
/** Input without a visible label, showing error and description via `aria-label`. */
export function InputErrorWithoutLabelDemo() {
return (
<div className="flex flex-col gap-4">
<Input
aria-label="Hostname"
placeholder="example.com"
value="not a host"
error="Please enter a valid hostname"
/>
<Input
aria-label="Path"
placeholder="/api/v1/users"
value="missing-slash"
error={{ message: "Path must start with /", match: true }}
/>
</div>
);
}Input 类型
支持所有 HTML input 类型:text、email、password、number、tel、
url 等。
import { Input } from "@cloudflare/kumo";
export function InputTypesDemo() {
return (
<div className="flex flex-col gap-4">
<Input type="email" label="Email" placeholder="you@example.com" />
<Input type="password" label="Password" placeholder="••••••••" />
<Input type="number" label="Age" placeholder="18" />
<Input type="tel" label="Phone" placeholder="+1 (555) 000-0000" />
</div>
);
}密码管理器浮层
对于密码管理器可能误判为登录字段的非凭据输入框,设置 passwordManagerIgnore。
import { Input } from "@cloudflare/kumo";
/** Side-by-side comparison: Keeper shows its icon on the default input but not the ignored one. */
export function InputPasswordManagerIgnoreDemo() {
return (
<div className="flex flex-col gap-4">
<Input
label="API Key (default)"
type="password"
placeholder="sk_live_..."
/>
<Input
label="API Key (passwordManagerIgnore)"
type="password"
placeholder="sk_live_..."
passwordManagerIgnore
/>
</div>
);
}API 参考
Input 接受所有标准 HTML input 属性,以及以下属性:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | ReactNode | - | Label content for the input (enables Field wrapper) - can be a string or any React node |
| labelTooltip | ReactNode | - | Tooltip content to display next to the label via an info icon |
| description | ReactNode | - | Helper text displayed below the input |
| error | string | object | - | Error message or validation error object |
| passwordManagerIgnore | boolean | - | Suppress browser extension password manager overlays on non-credential inputs. |
| size | "xs" | "sm" | "base" | "lg" | "base" | Input size. - `"xs"` — Extra small for compact UIs - `"sm"` — Small for secondary fields - `"base"` — Default size - `"lg"` — Large for prominent fields |
| variant | "default" | "error" | "default" | Visual variant. - `"default"` — Standard input - `"error"` — Error state for validation failures |
校验错误类型
将 error 作为对象使用时,match 属性对应 HTML5 ValidityState 的取值:
| Match | 说明 |
|---|---|
| valueMissing | 必填字段为空 |
| typeMismatch | 值与类型不匹配 (如无效的邮箱地址) |
| patternMismatch | 值与 pattern 属性不匹配 |
| tooShort | 值短于 minLength |
| tooLong | 值长于 maxLength |
| rangeUnderflow | 值小于 min |
| rangeOverflow | 值大于 max |
| true | 始终显示错误 (用于服务端校验) |