# Input UI

The Input UI component consumes [`MessageComposerContext`](/chat/docs/sdk/react/v14/components/message-composer/message-composer-context/) and renders the visible composer. The default implementation is [`MessageComposerUI`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageComposer/MessageComposerUI.tsx).

## Best Practices

- Start from the exported building blocks before replacing the whole composer.
- Scope `WithComponents` around a specific composer subtree when only one layout should differ.
- Use `WithComponents` for shared subcomponent overrides.
- Keep the preview stack and textarea together so autocomplete, uploads, and recording state remain coherent.
- If you want the default slash-command UX, keep `CommandChip` next to `TextareaComposer` and hide attachment or extra-action controls while a command is selected.
- Reuse the default `str-chat__message-composer*` classes if you want to keep the built-in styling.

## Basic Usage

Use `WithComponents` and the `MessageComposerUI` override key to replace the whole composer UI for a specific subtree.

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

const CustomInput = () => <div className="custom-input-shell">...</div>;

const App = () => (
  <Channel>
    <Window>
      <ChannelHeader />
      <MessageList />
      <WithComponents overrides={{ MessageComposerUI: CustomInput }}>
        <MessageComposer />
      </WithComponents>
    </Window>
    <Thread />
  </Channel>
);
```

## UI Customization

`MessageComposerUI` is a good reference for a custom composer. In v14 the default structure is:

- `AttachmentSelector`
- preview stack:
  - `EditedMessagePreview` or `QuotedMessagePreview`
  - `VoiceRecordingPreviewSlot`
  - `AttachmentPreviewList`
  - `LinkPreviewList`
- text and action controls:
  - `CommandChip`
  - `TextareaComposer`
  - `SendToChannelCheckbox`
  - `AdditionalMessageComposerActions`
  - `MessageComposerActions`

A simplified custom input can keep the same composition model:

```tsx
import {
  AttachmentPreviewList,
  AttachmentSelector,
  LinkPreviewList,
  MessageComposerActions,
  MessageComposer,
  QuotedMessagePreview,
  SendToChannelCheckbox,
  TextareaComposer,
  VoiceRecordingPreviewSlot,
  WithDragAndDropUpload,
} from "stream-chat-react";

const CustomInput = () => (
  <WithDragAndDropUpload
    className="str-chat__message-composer-container"
    component="div"
  >
    <div className="str-chat__message-composer">
      <AttachmentSelector />
      <div className="str-chat__message-composer-compose-area">
        <div className="str-chat__message-composer-previews">
          <QuotedMessagePreview />
          <VoiceRecordingPreviewSlot />
          <AttachmentPreviewList />
          <LinkPreviewList />
        </div>
        <div className="str-chat__message-composer-controls">
          <TextareaComposer />
          <SendToChannelCheckbox />
          <MessageComposerActions />
        </div>
      </div>
    </div>
  </WithDragAndDropUpload>
);

const Composer = () => (
  <WithComponents overrides={{ MessageComposerUI: CustomInput }}>
    <MessageComposer />
  </WithComponents>
);
```

When a slash command is selected, the default `MessageComposerUI` adds `str-chat__message-composer--command-active`, keeps the selected command visible through `CommandChip`, and collapses both `AttachmentSelector` and `AdditionalMessageComposerActions`. Mirror that behavior in your own layout only if you want parity with the default composer.

For a shared override across the app, register the input UI with `WithComponents`:

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

const CustomInput = () => <div className="custom-input-shell">...</div>;

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

## Props

| Prop | Description                                                                                                                                                                                                              | Type |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---- |
| none | The Input UI component itself does not receive required props. It should read the composer state it needs from `useMessageComposerContext()`, `useMessageComposerController()`, and the exported message-composer hooks. | -    |


---

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

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