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 校验。
当字段有效性匹配时显示错误。
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>
);
}输入类型
支持所有 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 属性,以及以下属性:
| Prop | Type | Default | Description |
|---|---|---|---|
| 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 值:
| 匹配 | 描述 |
|---|---|
| valueMissing | 必填字段为空 |
| typeMismatch | 值不符合类型(例如邮箱无效) |
| patternMismatch | 值不符合 pattern 属性 |
| tooShort | 值短于 minLength |
| tooLong | 值长于 maxLength |
| rangeUnderflow | 值小于 min |
| rangeOverflow | 值大于 max |
| true | 始终显示错误(用于服务端校验) |