Search
A field for a word or phrase to find something by, rather than by navigating to it. Use it where there is a set worth searching; for a short list, a Select or the list itself is faster.
Live preview
Rendered by the component itself from the same generated tokens as the rest of the site.
const [query, setQuery] = useState('')
<Search
label="Search components"
placeholder="Search components"
value={query}
onChange={setQuery}
/>Installation
Install it with the shadcn CLI, along with everything it uses. New project? Set it up first, as Quick start shows.
npx shadcn@latest add https://www.graphite-ui.com/r/search.jsonimport { Search } from '@/components/ui/search'Anatomy
The search icon, the value, and the clear once there is a value, on the shared field shell. The label is required: the Default set draws none, so it is the field’s only name for assistive tech.
- LabelRequiredThe field's accessible name. The Default set draws none, so it names the input for assistive tech; Fluid paints it inside the box.
- Search iconRequiredThe kit's 16px fi-rs-search, leading on Default, trailing on Fluid. Decorative.
- ClearOptionalThe kit's 16px fi-rs-cross-small, shown once there is a value, named "Clear search". Escape clears too.
Variants
Size sets the height: 48, 40 or 32, with the icon 16, 12 or 8 in. Fluid is the kit’s second set, a 64px box with the label inside. Expandable collapses the field to its icon until it is pressed.
States
Hover lifts only the placeholder, as the kit draws it. Focus is the field shell’s 2px ring. Filled shows the clear. Disabled takes the disabled fill and drops the rule.
API reference
Generated from the contract, versioned with it, and checked by drift-check. This table cannot describe props the component does not have.
| Prop | Type | Default | Notes |
|---|---|---|---|
| size | 'sm' | 'md' | 'lg' | — | The kit's Size, 32, 40 and 48 tall, with the icon 8, 12 or 16 in. Large by default, as the kit has it. |
| layout | 'default' | 'fluid' | — | The kit's Search - Default and Search - Fluid sets. Fluid is one 64px box with the label inside; size does not apply to it. |
| expandable | boolean | — | The kit's Expandable. Collapsed to the icon in a square of the field's height until pressed; it collapses again when it loses focus empty, or on Escape when empty. Default layout only. |
| value / defaultValue / onChange | — | — | Controlled or not. onChange receives the string. |
| onSubmit | — | — | Enter. Running the search is the caller's. |
| disabled | boolean | — |
Design tokens
Every swatch is live. Change the source color in the header and this table repaints, because it reads the same roles the component does.
elevationThe field, elevation-01 (the kit's field), and the clear's hover, elevation-02.outlineThe rest rule on the bottom, plain outline as the Search set draws it (Text input's is outline-strong); the placeholder, through outline-strong.on-surfaceThe value and the clear glyph.on-surface-variantThe search icon, the Fluid label, and the placeholder on hover, the kit's Hover state.surface-variantThe collapsed expandable square's hover.primaryThe focus ring, through the family's focus step, 2px inside; the disabled fill and content, through its disabled steps.dangerInherited through the shared field shell's error ring. The kit's Search draws no error state, so the component never applies it.textThe value at Body/3, the Fluid label at 12/16.spacingHeights, the icon inset and the Fluid box.radiusField corner, through the shared field shell.
Usage
The contract's prohibitions, written as the choices you will actually face.
Do
- Give it a label that says what is being searched (“Search components”), even though Default does not show it.
- Act on the value as the reader types, or on Enter through onSubmit, and say what was found.
- Use the expandable form where a toolbar or a list header has no room for a field at rest.
- Use Fluid inside a Fluid form, so it lines up with the fields around it.
Don’t
- Use it to choose one value from a short list. That is a Select.
- Leave out the label because the field shows a placeholder. The placeholder disappears as soon as anyone types.
- Hide the only way into the content behind an expandable search.
- Restyle the clear or the icon. They are the kit’s glyphs, so every Search reads the same.
Accessibility
What the component does for you, and what it leaves to you.
- Roles
- A
searchlandmark around a nativeinput type="search", named by the label. Fluid paints the label; Default puts it inaria-label. - Keyboard
- Escape clears the value, and on an empty expandable field collapses it. Enter calls onSubmit. The clear is a button, named “Clear search”, and returns focus to the field.
- Expandable
- Collapsed, it is a button named by the label with
aria-expanded; pressing it opens the field and moves focus into it. - Focus
- The field shell’s 2px
--graphite-primary-focusring, inside the field, while the input has focus. - Contrast
- The value is on-surface on the field. The placeholder is outline-strong, the same as every other field’s.
Figma parity
The kit’s Search page has two public sets, Default and Fluid. The code is one component with a layout prop for the two, and every axis of each.
| Kit axis | Values | Code | How it maps |
|---|---|---|---|
| Size | Large · Medium · Small | size | lg, md and sm: 48, 40 and 32 tall, the icon 16, 12 or 8 in. |
| State | Enabled · Hover · Focus · Filled · Disabled | — | Hover and Focus are pseudo-classes (governance rule 7). Filled is a value; the clear shows with it. Disabled is the prop. |
| State | Skeleton | — | No counterpart by rule. |
| Expandable · Expanded | False · True | expandable | Collapsed to the icon in a square that fills surface-variant on hover; expanded on press. |
| Set | Search - Fluid | layout="fluid" | The 64px box: the label inside, the search icon at the right and the clear beside it. |
| Placeholder | Disabled tone (Default) | — | A kit slip: the Default set colours the placeholder in the disabled tone, the Fluid set and Text input in outline-strong. The code follows the field shell. |
