Raft 设计系统

组件 · 消息

MessageAttachment

Files, images and video attached to a message — a file is a card with its name, size and an action; images and video show inline.

稳定也叫 Attachment, File card
import { MessageAttachment } from "@botiverse/raft-ui";
本页尚未翻译
译文完成之前,这里显示英文原文。 阅读英文版

What is attached to a message. A file is a card: its name, its size and one or two actions such as Download. Images show inline in a gallery, and a video shows in a player. Attachments sit under the message body, in MessageItemAttachments (MessageItem).

message-attachment/compositions/message-attachments-showcase

When to use

SituationUse
A file attached to a sent messageMessageAttachmentCard, in a MessageAttachmentGroup
Images attached to a messageMessageImageGallery
A video attached to a messageMessageVideoPreview
A file waiting to be sentA thumbnail in the Composer
A file's type, as an iconFilePreview
A link to a page, a forwarded messageA link card (Built from existing parts)

Anatomy

A file card:

  • MessageAttachmentGroup: holds the cards, at most 360px wide.
  • MessageAttachmentCard: one file. Required.
  • MessageAttachmentTitle: the file name. It can start with the file's type icon. Required.
  • MessageAttachmentSummary: an optional line about the contents, with MessageAttachmentCommentSummary for a comment count or MessageAttachmentDiffSummary, MessageAttachmentDiffAddition and MessageAttachmentDiffDeletion for changed lines.
  • MessageAttachmentMeta: the bottom line, with MessageAttachmentMetaStart (size and type) and MessageAttachmentMetaEnd (actions).
  • MessageAttachmentAction: an icon button, such as Download or Preview.

Images: MessageImageGallery, its rows (MessageImageGalleryRow, laid out by buildMessageImageGalleryRows), and in each MessageImageGalleryItem the MessageImageGalleryMedia, a MessageImageGalleryPreview button that opens the image, an optional MessageImageGalleryAction and a MessageImageGalleryOverlay while it is pending.

Video: MessageVideoPreview, with MessageVideoPreviewMedia, MessageVideoPreviewAction, MessageVideoPreviewFallback and the MessageVideoPreviewFailure* parts.

Variants

VariantUse for
DownloadA file people save
PreviewA file that opens in Raft, such as HTML or audio
With a summaryA document with comments, or a diff with its changed lines
With a type iconA file whose type the name doesn't make clear
message-attachment/compositions/file-attachments
message-attachment/compositions/document-summaries
message-attachment/compositions/diff-attachment
ImagesLayout
1Keeps its own proportions
2 or moreRows laid out from the images' shapes
message-media/compositions/image-gallery-single
message-media/compositions/image-gallery-pair
message-media/compositions/image-gallery-triple

States

StateLook
UploadingThe meta line says "Uploading · 64%", and a 4px progress track runs under the file name, inside the card and aligned with the text (Shape)
Opening or processingaria-busy on the card, and a Spinner in place of the action
Pending imageThe image dimmed under MessageImageGalleryOverlay
FailedA danger-strong border, a line that says why, and Remove or Retry
message-attachment/compositions/attachment-statuses
message-media/compositions/image-gallery-pending
message-media/compositions/video-states

Behavior

  • The whole card is clickable: the file name is the link, and it covers the card. The action buttons sit above it and work on their own.
  • The card is read, so it hovers with the subtle tier, like a file row or a comment card, and presses with the medium tier; its action buttons hover medium (Hover and press).
  • Selecting an image or a file opens it in the file viewer (Built from existing parts).
  • The gallery's action button shows on hover and on keyboard focus.
  • An action in a card's or a medium's corner (a file card's Download, a video's or an image's action) is a control embedded in its frame: it sits 6px from the corner and wears radius-chip (Shape).

Content

  • Show the file name as it is, on one line, truncated when it doesn't fit.
  • Write the size and type in Space Mono: "2.4 MB · PDF".
  • In a failure, say why and give the limit: "Larger than 25 MB. Remove it, or compress it and try again." Label the buttons Remove and Retry.
  • Say what is happening while a file is busy, such as "Uploading · 64%"; don't write "Processing…" (Writing).

Accessibility

  • Don't put a button inside the file name's <a>: lay the actions over the link instead, so each is its own control.
  • Give every MessageAttachmentAction an aria-label with the action and the file name: "Download release-notes.pdf".
  • Give the upload progress role="progressbar", labeled with the file it uploads.
  • Set aria-busy on a card while it uploads or opens.
  • Give every image an alt that says what it shows. Give MessageImageGalleryPreview an aria-label, such as "Open onboarding-step-2.png".

Rules

  • Keep a file card at most 360px wide.
  • Show images at most 360px wide, with radius-container and a line-hairline border.

API

MessageAttachmentAction, MessageAttachmentCard, MessageAttachmentCommentSummary, MessageAttachmentDiffAddition, MessageAttachmentDiffDeletion, MessageAttachmentDiffSummary, MessageAttachmentGroup, MessageAttachmentMeta, MessageAttachmentMetaEnd, MessageAttachmentMetaStart, MessageAttachmentSummary, MessageAttachmentTitle, MessageImageGallery, MessageImageGalleryAction

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

MessageImageGalleryItem

Prop类型默认值
layoutThe item's layout from `buildMessageImageGalleryRows`: sets the cell sizing and how the media fills it, so consumers never restate classes.MessageImageGalleryItemLayout
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

MessageImageGalleryMedia, MessageImageGalleryOverlay, MessageImageGalleryPreview

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

MessageImageGalleryRow

One row of a gallery: the grid and its height come from the row data, so consumers place the items (`MessageImageGalleryItem` with the row's item layouts) without touching layout classes.
Prop类型默认值
row (required)A row from `buildMessageImageGalleryRows`.MessageImageGalleryRowData
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

MessageVideoPreview, MessageVideoPreviewAction, MessageVideoPreviewFallback, MessageVideoPreviewFailureAction, MessageVideoPreviewFailureContent, MessageVideoPreviewFailureIcon, MessageVideoPreviewFailureTitle, MessageVideoPreviewMedia

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.