ساخت پرسشنامههای چندمرحلهای و دسترسپذیر با پشتیبانی از پاسخهای تکانتخابی، چندانتخابی، متنی و رد کردن عمدی سؤال.
Questionnaire یک primitive فرم بدون استایل است که هر بار یک سؤال را نمایش میدهد و مدیریت پاسخها، پیشرفت، اعتبارسنجی و جابهجایی بین مراحل را بر عهده دارد.
برای سناریوهایی مثل پرسشهای تکمیلی Agentها، Onboarding، نظرسنجی، فرمهای دریافت اطلاعات و تنظیمات چندمرحلهای مناسب است.
نسخهٔ بدون استایل کنترل کاملی روی ساختار HTML و ظاهر در اختیار شما قرار میدهد. برای نسخهٔ استایلدار و نمونههای دارای Theme، صفحهٔ Questionnaire را ببینید.
پکیج @farsiui/react را نصب کنید:
import { Questionnaire } from "@farsiui/react/questionnaire"Questionnaire تمام بخشهای خود را از طریق یک namespace ارائه میکند. هر بخش نیز Props مربوط به Element پیشفرض خود را میپذیرد.
<Questionnaire.Root>
<Questionnaire.Progress />
<Questionnaire.Item name="question">
<Questionnaire.Title />
<Questionnaire.Description />
<Questionnaire.Choices>
<Questionnaire.Choice>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel />
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
<Questionnaire.Input />
</Questionnaire.Choices>
<Questionnaire.Error />
</Questionnaire.Item>
<Questionnaire.Previous />
<Questionnaire.Skip />
<Questionnaire.Next />
<Questionnaire.Submit />
</Questionnaire.Root>Root یک فرم ایجاد میکند. هر Item یک fieldset است و Title بهعنوان legend آن استفاده میشود.
ChoiceInput نیز از ورودیهای Native رادیویی و چکباکس استفاده میکند.
کامپوننت استایلدار از نامهای تخت استفاده میکند:
در نسخهٔ استایلدار، QuestionnaireChoice ورودی، Label، میانبر و نشانگر بصری را برای شما ترکیب میکند. در نسخهٔ بدون استایل باید این بخشها را خودتان کنار هم قرار دهید.
هر Item یک مرحله از پرسشنامه است. مقدار name مرحله را مشخص میکند و بهعنوان نام فیلد فرم برای پاسخهای آن مرحله استفاده میشود.
مقدار Choice.value نیز پاسخی است که هنگام ارسال فرم ثبت میشود.
const items = [
{
name: "prototype",
required: true,
prompt: "بعداً چه چیزی را نمونهسازی کنیم؟",
description: "یک مسیر انتخاب کنید یا خودتان بنویسید.",
choices: [
{
value: "delegation",
label: "واگذاری",
description: "نشان دهد کار چگونه به متخصص منتقل میشود.",
},
{
value: "questions",
label: "پرسشهای راهنما",
description: "در زمان انتظار، گزینهها را نشان دهد.",
},
{ value: "both", label: "هر دو با هم" },
],
input: { label: "پاسخ دیگر", placeholder: "پاسخ دیگری بنویسید…" },
},
{
name: "detail",
required: false,
prompt: "چقدر جزئیات لازم است؟",
description: "اگر مطمئن نیستید، این سؤال را رد کنید.",
choices: [
{ value: "focused", label: "متمرکز" },
{ value: "complete", label: "جریان کامل" },
],
},
] as const"use client"
import * as React from "react"
import { Questionnaire } from "@farsiui/react/questionnaire"
export function ProjectQuestionnaire() {
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault()
const formData = new FormData(event.currentTarget)
console.log({
prototype: formData.get("prototype"),
detail: formData.get("detail"),
})
}
return (
<Questionnaire.Root items={items} onSubmit={handleSubmit}>
<Questionnaire.Progress />
{items.map((question) => (
<Questionnaire.Item
key={question.name}
name={question.name}
required={question.required}
>
<Questionnaire.Title>{question.prompt}</Questionnaire.Title>
<Questionnaire.Description>
{question.description}
</Questionnaire.Description>
<Questionnaire.Choices>
{question.choices.map((choice) => (
<Questionnaire.Choice key={choice.value} value={choice.value}>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>
<span>{choice.label}</span>
{"description" in choice ? (
<span>{choice.description}</span>
) : null}
</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
))}
{"input" in question ? (
<Questionnaire.Input
aria-label={question.input.label}
placeholder={question.input.placeholder}
/>
) : null}
</Questionnaire.Choices>
<Questionnaire.Error />
</Questionnaire.Item>
))}
<Questionnaire.Previous />
<Questionnaire.Skip />
<Questionnaire.Next />
<Questionnaire.Submit />
</Questionnaire.Root>
)
}همان مجموعهٔ items را به Root بدهید که در بخشهای Item و Choice رندر میکنید. با این کار ترتیب مراحل، وضعیت پیشرفت، نمایش دکمههای کنترلی و میانبرهای پاسخ در HTML رندرشده از سمت سرور در دسترس خواهند بود.
با فعال کردن multiple، گزینههای ثابت هر مرحله به Checkboxهای Native تبدیل میشوند.
برای خواندن پاسخها از FormData.getAll() استفاده کنید.
مقدار multiple را در دادههای اصلی برنامه نگه دارید و هنگام رندر به Item منتقل کنید.
const items = [
{
name: "signals",
required: true,
multiple: true,
prompt: "هر بهروزرسانی چه چیزهایی داشته باشد؟",
description: "همهٔ موارد مرتبط را انتخاب کنید.",
choices: [
{ value: "progress", label: "Progress" },
{ value: "decisions", label: "تصمیمها" },
{ value: "risks", label: "Risks" },
],
},
] as constitems.map((question) => (
<Questionnaire.Item
key={question.name}
name={question.name}
multiple={question.multiple}
required={question.required}
>
<Questionnaire.Title>{question.prompt}</Questionnaire.Title>
<Questionnaire.Description>
{question.description}
</Questionnaire.Description>
<Questionnaire.Choices>
{question.choices.map((choice) => (
<Questionnaire.Choice key={choice.value} value={choice.value}>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>{choice.label}</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
))}
</Questionnaire.Choices>
<Questionnaire.Error />
</Questionnaire.Item>
))const signals = new FormData(form).getAll("signals").map(String)Input امکان وارد کردن پاسخ آزاد را فراهم میکند و یک ورودی متنی Native رندر میکند.
const items = [
{
name: "prototype",
required: true,
prompt: "بعداً چه چیزی را نمونهسازی کنیم؟",
choices: [
{ value: "delegation", label: "واگذاری" },
{ value: "questions", label: "پرسشهای راهنما" },
],
input: {
label: "مسیر نمونهسازی دیگر",
placeholder: "مسیر دیگری بنویسید…",
},
},
] as constitems.map((question) => (
<Questionnaire.Item
key={question.name}
name={question.name}
required={question.required}
>
<Questionnaire.Title>{question.prompt}</Questionnaire.Title>
<Questionnaire.Choices>
{question.choices.map((choice) => (
<Questionnaire.Choice key={choice.value} value={choice.value}>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>{choice.label}</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
))}
<Questionnaire.Input
aria-label={question.input.label}
placeholder={question.input.placeholder}
/>
</Questionnaire.Choices>
<Questionnaire.Error />
</Questionnaire.Item>
))Skip ثبت میکند که یک سؤال اختیاری عمداً بدون پاسخ گذاشته شده است.
اگر برنامه باید بین سؤال ردشده و سؤالی که هنوز پاسخی برای آن ثبت نشده تفاوت بگذارد، از onStatusChange استفاده کنید.
"use client"
import * as React from "react"
import {
Questionnaire,
type QuestionnaireItemStatus,
} from "@farsiui/react/questionnaire"
export function PlanningQuestionnaire() {
const [timingStatus, setTimingStatus] =
React.useState<QuestionnaireItemStatus>("unanswered")
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault()
const formData = new FormData(event.currentTarget)
console.log({
timing:
timingStatus === "skipped"
? { status: "skipped" }
: {
status: "answered",
value: formData.get("timing"),
},
})
}
return (
<Questionnaire.Root defaultItem="timing" onSubmit={handleSubmit}>
<Questionnaire.Item name="timing" onStatusChange={setTimingStatus}>
<Questionnaire.Title>
این موضوع چه زمانی باید دوباره بررسی شود؟
</Questionnaire.Title>
<Questionnaire.Description>
اگر زمانبندی مشخص نیست، این سؤال را رد کنید.
</Questionnaire.Description>
<Questionnaire.Choices>
<Questionnaire.Choice value="week">
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>همین هفته</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
<Questionnaire.Choice value="cycle">
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>چرخهٔ بعدی</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
</Questionnaire.Choices>
</Questionnaire.Item>
<Questionnaire.Skip />
<Questionnaire.Submit />
</Questionnaire.Root>
)
}با استفاده از shortcuts="letters" یا shortcuts="numbers" میتوانید برای هر گزینهٔ فعال یک کلید میانبر تعیین کنید.
ترتیب میانبرها در صورت استفاده از items، بر اساس ترتیب همان مجموعه تعیین میشود.
هرجا میخواهید کلید میانبر نمایش داده شود، از ChoiceShortcut استفاده کنید.
<Questionnaire.Root shortcuts="letters">
<Questionnaire.Item name="review" required>
<Questionnaire.Title>عامل چه چیزی را بررسی کند؟</Questionnaire.Title>
<Questionnaire.Choices>
<Questionnaire.Choice value="api">
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>API عمومی</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
<Questionnaire.Choice value="tests">
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>پوشش تست</Questionnaire.ChoiceLabel>
<Questionnaire.ChoiceShortcut />
</Questionnaire.Choice>
</Questionnaire.Choices>
</Questionnaire.Item>
</Questionnaire.Root>"letters" میانبرهای A تا Z را اختصاص میدهد و "numbers" میانبرهای 1 تا 9 را. گزینههای غیرفعال در این ترتیب در نظر گرفته نمیشوند.
انتخاب پاسخ با میانبر، کاربر را به مرحلهٔ بعد منتقل نمیکند.
Questionnaire قبل از رفتن به مرحلهٔ بعد، مرحلهٔ فعلی را اعتبارسنجی میکند و هنگام ارسال فرم، تمام مراحل فعال را بررسی میکند.
استفاده از required متن قابل مشاهدهٔ «الزامی» به فرم اضافه نمیکند. در صورت نیاز، این موضوع را در Title یا Description مشخص کنید.
اگر اعتبارسنجی ناموفق باشد، Questionnaire همان مرحله را نگه میدارد یا دوباره باز میکند و فوکوس را روی یکی از گزینههای پاسخ قرار میدهد. برای نمایش پیام خطا، Error را اضافه کنید.
<Questionnaire.Item name="scope" required>
<Questionnaire.Title>
پروژه باید چه چیزهایی داشته باشد؟ (الزامی)
</Questionnaire.Title>
<Questionnaire.Choices>{/* choices */}</Questionnaire.Choices>
<Questionnaire.Error />
</Questionnaire.Item>Error تا زمانی که مرحله نامعتبر نباشد نمایش داده نمیشود. برای جایگزین کردن پیام پیشفرض، متن دلخواه خود را داخل آن قرار دهید.
<Questionnaire.Error>لطفاً محدودهٔ پروژه را انتخاب کنید.</Questionnaire.Error>اعتبارسنجی حتی بدون Error نیز انجام میشود. در صورت رندر شدن پیام خطا، متن آن برای Screen Readerها نیز اعلام میشود.
اگر از Zod یا Validator خارجی دیگری استفاده میکنید، مقدار Item.invalid را تنظیم کنید، پیام را داخل Error نمایش دهید و Root.item را روی اولین مرحلهٔ نامعتبر قرار دهید.
<Questionnaire.Root item={item} onItemChange={setItem} onSubmit={handleSubmit}>
<Questionnaire.Item invalid={Boolean(errors.detail)} name="detail" required>
<Questionnaire.Title>پاسخ باید چقدر جزئیات داشته باشد؟</Questionnaire.Title>
<Questionnaire.Choices>{/* choices */}</Questionnaire.Choices>
<Questionnaire.Error>{errors.detail}</Questionnaire.Error>
</Questionnaire.Item>
</Questionnaire.Root>برای کنترل مرحلهٔ فعال، مقدار item و تابع onItemChange را به Questionnaire بدهید.
const [item, setItem] = React.useState("scope")
<Questionnaire.Root item={item} onItemChange={setItem} onSubmit={handleSubmit}>
<Questionnaire.Item name="scope" required>
{/* question and answers */}
</Questionnaire.Item>
<Questionnaire.Item name="verification" required>
{/* question and answers */}
</Questionnaire.Item>
<Questionnaire.Previous />
<Questionnaire.Next>بعدی</Questionnaire.Next>
<Questionnaire.Submit>ارسال</Questionnaire.Submit>
</Questionnaire.Root>برای بازیابی یک پیشنویس ذخیرهشده، از defaultItem، defaultChecked و defaultValue استفاده کنید.
<Questionnaire.Root defaultItem="verification">
<Questionnaire.Item name="scope" required>
<Questionnaire.Title>Which files are in scope?</Questionnaire.Title>
<Questionnaire.Choices>
<Questionnaire.Choice value="component" defaultChecked>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>Component only</Questionnaire.ChoiceLabel>
</Questionnaire.Choice>
</Questionnaire.Choices>
</Questionnaire.Item>
<Questionnaire.Item name="verification" required>
<Questionnaire.Title>Any extra instructions?</Questionnaire.Title>
<Questionnaire.Input
aria-label="Extra instructions"
defaultValue="Run the package tests."
/>
</Questionnaire.Item>
<button type="reset">Reset draft</button>
</Questionnaire.Root>با تنظیم disabled میتوانید یک مرحله را از جریان فعلی پرسشنامه خارج کنید.
مراحل غیرفعال در پیشرفت، جابهجایی بین مراحل، اعتبارسنجی و ارسال فرم در نظر گرفته نمیشوند.
const [runtime, setRuntime] = React.useState("local")
<Questionnaire.Root>
<Questionnaire.Item name="runtime" required>
<Questionnaire.Title>Where should the agent run?</Questionnaire.Title>
<Questionnaire.Choices>
<Questionnaire.Choice
value="local"
checked={runtime === "local"}
onChange={() => setRuntime("local")}
>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>Locally</Questionnaire.ChoiceLabel>
</Questionnaire.Choice>
<Questionnaire.Choice
value="remote"
checked={runtime === "remote"}
onChange={() => setRuntime("remote")}
>
<Questionnaire.ChoiceInput />
<Questionnaire.ChoiceLabel>
Remote environment
</Questionnaire.ChoiceLabel>
</Questionnaire.Choice>
</Questionnaire.Choices>
</Questionnaire.Item>
<Questionnaire.Item name="region" disabled={runtime !== "remote"} required>
{/* remote-only question */}
</Questionnaire.Item>
</Questionnaire.Root>دکمههای جابهجایی بهصورت پیشفرض فعال هستند تا با انتخاب Next یا Submit، در صورت وجود خطا پیام اعتبارسنجی نمایش داده شود.
اگر میخواهید خودتان یک دکمه را غیرفعال کنید، از وضعیت رندر کامپوننت استفاده کنید.
<Questionnaire.Next
render={(props, state) => (
<button {...props} disabled={state.status === "unanswered"} />
)}
>
Next
</Questionnaire.Next>وضعیت رندر شامل visible، disabled، shortcut و status مرحلهٔ فعال است. اگر فقط ظاهر را تغییر میدهید، بهجای آن data-status را هدف بگیرید:
<Questionnaire.Next data-navigation-action>بعدی</Questionnaire.Next>[data-navigation-action][data-status="unanswered"] {
opacity: 0.5;
}Progress بهصورت پیشفرض عبارت سؤال {current} از {total} را نمایش میدهد.
برای تغییر Element یا قالب نمایش آن، از render استفاده کنید.
<Questionnaire.Progress
aria-label="Setup progress"
render={(props, state) => (
<output {...props}>
Checkpoint {state.current} of {state.total}
</output>
)}
/>وضعیت رندر شامل current، total، first و last است. در صورت نیاز، یک aria-label بومیسازیشده به آن اضافه کنید.
میتوانید مرحلهٔ فعال را متحرک کنید، بدون اینکه بخش پیشرفت یا کنترلهای جابهجایی حرکت کنند.
const itemClassName =
"data-active:animate-in data-active:fade-in-0 data-active:slide-in-from-bottom-2 data-active:duration-300 motion-reduce:animate-none"
<Questionnaire.Item
className={itemClassName}
name="task"
required
>
{/* ... */}
</Questionnaire.Item>آیتمهای غیرفعال بلافاصله پنهان میشوند؛ بنابراین فقط ورود را متحرک کنید.
Root را دور یک Card قرار دهید و Title و Description را داخل هدر کارت رندر کنید. چون عنوان جایگزین legend پیشفرض میشود، به عنوان یک id بدهید و آن را با aria-labelledby مرحله وصل کنید.
const titleId = React.useId()
<Questionnaire.Root onSubmit={handleSubmit}>
<Card>
<Questionnaire.Item aria-labelledby={titleId} name="task" required>
<CardHeader>
<Questionnaire.Title id={titleId} render={<CardTitle />}>
عامل روی چه چیزی کار کند؟
</Questionnaire.Title>
<Questionnaire.Description render={<CardDescription />}>
وظیفهای را انتخاب کنید که باید بعداً انجام شود.
</Questionnaire.Description>
<CardAction>
<Questionnaire.Progress />
</CardAction>
</CardHeader>
<CardContent>
<Questionnaire.Choices>{/* choices */}</Questionnaire.Choices>
<Questionnaire.Error />
</CardContent>
</Questionnaire.Item>
<CardFooter>
<Questionnaire.Next>بعدی</Questionnaire.Next>
<Questionnaire.Submit>ارسال</Questionnaire.Submit>
</CardFooter>
</Card>
</Questionnaire.Root>بستن Dialog را از Skip جدا نگه دارید: بستن جریان را لغو میکند، در حالی که رد کردن یک سؤال بدونپاسخِ عمدی را ثبت میکند.
const titleId = React.useId()
<Dialog>
<DialogTrigger>باز کردن شفافسازی</DialogTrigger>
<DialogContent>
<Questionnaire.Root onSubmit={handleSubmit}>
<Questionnaire.Item aria-labelledby={titleId} name="scope" required>
<DialogHeader>
<Questionnaire.Progress />
<Questionnaire.Title id={titleId} render={<DialogTitle />}>
کدام فایلها در محدوده هستند؟
</Questionnaire.Title>
<Questionnaire.Description render={<DialogDescription />}>
مشخص کنید عامل تا چه حد میتواند workspace را بهروزرسانی کند.
</Questionnaire.Description>
</DialogHeader>
<Questionnaire.Choices>{/* choices */}</Questionnaire.Choices>
<Questionnaire.Error />
</Questionnaire.Item>
<DialogFooter>
<DialogClose>لغو</DialogClose>
<Questionnaire.Next>بعدی</Questionnaire.Next>
<Questionnaire.Submit>ارسال پاسخ</Questionnaire.Submit>
</DialogFooter>
</Questionnaire.Root>
</DialogContent>
</Dialog>با render میتوانید Element پیشفرض هر بخش را جایگزین کنید. یک Element بدهید، یا وقتی به وضعیت آن نیاز دارید از یک تابع استفاده کنید.
<Questionnaire.Next render={<Button />}>بعدی</Questionnaire.Next>Root و Item همیشه بهترتیب یک form و یک fieldset رندر میکنند. اگر Title دیگر legend رندر نکند، به آن id بدهید و همان شناسه را با aria-labelledby به Item پاس دهید.
این primitive مقدار data-slot منتشر نمیکند. Wrapperهای استایلدار مالک slotها و نشانگرهای بصری هستند.
Root همیشه یک فرم Native رندر میکند و از onSubmit، onReset، action و سایر props فرم پشتیبانی میکند. Questionnaire را داخل فرم دیگری قرار ندهید.
پاسخها از طریق کنترلهای Native سریالایز میشوند:
FormData.get(itemName) یک پاسخ تکی را میخواند.FormData.getAll(itemName) چند پاسخ را میخواند.FormData حضور ندارند.Item.onStatusChange استفاده کنید.Root بهصورت پیشفرض noValidate را تنظیم میکند تا اعتبارسنجی از Questionnaire.Error استفاده کند، نه از UI اعتبارسنجی مرورگر.
form.reset() مرحلهٔ اولیه، پاسخهای پیشفرض، وضعیت رد کردن و وضعیت اعتبارسنجی را بازیابی میکند.
Questionnaire روی رفتار Native رادیو، چکباکس، ورودی و دکمه بنا شده است.
میانبرها و ناوبری با کلیدهای جهتدار هنگام تایپ در فیلد متنی متوقف میشوند.
جلوگیری از رویداد onKeyDown ریشه، مدیریت کلیدهای پرسشنامه را خاموش میکند.
دکمههای جابهجایی بهصورت پیشفرض فعال میمانند تا اقدام نافرجام بتواند بازخورد اعتبارسنجی را نشان دهد. برای غیرفعال یا تغییر ظاهر اکشنِ بدونپاسخ، وضعیت جابهجایی را ببینید.
Item یک fieldset رندر میکند.Title بهصورت پیشفرض legend همان fieldset را رندر میکند. اگر هدف رندر سفارشی داشته باشد، id آن را با aria-labelledby به مرحله وصل کنید.Description و Error فعال با aria-describedby متصل میشوند.aria-invalid دارند.Progress یک progressbar نامدار با مقادیر جاری، حداقل، حداکثر و متن رندر میکند.aria-keyshortcuts اعلام میشوند.همیشه به Input یک نام دسترسپذیر بدهید. از id صریح همراه با برچسب قابلمشاهده استفاده کنید:
<Label htmlFor="other-answer">پاسخ دیگر</Label>
<Questionnaire.Input
id="other-answer"
placeholder="پاسخ دیگری بنویسید…"
/>وقتی طراحی برچسب قابلمشاهده ندارد، از aria-label یا aria-labelledby استفاده کنید:
<Questionnaire.Input
aria-label="پاسخ دیگر"
placeholder="پاسخ دیگری بنویسید…"
/>Placeholder یک برچسب نیست.
از این attributeها برای استایلدهی استفاده کنید. attributeهای Boolean وقتی true باشند حاضرند و وقتی false باشند غایباند.
Title و Description ویژگی وضعیت ندارند. بخشهای headless مقدار data-slot منتشر نمیکنند.
Questionnaire.Rootریشهٔ فرم و مسئول هماهنگی مراحل پرسشنامه.
Root مقادیر current، total، first، last و shortcuts را از طریق Data Attributeها در اختیار میگذارد.
Typeهای مربوط به مجموعهها از @farsiui/react/questionnaire قابل Import هستند:
type QuestionnaireChoiceDefinition = {
value: string
disabled?: boolean
}
type QuestionnaireItemDefinition = {
name: string
required?: boolean
disabled?: boolean
choices?: readonly QuestionnaireChoiceDefinition[]
}Questionnaire.Progressموقعیت فعلی در میان مراحل فعال پرسشنامه.
وضعیت render شامل current، total، first و last است.
Questionnaire.Itemیک مرحله از پرسشنامه.
Item وضعیتهای active، disabled، invalid، multiple، required و status را از طریق Data Attributeها ارائه میکند.
نام مراحل باید در یک Root یکتا باشد. name متعلق به کنترلهای پاسخ است، نه fieldset.
Questionnaire.Titleعنوان مرحله. بهصورت پیشفرض یک legend معنایی رندر میکند.
Questionnaire.Descriptionمتن توضیحی که از طریق aria-describedby به مرحله متصل میشود.
Questionnaire.ChoicesContainer چیدمان برای پاسخهای ثابت و متنی.
وضعیت render شامل shortcuts است.
Questionnaire.ChoiceContainer یک پاسخ ثابت. داخل آن یک ChoiceInput، یک ChoiceLabel و در صورت نیاز یک ChoiceShortcut قرار دهید.
<label> پیشفرض باعث میشود کل ردیف به کنترل Native مربوط متصل باشد.
وضعیت render شامل checked، disabled، invalid، shortcut و type است.
Questionnaire.ChoiceInputرادیو یا چکباکس Native مربوط به Choice والد.
Questionnaire Props لازم برای انتخاب، ارسال فرم، اعتبارسنجی و تعامل با کیبورد را مدیریت میکند. این بخش همچنین className، id، ref، render و سایر Props غیرمتعارض Native input را میپذیرد.
ChoiceInput باید داخل Choice استفاده شود. وضعیت render آن با Choice یکسان است.
Questionnaire.ChoiceLabelمحتوای Label قابل مشاهده برای یک پاسخ ثابت.
این بخش یک <span> داخل Label مربوط به Choice رندر میکند و Props مربوط به span و render را میپذیرد.
Questionnaire.ChoiceShortcutمیانبر قابل مشاهدهٔ یک پاسخ ثابت.
یک <span> شامل حرف یا عدد اختصاصیافته رندر میکند و اگر میانبری برای Choice وجود نداشته باشد، مخفی میماند.
Props مربوط به span و render را میپذیرد و وضعیت render شامل shortcut است.
Questionnaire.Inputپاسخ متنی آزاد. مقدار Native name آن توسط Item والد مدیریت میشود.
وضعیت render شامل disabled، filled و invalid است.
Questionnaire.Errorپیام اعتبارسنجی که تا زمانی که مرحله نامعتبر نشود، مخفی است.
Previous، Skip، Next و Submit دکمههای Native رندر میکنند و با تغییر وضعیت نمایش، همچنان در DOM باقی میمانند.
هرکدام از این بخشها Props مربوط به دکمههای Native را میپذیرند و شامل Prop زیر هستند:
وضعیت render شامل visible، disabled، shortcut و status مرحلهٔ فعال است.