Expanding search
An icon that morphs into a search field with results beneath it.
npm install https://animui.stracture.net/__local/package.tgzLive · keyboard ready
- Header or toolbar search where a full field would crowd the layout.
- Quick navigation across local items with grouped results and recent suggestions.
- Use search-field to filter a visible list in place.
- Use combobox to set a form value.
- Use command-palette for searching commands across the app.
Installation
Install animui once, then import any component or block from its typed package entry.
animui · 250 components and blocks
React 19 and React DOM 19 are required. The package includes Free and Pro entries, styles and TypeScript declarations.
npm install https://animui.stracture.net/__local/package.tgzLoad the stylesheet once at your app root, then use the typed component import:
import 'animui/styles.css';
import { ExpandingSearch } from 'animui/expanding-search';Read the Code tab for the implementation files and the API reference below for required props.
Download animui 0.3.0 · Agent guideexample.tsx
import { ExpandingSearch } from "animui/expanding-search"; export function HeaderSearch() { const router = useRouter(); return ( <ExpandingSearch label="Search projects and docs" items={[ { id: "p1", title: "animui website", group: "Projects", meta: "Updated today" }, { id: "d1", title: "Motion tokens", group: "Docs", keywords: ["spring"] }, ]} onSelect={(item) => router.push(`/items/${item.id}`)} /> );}ExpandingSearch
An icon button that morphs into a search field with grouped, highlighted results beneath it.
PropTypeDefaultDescription
labelRequiredstring–Names the button, field, and results, such as "Search projects and docs".itemsRequiredExpandingSearchItem[]–{ id, title, meta?, group?, icon?, keywords? }. Filtered client-side by title and keywords.suggestionsExpandingSearchItem[][]Shown before anything is typed, such as recent searches.suggestionsLabelstring"Recent"Heading for suggestions.placeholderstring–Field placeholder. Defaults to label.onSelect(item: ExpandingSearchItem) => void–Called when a result is chosen; the field then folds back.onExpandedChange(expanded: boolean) => void–Called when the field opens or folds.expandedWidthnumber360Widest the field grows, never past its container.maxResultsnumber6Most results shown.anchor"start" | "end""end"Edge the button sits on; the field grows away from it.emptyHintstring"Try a shorter word or check the spelling."Tip under the empty state.classNamestring–Added to the root.- EnterorSpace
- On the icon button, expands the field.
- ArrowDownorArrowUp
- Moves through results, wrapping.
- Enter
- Chooses the active result.
- Escape
- Folds the field back into the icon.
- The field is role="combobox" with aria-expanded, aria-controls, aria-autocomplete="list", and aria-activedescendant.
- Results are a role="listbox" of role="option" items inside labelled role="group" sections.
- Result counts and empty states are announced through a polite live region; the collapsed field is inert.
- The button morphs into the field on a spring, results unfold beneath with a panel that tracks the field width, and a highlight travels between options.
- Reduced motion swaps states with fades and no width or position travel.
- The field grows to the smaller of expandedWidth and its container, and a ResizeObserver follows container resizes.
- The results panel matches the field width and caps at min(22rem, 60vh), scrolling itself.
- The idle lane takes no pointer events, so it never blocks what sits under it on small screens.
- Ranking is memoized and runs over all items per query; pass pre-filtered or server results for large sets.
- Result rows use layout position animation, capped by maxResults at 6 by default.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use in headers and toolbars where a full field would crowd the layout. Use search-field to filter a list in place and combobox to set a form value.
- Place it in the space it may grow into; it fills that space up to expandedWidth. Filtering is local, so pass pre-fetched items or update items as the query changes.
- Exported as both named and default.
The full library index for assistants is at /llms.txt.