ComponentsAI

Question card

Flo asks you to choose before it carries on. Each answer, your own words or Skip go back to Flo as your next message.

Playground

Change the controls to try each prop. The code under the preview updates as you go and lists only the props you changed; copy it into your page.

Which Sara should get the email?

States
import { QuestionCard } from '@/ui/question-card';<QuestionCard question="Which Sara should get the email?" />

Waiting for an answer

The question leads, then each answer on its own row with its number key. Press 1 or 2 to move to an answer and Enter to send it, or click it. With other, the last row is "Something else…": type an answer and press Enter.

Which Sara should get the email?

import { QuestionCard } from '@/ui/question-card';

export default function QuestionCardDefault() {
  return (
    <QuestionCard
      className="w-full max-w-90"
      question="Which Sara should get the email?"
      options={[{ label: 'Sara Lee', detail: 'Halcyon Bank' }, { label: 'Sara Okafor', detail: 'Northwind' }]}
      other
    />
  );
}

With details and Skip

An answer's detail says what it means, in subtle text after it. skip adds Skip, which answers "Skip".

Is the Senior Data Engineer role permanent or contract?

import { QuestionCard } from '@/ui/question-card';

export default function QuestionCardDetails() {
  return (
    <QuestionCard
      className="w-full max-w-[25rem]"
      question="Is the Senior Data Engineer role permanent or contract?"
      options={[{ label: 'Permanent', detail: '20% fee, as the Halcyon terms' }, { label: 'Contract', detail: 'day rate' }, { label: 'Both' }]}
      skip
    />
  );
}

Answered

Once answered, the card keeps only the answer on the current fill, and a status line says what was sent. In the chat, the answer also lands as your message.

Which Sara should get the email?

You answered: Sara Lee

import { QuestionCard } from '@/ui/question-card';

export default function QuestionCardAnswered() {
  return (
    <QuestionCard
      className="w-full max-w-90"
      question="Which Sara should get the email?"
      options={[{ label: 'Sara Lee', detail: 'Halcyon Bank' }, { label: 'Sara Okafor', detail: 'Northwind' }]}
      answer="Sara Lee"
    />
  );
}

Answered for a background run

When a background run waits on the question, the status line says Flo carries on.

Halcyon Bank has two owners in your tracker. Which one keeps it?

Sent. Flo carries on in the background.

import { QuestionCard } from '@/ui/question-card';

export default function QuestionCardBackground() {
  return (
    <QuestionCard
      className="w-full max-w-90"
      question="Halcyon Bank has two owners in your tracker. Which one keeps it?"
      options={[{ label: 'Tom Ellis' }, { label: 'Priya Shah' }]}
      answer="Priya Shah"
      sentNote="Sent. Flo carries on in the background."
    />
  );
}

An older question

Only the newest reply's question, or one a background run waits on, can be answered. Older ones are disabled.

Which Sara should get the email?

import { QuestionCard } from '@/ui/question-card';

export default function QuestionCardOlder() {
  return (
    <QuestionCard
      className="w-full max-w-90"
      disabled
      question="Which Sara should get the email?"
      options={[{ label: 'Sara Lee', detail: 'Halcyon Bank' }, { label: 'Sara Okafor', detail: 'Northwind' }]}
      other
    />
  );
}

Didn't reach Ascern

A failed send keeps the answers live and says so in danger. Nothing was sent.

Halcyon Bank has two owners in your tracker. Which one keeps it?

import { QuestionCard } from '@/ui/question-card';

export default function QuestionCardFailed() {
  return (
    <QuestionCard
      className="w-full max-w-90"
      question="Halcyon Bank has two owners in your tracker. Which one keeps it?"
      options={[{ label: 'Tom Ellis' }, { label: 'Priya Shah' }]}
      error="That didn't reach Ascern. Try again."
    />
  );
}

On this page