Info:
This is release candidate documentation for Stream Chat React SDK v15. For the latest stable version, see the latest version (v14).

WithDragAndDropUpload

WithDragAndDropUpload makes an area take dropped files and upload them to the composers inside it. The composer UI already wraps itself in one; wrap a larger area, such as a whole channel, to take drops there. Drop files on a larger area explains how it fits with uploads.

Best practices

  • Render it inside a Channel or a Thread. It reads the composer's upload settings from there, and throws outside both.
  • Wrap a channel and a thread separately. Files dropped on a wrapper go to every composer inside it, so a wrapper around both uploads each file twice.
  • Don't nest wrappers to add drop areas: only the outermost one takes drops. A wrapper inside another renders only its element, with its className but without its style.
  • Set the accepted file types in the composer configuration, attachments.acceptedFiles. The acceptedFiles prop has no effect.
  • To change the "Drag your files here" overlay, style .str-chat__dropzone-container, or translate messageComposer.dragDropUpload.dragFiles.text and messageComposer.dragDropUpload.someFilesNotAccepted.text. The FileDragAndDropContent override key has no effect: the wrapper renders FileDragAndDropContent directly.

Basic usage

import type {
  Channel as StreamChannel,
  Thread as StreamThread,
} from "stream-chat";
import {
  Channel,
  ChannelHeader,
  MessageComposer,
  MessageList,
  Thread,
  ThreadHeader,
  WithDragAndDropUpload,
} from "stream-chat-react";

export const ChannelAndThread = ({
  channel,
  thread,
}: {
  channel: StreamChannel;
  thread?: StreamThread;
}) => (
  <>
    <Channel channel={channel}>
      <WithDragAndDropUpload className="channel-drop-zone" component="section">
        <ChannelHeader />
        <MessageList />
        <MessageComposer />
      </WithDragAndDropUpload>
    </Channel>
    {thread && (
      <Thread thread={thread}>
        <WithDragAndDropUpload className="thread-drop-zone" component="section">
          <ThreadHeader />
          <MessageList />
          <MessageComposer />
        </WithDragAndDropUpload>
      </Thread>
    )}
  </>
);

A file dropped anywhere in the channel's section goes to the channel's composer, and one dropped in the thread's goes to the thread's. The composer's own wrapper sits inside each, so it renders only its element.

The wrapper renders its element with the class str-chat__dropzone-root, which the SDK's stylesheet gives position: relative and flex: 1. Directly inside Channel, it becomes the channel's content column, a flex column. While files are dragged over it, it shows .str-chat__dropzone-container over its content: "Drag your files here", or "Some of the files will not be accepted" when a dragged file type isn't accepted.

It takes the file types from attachments.acceptedFiles of the composer around it, and takes several files at once when attachments.maxNumberOfFilesPerMessage is more than 1. Outside a composer, it takes drops even while uploads aren't allowed; each composer's AttachmentManager.uploadFiles() then applies the limits. The composer's own wrapper turns off during a slow-mode cooldown and when the user can't upload.

Props

Prop Type Default Description
children ReactNode The area that takes drops.
className string Added to the element, next to str-chat__dropzone-root.
component React.ElementType "div" The element to render.
style React.CSSProperties Inline styles for the element. A wrapper inside another doesn't apply them.
acceptedFiles string[] No effect. The accepted types come from the composer configuration, attachments.acceptedFiles.

FileDragAndDropContent, the overlay's content, is exported too. It takes one prop, isDragRejected: boolean, which shows the "not accepted" text.