beUI Pro for mobile is live — 50 React Native blocks and screens
Questionnaire
2 variants
Composable, animated question-and-answer cards that help agents collect context and continue with clear instructions.
Guided questions
index.tsxComposable question cards with flat answer rows, keyboard shortcuts, single or multiple selection, freeform input, and optional skipping.
TSXcomponents/previews/premium/questionnaire-preview.tsx
"use client";
import { Check } from "lucide-react";
import { useState } from "react";
import { Button } from "@/components/motion/button";
import {
Questionnaire,
QuestionnaireActions,
QuestionnaireChoice,
QuestionnaireChoices,
QuestionnaireError,
QuestionnaireInput,
QuestionnaireItem,
QuestionnaireNext,
QuestionnairePrevious,
QuestionnaireProgress,
QuestionnaireSkip,
QuestionnaireSubmit,
QuestionnaireTitle,
} from "@/components/premium/questionnaire";
type DemoQuestion = {
name: string;
prompt: string;
required: boolean;
multiple: boolean;
choices: { value: string; label: string; description?: string }[];
input?: { label: string; placeholder: string };
};
const guidedQuestions: DemoQuestion[] = [
{
name: "task",
prompt: "What would you like to work on?",
required: false,
multiple: false,
choices: [
{
value: "build",
label: "Build something new",
description: "Turn an idea into a first version",
},
{
value: "fix",
label: "Fix a problem",
description: "Find what’s wrong and put it right",
},
{
value: "polish",
label: "Polish what’s there",
description: "Improve the details and interactions",
},
{
value: "explore",
label: "Explore an idea",
description: "Compare a few directions before building",
},
],
},
{
name: "starting-point",
prompt: "Where should I start?",
required: true,
multiple: false,
choices: [
{
value: "plan",
label: "Make a plan",
description: "Walk me through the approach first",
},
{
value: "draft",
label: "Show me a draft",
description: "Give me something I can react to",
},
{
value: "begin",
label: "Get started",
description: "Work through it and share the result",
},
],
},
{
name: "notes",
prompt: "Any details I should know?",
required: false,
multiple: false,
choices: [],
input: {
label: "Project details",
placeholder: "A reference, a constraint, or something to avoid…",
},
},
];
const selectionQuestions: DemoQuestion[] = [
{
name: "checks",
prompt: "What should I check before finishing?",
required: false,
multiple: true,
choices: [
{ value: "tests", label: "Run the relevant tests" },
{ value: "mobile", label: "Check the mobile layout" },
{ value: "keyboard", label: "Try the keyboard controls" },
{ value: "changes", label: "Review the final changes" },
],
},
{
name: "update",
prompt: "How would you like the update?",
required: true,
multiple: false,
choices: [
{ value: "brief", label: "Keep it short" },
{ value: "changes", label: "Explain what changed and why" },
{ value: "walkthrough", label: "Walk me through the result" },
],
},
{
name: "notes",
prompt: "Anything you’d like me to leave alone?",
required: false,
multiple: false,
choices: [],
input: {
label: "Things to leave unchanged",
placeholder: "For example, keep the existing colors and copy…",
},
},
];
function QuestionnaireExample({ controls = false }: { controls?: boolean }) {
const items = controls ? selectionQuestions : guidedQuestions;
const [result, setResult] = useState<[string, string][]>([]);
const [complete, setComplete] = useState(false);
return (
<div className="flex min-h-96 w-full items-center justify-center px-4 py-8">
{complete ? (
<div className="w-full max-w-xl rounded-2xl border border-border bg-background p-5">
<div className="flex items-center gap-2 text-sm">
<Check className="size-4" />
All set
</div>
<p className="mt-2 text-sm text-muted-foreground">
{result.length
? `${result.length} answer${result.length === 1 ? "" : "s"} noted for the next step.`
: "All optional questions were skipped."}
</p>
<Button
variant="outline"
className="mt-5 h-9 rounded-full"
onClick={() => setComplete(false)}
>
Start again
</Button>
</div>
) : (
<Questionnaire
items={items}
aria-label={controls ? "Review preferences" : "Plan your next task"}
shortcuts="numbers"
onSubmit={(event) => {
event.preventDefault();
setResult(
Array.from(new FormData(event.currentTarget).entries()).map(
([name, value]) => [name, String(value)],
),
);
setComplete(true);
}}
>
<QuestionnaireProgress />
{items.map((item) => (
<QuestionnaireItem
key={item.name}
name={item.name}
required={item.required}
multiple={item.multiple}
>
<QuestionnaireTitle>{item.prompt}</QuestionnaireTitle>
<QuestionnaireChoices
className={controls ? "space-y-1" : undefined}
>
{item.choices.map((choice) => (
<QuestionnaireChoice
key={choice.value}
value={choice.value}
variant={controls ? "control" : "row"}
>
<span className="font-medium">{choice.label}</span>
{!controls && (
<>
{" "}
<span className="text-muted-foreground">
{choice.description}
</span>
</>
)}
</QuestionnaireChoice>
))}
{item.input && (
<div className="px-3">
<QuestionnaireInput
aria-label={item.input.label}
placeholder={item.input.placeholder}
/>
</div>
)}
</QuestionnaireChoices>
<QuestionnaireError />
</QuestionnaireItem>
))}
<QuestionnaireActions>
<QuestionnairePrevious />
<QuestionnaireSkip />
<QuestionnaireNext />
<QuestionnaireSubmit />
</QuestionnaireActions>
</Questionnaire>
)}
</div>
);
}
export function QuestionnairePreview() {
return <QuestionnaireExample />;
}
export function QuestionnaireSelectionPreview() {
return <QuestionnaireExample controls />;
}
Source code is locked
Get access to install premium components and view the full source.
Open dashboardSelection list
index.tsxA vertical answer list with beUI checkboxes for multiple choices and radio controls for single choices.
TSXcomponents/previews/premium/questionnaire-preview.tsx
"use client";
import { Check } from "lucide-react";
import { useState } from "react";
import { Button } from "@/components/motion/button";
import {
Questionnaire,
QuestionnaireActions,
QuestionnaireChoice,
QuestionnaireChoices,
QuestionnaireError,
QuestionnaireInput,
QuestionnaireItem,
QuestionnaireNext,
QuestionnairePrevious,
QuestionnaireProgress,
QuestionnaireSkip,
QuestionnaireSubmit,
QuestionnaireTitle,
} from "@/components/premium/questionnaire";
type DemoQuestion = {
name: string;
prompt: string;
required: boolean;
multiple: boolean;
choices: { value: string; label: string; description?: string }[];
input?: { label: string; placeholder: string };
};
const guidedQuestions: DemoQuestion[] = [
{
name: "task",
prompt: "What would you like to work on?",
required: false,
multiple: false,
choices: [
{
value: "build",
label: "Build something new",
description: "Turn an idea into a first version",
},
{
value: "fix",
label: "Fix a problem",
description: "Find what’s wrong and put it right",
},
{
value: "polish",
label: "Polish what’s there",
description: "Improve the details and interactions",
},
{
value: "explore",
label: "Explore an idea",
description: "Compare a few directions before building",
},
],
},
{
name: "starting-point",
prompt: "Where should I start?",
required: true,
multiple: false,
choices: [
{
value: "plan",
label: "Make a plan",
description: "Walk me through the approach first",
},
{
value: "draft",
label: "Show me a draft",
description: "Give me something I can react to",
},
{
value: "begin",
label: "Get started",
description: "Work through it and share the result",
},
],
},
{
name: "notes",
prompt: "Any details I should know?",
required: false,
multiple: false,
choices: [],
input: {
label: "Project details",
placeholder: "A reference, a constraint, or something to avoid…",
},
},
];
const selectionQuestions: DemoQuestion[] = [
{
name: "checks",
prompt: "What should I check before finishing?",
required: false,
multiple: true,
choices: [
{ value: "tests", label: "Run the relevant tests" },
{ value: "mobile", label: "Check the mobile layout" },
{ value: "keyboard", label: "Try the keyboard controls" },
{ value: "changes", label: "Review the final changes" },
],
},
{
name: "update",
prompt: "How would you like the update?",
required: true,
multiple: false,
choices: [
{ value: "brief", label: "Keep it short" },
{ value: "changes", label: "Explain what changed and why" },
{ value: "walkthrough", label: "Walk me through the result" },
],
},
{
name: "notes",
prompt: "Anything you’d like me to leave alone?",
required: false,
multiple: false,
choices: [],
input: {
label: "Things to leave unchanged",
placeholder: "For example, keep the existing colors and copy…",
},
},
];
function QuestionnaireExample({ controls = false }: { controls?: boolean }) {
const items = controls ? selectionQuestions : guidedQuestions;
const [result, setResult] = useState<[string, string][]>([]);
const [complete, setComplete] = useState(false);
return (
<div className="flex min-h-96 w-full items-center justify-center px-4 py-8">
{complete ? (
<div className="w-full max-w-xl rounded-2xl border border-border bg-background p-5">
<div className="flex items-center gap-2 text-sm">
<Check className="size-4" />
All set
</div>
<p className="mt-2 text-sm text-muted-foreground">
{result.length
? `${result.length} answer${result.length === 1 ? "" : "s"} noted for the next step.`
: "All optional questions were skipped."}
</p>
<Button
variant="outline"
className="mt-5 h-9 rounded-full"
onClick={() => setComplete(false)}
>
Start again
</Button>
</div>
) : (
<Questionnaire
items={items}
aria-label={controls ? "Review preferences" : "Plan your next task"}
shortcuts="numbers"
onSubmit={(event) => {
event.preventDefault();
setResult(
Array.from(new FormData(event.currentTarget).entries()).map(
([name, value]) => [name, String(value)],
),
);
setComplete(true);
}}
>
<QuestionnaireProgress />
{items.map((item) => (
<QuestionnaireItem
key={item.name}
name={item.name}
required={item.required}
multiple={item.multiple}
>
<QuestionnaireTitle>{item.prompt}</QuestionnaireTitle>
<QuestionnaireChoices
className={controls ? "space-y-1" : undefined}
>
{item.choices.map((choice) => (
<QuestionnaireChoice
key={choice.value}
value={choice.value}
variant={controls ? "control" : "row"}
>
<span className="font-medium">{choice.label}</span>
{!controls && (
<>
{" "}
<span className="text-muted-foreground">
{choice.description}
</span>
</>
)}
</QuestionnaireChoice>
))}
{item.input && (
<div className="px-3">
<QuestionnaireInput
aria-label={item.input.label}
placeholder={item.input.placeholder}
/>
</div>
)}
</QuestionnaireChoices>
<QuestionnaireError />
</QuestionnaireItem>
))}
<QuestionnaireActions>
<QuestionnairePrevious />
<QuestionnaireSkip />
<QuestionnaireNext />
<QuestionnaireSubmit />
</QuestionnaireActions>
</Questionnaire>
)}
</div>
);
}
export function QuestionnairePreview() {
return <QuestionnaireExample />;
}
export function QuestionnaireSelectionPreview() {
return <QuestionnaireExample controls />;
}
Source code is locked
Get access to install premium components and view the full source.
Open dashboardInstall
Add this component with the shadcn CLI.
$ bunx --bun shadcn add @beui-pro/questionnaire