← All proposals

Chat Attachment

Net-new component: one attached item for chat.

Net-new componentOpen in Storybook

proposals/ChatAttachment/context.md33 lines · View on GitHub

Chat Attachment

Problem

ChatInput has a fieldHeader slot for attached files, but nothing to put in it. The first version was a story-only chip, which does not cover the design: three looks (generic file, image thumbnail, image without a preview), a remove button on hover, and long file names that must stay one size.

Proposal

Net-new component: one attached item for chat. PDS has FileUpload (a drop zone), which is a different thing. The item is built from existing parts: Icon, IconButton (remove) and Tooltip (full file name).

  • File (fileType='file'): fixed width chip with a file icon and the name. A long name is shortened in the middle so the extension stays visible, and wraps over two lines. The full name shows in a tooltip.
  • Error (status='error'): critical colors, an exclamation icon and the reason (errorMessage) in the tooltip and for screen readers.
  • Image (fileType='image'): a square thumbnail from previewUrl; without one, a grey square with an image icon.
  • Remove: a round button on the top corner, shown on hover, on keyboard focus, and always on touch screens. Only rendered when onRemove is passed.

It sits in ChatInput's fieldHeader slot, but does not depend on it.

Source

Designer's Figma frame "ChatFileUpload" (six states: file, image and image without preview, each with and without the remove button) and a hover screenshot of the full-name tooltip. The designer later built the Figma page by hand as a component set (FileType Image/Doc, State Default/Hover/Error); see figma.json. The Figma name is ChatFileUpload, the code name is ChatAttachment.

Constraints

  • Tokens only; fixed sizes come from spacing tokens.
  • Remove must work by keyboard and on touch (no hover).
  • The full file name must reach screen readers even though the visible text is shortened.
  • No content hardcoded: file name, remove label come from props.

Open questions

  • Does the grey image square mean "no preview" or "still loading"? Built as "no preview".
  • Error state is built (status='error', first try). Upload progress (uploading) and retry are not built; see decisions.md.