Search field

A recognizable search entry point with clear affordances.

fieldsearch
Preview
Search field preview

Type to search.

When to use

  • Filtering a visible list or table in place.
  • Toolbar search where the query should be clearable with one click.

When not to use

  • Use expanding-search for compact header search with results.
  • Use combobox when the search sets a form value.
  • Use filter-toolbar when search sits with other filters and sort.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "search-field",
  "type": "registry:ui",
  "title": "Search field",
  "description": "A recognizable search entry point with clear affordances.",
  "categories": [
    "inputs"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/search-field/search-field.tsx",
      "type": "registry:component",
      "target": "@components/manicat/search-field/search-field.tsx"
    },
    {
      "path": "registry/components/search-field/search-field.module.css",
      "type": "registry:component",
      "target": "@components/manicat/search-field/search-field.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/search-field",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/search-field",
    "markdown": "https://uiarc.dev/components/search-field/markdown",
    "tags": [
      "field",
      "search"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { useState } from "react";
import { SearchField } from "@/components/manicat/search-field/search-field";

export function SearchFieldExample() {
  const [value, setValue] = useState("");

  return (
    <div className="grid w-full max-w-sm gap-2">
      <SearchField label="Search" value={value} onValueChange={setValue} placeholder="Find a component" />
      <p className="text-sm text-(color:--text-muted)">{value ? `Searching for “${value}”` : "Type to search."}</p>
    </div>
  );
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Filter a list A search field that filters the list under it as you type.

Filter a list A search field that filters the list under it as you type. preview
  • ButtonActions
  • DialogDisclosure
  • Line chartData
  • Hero sectionBlocks

Keyboard interactions

KeysAction
EscapeClears the field (native type="search" behavior in most browsers).

Accessibility

  • Native input type="search" with a real label.
  • Clear button is labelled "Clear search" and returns focus to the input.
  • The search icon is aria-hidden.

Motion

  • The clear button scales in from 0.8 with a slight blur on a snappy spring and presses to 0.96.
  • Reduced motion fades it in and out without scale or blur; the reserved slot keeps the field width fixed either way.

Responsive behavior

  • The clear button has a reserved slot, so the field width never shifts when it appears.
  • It fills its column with min-width 0 and shrinks inside narrow toolbars.

Performance

  • onValueChange fires on every keystroke; debounce expensive filtering or fetching yourself.

Notes for AI

  • Use to filter a visible list in place. Use expanding-search for a compact header search with results, and combobox to choose a value.
  • Always controlled: pass value and onValueChange, and debounce expensive filtering yourself.