Toggle Sidebar B
AppearanceLight & dark mode D

Chat Composer

The box someone types a message into: text, files, and the two keys that send it. Paste a screenshot, drop a file, Enter to send and Shift+Enter for a newline. It knows nothing about where a message goes or what a reply looks like.

Default

Two v-models: the draft and the queued files. `submit` gives you the trimmed text; the files are already in the array you own.

Replay preview

Paste and drop

Every route to a file ends in the same place. Paste a screenshot from the clipboard, drag one onto the box, or use the + menu. A file the receiver cannot read is refused through `reject` rather than disappearing, and the drop overlay inherits the box's own radius so it fits whichever Style is active.

Replay preview

Paste a screenshot, drag a file onto the box, or use the + menu. A .txt is refused, because the default list is images and PDF.

Busy and read-only

`busy` turns Send into Stop and keeps Enter from sending on top of an answer that is still arriving. `disabled` locks the whole box for a surface someone may read but not write to; say why in the placeholder rather than leaving them guessing.

Replay preview

Limits

Mirror whatever the receiving endpoint enforces. The counter appears in the last tenth of `maxLength`, and the file rules are checked here so the reader learns about a refusal before a round trip rather than after one.

Replay preview

120 characters, two files, 1 MB each, images only. The counter appears in the last tenth; the file rules answer before a round trip rather than after.

API Reference

ChatComposer

PropTypeDefaultDescription
modelValuestring""The draft. Supports v-model.
attachmentsFile[][]Queued files. Supports v-model:attachments.
busybooleanfalseA reply is arriving: Send becomes Stop and Enter no longer sends.
disabledbooleanfalseLocks the textarea, the + menu and Send.
placeholderstring"Ask anything"Also where you explain a disabled box.
maxLengthnumber10000Character cap; a counter appears near it.
compactbooleanfalseA shorter box, for a floating panel rather than a page.
attachablebooleantrueOffer the + menu, paste and drop at all.
acceptstring[]CHAT_ATTACHMENT_MIMESMIME types the receiver can read.
maxFilesnumber5Files per message.
maxFileBytesnumber10485760Per-file ceiling in bytes.
classstringExtra classes, merged with cn().
SlotDescription
menuExtra items appended to the + dropdown.

ChatComposer events

PropTypeDefaultDescription
update:modelValue(value: string)Draft changed, and emptied on submit.
update:attachments(files: File[])A file was added or removed.
submit(text: string)Trimmed text. Files are in the array you own.
stop()The stop button, only reachable while busy.
reject(reason: string)A file was refused. Show it however your app shows problems.

ChatAttachments

PropTypeDefaultDescription
filesFile[]Rendered as a scrolling row of cards; images get a thumbnail.
disabledbooleanfalseLocks the remove button.

useChatAlerts(options)

PropTypeDefaultDescription
soundSrcstring"/sfx/chat-notification.mp3"Served from public/. Any short, quiet notification.
storageKeystring"pmone:chat-muted"localStorage key for the per-device mute.
vibrationnumber[][15]navigator.vibrate pattern. Keep it under a tick.
SlotDescription
ping()Announce one new message: sound, then a short buzz.
muted / setMuted / toggleMutedMute silences the sound only; the haptic is the discreet half.