Skip to content

Questionnaire

Kuesioner bertahap dengan pertanyaan pilihan tunggal, pilihan ganda, isian bebas, dan pertanyaan yang boleh dilewati.

Question 1 of 3
What should the agent build next?

Choose a direction or describe another task.

Instalasi

CLI

bash
npx shadcn-vue@latest add questionnaire

Manual

Salin dan tempel kode sumber di GitHub ke project Anda.

Sesuaikan path import dengan struktur project Anda.

Penggunaan

vue
<script setup lang="ts">
import {
  Questionnaire,
  QuestionnaireActions,
  QuestionnaireChoice,
  QuestionnaireChoices,
  QuestionnaireDescription,
  QuestionnaireError,
  QuestionnaireItem,
  QuestionnaireNext,
  QuestionnairePrevious,
  QuestionnaireProgress,
  QuestionnaireSkip,
  QuestionnaireSubmit,
  QuestionnaireTitle,
} from '@/components/ui/questionnaire'

const items = [
  { name: 'direction', required: true },
  { name: 'timing', required: true },
]

function handleSubmit(event: Event) {
  event.preventDefault()

  const answers = new FormData(event.target as HTMLFormElement)
  console.log(Object.fromEntries(answers))
}
</script>

<template>
  <Questionnaire :items="items" @submit="handleSubmit">
    <QuestionnaireProgress />

    <QuestionnaireItem name="direction" required>
      <QuestionnaireTitle>What should the agent build next?</QuestionnaireTitle>
      <QuestionnaireDescription>Choose a direction.</QuestionnaireDescription>
      <QuestionnaireChoices>
        <QuestionnaireChoice value="tool-calls">Tool call timeline</QuestionnaireChoice>
        <QuestionnaireChoice value="approvals">Approval checkpoints</QuestionnaireChoice>
      </QuestionnaireChoices>
      <QuestionnaireError />
    </QuestionnaireItem>

    <QuestionnaireItem name="timing" required>
      <QuestionnaireTitle>When should work begin?</QuestionnaireTitle>
      <QuestionnaireChoices>
        <QuestionnaireChoice value="now">Start now</QuestionnaireChoice>
        <QuestionnaireChoice value="backlog">Add it to the backlog</QuestionnaireChoice>
      </QuestionnaireChoices>
      <QuestionnaireError />
    </QuestionnaireItem>

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

Komposisi

Susunan berikut adalah cara membangun sebuah questionnaire:

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

Questionnaire menghasilkan <form> sungguhan, dan tiap itemnya menghasilkan <fieldset> beserta <legend>. Jawabannya terkirim lewat FormData, jadi Anda tidak perlu state tambahan.

Render di Sisi Server

Isi prop items supaya item aktif, progres, tombol aksi, dan pintasan jawaban ikut dirender di server. Tanpa itu, questionnaire baru mengetahui urutannya setelah semua item ter-mount di klien.

Fitur

  • Satu pertanyaan dalam satu waktu, dengan progres, navigasi, dan validasi yang sudah ditangani otomatis.
  • Jawaban pilihan tunggal, pilihan ganda, isian bebas, dan pertanyaan yang sengaja dilewati.
  • Pintasan keyboard untuk memilih jawaban, plus navigasi antar pertanyaan dan jawaban lewat tombol panah.
  • Prop items yang deklaratif untuk mengatur urutan, item bersyarat, dan penetapan pintasan yang konsisten.
  • Navigasi yang dikendalikan lewat v-model:item untuk alur validasi buatan sendiri.
  • Reset form bawaan browser mengembalikan jawaban ke nilai yang Anda tandai sebagai bawaan.

Contoh

Pilihan Ganda

Pakai multiple untuk pertanyaan yang menerima lebih dari satu jawaban tetap.

What context should the agent inspect?

Select every source that may affect the implementation.

Jawaban Bebas

Padukan QuestionnaireInput dengan pilihan tetap kalau pengguna boleh mengisi jawaban lain.

How should the agent approach this refactor?

Choose a strategy or write a more specific instruction.

Melewati Pertanyaan

Tambahkan QuestionnaireSkip kalau sebuah pertanyaan opsional boleh sengaja dikosongkan.

Question 1 of 3
What kind of change is this?

Choose the category that best describes the work.

Pintasan Keyboard

Tetapkan tombol huruf atau angka untuk tiap jawaban lewat shortcuts. Deklarasikan choices pada items supaya tombolnya tetap konsisten berapa pun urutan tampilnya.

What should the agent do next?

Use the displayed shortcut or navigate with the keyboard.

Validasi Buatan Sendiri

Padukan navigasi terkendali dengan skema eksternal seperti Zod untuk kembali ke pertanyaan yang belum valid dan menampilkan pesan error-nya.

How much detail should the answer include?

Choose the response depth.

1 / 2

QuestionnaireError sudah punya pesan bawaan, jadi tampilkan pesan Anda sendiri hanya kalau memang ada:

vue
<QuestionnaireError>
  <template v-if="errors.detail">
    {{ errors.detail }}
  </template>
</QuestionnaireError>

Dikendalikan dari Luar

Kendalikan item aktif dari state induk, misalnya untuk kembali ke langkah yang belum valid. Pakai v-model:item.

Current checkpoint: Change scope

Question 1 of 3
What may the agent change?

The host stores the active checkpoint while Questionnaire navigates.

Melanjutkan Sesi

Pulihkan item aktif dan jawaban bawaan yang tersimpan, lalu kembalikan perubahan ke keadaan simpanan itu.

Question 2 of 3
How should the migration be verified?

These checks were selected during the previous session.

Pertanyaan Bersyarat

Nonaktifkan pertanyaan yang tidak relevan dengan jawaban pengguna sebelumnya.

Question 1 of 2
Where should the agent run?

Cloud runs add an environment question to this flow.

State Navigasi

Baca status tiap item untuk menonaktifkan navigasi dan menyesuaikan style tombol aksi. Dengarkan @update:status pada item yang ingin Anda pantau.

Question 1 of 2
What may the agent modify?

Next is intentionally disabled until an answer is selected.

Indikator Progres Kustom

Pakai state pada slot progres untuk membuat indikator sendiri. QuestionnaireProgress menyediakan current, total, first, dan last.

Checkpoint 1 of 4
How large is the change?

Item Beranimasi

Animasikan item yang sedang aktif sementara progres dan navigasinya tetap diam. Item aktif ditandai dengan data-active.

Question 1 of 3
What should the agent do?

Choose the task for this run.

Card

Padukan Questionnaire dengan slot Card tanpa mengorbankan makna judul dan keterangan pertanyaannya. Pakai as-child untuk menampilkan sebuah bagian sebagai komponen lain:

vue
<QuestionnaireTitle as-child>
  <CardTitle>What should the agent work on?</CardTitle>
</QuestionnaireTitle>

What should the agent work on?

Choose the task that should be handled next.

Question 1 of 2

QuestionnaireProgress, QuestionnaireTitle, QuestionnaireDescription, QuestionnaireChoices, QuestionnaireError, QuestionnaireActions, dan keempat tombol navigasinya sama-sama menerima as dan as-child. Memakai as-child pada judul akan menggantikan legend yang menamai item, sehingga item itu dilabeli oleh judul yang ditampilkan. Judul dan keterangannya tetap mempertahankan id dari anak yang mereka render.

Dialog

Padukan Questionnaire di dalam Dialog, sementara urusan membatalkan dan menutupnya tetap dipegang komponen induk.

KeyDescription
Arrow DownMoves focus to the next answer.
Arrow UpMoves focus to the previous answer.
Arrow RightMoves to the next question once the current one is answered.
Arrow LeftMoves to the previous question.
EnterConfirms the focused answer and moves on, or submits on the last question.
Meta+Enter / Ctrl+EnterConfirms the active question from anywhere in the form.
AZ / 19Selects the matching choice when shortcuts is set.

Aksesibilitas

QuestionnaireItem menghasilkan fieldset beserta legend, jadi tiap pertanyaan dibacakan bersama jawabannya. Keterangan dan pesan error dikaitkan ke item lewat aria-describedby, dan item yang belum valid menyertakan aria-invalid.

QuestionnaireProgress menghasilkan progressbar bernama yang membacakan pertanyaan saat ini. Item yang tidak aktif diberi hidden dan inert, jadi tidak ikut urutan Tab maupun pohon aksesibilitas.

Tombol navigasinya adalah tombol sungguhan. QuestionnaireSubmit mengirim form, jadi questionnaire tetap bekerja dengan autofill browser dan pengiriman form bawaan.

Referensi API

Questionnaire

Form terluar. Mengurus item aktif, progres, validasi, dan navigasi keyboard.

PropTypeDefaultDescription
itemsQuestionnaireItemDefinition[]-Declares item order, required, disabled, and the choices used for shortcuts.
itemstring-The active item. Use with v-model:item.
defaultItemstring-The item shown first. Ignored when item is provided.
shortcuts"letters" | "numbers"-Assigns a keyboard shortcut to every choice.
noValidatebooleantrueSet to false to run native constraint validation on answered items.
classHTMLAttributes["class"]-Additional classes to apply to the form.
EmitPayloadDescription
update:itemstringThe active item changed.
submitEventEvery item is valid. Call event.preventDefault() to handle it yourself.
resetEventThe form was reset. Call event.preventDefault() to keep the answers.

QuestionnaireProgress

Sebuah progressbar yang membacakan pertanyaan aktif. Menyediakan current, total, first, dan last ke slot bawaannya.

PropTypeDefaultDescription
classHTMLAttributes["class"]-Additional classes to apply to the progress bar.
asAsTag | Component"div"The element or component to render as.
asChildbooleanfalseRender the child element instead.

QuestionnaireItem

Satu pertanyaan, ditampilkan sebagai fieldset. Hanya item yang aktif yang terlihat.

PropTypeDefaultDescription
namestring-Required. The name the answer submits under.
requiredbooleanfalseRequires an answer before the questionnaire can continue.
multiplebooleanfalseRenders choices as checkboxes and keeps every selected answer.
disabledbooleanfalseRemoves the item from the flow without unmounting it.
invalidbooleanfalseMarks the item invalid from outside, for example after schema validation.
classHTMLAttributes["class"]-Additional classes to apply to the item.
EmitPayloadDescription
update:status"unanswered" | "answered" | "skipped"The item status changed.

QuestionnaireTitle

Teks pertanyaannya, ditampilkan sebagai legend.

PropTypeDefaultDescription
classHTMLAttributes["class"]-Additional classes to apply to the title.
asAsTag | Component"legend"The element or component to render as.
asChildbooleanfalseRender the child element instead.

QuestionnaireDescription

Teks bantuan yang dikaitkan ke item lewat aria-describedby.

PropTypeDefaultDescription
idstring-Overrides the generated id.
asAsTag | Component"p"The element or component to render as.
asChildbooleanfalseRender the child element instead.
classHTMLAttributes["class"]-Additional classes to apply to the description.

QuestionnaireChoices

Daftar jawaban. Membungkus pilihan-pilihan beserta isian bebas kalau ada.

PropTypeDefaultDescription
classHTMLAttributes["class"]-Additional classes to apply to the list.
asAsTag | Component"div"The element or component to render as.
asChildbooleanfalseRender the child element instead.

QuestionnaireChoice

Satu jawaban, ditampilkan sebagai radio atau checkbox tergantung jenis pertanyaannya.

PropTypeDefaultDescription
valuestring-Required. The submitted value.
checkedboolean-Controlled checked state. Use with v-model:checked.
defaultCheckedbooleanfalseChecks the choice on mount and after a native form reset.
disabledbooleanfalseDisables the choice.
classHTMLAttributes["class"]-Additional classes to apply to the choice.
EmitPayloadDescription
update:checkedbooleanThe choice was checked or cleared.
changeEventThe native change event.

QuestionnaireChoiceDescription

Teks tambahan di dalam sebuah pilihan.

PropTypeDefaultDescription
classHTMLAttributes["class"]-Additional classes to apply to the description.

QuestionnaireInput

Jawaban bebas. Dianggap menjawab pertanyaan selama isiannya tidak kosong, dan dikirim memakai nama item tersebut.

PropTypeDefaultDescription
modelValuestring | number-Controlled value. Use with v-model.
defaultValuestring | number-Fills the answer on mount and after a native reset.
typeQuestionnaireInputType"text"The input type.
disabledbooleanfalseDisables the input.
classHTMLAttributes["class"]-Additional classes to apply to the input.

QuestionnaireError

Pesan error item. Tersembunyi sampai item itu dinyatakan tidak valid, dan memakai pesan bawaan kalau Anda tidak menyediakannya.

PropTypeDefaultDescription
idstring-Overrides the generated id.
asAsTag | Component"p"The element or component to render as.
asChildbooleanfalseRender the child element instead.
classHTMLAttributes["class"]-Additional classes to apply to the error.

QuestionnaireActions

Baris tombol navigasi.

PropTypeDefaultDescription
classHTMLAttributes["class"]-Additional classes to apply to the row.
asAsTag | Component"div"The element or component to render as.
asChildbooleanfalseRender the child element instead.

QuestionnairePrevious, QuestionnaireSkip, QuestionnaireNext, dan QuestionnaireSubmit

Tombol-tombol navigasi. Masing-masing menyembunyikan diri saat tidak relevan: QuestionnairePrevious di item pertama, QuestionnaireSkip di item wajib, QuestionnaireNext di item terakhir, dan QuestionnaireSubmit di semua item selain yang terakhir.

PropTypeDefaultDescription
variantButtonVariants["variant"]"outline" / "default"The button variant.
sizeButtonVariants["size"]"default"The button size.
disabledbooleanfalseDisables the button.
asAsTag | Component"button"The element or component to render as.
asChildbooleanfalseRender the child element instead.
classHTMLAttributes["class"]-Additional classes to apply to the button.

Dirilis di bawah lisensi MIT. Fork dari shadcn-vue.