Attachments
Files a message carries — images shown as pictures, other files as their name and type — and the pending files in the composer before they are sent.
<aparte-chat-bubble message-id="u1" data-role="user" name="You" content="Can you check the cover and the brief?"></aparte-chat-bubble>
<script>
// An image shows its picture, any other file its name and type.
const canvas = Object.assign(document.createElement('canvas'), { width: 160, height: 100 });
const paint = canvas.getContext('2d');
paint.fillStyle = '#b07d33';
paint.fillRect(0, 0, 160, 100);
document.querySelector('aparte-chat-bubble').setAttachments([
{ id: 'f1', name: 'cover.png', type: 'image/png', url: canvas.toDataURL('image/png') },
{ id: 'f2', name: 'brief.pdf', type: 'application/pdf', url: '#', size: 182000 },
]);
</script>A message can carry files. An image shows its picture; any other file shows a tile with its name and its type. They are the same tiles before sending, in the composer, and after, in the message.
Attachments are opt-in, because the library only collects the files: reading them, uploading them or sending them to a model is your app’s job. Until your app takes that job, the chat shows no attach button.
Variants
Section titled “Variants”A chat that accepts files
Section titled “A chat that accepts files”<!-- attachments adds the file picker and the pending files to the composer the tag
composes. Opt-in: the files reach you on aparte-send, and reading them is yours. -->
<aparte-chat attachments center-empty placeholder="Attach a file and ask about it" style="height: 22rem"></aparte-chat>attachments on <aparte-chat> adds the file picker and the pending files
to the composer it composes. The files reach you on aparte-send, as event.detail.files, and
filesToAttachments() turns them into what a message carries.
In the composer, before sending
Section titled “In the composer, before sending”<aparte-composer placeholder="Ask about these files…">
<div class="aparte-composer-shell">
<!-- The pending files, above the field. Hidden while there are none. -->
<aparte-composer-attachments></aparte-composer-attachments>
<div class="aparte-composer-row">
<!-- Opens the file picker, and makes the whole composer a drop target. -->
<aparte-composer-add-attachment accept="image/*,.pdf,.md"></aparte-composer-add-attachment>
<aparte-composer-input></aparte-composer-input>
<aparte-composer-send></aparte-composer-send>
</div>
</div>
</aparte-composer>
<script>
// Two files already picked, standing in for what a reader would choose.
const composer = document.querySelector('aparte-composer');
const notes = new File(['# Launch notes'], 'launch-notes.md', { type: 'text/markdown' });
const canvas = Object.assign(document.createElement('canvas'), { width: 120, height: 80 });
const paint = canvas.getContext('2d');
paint.fillStyle = '#b07d33';
paint.fillRect(0, 0, 120, 80);
canvas.toBlob((blob) => composer.addAttachments([notes, new File([blob], 'cover.png', { type: 'image/png' })]));
</script>In a composer you assemble yourself, <aparte-composer-add-attachment> opens the picker and
accepts drops, and <aparte-composer-attachments> shows what is waiting. See
Composer.
import { filesToAttachments } from '@aparte/core';
import type { AparteSendEventDetail } from '@aparte/core';
const chat = document.querySelector('aparte-chat')!;
chat.addEventListener('aparte-send', (e) => {
const { files = [] } = (e as CustomEvent<AparteSendEventDetail>).detail;
const attachments = filesToAttachments(files); // what a message carries
});A message from your store sets them with bubble.setAttachments(), or the attachments field
of the message you append.
Customize
Section titled “Customize”Clicking an image can open it full size: declare it with
aparteGlobalConfig.setHostHandlers({ attachmentPreview: true }) and open your own lightbox on
aparte-attachment-preview. Until you declare it, the tile is not a button. To draw the tiles
yourself, setAttachmentRenderer() replaces them.
Accessibility
Section titled “Accessibility”- An image tile becomes a keyboard-reachable button only when your app opens previews.
- The remove button on a pending file is named after the file.
Related
Section titled “Related”- Composer — where files are picked and dropped.
- Thumbnail — the kit recipe the tiles wear.
- Attachments guide — the full flow, upload included.