"use client"
import * as React from "react"安装#
pnpm dlx shadcn@latest add questionnaire
用法#
import {
Questionnaire,
QuestionnaireActions,
QuestionnaireChoice,
QuestionnaireChoices,
QuestionnaireDescription,
QuestionnaireError,
QuestionnaireInput,
QuestionnaireItem,
QuestionnaireNext,
QuestionnairePrevious,
QuestionnaireProgress,
QuestionnaireSkip,
QuestionnaireSubmit,
QuestionnaireTitle,
} from "@/components/ui/questionnaire"const items = [
{
name: "direction",
required: true,
prompt: "What should we prototype next?",
description: "Choose a direction or write your own.",
choices: [
{
value: "delegation",
label: "Delegation",
description: "Show how work moves to a specialist.",
},
{
value: "questions",
label: "Question prompts",
description: "Show choices while the interface waits.",
},
{ value: "both", label: "Both together" },
],
input: { label: "Another answer", placeholder: "Type another answer…" },
},
{
name: "detail",
required: false,
prompt: "How much detail should it include?",
description: "Skip this if you are not sure yet.",
choices: [
{ value: "focused", label: "Focused" },
{ value: "complete", label: "Complete flow" },
],
},
] as const只需定义一次集合:将其传递给 Questionnaire,以用于服务器渲染的进度、操作和快捷方式,然后将其映射到各个部分。
<Questionnaire items={items} onSubmit={handleSubmit}>
<QuestionnaireProgress />
{items.map((question) => (
<QuestionnaireItem
key={question.name}
name={question.name}
required={question.required}
>
<QuestionnaireTitle>{question.prompt}</QuestionnaireTitle>
<QuestionnaireDescription>
{question.description}
</QuestionnaireDescription>
<QuestionnaireChoices>
{question.choices.map((choice) => (
<QuestionnaireChoice key={choice.value} value={choice.value}>
<span className="font-medium">{choice.label}</span>
{"description" in choice ? (
<span className="text-muted-foreground">
{choice.description}
</span>
) : null}
</QuestionnaireChoice>
))}
{"input" in question ? (
<QuestionnaireInput
aria-label={question.input.label}
placeholder={question.input.placeholder}
/>
) : null}
</QuestionnaireChoices>
<QuestionnaireError />
</QuestionnaireItem>
))}
<QuestionnaireActions>
<QuestionnairePrevious />
<QuestionnaireSkip />
<QuestionnaireNext />
<QuestionnaireSubmit />
</QuestionnaireActions>
</Questionnaire>function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault()
const answers = new FormData(event.currentTarget)
// answers.get("direction"), answers.getAll(...) for multiple items.
}组成#
Questionnaire
├── QuestionnaireProgress
├── QuestionnaireItem
│ ├── QuestionnaireTitle
│ ├── QuestionnaireDescription
│ ├── QuestionnaireChoices
│ │ ├── QuestionnaireChoice
│ │ └── QuestionnaireInput
│ └── QuestionnaireError
└── QuestionnaireActions
├── QuestionnairePrevious
├── QuestionnaireSkip
├── QuestionnaireNext
└── QuestionnaireSubmitQuestionnaire 负责管理有序项目、当前项目、答案状态、验证、 进度和导航。包含它的页面、卡片、对话框或抽屉负责管理 关闭和取消行为、持久化、传输以及分支逻辑。
服务端渲染#
将 items 传递给服务端,以渲染当前项目、进度、操作和回答快捷方式。请参阅
headless Questionnaire 了解完整行为。
多项选择#
使用 multiple 表示可接受多个固定答案的项目。
"use client"
import * as React from "react"自由回答#
当用户可以提供其他答案时,使用固定选项组合 QuestionnaireInput。
"use client"
import * as React from "react"明确跳过#
当可选项目可能会被有意留空时,添加 QuestionnaireSkip。
"use client"
import * as React from "react"快捷键#
使用 shortcuts 为每个答案分配一个字母或数字键。
"use client"
import * as React from "react"自定义验证#
将受控导航与 Zod 等外部架构结合,在返回无效项目的同时显示其错误。
"use client"
import * as React from "react"受控#
从主机状态控制当前项目,例如返回到无效步骤。
Current checkpoint: Change scope
"use client"
import * as React from "react"恢复#
恢复已保存的活动项目和默认答案,然后将更改重置为该保存状态。
"use client"
import * as React from "react"条件项目#
禁用不适用于用户之前回答的项目。
"use client"
import * as React from "react"导航状态#
读取项目状态,以启用禁用导航和自定义操作样式。
"use client"
import * as React from "react"自定义进度#
使用 Progress 渲染状态构建自定义进度指示器。
"use client"
import * as React from "react"动画项目#
为活动项目添加动画,同时保持进度和导航静止不动。
"use client"
import * as React from "react"Card#
使用 Card 插槽组合问卷,同时保留问题标题和描述的语义。
"use client"
import * as React from "react"Dialog#
在 Dialog 中组合 Questionnaire,同时让取消和关闭操作由宿主负责。
"use client"
import * as React from "react"无障碍#
QuestionnaireItem 渲染一个 fieldset,而 QuestionnaireTitle 渲染其
legend。描述和活动错误会与当前项目相关联,无效项目和答案控件会暴露
aria-invalid。
固定选项保留原生单选框和复选框行为。进度会作为带名称的 progressbar 暴露, 导航使用真正的按钮,非活动项目和操作会被隐藏且不可交互。导航成功后会聚焦 新激活的项目;验证失败后会聚焦可用的答案控件。
始终为 QuestionnaireInput 提供可访问名称,可使用可见标签、
aria-label 或 aria-labelledby。占位符不是标签。有关自定义组合的标记方式
以及完整的键盘行为,请参阅
Questionnaire 无障碍指南。
无样式#
Questionnaire 中的行为来自 @shadcn/react package。要直接将其与
你自己的标记和样式结合使用,请参阅 @shadcn/react 下的
Questionnaire。
API 参考#
每个部分的属性、数据属性和渲染状态都记录在
@shadcn/react Questionnaire 页面中。
样式化组件继承相应的无样式属性。导航组件还接受 Button 的 size 和 variant 属性,
而 QuestionnaireActions 是仅用于样式化的布局辅助组件。