Skip to content
Lenso UI

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类型默认值描述
childrenReact.ReactNode | (values: SearchFieldRenderProps) => React.ReactNode-子组件(Label、Group、Input 等)或渲染函数。
classNamestring | (values: SearchFieldRenderProps) => string-用于样式的 CSS 类,支持渲染 prop。
styleReact.CSSProperties | (values: SearchFieldRenderProps) => React.CSSProperties-行内样式,支持渲染 prop。
fullWidthbooleanfalse搜索字段是否占满容器宽度
idstring-元素的唯一标识符。
variant"primary" | "secondary""primary"组件的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, SearchFieldRenderProps>-使用自定义渲染函数覆盖默认 DOM 元素。

Value Props

Prop类型默认值描述
valuestring-当前值(受控)。
defaultValuestring-默认值(非受控)。
onChange(value: string) => void-值变化时触发的事件处理函数。

Validation Props

Prop类型默认值描述
isRequiredbooleanfalse提交表单前是否要求用户输入。
isInvalidboolean-当前值是否无效。
validate(value: string) => ValidationError | true | null | undefined-自定义校验函数。
validationBehavior'native' | 'aria''native'使用原生 HTML 表单校验或 ARIA 属性。
validationErrorsstring[]-服务端校验错误。

State Props

Prop类型默认值描述
isDisabledboolean-是否禁用输入。
isReadOnlyboolean-是否可选中但不可修改。

Form Props

Prop类型默认值描述
namestring-input 元素的名称,用于 HTML 表单提交。
autoFocusboolean-元素渲染后是否应获得焦点。

Event Props

Prop类型默认值描述
onSubmit(value: string) => void-用户提交搜索(Enter)时触发的事件处理函数。
onClear() => void-按下清除按钮时触发的事件处理函数。

Accessibility Props

Prop类型默认值描述
aria-labelstring-没有可见标签时的无障碍标签。
aria-labelledbystring-用于标注该字段的元素 ID。
aria-describedbystring-用于描述该字段的元素 ID。
aria-detailsstring-包含更多详情的元素 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类型默认值描述
childrenReact.ReactNode | (values: GroupRenderProps) => React.ReactNode-子组件(SearchIcon、Input、ClearButton)或渲染函数。
classNamestring | (values: GroupRenderProps) => string-用于样式的 CSS 类。

SearchField.Input Props

SearchField.Input 继承 React Aria Input 组件的 props。

Prop类型默认值描述
classNamestring-用于样式的 CSS 类。
variant"primary" | "secondary""primary"输入的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。
placeholderstring-输入为空时显示的占位符文本。
typestring"search"输入类型(会自动设置为 "search")。

SearchField.SearchIcon Props

SearchField.SearchIcon 是一个用于渲染搜索图标的自定义组件。

Prop类型默认值描述
childrenReact.ReactNode<IconSearch />自定义图标元素。默认为搜索图标。
classNamestring-用于样式的 CSS 类。

SearchField.ClearButton Props

SearchField.ClearButton 继承 React Aria Button 组件的 props。

Prop类型默认值描述
childrenReact.ReactNode<CloseButton icon />按钮的图标或内容。默认为关闭图标。
classNamestring-用于样式的 CSS 类。
slot"clear""clear"必须设置为 "clear"(会自动设置)。

SearchFieldRenderProps

在 className、style 或 children 上使用渲染 prop 时,可使用以下值:

Prop类型描述
isDisabledboolean字段是否禁用。
isInvalidboolean字段当前是否无效。
isReadOnlyboolean字段是否只读。
isRequiredboolean字段是否必填。
isFocusedboolean字段是否聚焦(已弃用,请使用 isFocusWithin)。
isFocusWithinboolean是否有任意子元素聚焦。
isFocusVisibleboolean是否为可见焦点(键盘导航)。
valuestring当前值。
isEmptyboolean字段是否为空。

相关案例

See upstream SearchField showcases. Product showcases are not part of the local component runtime.

相关组件