SakaniUI

Prompt Composer

The prompt box of an AI product: it grows with the text, Enter sends, send becomes Stop while the reply streams, and files sit above it.

It owns no model, files or voice. The + button calls onAttach, the mic onVoice, and the model picker and the like go beside it, in actions or in a row under the box. The ember light sweeps the border once, shortly after the box appears, then rests; focus draws a soft ember border in. Enter sends and Shift+Enter breaks the line.

Basic

Type something and press Enter: the send button turns into Stop for three seconds, as if the reply were streaming.

With attachments

Pass AttachmentChips as attachments and they sit above the field.

Q4 pipeline.pdfPDF · 2.4 MB
renewals.csvUploading 64%

Props

PropTypeDefaultDescription
valuestringControlled value.
defaultValuestringInitial value when uncontrolled.
onValueChange(value: string) => voidCalled as the text changes.
placeholderstringPlaceholder text.
status'idle' | 'streaming''idle'While streaming, the send button becomes Stop.
onSubmit(value: string) => voidEnter, or the send button. Receives the trimmed text.
onStop() => voidThe Stop button.
onAttach() => voidThe + button. Pass it to show the button.
onVoice() => voidThe mic. Hidden when there is no handler.
attachmentsReactNodeChips above the field, usually AttachmentChip.
actionsReactNodeExtra controls on the left, after the +.
maxRowsnumber8The most lines the field grows to before it scrolls.
glow'once' | 'pulse' | 'focus' | 'off''once'The ember light round the border: one lap shortly after it appears, then still (once); every 2.5s while idle (pulse); one lap on each focus (focus); none (off).
disabledbooleanDisables the field and the buttons.
autoFocusbooleanFocus the field on mount.
aria-labelstringAccessible name of the field.
classNamestringExtra class on the root.