Composer

The input grows with its text. While a response generates, the submit button becomes a stop button, or a queue button once the user starts typing again.

Installation

Copy the command below and run it in your terminal.

bunx @sivir-ui/svelte add composer

Usage

onSubmit is required. Empty prompts are not submitted unless you set allowEmpty. While an async onSubmit runs, the input is read-only and the submit button shows a pending state. Pass generating and onStop to show the stop button while a response streams.

import * as Composer from '@sivir-ui/svelte/components/composer';

let value = $state('');

async function sendPrompt(prompt: string) {
  await chat.send(prompt);
  value = '';
}

<Composer.Root bind:value onSubmit={sendPrompt}>
  <Composer.Input placeholder="Ask about this repository..." />
  <Composer.Toolbar>
    <Composer.Actions>
      <!-- Attachment, model, or permission controls -->
    </Composer.Actions>
    <Composer.Submit />
  </Composer.Toolbar>
</Composer.Root>

To accept files, wrap Root in Attachment.Root and place Attachment.List directly before Input. Dropped and pasted files show as chips beside the prompt.

By default, submits and inserts a new line. Set submitOnEnter=false on Input when Enter should always create a new line.

Examples

Set status when your app tracks submission itself. "error" shows “Message could not be sent.” above the form.

Idle

Submitting

Error

Toolbar inset

By default the toolbar shares the input's surface. Set variant="inset" on Toolbar to place it in a recessed tray along the bottom edge.

Anatomy

Composer.Root - Submits the prompt and tracks its status.

Composer.Input - Grows with the prompt text.

Composer.Toolbar - Holds the actions and submit button.

Composer.Actions - Holds controls such as attach or model pickers.

Composer.Submit - Sends, queues, or stops the prompt.