Attachments

Pro

The files of an AI conversation. Queued in the composer from the picker, a paste or a drop; uploading with progress and a retry; shown on the message they went out with. Images read as their thumbnail, everything else as its icon, name and size.

Attach with the paperclip, paste a screenshot, or drop files on the box. Every fifth upload fails, to show the retry.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Activate your Pro license (once per machine)npx koalaui-cli@latest login <key># Add this component (its dependencies come along)npx koalaui-cli@latest add attachments

Usage#

useAttachments keeps the list; your upload reports back through update. The hook releases each image preview when its file is removed.

This example is part of Koala UI Pro

The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.

Have a license? Unlock it here

States#

Ready, uploading (a spinner, or the percent once progress is known) and failed, with a retry when you pass onRetry. Send stays off while anything uploads.

  • koala-q3-report.pdfPDF · 1.2 MB
  • koala-brand-kit.zip42%
  • CHANGELOG.mdNetwork error

In a message#

On a sent message the files are read-only: no onRemove. Give them onOpen to open a Lightbox or a File Preview, or an href. In a user turn they line up with the bubble.

Does the report match what the room photo shows for Q3 sales?

Inline#

variant="inline" sets the files as small chips: the files a reply read, a header over a long thread, a compact composer.

  • schema.sql
  • carved-vase.webp

API reference#

Attachments

The row of files: a list that wraps. Forwards native <ul> props.

PropTypeDefaultDescription
variant"default" | "inline""default"default shows images as tiles and files as cards with their type and size; inline is a line of small chips.

Attachment

One file. An image with a src reads as its thumbnail; anything else as its icon, name and size. Forwards native <li> props.

PropTypeDefaultDescription
name*string-The file name. Its extension chooses the icon and the label under the name.
sizenumber-In bytes, shown as 1.2 MB.
typestring-The MIME type, when the name alone does not tell an image.
srcstring-The thumbnail: an object URL while queued, the stored URL once sent.
status"ready" | "uploading" | "error""ready"Uploading shows a spinner or the percent; error tints the card and shows error.
progressnumber-Upload progress from 0 to 1, shown as a percent.
errorstring"Upload failed"What went wrong, in place of the size.
onRemove() => void-Shows a remove button, on hover and focus (always on touch). Leave it out on a sent message.
onRetry() => void-Shows a retry button on a failed upload.
onOpen() => void-Makes the attachment a button: open a lightbox or a preview.
hrefstring-Makes the attachment a link, opened in a new tab.

useAttachments

The composer's list: { items, add, update, remove, clear }. add(files) keeps the files that pass accept, maxSize and maxFiles, gives images an object URL, and returns the new items so you can start their uploads. onReject hears about the rest.

PromptInput

Two props make the composer take files.

PropTypeDefaultDescription
onFiles(files: File[]) => void-Pasted files, files dropped on the composer, and the ones PromptInputAttachButton picks arrive here.
hasAttachmentsbooleanfalseLets the composer send with no text, when files are attached.

PromptInputAttachButton

Opens the file picker. Takes accept and multiple (on by default); forwards Button props.

FAQ#

No. Attachments shows them and useAttachments keeps the list; the upload is yours (a presigned URL, your API, the AI SDK's files), reporting back through update with status and progress.