SearchField 搜索框
搜索输入字段,包含清除按钮与搜索图标。
用法
import { SearchField } from '@lenso/ui';此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";
// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ input: { width: 280 } });
export function Basic() { return ( <SearchField name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> </SearchField> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
组件结构
import {SearchField, Label, Description, FieldError} from '@lenso/ui';
export default () => ( <SearchField> <Label /> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input /> <SearchField.ClearButton /> </SearchField.Group> <Description /> <FieldError /> </SearchField>)SearchField 允许用户输入并清空搜索关键词。它包含搜索图标,并提供可选的清除按钮以便快速重置。
示例
变体
SearchField 组件支持两种视觉变体:
primary(默认)— 带阴影的标准样式,适用于大多数场景secondary— 低强调、无阴影,适合在 Surface 等表面背景上使用
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function Variants() { return ( <div {...stylex.props(styles.root)}> <SearchField name="primary-search" variant="primary"> <Label>Primary variant</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> </SearchField> <SearchField name="secondary-search" variant="secondary"> <Label>Secondary variant</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
表面样式
在 Surface 内使用时,请使用 variant="secondary",以应用适合表面背景的低强调变体。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, Label, SearchField, Surface } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", width: "100%", maxWidth: 384, flexDirection: "column", gap: 16, borderRadius: 24, padding: 24, }, input: { width: "100%" },});export function OnSurface() { return ( <Surface xstyle={styles.root}> <SearchField name="search" variant="secondary"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>Enter keywords to search</Description> </SearchField> <SearchField name="search-2" variant="secondary"> <Label>Advanced search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Advanced search..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>Use filters to refine your search</Description> </SearchField> </Surface> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
带描述
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function WithDescription() { return ( <div {...stylex.props(styles.root)}> <SearchField name="search"> <Label>Search products</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search products..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>Enter keywords to search for products</Description> </SearchField> <SearchField name="search-users"> <Label>Search users</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search users..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>Search by name, email, or username</Description> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
必填字段
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function Required() { return ( <div {...stylex.props(styles.root)}> <SearchField name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input required xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> </SearchField> <SearchField name="search-query"> <Label>Search query</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input required xstyle={styles.input} placeholder="Enter search query..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>Minimum 3 characters required</Description> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
禁用状态
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function Disabled() { return ( <div {...stylex.props(styles.root)}> <SearchField disabled name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} value="Disabled search" placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>This search field is disabled</Description> </SearchField> <SearchField disabled name="search-empty"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>This search field is disabled</Description> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
宽度充满
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { width: 400 } });export function FullWidth() { return ( <div {...stylex.props(styles.root)}> <SearchField fullWidth name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
表单校验
将 isInvalid 与 FieldError 配合使用,以展示校验消息。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { FieldError, Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function Validation() { return ( <div {...stylex.props(styles.root)}> <SearchField invalid name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input required value="ab" xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> <FieldError match>Search query must be at least 3 characters</FieldError> </SearchField> <SearchField invalid name="search-invalid"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." value="invalid@query" /> <SearchField.ClearButton /> </SearchField.Group> <FieldError match>Invalid characters in search query</FieldError> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
受控组件
控制 value 以与其他组件同步或执行自定义格式化。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Button, Description, Label, SearchField } from "@lenso/ui";import * as React from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, actions: { display: "flex", gap: 8 }, input: { width: 280 },});export function Controlled() { const [value, setValue] = React.useState(""); return ( <div {...stylex.props(styles.root)}> <SearchField name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." value={value} onValueChange={setValue} /> <SearchField.ClearButton /> </SearchField.Group> <Description>Current value: {value || "(empty)"}</Description> </SearchField> <div {...stylex.props(styles.actions)}> <Button variant="tertiary" onClick={() => setValue("")}> Clear </Button> <Button variant="tertiary" onClick={() => setValue("example query")}> Set example </Button> </div> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
表单示例
完整的表单集成示例,包含校验与提交处理。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Button, Description, FieldError, Form, Label, SearchField, Spinner } from "@lenso/ui";import * as React from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", width: 280, flexDirection: "column", gap: 16 }, full: { width: "100%" },});export function FormExample() { const [value, setValue] = React.useState(""); const [isSubmitting, setIsSubmitting] = React.useState(false); const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null); React.useEffect( () => () => { if (timer.current) clearTimeout(timer.current); }, [], ); const MIN_LENGTH = 3; const isInvalid = value.length > 0 && value.length < MIN_LENGTH; const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); if (value.length < MIN_LENGTH || isSubmitting) return; setIsSubmitting(true); timer.current = setTimeout(() => { console.log("Search submitted:", { query: value }); setValue(""); setIsSubmitting(false); }, 1500); }; return ( <Form xstyle={styles.root} onSubmit={handleSubmit}> <SearchField invalid={isInvalid} name="search"> <Label>Search products</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input required xstyle={styles.full} placeholder="Search products..." value={value} onValueChange={setValue} /> <SearchField.ClearButton /> </SearchField.Group> {isInvalid ? ( <FieldError match>Search query must be at least {MIN_LENGTH} characters</FieldError> ) : ( <Description style={{ display: "block" }}> Enter at least {MIN_LENGTH} characters to search </Description> )} </SearchField> <Button xstyle={styles.full} disabled={value.length < MIN_LENGTH} isLoading={isSubmitting} type="submit" variant="primary" > {isSubmitting ? ( <> <Spinner color="current" size="sm" /> Searching... </> ) : ( "Search" )} </Button> </Form> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
带校验
通过受控 value 实现自定义校验逻辑。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, FieldError, Label, SearchField } from "@lenso/ui";import * as React from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function WithValidation() { const [value, setValue] = React.useState(""); const isInvalid = value.length > 0 && value.length < 3; return ( <div {...stylex.props(styles.root)}> <SearchField invalid={isInvalid} name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input required xstyle={styles.input} placeholder="Search..." value={value} onValueChange={setValue} /> <SearchField.ClearButton /> </SearchField.Group> {isInvalid ? ( <FieldError match>Search query must be at least 3 characters</FieldError> ) : ( <Description style={{ display: "block" }}> Enter at least 3 characters to search </Description> )} </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
自定义图标
自定义搜索图标与清除按钮图标。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 },});export function CustomIcons() { return ( <div {...stylex.props(styles.root)}> <SearchField name="search-custom"> <Label>Search (Custom Icons)</Label> <SearchField.Group> <SearchField.SearchIcon height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="none" > <path clipRule="evenodd" d="M12.5 4c0 .174-.071.513-.885.888S9.538 5.5 8 5.5s-2.799-.237-3.615-.612C3.57 4.513 3.5 4.174 3.5 4s.071-.513.885-.888S6.462 2.5 8 2.5s2.799.237 3.615.612c.814.375.885.714.885.888m-1.448 2.66C10.158 6.888 9.115 7 8 7s-2.158-.113-3.052-.34l1.98 2.905c.21.308.322.672.322 1.044v3.37q.088.02.25.021c.422 0 .749-.14.95-.316c.185-.162.3-.38.3-.684v-2.39c0-.373.112-.737.322-1.045zM8 1c3.314 0 6 1 6 3a3.24 3.24 0 0 1-.563 1.826l-3.125 4.584a.35.35 0 0 0-.062.2V13c0 1.5-1.25 2.5-2.75 2.5s-1.75-1-1.75-1v-3.89a.35.35 0 0 0-.061-.2L2.563 5.826A3.24 3.24 0 0 1 2 4c0-2 2.686-3 6-3m-.88 12.936q-.015-.008-.013-.01z" fill="currentColor" fillRule="evenodd" /> </SearchField.SearchIcon> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" > <path clipRule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14M6.53 5.47a.75.75 0 0 0-1.06 1.06L6.94 8L5.47 9.47a.75.75 0 1 0 1.06 1.06L8 9.06l1.47 1.47a.75.75 0 1 0 1.06-1.06L9.06 8l1.47-1.47a.75.75 0 1 0-1.06-1.06L8 6.94z" fill="currentColor" fillRule="evenodd" /> </svg> </SearchField.ClearButton> </SearchField.Group> <Description>Custom icon children</Description> </SearchField> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
键盘快捷键
添加快捷键以快速聚焦搜索框。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Description, Kbd, Label, SearchField } from "@lenso/ui";import * as React from "react";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { display: "flex", flexDirection: "column", gap: 16 }, input: { width: 280 }, hint: { display: "flex", alignItems: "center", gap: 8, fontSize: 14, color: "var(--default-500)", },});export function WithKeyboardShortcut() { const inputRef = React.useRef<HTMLInputElement>(null); const [value, setValue] = React.useState(""); React.useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if ( event.shiftKey && event.key === "S" && !event.metaKey && !event.ctrlKey && !event.altKey ) { event.preventDefault(); inputRef.current?.focus(); } if (event.key === "Escape" && document.activeElement === inputRef.current) inputRef.current?.blur(); }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, []); return ( <div {...stylex.props(styles.root)}> <div> <SearchField name="search"> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input ref={inputRef} xstyle={styles.input} placeholder="Search..." value={value} onValueChange={setValue} /> <SearchField.ClearButton /> </SearchField.Group> <Description>Use keyboard shortcut to quickly focus this field</Description> </SearchField> </div> <div {...stylex.props(styles.hint)}> <span>Press</span> <Kbd> <Kbd.Abbr keyValue="shift" /> <Kbd.Content>S</Kbd.Content> </Kbd> <span>to focus the search field</span> </div> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
渲染函数
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ input: { width: 280 } });export function RenderFunction() { return ( <SearchField name="search" render={(props) => <div {...props} data-custom="foo" />}> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input xstyle={styles.input} placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> </SearchField> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
自定义样式
Tailwind CSS
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Label, SearchField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";const styles = stylex.create({ root: { width: "100%", maxWidth: 256 }, label: { fontWeight: 500, color: "var(--foreground)" }, group: { borderRadius: 12, backgroundColor: "var(--default)" }, muted: { color: "var(--muted)" }, input: { "::placeholder": { color: "var(--muted)" } },});export function CustomStyles() { return ( <SearchField xstyle={styles.root} name="docs" variant="secondary"> <Label xstyle={styles.label}>Search docs</Label> <SearchField.Group xstyle={styles.group}> <SearchField.SearchIcon xstyle={styles.muted} /> <SearchField.Input xstyle={styles.input} placeholder="Components, guides..." /> <SearchField.ClearButton xstyle={styles.muted} /> </SearchField.Group> </SearchField> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
全局 CSS
若要自定义组件类,可使用 @layer components 指令。了解更多。
@layer components { .search-field { @apply flex flex-col gap-1; }
/* When invalid, the description is hidden automatically */ .search-field[data-invalid], .search-field[aria-invalid] { [data-slot="description"] { @apply hidden; } }
.search-field__group { @apply bg-field text-field-foreground shadow-field rounded-field inline-flex h-9 items-center overflow-hidden border; }
.search-field__input { @apply flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none; }
.search-field__search-icon { @apply text-field-placeholder pointer-events-none shrink-0 ml-3 mr-0 size-4; }
.search-field__clear-button { @apply mr-1 shrink-0; }}样式参考
HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。
CSS 类
基础类 [!toc]
.search-field– 根容器,样式非常克制(flex flex-col gap-1).search-field__group– 搜索图标、输入框与清除按钮的容器,包含边框与背景样式.search-field__input– 搜索输入字段.search-field__search-icon– 左侧显示的搜索图标.search-field__clear-button– 用于清空搜索字段的按钮
变体类 [!toc]
.search-field--primary– 带阴影的主变体(默认).search-field--secondary– 无阴影的次变体,适合用在 surface 上
说明: 子组件(Label、Description、FieldError)拥有各自的 CSS 类与样式。自定义方式请参见对应文档。
交互状态
SearchField 会根据状态自动管理以下 data 属性:
- Invalid:
[data-invalid="true"]或[aria-invalid="true"]– 无效时会自动隐藏 description 插槽 - Disabled:
[data-disabled="true"]– 当isDisabled为 true 时应用 - Focus Within:
[data-focus-within="true"]– 当输入框聚焦时应用 - Focus Visible:
[data-focus-visible="true"]– 当焦点可见(键盘导航)时应用 - Hovered:
[data-hovered="true"]– 当悬停在整个组合上时应用 - Empty:
[data-empty="true"]– 当字段为空时应用(会隐藏清除按钮)
更多属性可通过渲染 prop 获得(见下方的 SearchFieldRenderProps)。
API 参考
SearchField
SearchField 继承 React Aria SearchField 组件的全部 props。
Base Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | React.ReactNode | (values: SearchFieldRenderProps) => React.ReactNode | - | 子组件(Label、Group、Input 等)或渲染函数。 |
className | string | (values: SearchFieldRenderProps) => string | - | 用于样式的 CSS 类,支持渲染 prop。 |
style | React.CSSProperties | (values: SearchFieldRenderProps) => React.CSSProperties | - | 行内样式,支持渲染 prop。 |
fullWidth | boolean | false | 搜索字段是否占满容器宽度 |
id | string | - | 元素的唯一标识符。 |
variant | "primary" | "secondary" | "primary" | 组件的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。 |
render | DOMRenderFunction<keyof React.JSX.IntrinsicElements, SearchFieldRenderProps> | - | 使用自定义渲染函数覆盖默认 DOM 元素。 |
Value Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
value | string | - | 当前值(受控)。 |
defaultValue | string | - | 默认值(非受控)。 |
onChange | (value: string) => void | - | 值变化时触发的事件处理函数。 |
Validation Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
isRequired | boolean | false | 提交表单前是否要求用户输入。 |
isInvalid | boolean | - | 当前值是否无效。 |
validate | (value: string) => ValidationError | true | null | undefined | - | 自定义校验函数。 |
validationBehavior | 'native' | 'aria' | 'native' | 使用原生 HTML 表单校验或 ARIA 属性。 |
validationErrors | string[] | - | 服务端校验错误。 |
State Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
isDisabled | boolean | - | 是否禁用输入。 |
isReadOnly | boolean | - | 是否可选中但不可修改。 |
Form Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
name | string | - | input 元素的名称,用于 HTML 表单提交。 |
autoFocus | boolean | - | 元素渲染后是否应获得焦点。 |
Event Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
onSubmit | (value: string) => void | - | 用户提交搜索(Enter)时触发的事件处理函数。 |
onClear | () => void | - | 按下清除按钮时触发的事件处理函数。 |
Accessibility Props
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
aria-label | string | - | 没有可见标签时的无障碍标签。 |
aria-labelledby | string | - | 用于标注该字段的元素 ID。 |
aria-describedby | string | - | 用于描述该字段的元素 ID。 |
aria-details | string | - | 包含更多详情的元素 ID。 |
Composition Components
SearchField 需要与以下独立组件组合使用,请分别导入并直接使用:
- SearchField.Group – 搜索图标、输入框与清除按钮的容器
- SearchField.Input – 搜索输入字段
- SearchField.SearchIcon – 左侧显示的搜索图标
- SearchField.ClearButton – 用于清空搜索字段的按钮
- Label – 字段标签组件(
@lenso/ui) - Description – 辅助说明文本组件(
@lenso/ui) - FieldError – 校验错误信息组件(
@lenso/ui)
这些组件各自拥有 props API。请直接在 SearchField 内组合使用:
<SearchField isRequired isInvalid={hasError} value={value} onChange={setValue}> <Label>Search</Label> <SearchField.Group> <SearchField.SearchIcon /> <SearchField.Input placeholder="Search..." /> <SearchField.ClearButton /> </SearchField.Group> <Description>Enter keywords to search</Description> <FieldError>Search query is required</FieldError></SearchField>SearchField.Group Props
SearchField.Group 继承 React Aria Group 组件的 props。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | React.ReactNode | (values: GroupRenderProps) => React.ReactNode | - | 子组件(SearchIcon、Input、ClearButton)或渲染函数。 |
className | string | (values: GroupRenderProps) => string | - | 用于样式的 CSS 类。 |
SearchField.Input Props
SearchField.Input 继承 React Aria Input 组件的 props。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 用于样式的 CSS 类。 |
variant | "primary" | "secondary" | "primary" | 输入的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。 |
placeholder | string | - | 输入为空时显示的占位符文本。 |
type | string | "search" | 输入类型(会自动设置为 "search")。 |
SearchField.SearchIcon Props
SearchField.SearchIcon 是一个用于渲染搜索图标的自定义组件。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | React.ReactNode | <IconSearch /> | 自定义图标元素。默认为搜索图标。 |
className | string | - | 用于样式的 CSS 类。 |
SearchField.ClearButton Props
SearchField.ClearButton 继承 React Aria Button 组件的 props。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | React.ReactNode | <CloseButton icon /> | 按钮的图标或内容。默认为关闭图标。 |
className | string | - | 用于样式的 CSS 类。 |
slot | "clear" | "clear" | 必须设置为 "clear"(会自动设置)。 |
SearchFieldRenderProps
在 className、style 或 children 上使用渲染 prop 时,可使用以下值:
| Prop | 类型 | 描述 |
|---|---|---|
isDisabled | boolean | 字段是否禁用。 |
isInvalid | boolean | 字段当前是否无效。 |
isReadOnly | boolean | 字段是否只读。 |
isRequired | boolean | 字段是否必填。 |
isFocused | boolean | 字段是否聚焦(已弃用,请使用 isFocusWithin)。 |
isFocusWithin | boolean | 是否有任意子元素聚焦。 |
isFocusVisible | boolean | 是否为可见焦点(键盘导航)。 |
value | string | 当前值。 |
isEmpty | boolean | 字段是否为空。 |
相关案例
See upstream SearchField showcases. Product showcases are not part of the local component runtime.