Question

A focused question in an inset Card. Collect an answer or guide someone through a few decisions, one at a time.

Where should we start?

Choose a starting point for the next round of work.

Question 1 of 3

Installation

Copy the command below and run it in your terminal.

bunx --package @sivir-ui/svelte sivir add question

Usage

Render Question.Root in the same layout slot as Composer.Root. Keep the prompt value in their shared parent so swapping the forms never clears an unsent draft.

import * as Question from '@sivir-ui/svelte/components/question';
import type { QuestionAnswer } from '@sivir-ui/svelte/components/question';

let answer = $state<QuestionAnswer>();

<Question.Root variant="inset" bind:value={answer} onSubmit={(value) => continueAgent(value)}>
  <Question.Content>
    <Question.Title>Which environment should I use?</Question.Title>
    <Question.Description>Your prompt draft remains untouched.</Question.Description>
    <Question.Options>
      <Question.Option value="preview" label="Preview" />
      <Question.Option value="production" label="Production" />
    </Question.Options>
  </Question.Content>
  <Question.Actions>
    <Question.Cancel onclick={() => skipQuestion()}>Skip question</Question.Cancel>
    <Question.Submit />
  </Question.Actions>
</Question.Root>

Use type="single" for one option, type="multiple" for several, or type="text" with Question.Input. Async submit handlers are awaited and cannot run twice while unresolved. Changing type resets the bound answer to the new mode's empty value.

Composition

Set variant="inset" on Question.Root for the shared Card frame and recessed content surface. The default variant uses a plain Card. Place Question.Actions after Question.Content to keep controls in the footer. Both parts are optional; omit the description or restyle the actions to suit the space.

<Question.Root variant="inset" bind:value={answer} onSubmit={next}>
  <Question.Content>
    <Question.Title>{question.title}</Question.Title>
    <Question.Options>
      {#each question.options as option (option.value)}
        <Question.Option {...option} />
      {/each}
    </Question.Options>
  </Question.Content>
  <Question.Actions class="justify-between">
    <Question.Cancel disabled={index === 0} onclick={(event) => {
      event.preventDefault();
      back();
    }}>Back</Question.Cancel>
    <Question.Submit label="Next" />
  </Question.Actions>
</Question.Root>

Question.Content is a static fieldset grouping for the title, description, and answer controls. Keep navigation state and any transitions in the parent when a flow needs them. The component itself stays still so the question remains easy to read and answer.

Keep the step index and each answer in the parent, as in the example above. Content keeps changes without resetting answers or managing navigation. Keep a flow within one answer type, or key the Root per question when mixing types: changing the type on an existing Root clears its answer. When using Cancel as Back, prevent its default behavior to avoid calling the Root’s cancellation handler.

Examples

Use the same inset composition for multiple selections, a written answer, or a question beneath a live transcript.

Multiple choice

Which checks should I run before opening the pull request?

Select every check you want included.

No checks queued

Free text

What constraint should I preserve?

Add any implementation detail that is not captured by the current plan.

Waiting for an answer

Conversation takeover

Answer or skip the question to restore the composer with its draft intact.

Add the account migration and keep the rollout safe. I started a follow-up in the composer.
I can continue after I know which environment should receive the first run.

Where should I run the migration first?

Your unsent composer draft will stay in place while you answer.

Anatomy

Question.Root - Renders a full question form.

Question.Title - Shows the question heading.

Question.Description - Explains the question context.

Question.Options - Wraps answer option items.

Question.Option - Represents a question option.

Question.Input - Collects a free-form response.

Question.Actions - Groups cancellation and submit actions.

Question.Cancel - Cancels question submission.

Question.Submit - Submits the selected answer.