Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
On this page

Questionnaire

Collect ordered answers with progress, validation, and keyboard navigation.

Powered by

Installation

npx shadcn@latest add @redpanda/questionnaire
pnpm dlx shadcn@latest add @redpanda/questionnaire
yarn dlx shadcn@latest add @redpanda/questionnaire
bunx shadcn@latest add @redpanda/questionnaire
nubx shadcn@latest add @redpanda/questionnaire
aube dlx shadcn@latest add @redpanda/questionnaire

Usage

Questionnaire manages an ordered set of questions, answer state, validation, progress, and navigation.

import {
  Questionnaire,
  QuestionnaireActions,
  QuestionnaireChoice,
  QuestionnaireChoiceDescription,
  QuestionnaireChoices,
  QuestionnaireDescription,
  QuestionnaireError,
  QuestionnaireInput,
  QuestionnaireItem,
  QuestionnaireNext,
  QuestionnairePrevious,
  QuestionnaireProgress,
  QuestionnaireSkip,
  QuestionnaireSubmit,
  QuestionnaireTitle,
} from "@/components/redpanda-ui/questionnaire"

Define the ordered items on the root. Keep each rendered QuestionnaireItem name and selection mode aligned with its definition.

const items = [
  {
    name: "direction",
    required: true,
    choices: [
      { value: "delegation" },
      { value: "questions" },
    ],
  },
] as const

<Questionnaire items={items} defaultItem="direction" onSubmit={handleSubmit}>
  <QuestionnaireProgress />
  <QuestionnaireItem name="direction" required>
    <QuestionnaireTitle>What should we prototype next?</QuestionnaireTitle>
    <QuestionnaireDescription>Choose one direction.</QuestionnaireDescription>
    <QuestionnaireChoices>
      <QuestionnaireChoice value="delegation">Sub-agent delegation</QuestionnaireChoice>
      <QuestionnaireChoice value="questions">Question prompts</QuestionnaireChoice>
      <QuestionnaireInput aria-label="Another direction" />
    </QuestionnaireChoices>
    <QuestionnaireError />
  </QuestionnaireItem>
  <QuestionnaireActions>
    <QuestionnairePrevious />
    <QuestionnaireSkip />
    <QuestionnaireNext />
    <QuestionnaireSubmit />
  </QuestionnaireActions>
</Questionnaire>

Anatomy

Questionnaire
├── QuestionnaireProgress
├── QuestionnaireItem
│   ├── QuestionnaireTitle
│   ├── QuestionnaireDescription
│   ├── QuestionnaireChoices
│   │   ├── QuestionnaireChoice
│   │   │   └── QuestionnaireChoiceDescription
│   │   └── QuestionnaireInput
│   └── QuestionnaireError
└── QuestionnaireActions
    ├── QuestionnairePrevious
    ├── QuestionnaireSkip
    ├── QuestionnaireNext
    └── QuestionnaireSubmit

Selection patterns

Use the default single-select mode for radio choices. Add multiple to both the item definition and QuestionnaireItem for checkbox choices.

<QuestionnaireItem name="signals" multiple>
  <QuestionnaireTitle>What should every update include?</QuestionnaireTitle>
  <QuestionnaireChoices>
    <QuestionnaireChoice value="progress">Progress</QuestionnaireChoice>
    <QuestionnaireChoice value="decisions">Decisions</QuestionnaireChoice>
  </QuestionnaireChoices>
</QuestionnaireItem>

QuestionnaireInput provides a freeform answer within the active item. Always give it an accessible name using a visible label, aria-label, or aria-labelledby.

Validation

Required items prevent navigation and submission until they have an answer. QuestionnaireError shows the active validation message and the answer controls expose aria-invalid.

Use the controlled item, onItemChange, and invalid props when validation or navigation is owned by application state.

Keyboard behavior

  • Set shortcuts="letters" or shortcuts="numbers" to select fixed choices with matching keys. Shortcuts are off by default.
  • Up and down arrows move focus between answers.
  • Left and right arrows move between answered questions.
  • Enter advances from a selected choice. Control or Command + Enter advances from a freeform input.

Accessibility

QuestionnaireItem renders a fieldset, while QuestionnaireTitle renders its legend. Descriptions and active errors are associated with the current item. Progress uses a named progress bar, and navigation uses real buttons. Inactive items and actions are hidden and inert.

Credits

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on October 7, 2026

Was this page helpful?