# Input UI

The input UI is the component `MessageComposer` renders inside [`MessageComposerContext`](https://getstream.io/chat/docs/sdk/react/component-reference/message-composer/messagecomposercontext/): the whole visible composer. The default is `<MessageComposerUI/>`, and you replace it with the `MessageComposerUI` override key. [Message composer UI](https://getstream.io/chat/docs/sdk/react/ui/components/message-composer-ui/) explains its parts and what each one reads.

## Best practices

- Replace one part before you replace the whole layout. Each part has its own override key; see [Composer UI components](https://getstream.io/chat/docs/sdk/react/component-reference/message-composer/composer-ui-components/).
- Build a custom layout from the exported parts. They read the composer themselves, so suggestions, uploads and commands keep working.
- Scope `WithComponents` around one `MessageComposer` when only that composer should look different.
- Keep the `str-chat__message-composer*` class names if you want the default styling.

## Basic usage

Register your layout as `MessageComposerUI`. `MessageComposer` still provides the composer and the context:

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

const CompactComposerUI = () => {
  const submit = useMessageComposerSubmitFn();

  return (
    <div className="compact-composer">
      <TextareaComposer />
      <SendButton sendMessage={submit} />
    </div>
  );
};

const overrides = { MessageComposerUI: CompactComposerUI };

export const ChannelWithCompactComposer = () => (
  <Channel channel={channel}>
    <MessageList />
    <WithComponents overrides={overrides}>
      <MessageComposer />
    </WithComponents>
  </Channel>
);
```

The send button and the Enter key both submit through `useMessageComposerSubmitFn()`: `MessageComposer.update()` while a message is being edited, `MessageComposer.send()` otherwise.

## UI customization

The default `<MessageComposerUI/>` renders, in order:

1. `<WithDragAndDropUpload/>` around everything, so files dropped on the composer are uploaded into it.
2. While a voice recording is in progress, `<AudioRecorder/>` in place of all the rest.
3. `<AttachmentSelector/>`. While the composer edits a message (it renders inside that message's `MessageContext`), `<SimpleAttachmentSelector/>` instead: a plain upload button, shown under the same rule as the attachment selector's File action. [Attachment Selector](https://getstream.io/chat/docs/sdk/react/component-reference/message-composer/attachment-selector/#default-behavior) explains the File action and `<SimpleAttachmentSelector/>`.
4. `<MessageComposerPreviews/>`: the previews of what the message will carry, from its preview set. [Previews](https://getstream.io/chat/docs/sdk/react/ui/components/message-composer-ui/#previews) lists the default set and how to change it.
5. The controls:
   - `<CommandChip/>`, while a command is selected;
   - `TextareaComposer`;
   - `SendToChannelCheckbox`, in a thread;
   - `<AdditionalMessageComposerActions/>`, which holds the `EmojiPicker` override;
   - `<MessageComposerActions/>`: the first that applies of the stop button for an AI reply, the cooldown timer, the record button and the send button.

Every part except `WithDragAndDropUpload` and `MessageComposerActions` is read from an override key, so a replacement registered with `WithComponents` shows in the default layout too.

A custom layout can keep the same structure. This one leaves out the command chip, the also-send-to-channel checkbox and the emoji picker:

```tsx
import {
  AttachmentSelector,
  AudioRecorder,
  MessageComposer,
  MessageComposerActions,
  MessageComposerPreviews,
  TextareaComposer,
  useMessageComposerContext,
  WithComponents,
  WithDragAndDropUpload,
} from "stream-chat-react";

const CustomComposerUI = () => {
  const { recordingController } = useMessageComposerContext();

  return (
    <WithDragAndDropUpload
      className="str-chat__message-composer-container"
      component="div"
    >
      <div className="str-chat__message-composer">
        {recordingController.recordingState ? (
          <AudioRecorder />
        ) : (
          <>
            <AttachmentSelector />
            <div className="str-chat__message-composer-compose-area">
              <MessageComposerPreviews />
              <div className="str-chat__message-composer-controls">
                <TextareaComposer />
                <MessageComposerActions />
              </div>
            </div>
          </>
        )}
      </div>
    </WithDragAndDropUpload>
  );
};

const overrides = { MessageComposerUI: CustomComposerUI };

export const ComposerWithCustomLayout = () => (
  <WithComponents overrides={overrides}>
    <MessageComposer audioRecordingEnabled />
  </WithComponents>
);
```

Without the command chip, an active command shows nowhere: the composer takes the command's name out of the text, and sends it in front of the text. To keep the command in the text instead, remove the command middlewares, as [A UI without a command chip](https://getstream.io/chat/docs/sdk/react/state/writing-messages/commands/#a-ui-without-a-command-chip) shows.

`SendToChannelCheckbox` and `StopAIGenerationButton` aren't exported, so a custom layout can't render their defaults. `MessageComposerActions` still renders the default stop button. When a command is selected, the default layout also adds the `str-chat__message-composer--command-active` class; see [Command-state behavior](https://getstream.io/chat/docs/sdk/react/component-reference/message-composer/composer-ui-components/#command-state-behavior).

The [Custom composer recipe](https://getstream.io/chat/docs/sdk/react/ui-cookbooks/composer/custom-composer/) builds a complete layout.

## Props

The input UI receives no props. It reads what it needs from:

- `useMessageComposerContext()`: the `MessageComposer` props, the textarea ref and the recorder;
- `useMessageComposerController()`: the composer and its stores;
- the [composer hooks](https://getstream.io/chat/docs/sdk/react/reference/hooks/composer-hooks/), such as `useMessageComposerSubmitFn()` and `useAttachmentManagerState()`.

---

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