Questionnaire
質問の間を方向感を持って移動し、実際の進捗を表示し、キーボードで回答できる、ステップ形式のフォーム。
pnpm dlx shadcn@latest add https://hextaui.com/r/questionnaire.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @shadcn/react @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/questionnaire.tsx components/ui/button.tsx components/ui/input.tsx components/ui/kbd.tsx components/ui/number-flow.tsx lib/motion.ts インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
回答は通常のフォームとして送信され、各項目の name をキーにします。質問は進む方向に向かって動き、カードは各質問の高さになめらかに変化し、進捗は回答済みまたはスキップされた質問に対してのみ満たされます。
リフトのトランジションとバー
transition="lift" は質問をスタックのように上下に動かします。進捗の variant="bar" は連続した1本のバーを表示します。
自動で進む
autoAdvance を指定すると、単一回答を選んだ後、短い間をおいて次へ進むので、1〜5 だけで回答できます。以前の回答を変更しても先へジャンプすることはなく、最後の質問が自動で送信されることもありません。
条件付きの質問
項目を無効にすると除外されます。適用されるまで、進捗とフローから外れます。
右から左
スライドは文字の読み方向に従います。
| キー | アクション |
|---|---|
| ↑↓ | テキストフィールドを含め、回答の間を移動します。移動しても選択はされません。 |
| Space | フォーカスされている回答を選ぶか、複数選択ではそれを切り替えます。 |
| Enter | 次へ進みます。未選択の単一回答では、先にそれを選びます。最後の質問では送信します。 |
| ←→ | 前または次の質問。右から左では左右が反転します。回答が必要なとき、Next は揺れます。テキストフィールド内ではカーソルを動かします。 |
| HomeEnd | 最初または最後の回答。 |
| A1 | shortcuts が設定されていると、キーで回答を選びます。キーキャップは questionnaire がフォーカスされると明るくなります。開始するには内側のどこかをクリックしてください。 |
| Esc | テキストフィールドから抜け、文字のショートカットが再び使えるようになります。 |
| ⌘Enter | どこからでも送信します。 |
- 各
QuestionnaireItemは<fieldset>で、そのタイトルが<legend>です。非アクティブな質問は、退場アニメーション中のものも含めて、非表示かつ inert になります。 - 進捗は「Question 2 of 5」と読み上げる
progressbarで、セグメントと回転する数字は装飾です。 - エラーには
role="alert"を使い、無効な回答にはaria-invalidが付きます。 - 視差効果の軽減が有効な場合、質問は即座に切り替わり、揺れもありません。
| プロパティ | 型 | デフォルト |
|---|---|---|
transition | "slide" | "lift" | "slide" |
autoAdvance単一回答が初めて選ばれてから350ms後に進みます。 | boolean | false |
shortcutsすべての回答にキーのショートカットを追加します。 | "letters" | "numbers" | – |
item | string | – |
defaultItem | string | – |
onItemChange | (item: string) => void | – |
| 属性 | 説明 |
|---|---|
data-slot="questionnaire" | フォーム。data-transition を持ちます。 |
data-current / data-total | 現在の位置と質問数。 |
data-first / data-last | 最初または最後の質問に付きます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
variant | "segments" | "bar" | "segments" |
| 属性 | 説明 |
|---|---|
data-slot="questionnaire-progress-segment" | 質問ごとに1つ。data-status、data-active、data-invalid を持ちます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
nameフォームフィールドの名前。 | string | – |
required | boolean | false |
multipleラジオの代わりにチェックボックス。 | boolean | false |
disabledその質問をフローから除外します。 | boolean | false |
onStatusChange | (status) => void | – |
| 属性 | 説明 |
|---|---|
data-status | "unanswered"、"answered"、"skipped"。 |
data-active | 現在の質問。 |
data-invalid | 回答が必要です。 |
data-leaving | 退場アニメーション中の質問。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
value | string | – |
defaultChecked | boolean | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <label> |
| 属性 | 説明 |
|---|---|
data-checked / data-unchecked | その回答が選ばれているかどうか。 |
data-type | "radio" または "checkbox"。 |
data-shortcut | その回答のキー。 |
選択肢と並ぶ自由記述の回答。入力すると選んだ選択肢が解除されます。ラベルか aria-label を付けてください。
| プロパティ | 型 | デフォルト |
|---|---|---|
variant | Button variant | "ghost", or "default" for Next and Submit |
size | Button size | "default" |
QuestionnaireNext と QuestionnaireSubmit は同じスロットを共有するため、最後の質問では何も動かさずに Next が Submit に入れ替わります。
- Buttonすべてのバリアントとサイズのボタンです。読み込み、成功、エラーのフローを内蔵し、高速なリクエストではスピナーを省略します。
- Input3つのサイズ、無効状態と読み取り専用状態、ネイティブのバリデーションスタイル、スマートフォンでズームされない16pxのタッチ用フォントを備えたテキスト入力です。
- Kbdショートカット用のキーキャップです。プラットフォームごとに正しい記号を表示し、正しく読み上げ、実際のキーと同じように押し込まれます。
- Motionすべてのコンポーネントがアニメーションに使うイージングカーブ、継続時間、モーション軽減のチェックと、サイズのモーフィングやスライドするハイライト用のフックです。
- Number flow変化した桁だけが回転するアニメーション付きの数値です。任意のIntlフォーマットとロケールに対応します。
- Calendar単一、範囲、複数選択に対応する日付グリッドです。月のスライド、範囲のプレビュー、タッチしやすいサイズの日付セルを備えています。
使用しているブロック
Questionnaire の上に構築されるブロック。