121k

问卷

包含单选题、多选题、自由回答题和可跳过问题的多步骤问卷。

Question 1 of 3
What should the agent build next?

Choose a direction or describe another task.

"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
    └── QuestionnaireSubmit

Questionnaire 负责管理有序项目、当前项目、答案状态、验证、 进度和导航。包含它的页面、卡片、对话框或抽屉负责管理 关闭和取消行为、持久化、传输以及分支逻辑。

服务端渲染

items 传递给服务端,以渲染当前项目、进度、操作和回答快捷方式。请参阅 headless Questionnaire 了解完整行为。

多项选择

使用 multiple 表示可接受多个固定答案的项目。

What context should the agent inspect?

Select every source that may affect the implementation.

"use client"

import * as React from "react"

自由回答

当用户可以提供其他答案时,使用固定选项组合 QuestionnaireInput

How should the agent approach this refactor?

Choose a strategy or write a more specific instruction.

"use client"

import * as React from "react"

明确跳过

当可选项目可能会被有意留空时,添加 QuestionnaireSkip

Question 1 of 3
What kind of change is this?

Choose the category that best describes the work.

"use client"

import * as React from "react"

快捷键

使用 shortcuts 为每个答案分配一个字母或数字键。

What should the agent do next?

Use the displayed shortcut or navigate with the keyboard.

"use client"

import * as React from "react"

自定义验证

将受控导航与 Zod 等外部架构结合,在返回无效项目的同时显示其错误。

How much detail should the answer include?

Choose the response depth.

1 / 2
"use client"

import * as React from "react"

受控

从主机状态控制当前项目,例如返回到无效步骤。

Current checkpoint: Change scope

Question 1 of 3
What may the agent change?

The host stores the active checkpoint while Questionnaire navigates.

"use client"

import * as React from "react"

恢复

恢复已保存的活动项目和默认答案,然后将更改重置为该保存状态。

Question 2 of 3
How should the migration be verified?

These checks were selected during the previous session.

"use client"

import * as React from "react"

条件项目

禁用不适用于用户之前回答的项目。

Question 1 of 2
Where should the agent run?

Cloud runs add an environment question to this flow.

"use client"

import * as React from "react"

导航状态

读取项目状态,以启用禁用导航和自定义操作样式。

Question 1 of 2
What may the agent modify?

Next is intentionally disabled until an answer is selected.

"use client"

import * as React from "react"

自定义进度

使用 Progress 渲染状态构建自定义进度指示器。

Checkpoint 1 of 4
How large is the change?
"use client"

import * as React from "react"

动画项目

为活动项目添加动画,同时保持进度和导航静止不动。

Question 1 of 3
What should the agent do?

Choose the task for this run.

"use client"

import * as React from "react"

Card

使用 Card 插槽组合问卷,同时保留问题标题和描述的语义。

What should the agent work on?
Choose the task that should be handled next.
Question 1 of 2
"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-labelaria-labelledby。占位符不是标签。有关自定义组合的标记方式 以及完整的键盘行为,请参阅 Questionnaire 无障碍指南

无样式

Questionnaire 中的行为来自 @shadcn/react package。要直接将其与 你自己的标记和样式结合使用,请参阅 @shadcn/react 下的 Questionnaire

API 参考

每个部分的属性、数据属性和渲染状态都记录在 @shadcn/react Questionnaire 页面中。 样式化组件继承相应的无样式属性。导航组件还接受 Button 的 sizevariant 属性, 而 QuestionnaireActions 是仅用于样式化的布局辅助组件。