Expanding Navbar Search
A navbar search icon that expands into a full input on click and collapses when empty.
3 frameworksIntermediate
A large hero search field with a live combobox suggestion list driven by the keyboard.
<!--
The combobox pattern: the INPUT keeps focus and owns aria-activedescendant;
the popup is a separate role="listbox". Keyboard users drive the whole thing
from one control - focus never moves into the list. Shown here in its open
state; wiring the filtering/keyboard logic is the React/TS tab's job.
-->
<section class="mx-auto w-full max-w-xl px-4 py-8 text-center">
<h1 class="text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl dark:text-gray-100">Find anything</h1>
<div class="relative mt-5 text-left">
<label class="sr-only" for="hero-search">Find anything</label>
<svg class="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="9" cy="9" r="6" />
<path d="m14 14 3 3" stroke-linecap="round" />
</svg>
<input
id="hero-search"
type="text"
role="combobox"
aria-expanded="true"
aria-controls="hero-search-list"
aria-autocomplete="list"
aria-activedescendant="hero-opt-0"
autocomplete="off"
placeholder="Search…"
class="w-full rounded-xl border border-gray-300 bg-white py-3 pl-10 pr-3 text-sm text-gray-900 placeholder:text-gray-500 focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:border-gray-700 dark:bg-gray-950 dark:text-gray-100 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400"
/>
<ul id="hero-search-list" role="listbox" class="absolute z-10 mt-2 max-h-64 w-full overflow-auto rounded-xl border border-gray-200 bg-white py-1 text-left shadow-lg dark:border-gray-800 dark:bg-gray-900">
<li id="hero-opt-0" role="option" aria-selected="true" class="cursor-pointer px-4 py-2 text-sm bg-blue-600 text-white">Dashboard</li>
<li id="hero-opt-1" role="option" aria-selected="false" class="cursor-pointer px-4 py-2 text-sm text-gray-700 dark:text-gray-200">Billing settings</li>
<li id="hero-opt-2" role="option" aria-selected="false" class="cursor-pointer px-4 py-2 text-sm text-gray-700 dark:text-gray-200">API keys</li>
</ul>
</div>
</section>| Prop | Type | Default | Description |
|---|---|---|---|
suggestionsrequired | string[] | - | Suggestions |
heading | string | 'Find anything' | Heading |
placeholder | string | 'Search…' | Placeholder |
onSelect | (value: string) => void | - | Fired with the menu item the user chose. |
className | string | - | Additional classes merged onto the root element. |
The input keeps focus and owns `aria-activedescendant`; the popup is a separate `role="listbox"`, so Arrow/Enter/Escape all work without focus ever leaving the field. Pass your own `suggestions` pool - filtering is client-side and capped at six matches.