# Attachment Selector

Messages can include attachments, polls, location shares, and slash commands. `AttachmentSelector` renders the action button and the action menu for those composer features.

## Best Practices

- Keep the default action set unless your product needs extra tools or a different order.
- Configure permissions and channel-type features before exposing selector actions.
- Use `WithComponents` for shared selector overrides.
- Audit nested scroll containers and set a custom portal destination when modal placement needs it.
- If you rebuild the whole composer, decide whether command selection should hide the selector the same way `MessageComposerUI` does.
- Expect the selector to hide or remove actions that are not available in the current channel, thread, or runtime upload state.

## Default Behavior

The default selector can expose these actions:

- `uploadFile`
- `createPoll`
- `addLocation`
- `selectCommand`

The SDK filters them at runtime:

- file upload is removed when uploads are disabled or unavailable
- poll creation is removed in threads and when polls are disabled
- location sharing is removed in threads and when shared locations are disabled
- the commands submenu appears only when the channel type has commands

If the only available action is file upload, the SDK renders `SimpleAttachmentSelector` automatically.

The selector button is also disabled while slow-mode cooldown is active.

`MessageComposerUI` also hides the selector while a slash command is selected. That is composer-layout behavior rather than `AttachmentSelector` behavior, so custom input UIs can opt in or out.

## Enabling Features

The default action set depends on:

1. role permissions
2. channel-type configuration
3. runtime upload availability from the current composer

## Custom Action Sets

Customize the action menu with `attachmentSelectorActionSet` and register the selector through `WithComponents`.

```tsx
import {
  AttachmentSelector,
  Channel,
  MessageComposer,
  WithComponents,
  defaultAttachmentSelectorActionSet,
} from "stream-chat-react";
import type {
  AttachmentSelectorAction,
  AttachmentSelectorActionProps,
  AttachmentSelectorModalContentProps,
} from "stream-chat-react";

const AddEventAction = ({
  closeMenu,
  openModalForAction,
}: AttachmentSelectorActionProps) => (
  <button
    onClick={() => {
      openModalForAction("addEvent");
      closeMenu();
    }}
  >
    Event
  </button>
);

const AddEventModalContent = ({
  close,
}: AttachmentSelectorModalContentProps) => (
  <div>
    <button onClick={close}>Done</button>
  </div>
);

const attachmentSelectorActionSet: AttachmentSelectorAction[] = [
  {
    ActionButton: AddEventAction,
    ModalContent: AddEventModalContent,
    id: "event",
    type: "addEvent",
  },
  ...defaultAttachmentSelectorActionSet,
];

const CustomAttachmentSelector = () => (
  <AttachmentSelector
    attachmentSelectorActionSet={attachmentSelectorActionSet}
  />
);

const App = () => (
  <WithComponents overrides={{ AttachmentSelector: CustomAttachmentSelector }}>
    <Channel>
      <MessageComposer />
    </Channel>
  </WithComponents>
);
```

Each `AttachmentSelectorAction` can define:

| Field          | Purpose                                  |
| -------------- | ---------------------------------------- |
| `ActionButton` | menu item UI                             |
| `id`           | stable identifier for custom actions     |
| `ModalContent` | modal content rendered after selection   |
| `Header`       | submenu header component                 |
| `Submenu`      | submenu contents                         |
| `type`         | action type used by the selector runtime |

The built-in `selectCommand` action uses the submenu fields rather than modal content.

## Poll And Location Dialogs

The selector uses `PollCreationDialog` and `ShareLocationDialog` for its default modal actions. Both are shared overrides from `ComponentContext`, so customize them with `WithComponents`:

```tsx
import { Channel, MessageComposer, WithComponents } from "stream-chat-react";

const CustomPollCreationDialog = ({ close }) => (
  <div>
    <button onClick={close}>Close poll dialog</button>
  </div>
);

const CustomShareLocationDialog = ({ close }) => (
  <div>
    <button onClick={close}>Close location dialog</button>
  </div>
);

const App = () => (
  <WithComponents
    overrides={{
      PollCreationDialog: CustomPollCreationDialog,
      ShareLocationDialog: CustomShareLocationDialog,
    }}
  >
    <Channel>
      <MessageComposer />
    </Channel>
  </WithComponents>
);
```

## Custom Modal Portal Destination

By default, selector modals are portaled to the channel container. Use `getModalPortalDestination` when your layout needs a different portal root.

```tsx
import { AttachmentSelector } from "stream-chat-react";

const getModalPortalDestination = () =>
  document.querySelector<HTMLElement>("#my-modal-root");

const CustomAttachmentSelector = () => (
  <AttachmentSelector getModalPortalDestination={getModalPortalDestination} />
);
```

## `AttachmentSelectorContext`

Children rendered inside `AttachmentSelector` can access `AttachmentSelectorContext`.

| Value       | Description                                                                                          | Type                       |
| ----------- | ---------------------------------------------------------------------------------------------------- | -------------------------- |
| `fileInput` | Reference to the hidden file input used for uploads. It is `null` when file uploads are unavailable. | `HTMLInputElement \| null` |


---

This page was last updated at 2026-04-13T07:26:58.270Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v14/components/message-composer/attachment-selector/](https://getstream.io/chat/docs/sdk/react/v14/components/message-composer/attachment-selector/).