SearchBar
Mobile search field.
Installation
npx axiom add search-barpnpm dlx axiom add search-baryarn dlx axiom add search-barbun x axiom add search-barAlso copies: icon, spinner, text, tappable and useControllableState.
Requires the search and close icons in your icon registry. Colors come from searchBar.{filled,outline}.{default,focused,disabled} in the component tokens.
Usage
import { SearchBar } from "@/components/ui/search-bar";
<SearchBar value={query} onChangeText={setQuery} />;The bar is the field alone: icon, text, clear button and loading state. An iOS-style Cancel that slides in next to the field is part of SearchAppBar, with its onCancel prop.
Props
SearchBar forwards TextInput props (autoFocus, returnKeyType, onSubmitEditing…) and adds:
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The query. |
onChangeText | (text: string) => void | — | Called on every keystroke. Debounce your request, not this callback. |
onSubmit | (text: string) => void | — | Called when the user presses the search key on the keyboard. |
placeholder | string | 'Search' | Hint in the empty field. Say what is searched: “Search messages”. |
clearable | boolean | true | Shows a clear button when the field has text. |
loading | boolean | false | Replaces the search icon with a spinner while results load. |
trailing | ReactNode | — | Extra content inside the field on the right, like a microphone or a filter button. Hidden while there is text. |
variant | 'filled' | 'outline' | 'filled' | filled is the iOS gray field, outline has a border for light surfaces. |
size | 'sm' | 'md' | 'sm' | Height from the input size tokens: 50 or 56pt. |
disabled | boolean | false | Greys the bar and stops every interaction. |
containerStyle | StyleProp<ViewStyle> | — | The box around the icon, the text and the buttons. style goes to the TextInput. |
ref | Ref<TextInput> | — | focus(), blur(), clear(). |
SearchBar in an AppBar
Put the bar in AppBar.Center, in place of the title, between the navigation and the actions. SearchAppBar wraps that layout.
Use cases
Search in the app bar
The field replaces the title, so the screen keeps its navigation and an avatar or action at the end.
<AppBar>
<AppBar.Row>
<IconButton icon="arrow-left" accessibilityLabel="Back" onPress={goBack} />
<AppBar.Center>
<SearchBar
placeholder="Search"
value={query}
onChangeText={setQuery}
trailing={
<IconButton
icon="mic"
size="sm"
accessibilityLabel="Dictate"
onPress={dictate}
/>
}
/>
</AppBar.Center>
<Avatar name="Ada Lovelace" size="sm" />
</AppBar.Row>
</AppBar>Live results while typing
loading while the debounced request runs. Matches are highlighted in the results.
const [query, setQuery] = useState("");
const debounced = useDebouncedValue(query, 250);
const results = useQuery({
queryKey: ["search", debounced],
queryFn: () => search(debounced),
enabled: !!debounced,
});
<SearchBar
autoFocus
value={query}
onChangeText={setQuery}
loading={results.isFetching}
/>;Filtering a local list
No Cancel, an outline bar at the top of a sheet that filters the options below.
<SearchBar variant="outline" placeholder="Search countries" value={filter} onChangeText={setFilter} />
<BottomSheet.FlatList data={countries.filter(matches(filter))} renderItem={renderCountry} />Related
- Search experience, for history, debounce and no-results handling
- Input
- AppBar