Blode UI
GitHub

Ask User Questions

A stepped questionnaire with single- or multi-select options, free-form answers, and a skip control.

Loading
Loading...
"use client";
 
import { useState } from "react";
 
import { AskUserQuestions } from "@/components/ui/ask-user-questions";
import type { AskUserAnswer, AskUserQuestion } from "@/components/ui/ask-user-questions";
 
const questions: AskUserQuestion[] = [
  {
    id: "role",
    options: [
      { description: "Prototyping flows and pages", id: "design", title: "Designer" },
      { description: "Shipping production UI", id: "eng", title: "Engineer" },
      { description: "Aligning the team on patterns", id: "pm", title: "PM" },
      { description: "Bootstrapping a product", id: "founder", title: "Founder" },
    ],
    title: "How do you plan to use Blode UI?",
  },
  {
    id: "shape",
    options: [
      { description: "Soft, familiar corners", id: "rounded", title: "Rounded" },
      { description: "Fully rounded, friendly", id: "pill", title: "Pill" },
    ],
    title: "Which shape language fits your brand?",
  },
  {
    id: "components",
    multiSelect: true,
    nextLabel: "Continue",
    options: [
      { description: "Chat-style composer with attachments", id: "input", title: "Input Message" },
      { description: "Streamed reasoning steps", id: "thinking", title: "Thinking Steps" },
      { description: "Stepped question flows", id: "ask", title: "Ask User Questions" },
      { description: "Sortable, filterable rows", id: "table", title: "Table" },
    ],
    title: "Which components are you reaching for first?",
  },
  {
    allowOther: true,
    id: "drew",
    options: [
      { description: "Springs that feel alive", id: "motion", title: "Motion" },
      { description: "Pixel-level polish", id: "craft", title: "Craft" },
      { description: "Shape and elevation systems", id: "tokens", title: "Tokens" },
    ],
    otherPlaceholder: "Something else?",
    title: "What drew you to Blode UI?",
  },
  {
    id: "frameworks",
    multiSelect: true,
    options: [
      { description: "App Router projects", id: "next", title: "Next.js" },
      { description: "Full-stack apps", id: "remix", title: "Remix" },
      { description: "SPAs and dashboards", id: "vite", title: "Vite + React" },
      { description: "Content-first sites", id: "astro", title: "Astro" },
    ],
    title: "Where will you ship these components?",
  },
  {
    id: "themes",
    options: [
      { id: "light", title: "Light only" },
      { id: "dark", title: "Dark only" },
      { id: "system", title: "System-aware" },
      { id: "toggle", title: "User toggle" },
    ],
    title: "Which theme mode do you support?",
  },
  {
    allowOther: true,
    id: "missing",
    multiSelect: true,
    nextLabel: "Send feedback",
    options: [
      { description: "Date picker and range", id: "calendar", title: "Calendar" },
      { description: "Fast keyboard launcher", id: "command", title: "Command menu" },
      { description: "Drag-and-drop boards", id: "kanban", title: "Kanban" },
    ],
    otherPlaceholder: "Tell us what to build next…",
    title: "What's missing from the registry today?",
  },
  {
    id: "recommend",
    options: [
      { description: "Already have", id: "yes", title: "Yes" },
      { description: "Once it covers more ground", id: "soon", title: "Soon" },
      { description: "Still evaluating", id: "unsure", title: "Not sure yet" },
    ],
    skippable: false,
    title: "Would you recommend Blode UI to a teammate?",
  },
];
 
export function AskUserQuestionsDemo() {
  const [answers, setAnswers] = useState<Record<string, AskUserAnswer> | null>(null);
 
  if (answers) {
    return (
      <div className="flex w-full max-w-md flex-col gap-1 rounded-xl border p-4 text-sm">
        <p className="font-medium text-foreground">Thanks — that's everything!</p>
        <p className="text-muted-foreground">We'll tailor your setup to those answers.</p>
      </div>
    );
  }
 
  return <AskUserQuestions onComplete={setAnswers} questions={questions} />;
}

Installation

npx shadcn@latest add "https://ui.blode.co/r/styles/default/ask-user-questions"

Usage

import { AskUserQuestions } from "@/components/ui/ask-user-questions";
<AskUserQuestions
  questions={[
    {
      id: "framework",
      title: "Which framework should we scaffold with?",
      options: [
        { id: "next", title: "Next.js", description: "App Router, RSC" },
        { id: "vite", title: "Vite", description: "Fast dev server" },
      ],
    },
  ]}
  onComplete={(answers) => console.log(answers)}
/>

Examples

Multi-select

Set multiSelect to allow more than one answer, and allowOther to reveal a free-form textarea. Multi-select questions advance with an explicit Next / Finish button.

Loading
Loading...
"use client";
 
import { useState } from "react";
 
import { AskUserQuestions } from "@/components/ui/ask-user-questions";
import type { AskUserAnswer, AskUserQuestion } from "@/components/ui/ask-user-questions";
 
const questions: AskUserQuestion[] = [
  {
    id: "features",
    multiSelect: true,
    nextLabel: "Continue",
    options: [
      { description: "System-aware theme switching", id: "dm", title: "Dark mode" },
      { description: "Screen-reader and keyboard support", id: "a11y", title: "Accessibility" },
      { description: "Faster initial load", id: "perf", title: "Performance" },
      { description: "Multi-language support", id: "i18n", title: "Translations" },
    ],
    title: "Which features should we prioritize?",
  },
  {
    id: "platforms",
    multiSelect: true,
    options: [
      { description: "Desktop browsers", id: "web", title: "Web" },
      { description: "iPhone and iPad", id: "ios", title: "iOS" },
      { description: "Phones and tablets", id: "android", title: "Android" },
      { description: "macOS / Windows / Linux apps", id: "desktop", title: "Native desktop" },
    ],
    title: "Which platforms do you target?",
  },
  {
    allowOther: true,
    id: "integrations",
    multiSelect: true,
    nextLabel: "Finish",
    options: [
      { description: "Notifications and approvals", id: "slack", title: "Slack" },
      { description: "PR and issue sync", id: "github", title: "GitHub" },
      { description: "Two-way ticket linking", id: "linear", title: "Linear" },
      { description: "Design hand-off", id: "figma", title: "Figma" },
    ],
    otherPlaceholder: "Anything else?",
    title: "Which integrations matter most?",
  },
];
 
export function AskUserQuestionsMultiSelect() {
  const [answers, setAnswers] = useState<Record<string, AskUserAnswer> | null>(null);
 
  if (answers) {
    return (
      <div className="flex w-full max-w-md flex-col gap-1 rounded-xl border p-4 text-sm">
        <p className="font-medium text-foreground">Got it — thanks!</p>
        <p className="text-muted-foreground">We'll tailor the build to your selections.</p>
      </div>
    );
  }
 
  return <AskUserQuestions onComplete={setAnswers} questions={questions} />;
}