# Search

> A search field that expands into a list of suggestions or results.

- Category: Navigation
- API status: Expressive
- Compose APIs: `AppBarWithSearch`, `ExpandedDockedSearchBar`, `ExpandedFullScreenSearchBar`, `SearchBarDefaults.InputField`, `rememberSearchBarState`
- Interactive page: https://m3e.ljzapps.app/#components/search

## When to use

The app bar with search combines a search field with navigation icon and actions. When it expands, show suggestions or results either full screen or docked below the field.

Both variants share a SearchBarState and a TextFieldState, so the field, the expansion animation and the result list stay in sync.

## Examples

### Docked results

Focus the field and type.

```kotlin
val searchBarState = rememberSearchBarState()
val textFieldState = rememberTextFieldState()
val scope = rememberCoroutineScope()
val fruits = listOf("Apple", "Apricot", "Banana", "Blueberry", "Cherry", "Mango")
val results = fruits.filter { it.contains(textFieldState.text, ignoreCase = true) }

val inputField = @Composable {
    SearchBarDefaults.InputField(
        textFieldState = textFieldState,
        searchBarState = searchBarState,
        onSearch = { scope.launch { searchBarState.animateToCollapsed() } },
        placeholder = { Text("Search fruit") },
        leadingIcon = { Icon(Icons.Rounded.Search, contentDescription = null) },
        trailingIcon = {
            if (textFieldState.text.isNotEmpty()) {
                IconButton(onClick = { textFieldState.clearText() }) {
                    Icon(Icons.Rounded.Close, contentDescription = "Clear")
                }
            }
        },
    )
}

Box(Modifier.fillMaxWidth().height(320.dp), contentAlignment = Alignment.TopCenter) {
    AppBarWithSearch(
        state = searchBarState,
        inputField = inputField,
    )
    ExpandedDockedSearchBar(state = searchBarState, inputField = inputField) {
        results.forEach { fruit ->
            ListItem(
                headlineContent = { Text(fruit) },
                modifier = Modifier.fillMaxWidth(),
            )
        }
    }
}
```

## Parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `state` | `SearchBarState` |  | rememberSearchBarState(). Animates between Collapsed and Expanded. |
| `inputField` | `@Composable () -> Unit` |  | Usually SearchBarDefaults.InputField. |
| `navigationIcon / actions` | `@Composable` | `null` | AppBarWithSearch only. |
| `content` | `@Composable ColumnScope.() -> Unit` |  | Suggestions or results of the expanded bar. |

## Guidelines

Do:
- Show recent searches before the user types.
- Provide a clear button.

Don't:
- Do not start searching on every keystroke without debouncing.
- Do not hide the field behind an icon on large windows.

## Accessibility

- The input field is a text field with a search action on the keyboard.
- Announce the number of results when they change.
- Escape collapses the expanded search.

## Related components

- [Top app bar](https://m3e.ljzapps.app/docs/components/top-app-bar.md)
- [Chips](https://m3e.ljzapps.app/docs/components/chips.md)
- [List](https://m3e.ljzapps.app/docs/components/list.md)
