Skip to content

Search Box

A search field with a search icon and a clear button. Two sizes, three fills and every state.

Version 0.4.1 ·

Search Box states

Installation

bunx --bun shadcn@latest add @dga/search-box

Installs Input and Field too.

Usage

page.tsx
tsx
import { useState } from "react";
import { Field, FieldLabel } from "@/components/ui/field";
import { SearchBox } from "@/components/ui/search-box";

export function ServiceSearch() {
  const [query, setQuery] = useState("");
  return (
    <Field>
      <FieldLabel>Search services</FieldLabel>
      <SearchBox
        value={query}
        onValueChange={setQuery}
        placeholder="Search services"
        clearLabel="Clear search"
      />
    </Field>
  );
}

Use Search Box for finding things in a list, a table or the whole site. Give it a visible label or an aria-label, and a placeholder that says what is searched. Translate clearLabel on Arabic pages. Search results are your own: this component only collects the query.

Anatomy

  • Box: the same border and fill as Input.
  • Search icon: on the start side, decorative.
  • Input (type="search"): the query.
  • Clear button: on the end side, shown when there is text.

Examples

Clear button

Type to show the clear button. It empties the field, returns focus to it and calls onValueChange with an empty string. Esc does the same.

Clear button

States

Default, filled with the clear button, read-only, disabled, and the medium size with a darker fill.

States

RTL

The search icon is on the right (start) and the clear button on the left (end). The icons are not directional, so they are not flipped. Arabic placeholders and queries align right.

LTR (English)
RTL (Arabic)

Accessibility

KeyAction
TabMoves focus to the field, then to the clear button when there is text.
EscClears the text.
EnterSubmits the form it is in.
  • A native type="search" input, announced as a search field.
  • The clear button has an accessible name (clearLabel), a 24px target and its own focus ring.
  • Put the field in a <form role="search"> or a search landmark so people can jump to it.
  • Announce the number of results in a live region (role="status") when they update.

API Reference

A search field with a search icon on the start side and a clear button on the end side that appears once there is text. It is `type="search"`, so Escape clears it too.

SearchBox props
PropTypeDefault
"md" | "lg"

Height: `md` 32px, `lg` 40px.

No default
(value: string) => void

Called with the new text whenever it changes, including when it is cleared.

No default
"default" | "lighter" | "darker"

Fill style. `lighter` and `darker` keep the border.

No default
string

The value of the input. Use when controlled.

No default
string

Accessible name of the clear button. Translate it on Arabic pages.

"Clear search"
string

Class names for the native `<input>`. `className` styles the box around it.

No default
string

The default value of the input. Use when uncontrolled.

No default
boolean

Disables the field.

No default
boolean

The text can be read but not changed. The clear button is hidden.

No default
string

Hint shown while empty.

No default

Also accepts every prop of the Base UI Input (opens in a new tab).

Deviations from DGA

  • Figma's trailing icon variant (clear or voice) is a real clear button with a name, and returns focus to the field.
  • States follow Input: no outline, a centre-out underline, and lighter and darker without a border at rest.
ChangeReason
Search Box: clear buttonIcon-only controls need a name and a keyboard path.

View all 1 deviations for this component

Contrast

282 pairs checked · all pass WCAG 2.1 AAShow 47 states
Variant / stateLightDark
filled text18.09:1 AAA15.87:1 AAA
hovered text18.09:1 AAA15.87:1 AAA
focused text10.17:1 AAA12.04:1 AAA
pressed text9.24:1 AAA9.64:1 AAA
pressed placeholder6.69:1 AA5.06:1 AA
pressed prefix and suffix text9.24:1 AAA9.64:1 AAA
underline, focused and pressed18.74:1 3:116.80:1 3:1
placeholder4.77:1 AA6.32:1 AA
prefix and suffix text10.17:1 AAA12.04:1 AAA
icon4.77:1 3:19.38:1 3:1
border, default4.57:1 3:13.80:1 3:1
border, hovered9.73:1 3:112.04:1 3:1
border, focused and pressed17.93:1 3:116.80:1 3:1
underline, error4.62:1 3:14.65:1 3:1
border, error4.62:1 3:14.65:1 3:1
filled text (lighter)17.64:1 AAA14.42:1 AAA
hovered text (lighter)17.64:1 AAA14.42:1 AAA
focused text (lighter)10.17:1 AAA12.04:1 AAA
pressed text (lighter)9.24:1 AAA9.64:1 AAA
pressed placeholder (lighter)6.69:1 AA5.06:1 AA
pressed prefix and suffix text (lighter)9.24:1 AAA9.64:1 AAA
underline, focused and pressed (lighter)18.28:1 3:115.27:1 3:1
placeholder (lighter)4.65:1 AA5.75:1 AA
prefix and suffix text (lighter)9.92:1 AAA10.95:1 AAA
icon (lighter)4.65:1 3:18.52:1 3:1
border, hovered (lighter)9.73:1 3:112.04:1 3:1
border, focused and pressed (lighter)17.93:1 3:116.80:1 3:1
underline, error (lighter)4.62:1 3:14.65:1 3:1
border, error (lighter)4.62:1 3:14.65:1 3:1
filled text (darker)16.44:1 AAA17.04:1 AAA
hovered text (darker)16.44:1 AAA17.04:1 AAA
focused text (darker)10.17:1 AAA12.04:1 AAA
pressed text (darker)9.24:1 AAA9.64:1 AAA
pressed placeholder (darker)6.69:1 AA5.06:1 AA
pressed prefix and suffix text (darker)9.24:1 AAA9.64:1 AAA
underline, focused and pressed (darker)17.03:1 3:118.03:1 3:1
placeholder (darker)6.69:1 AA6.79:1 AA
prefix and suffix text (darker)9.24:1 AAA12.93:1 AAA
icon (darker)4.34:1 3:110.07:1 3:1
border, hovered (darker)9.73:1 3:112.04:1 3:1
border, focused and pressed (darker)17.93:1 3:116.80:1 3:1
underline, error (darker)4.62:1 3:14.65:1 3:1
border, error (darker)4.62:1 3:14.65:1 3:1
border, hover and focus (lighter and darker)4.57:1 3:13.80:1 3:1
read-only text18.09:1 AAA15.87:1 AAA
clear button icon4.77:1 3:19.38:1 3:1
clear button icon, hovered16.44:1 3:112.71:1 3:1

Text needs 4.5:1, icons and focus rings 3:1. Disabled states are exempt. Full contrast report