question-tool
agent-elements/question-toolFreeComponent
agent-elements publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by agent-elements on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://agent-elements.21st.dev/r/question-tool.jsonSource
1import { useEffect, useMemo, useState } from "react";2import {3 IconChevronDown,4 IconChevronUp,5 IconMessageCircleQuestion,6} from "@tabler/icons-react";7import { QuestionPrompt } from "./question-prompt";8import type { QuestionAnswer, QuestionConfig } from "./question-prompt";910export type QuestionToolPart = {11 type: string;12 toolCallId?: string;13 state?: string;14 input?: {15 questions: QuestionConfig[];16 questionIndex?: number;17 totalQuestions?: number;18 onPreviousQuestion?: () => void;19 onNextQuestion?: () => void;20 submitLabel?: string;21 nextLabel?: string;22 skipLabel?: string;23 allowSkip?: boolean;24 onSubmitAnswer?: (answer: QuestionAnswer) => void;25 };26 output?: {27 answer?: QuestionAnswer;28 };29};3031export type QuestionToolProps = {32 part: QuestionToolPart;33 chatStatus?: string;34};3536function formatAnswer(answer: QuestionAnswer) {37 if (answer.kind === "skip") return "Skipped";38 if (answer.kind === "text") return answer.text || "Answered";39 const ids = answer.selectedIds?.length ? answer.selectedIds.join(", ") : "";40 if (answer.text) return ids ? `${ids} (${answer.text})` : answer.text;41 return ids || "Answered";42}4344export function QuestionTool({ part }: QuestionToolProps) {45 const [localIndex, setLocalIndex] = useState(part.input?.questionIndex ?? 1);46 const questions: QuestionConfig[] = part.input?.questions ?? [];47 const totalQuestions = part.input?.totalQuestions ?? questions.length;48 const isControlled = typeof part.input?.questionIndex === "number";49 const questionIndex = isControlled50 ? (part.input?.questionIndex ?? 1)51 : questions.length > 052 ? localIndex53 : (part.input?.questionIndex ?? 1);54 const clampedIndex = Math.max(1, Math.min(questionIndex, totalQuestions));55 const question = questions[clampedIndex - 1];56 const [localAnswers, setLocalAnswers] = useState<57 Record<number, QuestionAnswer>58 >({});5960 useEffect(() => {61 if (typeof part.input?.questionIndex === "number") {62 setLocalIndex(part.input.questionIndex);63 }64 }, [part.input?.questionIndex]);6566 useEffect(() => {67 setLocalAnswers({});68 setLocalIndex(part.input?.questionIndex ?? 1);69 }, [part.toolCallId]);7071 if (!question) return null;7273 const outputAnswer = part.output?.answer;74 const answeredCount = Object.keys(localAnswers).length;75 const isComplete =76 totalQuestions === 177 ? !!outputAnswer || answeredCount >= 178 : totalQuestions > 0 && answeredCount >= totalQuestions;79// … truncated
More from agent-elements
All 25 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| agent-chatagent-chat | agent-elements | Components | Free | no deps | |
| attachment-buttonattachment-button | agent-elements | Components | Free | no deps | |
| bash-toolbash-tool | agent-elements | Components | Free | no deps | |
| edit-tooledit-tool | agent-elements | Components | Free | no deps | |
| error-messageerror-message | agent-elements | Components | Free | no deps | |
| file-attachmentfile-attachment | agent-elements | Components | Free | no deps | |
| generic-toolgeneric-tool | agent-elements | Components | Free | no deps | |
| input-barinput-bar | agent-elements | Components | Free | no deps |
