Attachments

A drop area for files that lists them as cards once they are added, for attaching files to a chat message.

Usage

When to reach for Attachments, where its files go, and what it leaves for you to wire up.

When to use

Attachments collects files to send with a message: a drop area while it is empty, then a row of file cards with a button to add more.
  • The reader attaches files to a chat message or a prompt, and sees them before sending.
  • The files are part of what the reader is writing, so they belong next to the input, usually inside a Sender.Header.
Use something else when
  • The upload is a form field, like an avatar or a document on a profile. Upload fits a form better and has its own list styles.
  • You only need to show files that were already sent. That is FileCard, with no add or remove buttons to hide.

Decide where a file goes

Pass beforeUpload, action or customRequest. With none of them, each picked file is posted to the URL of the page you are on, and the card turns red when that fails.
  • For a chat, return false from beforeUpload. The file stays in the browser, and you read it from items when the message is sent. Each item's originFileObj is the File.
  • To upload as soon as a file is picked, pass action or customRequest, and disable sending until every item's status is done.

Controlling the list

Pass items and set them from onChange, so you can clear the list after sending and read it when you need it.
  • Set your state to fileList in every onChange. With items set and no onChange, picking a file or clicking remove changes nothing on screen.
  • Give every item a unique uid. Removing a file looks items up by it.
  • The card text comes from the item. For a failed file, set response to a short reason like “Too large”, or the card says “error”. A description replaces both the reason and the progress percent.
  • Clear the list after sending by setting items to an empty array.

The empty area and dropping

While the list is empty, Attachments shows the placeholder as a drop area that also opens the picker on click. Once a file is added, the area is replaced by the cards.
  • Say what you accept in the description: the types, the size limit, the count. The reader cannot see accept.
  • The same placeholder shows while a file is dragged over. Pass a function to word the two differently: it gets "drop" for the drag overlay.
  • In a full-height chat, return document.body from getDropContainer, so a file dropped anywhere on the page is attached.

Inside a Sender

The usual home for Attachments is a Sender.Header, opened by a paperclip button in the Sender's prefix.
  • Control the header's open with your own state, and open it when a file is dropped or pasted so the reader sees what was attached.
  • For pasted files, use the Sender's onPasteFile and pass each file to ref.current.upload(file) on Attachments.
  • Empty items in the Sender's onSubmit, next to clearing the text.

A trigger of your own

Pass one element as children and Attachments renders only that element, which opens the picker, plus the drop overlay. There is no file list, so show the files yourself.
  • Use rootClassName with children. className is ignored in this form.
  • To open the picker from a button you cannot nest, like one in a toolbar, call ref.current.select() instead.

Limits and long lists

  • maxCount hides the add button once the list is full. Say the limit in the placeholder too, or the button vanishing reads as a bug.
  • accept limits the file types. It cannot limit the size, so check that in beforeUpload.
  • In a narrow input, set overflow to scrollX, so many files stay on one row with arrows instead of pushing the input down.
  • disabled keeps the files on screen without add or remove buttons, for a message that is being sent.

Restyling it

Reach for the semantic keys before a descendant selector: root, list, card, file, icon, name, description, placeholder and upload. A part with a key keeps its name across versions, and a part reached by class name may not.
  • The empty area and the drop overlay use a translucent, blurred fill. Change colorBgPlaceholderHover under components.Attachments to recolor it.