# Custom Autocomplete Suggestion List

Autocomplete suggestion list components can be customized via `Channel` props:

- [`AutoCompleteSuggestionHeader`](/chat/docs/sdk/react-native/v8/core-components/channel#autocompletesuggestionheader/)
- [`AutoCompleteSuggestionItem`](/chat/docs/sdk/react-native/v8/core-components/channel#autocompletesuggestionitem/)
- [`AutoCompleteSuggestionList`](/chat/docs/sdk/react-native/v8/core-components/channel#autocompletesuggestionlist/)

## Best Practices

- Preserve default components for triggers you don't customize to keep expected behavior.
- Keep list rendering lightweight; suggestion updates happen on every keystroke.
- Use `keyboardShouldPersistTaps="always"` in custom lists to avoid dismissing the keyboard.
- Normalize `triggerType` mapping (`/`, `:`, `@`) to avoid mismatched UI.
- Ensure `onSelect` updates the composer state rather than mutating input directly.

Header and item components are used inside the list's `FlatList`. These props let you customize the header, items, or the entire list.

The available suggestion trigger types are:

- `command` for `/`
- `emoji` for `:`
- `mention` for `@`

You can render custom UI for specific triggers and fall back to defaults for the rest.

### Customizing Header component

The header renders at the top of the list and is customized via `AutoCompleteSuggestionHeader`.

The props for the component are:

- `triggerType`: The trigger type of the suggestion list.
- `queryText`: The value to display in the header.

An example for the same would be as follows:

```tsx
import { AutoCompleteSuggestionHeader } from "stream-chat-react-native";
import { Text } from "react-native";

<Channel
  AutoCompleteSuggestionHeader={({ queryText, triggerType }) => {
    if (triggerType === "command") {
      return <Text>Command Header Component</Text>;
    } else if (triggerType === "emoji") {
      return <Text>Emoji Header Component</Text>;
    } else {
      return (
        <AutoCompleteSuggestionHeader
          queryText={queryText}
          triggerType={triggerType}
        />
      );
    }
  }}
>
  {/* The underlying components */}
</Channel>;
```

Note: Return the default `AutoCompleteSuggestionHeader` to keep default behavior for a trigger.

### Customizing Item Component

Customize list items via the `AutoCompleteSuggestionItem` prop on `Channel`.

The props for the component are as follows:

- `triggerType`: The trigger type of the suggestion list.
- `itemProps`: Varies by trigger. `command` has `name` and `args`, `emoji` is an `Emoji`, and `mention` is `SuggestionUser<Us>`.

```tsx
import { Avatar, AutoCompleteSuggestionItem } from "stream-chat-react-native";
import { Text, View } from "react-native";

<Channel
  AutoCompleteSuggestionItem={({ itemProps, triggerType }) => {
    if (triggerType === "command") {
      return (
        <View>
          <Text>{itemProps.name}</Text>
          <Text>{itemProps.args}</Text>
        </View>
      );
    } else if (triggerType === "mention") {
      const { id, image, name, online } = itemProps;
      return (
        <View>
          <Avatar image={image} name={name} online={online} size={30} />
          <Text>{itemProps.name}</Text>
        </View>
      );
    } else {
      return (
        <AutoCompleteSuggestionItem
          itemProps={itemProps}
          triggerType={triggerType}
        />
      );
    }
  }}
>
  {/*The underlying components*/}
</Channel>;
```

Note: Return the default `AutoCompleteSuggestionItem` to keep default behavior for a trigger.

### Customizing the AutoComplete suggestion list

You can also replace the entire list via `AutoCompleteSuggestionList` on `Channel`.

The props available to the component are:

- `AutoCompleteSuggestionHeader` - The header component to be used in the list.
- `AutoCompleteSuggestionItem` - The item component to be used in the list.

Example:

```tsx
import {
  AutoCompleteSuggestionHeader,
  AutoCompleteSuggestionItem,
  useMessageComposer,
  useStateStore,
  Channel,
} from "stream-chat-react-native";
import { FlatList, Text, View } from "react-native";
import { TextComposerState, SearchSourceState } from "stream-chat";

const textComposerStateSelector = (state: TextComposerState) => ({
  suggestions: state.suggestions,
  text: state.text,
});

const searchSourceStateSelector = (nextValue: SearchSourceState) => ({
  items: nextValue.items,
});

const CustomAutoCompleteSuggestionList = () => {
  const messageComposer = useMessageComposer();
  const { textComposer } = messageComposer;
  const { suggestions } = useStateStore(
    textComposer.state,
    textComposerStateSelector,
  );
  const { items } =
    useStateStore(suggestions?.searchSource.state, searchSourceStateSelector) ??
    {};
  const trigger = suggestions?.trigger;
  const queryText = suggestions?.query;

  const triggerType = {
    "/": "command",
    ":": "emoji",
    "@": "mention",
  }[trigger ?? ""];

  const onSelect = (item) => {
    // Handle the selection of the item
    console.log("Selected item:", item);
  };

  if (triggerType === "command") {
    return (
      <View>
        <View>
          <Text>Command suggestions for {queryText}</Text>
        </View>
        {data.map((item) => (
          <AutoCompleteSuggestionItem
            itemProps={item}
            key={item.name}
            triggerType={triggerType}
          />
        ))}
      </View>
    );
  } else if (triggerType === "emoji") {
    return (
      <FlatList
        data={data}
        keyboardShouldPersistTaps="always"
        ListHeaderComponent={
          <AutoCompleteSuggestionHeader
            queryText={queryText}
            triggerType={triggerType}
          />
        }
        renderItem={({ index, item }) => (
          <TouchableOpacity
            onPress={() => {
              onSelect(item);
            }}
          >
            <Text>{item.unicode}</Text>
          </TouchableOpacity>
        )}
      />
    );
  } else {
    return (
      <View>
        <AutoCompleteSuggestionHeader
          queryText={queryText}
          triggerType={triggerType}
        />
        {data.map((item) => (
          <AutoCompleteSuggestionItem
            itemProps={item}
            key={item.name}
            triggerType={triggerType}
          />
        ))}
      </View>
    );
  }
};

<Channel AutoCompleteSuggestionList={CustomAutoCompleteSuggestionList}>
  {/*The underlying components*/}
</Channel>;
```

Note: Return the default `AutoCompleteSuggestionList` to keep default behavior for a trigger.


---

This page was last updated at 2026-04-17T17:33:45.246Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v8/guides/customize-autocomplete-suggestion-list/](https://getstream.io/chat/docs/sdk/react-native/v8/guides/customize-autocomplete-suggestion-list/).