Search field
A recognizable search entry point with clear affordances.
fieldsearch
Preview
Search field preview
Live · keyboard ready
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
Live · keyboard ready
- ButtonActions
- DialogDisclosure
- Line chartData
- Hero sectionBlocks
filter-a-list-a-search-field-that-filters-the-list-under-it-as-you-type-.tsxtsx
"use client";
import { useState } from "react";
import { SearchField } from "@/components/manicat/search-field/search-field";
const components = [
{ id: "button", title: "Button", group: "Actions", meta: "component", keywords: ["cta", "action"] },
{ id: "dialog", title: "Dialog", group: "Disclosure", meta: "component" },
{ id: "line-chart", title: "Line chart", group: "Data", meta: "component", keywords: ["graph", "series"] },
{ id: "hero-section", title: "Hero section", group: "Blocks", meta: "block" },
];
export function SearchFieldFilterExample() {
const [query, setQuery] = useState("");
const results = components.filter((item) => item.title.toLowerCase().includes(query.toLowerCase()));
return (
<div className="grid w-full max-w-sm gap-3">
<SearchField label="Search" value={query} onValueChange={setQuery} placeholder="Find a component" />
<ul className="grid gap-1 text-sm">
{results.map((item) => (
<li key={item.id} className="flex justify-between rounded-[var(--radius-control)] px-3 py-1.5 hover:bg-fd-accent">
<span className="text-(color:--foreground)">{item.title}</span>
<span className="text-(color:--text-muted)">{item.group}</span>
</li>
))}
{results.length === 0 && <li className="px-3 py-1.5 text-(color:--text-muted)">No match for “{query}”.</li>}
</ul>
</div>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| Escape | Clears 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.