Search Input
FreeA specialised input for search queries with a leading magnifying glass icon and a trailing clear button. Supports instant search (on keystroke) and submit-on-enter patterns. Uses role="search" for landmark navigation.
8 variants
Variants
| Variant | Description | When to use |
|---|---|---|
| Default | Search input with magnifying glass icon and placeholder text. | Use for filtering lists, tables, or initiating site-wide search. |
| With Suggestions | ||
| Inline |
Usage Guidelines
Do
Wrap in a <form> with role="search" for screen reader landmark navigation.
Don't
Omit the magnifying glass icon — it is the universal signifier for search.
Do
Show the clear button only when the input has a value.
Don't
Auto-submit on every keystroke without debouncing.
Do
Provide a visible label or aria-label describing what is being searched.
Don't
Use a generic Input when search-specific affordances are needed.
Do
Debounce instant search to avoid excessive API calls.
Don't
Code
HTML
<form role="search" class="lex-search">
<label for="site-search" class="lex-sr-only">Search</label>
<div class="lex-search__wrapper">
<svg class="lex-search__icon" width="16" height="16" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg>
<input
id="site-search"
class="lex-input lex-search__input"
type="search"
placeholder="Search..."
aria-label="Search"
/>
<button
type="button"
class="lex-search__clear"
aria-label="Clear search"
hidden
>
<svg width="16" height="16" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" />
</svg>
</button>
</div>
</form>CSS Custom Properties
.lex-search__wrapper {
position: relative;
display: flex;
align-items: center;
}
.lex-search__icon {
position: absolute;
left: var(--lex-input-padding, 12px);
color: var(--lex-input-placeholder);
pointer-events: none;
}
.lex-search__input {
padding-left: calc(var(--lex-input-padding, 12px) + 24px);
padding-right: calc(var(--lex-input-padding, 12px) + 28px);
}
.lex-search__input::-webkit-search-cancel-button {
display: none;
}
.lex-search__clear {
position: absolute;
right: var(--lex-input-padding, 12px);
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border: none;
background: transparent;
color: var(--lex-input-placeholder);
cursor: pointer;
border-radius: var(--lex-radius-sm);
transition: color 150ms ease;
}
.lex-search__clear:hover {
color: var(--lex-input-text);
}React
// Using Lexicon CSS classes with React
export function SiteSearch() {
const [query, setQuery] = useState('');
return (
<SearchInput
placeholder="Search..."
value={query}
onChange={setQuery}
onClear={() => setQuery('')}
aria-label="Search"
/>
);
}
export function FilterSearch({ onFilter }: { onFilter: (q: string) => void }) {
return (
<SearchInput
placeholder="Filter items..."
onChange={(value) => onFilter(value)}
debounce={300}
/>
);
}Design Tokens
| Token | Value (dark) | Value (light) | CSS property |
|---|---|---|---|
| --lex-input-bg | — | — | bg |
| --lex-input-border | — | — | border |
| --lex-input-radius | — | — | radius |
| --lex-search-icon-color | — | — | color |
Accessibility
- Wrap in a <form> or <div> with role="search" for landmark navigation.
- Use type="search" on the input for semantic correctness.
- Provide aria-label="Search" or a visible label for screen readers.
- Clear button must have aria-label="Clear search" and be hidden when the field is empty.
- Escape key should clear the input and optionally close search results.