Ask Question
Cursor-style questionnaire the agent can drop into a turn: single-select radios, multi-select checkboxes, an Other… field, Skip, and Continue.
Installation
npx shadcn@latest add miskibin/chat-components/ask-questionAlso installs collapsible.
Usage
"use client"
import { AskQuestion } from "@/components/ui/ask-question"
export function Clarify() {
return (
<AskQuestion
title="A couple of questions"
questions={[
{
id: "next",
prompt: "What would you like to test next?",
options: [
{ id: "options", label: "Different options (Recommended)" },
{ id: "one", label: "One question only" },
],
},
]}
onSubmit={(result) => {
if (result.skipped) return
save(result.answers)
}}
/>
)
}Examples
Restyle the selected option
Selected options carry data-state="checked", and the card, the submit button, and every fieldset have their own slots — so the questionnaire wears your accent without a fork. hideOther drops the free-text field, skipLabel and submitLabel rename the buttons.
Render it from a tool call
MessageToolCall swaps in this card whenever isOpenAskTool holds: the tool name is Ask Question and it is either still running or already closed by the agent with nothing selected. After the user hits Skip or Continue it becomes the usual “Done Ask Question” row.
Skipped — nothing was selected.
- title
- A couple of questions
- questions
- [{"id":"next","prompt":"What would you like to test next?","options":[{"id":"options","label":"Different options (Recommended)"},{"id":"one","label":"One question only"},{"id":"pr…
Notes
API reference
AskQuestion
questions*AskQuestionItem[]- Each item is
{ id, prompt, options: [{ id, label }], allowMultiple? }. Append(Recommended)to a label to badge it. Other… is added automatically unlesshideOther. titlestring- Header label. Defaults to "Questions".
valueRecord<string, AskQuestionSelection>- Controlled selections keyed by question id.
defaultValueRecord<string, AskQuestionSelection>- Initial selections when uncontrolled.
onChange(value: Record<string, AskQuestionSelection>) => void- Fired on every option or Other… edit.
onSubmit(result: AskQuestionResult) => void- Continue. If onSkip is omitted, Skip also fires this with skipped: true.
onSkip() => void- Skip. Continue stays disabled until every question has a selection.
hideOtherboolean = false- Do not append the Other… option.
disabledboolean = false- Locks the form after a parent has recorded the answer.
defaultOpenboolean = true- Start the panel expanded. Collapse it to read the turn behind it.
skipLabelstring = "Skip"- Label on the secondary action.
submitLabelstring = "Continue"- Label on the primary action.
AskQuestionSummary
questions*AskQuestionItem[]- The same questions the answer was collected for.
result*AskQuestionResult- Settled answer. skipped: true renders the one-line skipped note instead.
hideOtherboolean = false- Match the AskQuestion setting so labels resolve.
Data slots
Every part below is addressable from a parent, so you can restyle internals without forking the component.
ask-questionask-question-triggerask-question-formask-question-itemask-question-promptask-question-groupask-question-optionask-question-indicatorask-question-otherask-question-actionsask-question-skipask-question-submitask-question-summary