Patternassessment

Questionnaire

Stable

Uma pergunta por vez, e o caminho de ida e volta entre elas: posição, alternativas de uma ou de várias escolhas, resposta digitada, atalho de teclado por alternativa e a linha de ações. Guarda as respostas e a posição, cada uma podendo ser do chamador. Não sabe o que é certo — devolve as respostas e quem chamou decide.

Instalação

npx up-web-ds add questionnaire

Preview

Basic

Pergunta 1 de 0

Multiple Choice

Progresso da trilha
x

Etapa 1 de 3.

With Choice Descriptions

In English

Question 1 of 0

Graded

Pergunta 1 de 0

Respondidas até agora: 0

All states

Basic

Pergunta 1 de 0

Multiple Choice

Progresso da trilha
x

Etapa 1 de 3.

With Choice Descriptions

In English

Question 1 of 0

Graded

Pergunta 1 de 0

Respondidas até agora: 0

Usage

@/components/questionnaire
import {
  Questionnaire,
  QuestionnaireActions,
  QuestionnaireChoice,
  QuestionnaireChoices,
  QuestionnaireDescription,
  QuestionnaireError,
  QuestionnaireInput,
  QuestionnaireItem,
  QuestionnaireNext,
  QuestionnairePrevious,
  QuestionnaireProgress,
  QuestionnaireSkip,
  QuestionnaireSubmit,
  QuestionnaireTitle,
} from '@/components/questionnaire'
Questionnaire
<Questionnaire className="max-w-lg">
  <QuestionnaireProgress />

  <QuestionnaireItem name="nivel" required>
    <QuestionnaireTitle>
      Como você descreveria seu nível em React?
    </QuestionnaireTitle>
    <QuestionnaireDescription>
      Serve para escolher o ritmo da trilha, não para avaliar ninguém.
    </QuestionnaireDescription>
    <QuestionnaireChoices>
      <QuestionnaireChoice shortcut="1" value="inicio">
        Começando agora
      </QuestionnaireChoice>
      <QuestionnaireChoice shortcut="2" value="projetos">
        Já entreguei alguns projetos
      </QuestionnaireChoice>
      <QuestionnaireChoice shortcut="3" value="producao">
        Mantenho React em produção
      </QuestionnaireChoice>
    </QuestionnaireChoices>
    <QuestionnaireError />
  </QuestionnaireItem>

  <QuestionnaireItem name="ritmo">
    <QuestionnaireTitle>Quanto tempo por semana?</QuestionnaireTitle>
    <QuestionnaireChoices>
      <QuestionnaireChoice shortcut="1" value="2h">
        Até 2 horas
      </QuestionnaireChoice>
      <QuestionnaireChoice shortcut="2" value="5h">
        Entre 2 e 5 horas
      </QuestionnaireChoice>
      <QuestionnaireChoice shortcut="3" value="mais">
        Mais de 5 horas
      </QuestionnaireChoice>
    </QuestionnaireChoices>
    <QuestionnaireError />
  </QuestionnaireItem>

  <QuestionnaireItem name="objetivo">
    <QuestionnaireTitle>
      O que você quer conseguir fazer?
    </QuestionnaireTitle>
    <QuestionnaireInput placeholder="Em uma frase" />
    <QuestionnaireError />
  </QuestionnaireItem>

  <QuestionnaireActions>
    <QuestionnairePrevious />
    <QuestionnaireSkip />
    <QuestionnaireNext />
    <QuestionnaireSubmit />
  </QuestionnaireActions>
</Questionnaire>

Props

Questionnaire

Props de Questionnaire
PropTypeDefaultDescription
defaultStepnumber0The question to open on.
defaultValueReadonly<Record<string, QuestionnaireAnswer>>{}The answers to start from.
labelsPartial<QuestionnaireLabels>sem valor padrãoOverrides for the fixed strings. Pass only the ones to change.
onStepChange((step: number) => void)sem valor padrão
onSubmit((answers: QuestionnaireAnswers) => void)sem valor padrãoCalled with every answer once the last question is submitted.
onValueChange((answers: QuestionnaireAnswers) => void)sem valor padrão
stepnumbersem valor padrãoIndex of the question on screen, when the caller owns it.
valueReadonly<Record<string, QuestionnaireAnswer>>sem valor padrãoEvery answer, when the caller owns them.

Estende Omit< ComponentProps<'form'>, 'defaultValue' | 'onSubmit' >. Aceita também os atributos padrão de um elemento React (286 não listados).

QuestionnaireProgress

Estende ComponentProps<'p'>. Aceita também os atributos padrão de um elemento React (280 não listados).

QuestionnaireItem

Props de QuestionnaireItem
PropTypeDefaultDescription
name, obrigatóriastringsem valor padrãoKey this question's answer is stored under.
requiredbooleanfalseWhether the reader may move on without answering.

Estende Omit<ComponentProps<'div'>, 'title'>. Aceita também os atributos padrão de um elemento React (279 não listados).

QuestionnaireTitle

Estende ComponentProps<'h3'>. Aceita também os atributos padrão de um elemento React (280 não listados).

QuestionnaireDescription

Estende ComponentProps<'p'>. Aceita também os atributos padrão de um elemento React (280 não listados).

QuestionnaireChoices

Props de QuestionnaireChoices
PropTypeDefaultDescription
type"multiple" | "single"'single'Whether the question takes one answer or several. `single` is a radio group, `multiple` a group of checkboxes.

Estende HTMLAttributes<HTMLElement>. Aceita também os atributos padrão de um elemento React (278 não listados).

QuestionnaireChoice

Props de QuestionnaireChoice
PropTypeDefaultDescription
value, obrigatóriastringsem valor padrãoWhat this choice records as the answer.
disabledbooleanfalse
shortcutstringsem valor padrãoA key that chooses it. Shown as a `Kbd`, and pressed anywhere in the form.

Estende Omit< ComponentProps<'label'>, 'onChange' >. Aceita também os atributos padrão de um elemento React (281 não listados).

QuestionnaireChoiceDescription

Estende ComponentProps<'span'>. Aceita também os atributos padrão de um elemento React (280 não listados).

QuestionnaireInput

Props de QuestionnaireInput
PropTypeDefaultDescription
classNamestring | ((state: InputState) => string | undefined)sem valor padrãoCSS class applied to the element, or a function that returns a class based on the component's state.
onValueChange((value: string, eventDetails: Input.ChangeEventDetails) => void)sem valor padrãoCallback fired when the `value` changes. Use when controlled.
renderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, InputState>sem valor padrãoAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
styleReact.CSSProperties | ((state: InputState) => React.CSSProperties | undefined)sem valor padrãoStyle applied to the element, or a function that returns a style object based on the component's state.

Estende Omit< ComponentProps<typeof Input>, 'value' | 'defaultValue' | 'onChange' >. Aceita também os atributos padrão de um elemento React (303 não listados).

QuestionnaireError

Estende ComponentProps<'p'>. Aceita também os atributos padrão de um elemento React (280 não listados).

QuestionnaireActions

Estende ComponentProps<'div'>. Aceita também os atributos padrão de um elemento React (280 não listados).

QuestionnairePrevious

Props de QuestionnairePrevious
PropTypeDefaultDescription
onClick((event: BaseUIEvent<MouseEvent<HTMLButtonElement, MouseEvent>>) => void)sem valor padrão
size"default" | "sm" | "xs" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | nullsem valor padrão
variant"link" | "destructive" | "primary" | "outline" | "secondary" | "ghost" | null'outline'
classNamestring | ((state: ButtonState) => string | undefined)sem valor padrãoCSS class applied to the element, or a function that returns a class based on the component's state.
focusableWhenDisabledbooleanfalseWhether the button should be focusable when disabled.
nativeButtonbooleantrueWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).
renderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ButtonState>sem valor padrãoAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
styleReact.CSSProperties | ((state: ButtonState) => React.CSSProperties | undefined)sem valor padrãoStyle applied to the element, or a function that returns a style object based on the component's state.

Estende Omit<ComponentProps<typeof Button>, 'onClick'>. Aceita também os atributos padrão de um elemento React (284 não listados).

QuestionnaireSkip

Props de QuestionnaireSkip
PropTypeDefaultDescription
onClick((event: BaseUIEvent<MouseEvent<HTMLButtonElement, MouseEvent>>) => void)sem valor padrão
size"default" | "sm" | "xs" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | nullsem valor padrão
variant"link" | "destructive" | "primary" | "outline" | "secondary" | "ghost" | null'ghost'
classNamestring | ((state: ButtonState) => string | undefined)sem valor padrãoCSS class applied to the element, or a function that returns a class based on the component's state.
focusableWhenDisabledbooleanfalseWhether the button should be focusable when disabled.
nativeButtonbooleantrueWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).
renderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ButtonState>sem valor padrãoAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
styleReact.CSSProperties | ((state: ButtonState) => React.CSSProperties | undefined)sem valor padrãoStyle applied to the element, or a function that returns a style object based on the component's state.

Estende Omit<ComponentProps<typeof Button>, 'onClick'>. Aceita também os atributos padrão de um elemento React (284 não listados).

QuestionnaireNext

Props de QuestionnaireNext
PropTypeDefaultDescription
onClick((event: BaseUIEvent<MouseEvent<HTMLButtonElement, MouseEvent>>) => void)sem valor padrão
size"default" | "sm" | "xs" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | nullsem valor padrão
variant"link" | "destructive" | "primary" | "outline" | "secondary" | "ghost" | nullsem valor padrão
classNamestring | ((state: ButtonState) => string | undefined)sem valor padrãoCSS class applied to the element, or a function that returns a class based on the component's state.
focusableWhenDisabledbooleanfalseWhether the button should be focusable when disabled.
nativeButtonbooleantrueWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).
renderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ButtonState>sem valor padrãoAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
styleReact.CSSProperties | ((state: ButtonState) => React.CSSProperties | undefined)sem valor padrãoStyle applied to the element, or a function that returns a style object based on the component's state.

Estende Omit<ComponentProps<typeof Button>, 'onClick'>. Aceita também os atributos padrão de um elemento React (284 não listados).

QuestionnaireSubmit

Props de QuestionnaireSubmit
PropTypeDefaultDescription
size"default" | "sm" | "xs" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | nullsem valor padrão
variant"link" | "destructive" | "primary" | "outline" | "secondary" | "ghost" | nullsem valor padrão
classNamestring | ((state: ButtonState) => string | undefined)sem valor padrãoCSS class applied to the element, or a function that returns a class based on the component's state.
focusableWhenDisabledbooleanfalseWhether the button should be focusable when disabled.
nativeButtonbooleantrueWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).
renderReact.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ButtonState>sem valor padrãoAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
styleReact.CSSProperties | ((state: ButtonState) => React.CSSProperties | undefined)sem valor padrãoStyle applied to the element, or a function that returns a style object based on the component's state.

Estende Omit<ActionProps, 'onClick'>. Aceita também os atributos padrão de um elemento React (284 não listados).

prop obrigatória.

Composition

O Questionnaire é o form: guarda as respostas, a posição e as strings fixas. O QuestionnaireProgress diz onde a pessoa está; cada QuestionnaireItem é uma pergunta, e só a atual fica visível; o QuestionnaireActions é a linha de baixo, onde Avançar e Enviar dividem a mesma célula — escreva os dois e aparece o que couber.

Composição de Questionnaire

Questionnaire

  • QuestionnaireProgress
  • QuestionnaireItem
    • QuestionnaireTitle
    • QuestionnaireDescription
    • QuestionnaireChoices
      • QuestionnaireChoice
        • QuestionnaireChoiceDescription
    • QuestionnaireInput
    • QuestionnaireError
  • QuestionnaireActions
    • QuestionnairePrevious
    • QuestionnaireSkip
    • QuestionnaireNext
    • QuestionnaireSubmit

Metadata

Notas de acessibilidade

Verificado em tests/e2e/questionnaire.spec.ts no Chromium desktop e mobile, em light e dark, com Axe sem violações WCAG 2.2 AA. Teclado: o grupo de alternativas é uma parada de tabulação só e as setas escolhem dentro dele, com anel de foco lido do navegador; a próxima parada é a linha de ações. O atalho de cada alternativa funciona de qualquer lugar do formulário e se cala enquanto uma resposta de texto está sendo digitada, então um dígito digitado é um dígito. Leitor de tela: uma escolha é um radiogroup e várias são um fieldset, os dois nomeados pela pergunta e descritos pela descrição dela e, quando existe, pelo erro; a posição é um role="status", então avançar é anunciado sem roubar o foco; o atalho entra no nome como atalho e não como parte da resposta, com o keycap aria-hidden ao lado do texto que o diz. A pergunta que não é a atual continua montada — para que a contagem seja a que o autor escreveu — e fica hidden, que é display:none: fora da ordem de tabulação e fora da árvore, verificado em navegador. Toque verificado em 375px com emulação de toque: o controle tem 16px e não é o alvo — o alvo é o cartão, um label de 44px cujas quatro bordas respondem ao toque —, os botões da linha de ações atingem 24x24 e nada rola horizontalmente. Reduced motion verificado em navegador com prefers-reduced-motion: reduce — trocar de pergunta é uma troca de visibilidade e não uma travessia, nada se desloca, e o que transita é cor, que fica.

Classificação

Layer
Pattern
Domínio
Education
Categoria
assessment
Status
Stable

Origem e distribuição

Fonte
shadcn registry / questionnaire
Licença
MIT
Distribuição
Interna

Acessibilidade

  • Teclado: revisado
  • Leitor de tela: revisado
  • Touch: revisado
  • Reduced motion: revisado

Dependências

Pacotes
Nenhuma
Ícones
Nenhum
Usado por
Nenhum ainda