# Attachment Selector

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

`AttachmentSelector` is the button before the composer's input. It opens a menu to upload a file, create a poll, share a location or pick a command. The menu is an action set: a list of actions, each with a type and a component. [Attachments and uploads](https://getstream.io/chat/docs/sdk/react/v15/features/rich-content/attachments-and-uploads/) explains uploads, and [Actions](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/actions/#attachment-selector-actions) explains the action set.

## Best practices

- Change the menu by passing your own `attachmentSelectorActionSet`, built from `defaultAttachmentSelectorActionSet`. Register the selector that renders it under the `AttachmentSelector` key.
- Decide who can upload, create polls and share locations on the server and in `client.config`. The selector shows only what the user can do, and that filter can't be turned off.
- Give a custom action a `type` of its own. The four built-in types are filtered, whatever component you give them.
- Set `getModalPortalDestination` when the selector renders outside a `Channel`, or when the channel's container clips its dialogs.

## Default behavior

The default menu has four actions, in this order:

| Type            | Label    | What it does                              | Shown when                                                                          |
| --------------- | -------- | ----------------------------------------- | ----------------------------------------------------------------------------------- |
| `uploadFile`    | File     | Opens the file picker                     | Uploads are allowed and the message has room for another file                       |
| `createPoll`    | Poll     | Opens the poll creation dialog            | Polls are turned on, the user has the `send-poll` capability, and it's not a thread |
| `addLocation`   | Location | Opens the location sharing dialog         | Location sharing is turned on, and it's not a thread                                |
| `selectCommand` | Commands | Opens a submenu of the channel's commands | The channel type has commands                                                       |

`AttachmentSelector` applies this filter itself, every time it renders, to the default set and to any set you pass. An action of any other type is always shown.

What the selector renders depends on what's left:

- **No actions:** nothing.
- **Only `uploadFile`:** `SimpleAttachmentSelector`, a button that opens the file picker directly. It renders only when the user has the `upload-file` capability, even when `attachments.customCdn` is `true`. So with a custom CDN and no `upload-file`, a user who can only upload sees no button at all.
- **Otherwise:** the button and its menu.

The button is disabled during a slow-mode cooldown. While a command is selected, it's hidden with a CSS transition and taken out of the tab order. Inside a message, as when a message is edited where it sits, the default layout renders `SimpleAttachmentSelector` in its place, which checks only the `upload-file` capability.

## Enabling features

Each action follows the settings below. [Configuration](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/configuration/#who-decides-what) explains how the server and `client.config` combine.

- **File:** `attachments.enabled` in the composer configuration, the channel type's `uploads` setting and the user's `upload-file` capability. With `attachments.customCdn: true`, only `attachments.enabled` counts. The action also disappears when the message holds `attachments.maxNumberOfFilesPerMessage` files. See [Attachments and uploads](https://getstream.io/chat/docs/sdk/react/v15/features/rich-content/attachments-and-uploads/#turning-it-on-or-off).
- **Poll:** `polls.enabled` in the composer configuration, the channel type's `polls` setting and the `send-poll` capability. See [Polls](https://getstream.io/chat/docs/sdk/react/v15/features/rich-content/polls/).
- **Location:** `location.enabled` in the composer configuration and the channel type's `shared_locations` setting. See [Location sharing](https://getstream.io/chat/docs/sdk/react/v15/features/rich-content/location-sharing/).
- **Commands:** the channel type's `commands`. See [Commands and Giphy](https://getstream.io/chat/docs/sdk/react/v15/features/rich-content/commands-and-giphy/).

## Custom action sets

`AttachmentSelector` props:

| Prop                          | Type                           | Default                              | Description                                                                                                          |
| ----------------------------- | ------------------------------ | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `attachmentSelectorActionSet` | `AttachmentSelectorAction[]`   | `defaultAttachmentSelectorActionSet` | The actions of the menu, top to bottom. The filter in [Default behavior](#default-behavior) still applies.           |
| `buttonProps`                 | `Omit<ButtonProps, "onClick">` | none                                 | Props for the button that opens the menu, or for the button of `SimpleAttachmentSelector`.                           |
| `getModalPortalDestination`   | `() => HTMLElement \| null`    | the `Channel` container              | The element the action dialogs render into. See [Custom modal portal destination](#custom-modal-portal-destination). |

An `AttachmentSelectorAction` has these fields:

| Field          | Type                                                                         | Description                                                                                                              |
| -------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `type`         | `"uploadFile" \| "createPoll" \| "addLocation" \| "selectCommand" \| string` | What the action is. Also the key passed to `openModalForAction`.                                                         |
| `ActionButton` | `ComponentType<AttachmentSelectorActionProps>`                               | The menu item. It gets `openModalForAction(type)`, and `submenuItems` and `submenuHeader` when the action has a submenu. |
| `ModalContent` | `ComponentType<AttachmentSelectorModalContentProps>`                         | What `openModalForAction(type)` opens in a modal. It gets `close`.                                                       |
| `Submenu`      | `ContextMenuSubmenu`                                                         | A submenu, as the commands action has.                                                                                   |
| `Header`       | `ContextMenuHeaderComponent`                                                 | The header of the submenu.                                                                                               |
| `id`           | `string`                                                                     | An identifier of your own. The selector doesn't read it.                                                                 |

A menu item closes the menu with `closeMenu()` from `useContextMenuContext()`. The default items are exported as `DefaultAttachmentSelectorComponents`: `File`, `Poll`, `Location` and `Command`.

This selector leaves out Location:

```tsx
import type { PropsWithChildren } from "react";
import {
  AttachmentSelector,
  defaultAttachmentSelectorActionSet,
  WithComponents,
} from "stream-chat-react";

const actionSet = defaultAttachmentSelectorActionSet.filter(
  ({ type }) => type !== "addLocation",
);

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

const overrides = { AttachmentSelector: AttachmentSelectorWithoutLocation };

export const WithoutLocationAction = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>{children}</WithComponents>
);
```

[Attachment selector actions](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/actions/#attachment-selector-actions) adds an action of its own, and the [Attachment actions recipe](https://getstream.io/chat/docs/sdk/react/v15/recipes/composer/attachment-actions/) builds one with a dialog.

## Poll and location dialogs

The `createPoll` and `addLocation` actions open the `PollCreationDialog` and `ShareLocationDialog` overrides, unless the action has a `ModalContent` of its own. Both dialogs get `close`. Opening the poll dialog starts a new poll in the composer's `pollComposer`.

```tsx
import type { PropsWithChildren } from "react";
import type { PollCreationDialogProps } from "stream-chat-react";
import { PollCreationDialog, WithComponents } from "stream-chat-react";

const PollDialogWithIntro = (props: PollCreationDialogProps) => (
  <div className="poll-dialog">
    <p>Polls close after a week.</p>
    <PollCreationDialog {...props} />
  </div>
);

const overrides = { PollCreationDialog: PollDialogWithIntro };

export const WithPollDialogIntro = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>{children}</WithComponents>
);
```

The dialogs' own props are on [Poll components](https://getstream.io/chat/docs/sdk/react/v15/component-reference/poll-components/) and [Location sharing](https://getstream.io/chat/docs/sdk/react/v15/features/rich-content/location-sharing/).

## Custom modal portal destination

The action dialogs render into the `Channel` container, the element with the `str-chat__channel` id. Outside a `Channel`, or when that container clips them, pass `getModalPortalDestination`:

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

const getModalPortalDestination = () =>
  document.getElementById("chat-modal-root");

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

Register it under the `AttachmentSelector` key. [Dialogs](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/dialogs/#modals) explains modals.

## `AttachmentSelectorContext`

The menu items of `AttachmentSelector` can read `AttachmentSelectorContext` with `useAttachmentSelectorContext()`:

| Value       | Type                       | Description                                                                                                                                        |
| ----------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fileInput` | `HTMLInputElement \| null` | The hidden file input of the selector. Call `fileInput.click()` to open the file picker. `null` until the input renders, and outside the selector. |

`SimpleAttachmentSelector` doesn't provide this context.

## Hooks

- [`useAttachmentManagerState`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/#useattachmentmanagerstate): whether uploads, polls and locations are turned on, and how many files still fit.
- [`useCanCreatePoll`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/#usecancreatepoll): whether the poll being composed can be sent.
- [`useMessageComposerCommands`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/#usemessagecomposercommands): the channel's commands, as the commands submenu shows them.
- [`useChannelCapabilities`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/channel-and-thread-hooks/#usechannelcapabilities): the user's capabilities, such as `upload-file` and `send-poll`.

---

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