دکمه رادیویی (Radio Group)
مجموعهای از دکمههای قابل انتخاب که فقط یکی از آنها میتواند در یک زمان انتخاب شود.
نصب (Installation)
1npx @quark-lab/rad-ui add radio-groupنمونهها (Examples)
استفاده پایه (Basic Usage)
استفاده ساده از گروه دکمههای رادیویی.
مشاهده کد
1import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
2import { Label } from "@/components/ui/label";
3
4export default function BasicExample() {
5 return (
6 <RadioGroup defaultValue="option-one">
7 <div className="flex flex-row-reverse items-center gap-2">
8 <RadioGroupItem value="option-one" id="option-one" />
9 <Label htmlFor="option-one">گزینه اول</Label>
10 </div>
11 <div className="flex flex-row-reverse items-center gap-2">
12 <RadioGroupItem value="option-two" id="option-two" />
13 <Label htmlFor="option-two">گزینه دوم</Label>
14 </div>
15 <div className="flex flex-row-reverse items-center gap-2">
16 <RadioGroupItem value="option-three" id="option-three" />
17 <Label htmlFor="option-three">گزینه سوم</Label>
18 </div>
19 </RadioGroup>
20 );
21}
22با توضیحات (With Description)
افزودن توضیحات اضافی برای هر گزینه.
فاصلهگذاری استاندارد برای اکثر موارد استفاده
فاصلهگذاری بیشتر برای خوانایی بهتر
فاصلهگذاری کمتر برای نمایش بیشتر
مشاهده کد
1import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
2import { Label } from "@/components/ui/label";
3
4export default function WithDescriptionExample() {
5 return (
6 <RadioGroup defaultValue="comfortable">
7 <div className="flex flex-row-reverse items-center gap-2">
8 <RadioGroupItem value="default" id="r1" />
9 <div className="flex flex-col items-end">
10 <Label htmlFor="r1">پیشفرض</Label>
11 <p className="text-sm text-muted-foreground">
12 فاصلهگذاری استاندارد برای اکثر موارد استفاده
13 </p>
14 </div>
15 </div>
16 <div className="flex flex-row-reverse items-center gap-2">
17 <RadioGroupItem value="comfortable" id="r2" />
18 <div className="flex flex-col items-end">
19 <Label htmlFor="r2">راحت</Label>
20 <p className="text-sm text-muted-foreground">
21 فاصلهگذاری بیشتر برای خوانایی بهتر
22 </p>
23 </div>
24 </div>
25 <div className="flex flex-row-reverse items-center gap-2">
26 <RadioGroupItem value="compact" id="r3" />
27 <div className="flex flex-col items-end">
28 <Label htmlFor="r3">فشرده</Label>
29 <p className="text-sm text-muted-foreground">
30 فاصلهگذاری کمتر برای نمایش بیشتر
31 </p>
32 </div>
33 </div>
34 </RadioGroup>
35 );
36}
37کنترل شده (Controlled)
کنترل مقدار انتخاب شده با استفاده از React State.
گزینه انتخاب شده: comfortable
مشاهده کد
1import { useState } from "react";
2import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
3import { Label } from "@/components/ui/label";
4
5export default function ControlledExample() {
6 const [selectedOption, setSelectedOption] = useState("comfortable");
7
8 return (
9 <div className="space-y-4">
10 <RadioGroup value={selectedOption} onValueChange={setSelectedOption}>
11 <div className="flex flex-row-reverse items-center gap-2">
12 <RadioGroupItem value="default" id="c1" />
13 <Label htmlFor="c1">پیشفرض</Label>
14 </div>
15 <div className="flex flex-row-reverse items-center gap-2">
16 <RadioGroupItem value="comfortable" id="c2" />
17 <Label htmlFor="c2">راحت</Label>
18 </div>
19 <div className="flex flex-row-reverse items-center gap-2">
20 <RadioGroupItem value="compact" id="c3" />
21 <Label htmlFor="c3">فشرده</Label>
22 </div>
23 </RadioGroup>
24 <p className="text-sm text-muted-foreground">
25 گزینه انتخاب شده: {selectedOption}
26 </p>
27 </div>
28 );
29}
30حالت غیرفعال (Disabled State)
غیرفعال کردن یک گزینه یا کل گروه.
مشاهده کد
1import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
2import { Label } from "@/components/ui/label";
3
4export default function DisabledExample() {
5 return (
6 <RadioGroup defaultValue="option-one">
7 <div className="flex flex-row-reverse items-center gap-2">
8 <RadioGroupItem value="option-one" id="d1" />
9 <Label htmlFor="d1">گزینه فعال</Label>
10 </div>
11 <div className="flex flex-row-reverse items-center gap-2">
12 <RadioGroupItem value="option-two" id="d2" disabled />
13 <Label htmlFor="d2" className="opacity-50">
14 گزینه غیرفعال
15 </Label>
16 </div>
17 <div className="flex flex-row-reverse items-center gap-2">
18 <RadioGroupItem value="option-three" id="d3" />
19 <Label htmlFor="d3">گزینه دیگر</Label>
20 </div>
21 </RadioGroup>
22 );
23}
24یکپارچگی با فرم (Form Integration)
استفاده از دکمههای رادیویی در یک فرم.
مشاهده کد
1import { useState } from "react";
2import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
3import { Label } from "@/components/ui/label";
4
5export default function FormExample() {
6 const [notifyMethod, setNotifyMethod] = useState("email");
7
8 return (
9 <form
10 className="space-y-6"
11 onSubmit={(e) => {
12 e.preventDefault();
13 console.log("Notify method:", notifyMethod);
14 }}
15 >
16 <div className="space-y-3">
17 <Label className="text-base font-semibold">
18 چگونه میخواهید مطلع شوید؟
19 </Label>
20 <RadioGroup
21 value={notifyMethod}
22 onValueChange={setNotifyMethod}
23 name="notifyMethod"
24 >
25 <div className="flex flex-row-reverse items-center gap-2">
26 <RadioGroupItem value="email" id="email" />
27 <div className="flex flex-col items-end">
28 <Label htmlFor="email">ایمیل</Label>
29 <p className="text-sm text-muted-foreground">
30 دریافت اعلان از طریق ایمیل
31 </p>
32 </div>
33 </div>
34 <div className="flex flex-row-reverse items-center gap-2">
35 <RadioGroupItem value="sms" id="sms" />
36 <div className="flex flex-col items-end">
37 <Label htmlFor="sms">پیامک</Label>
38 <p className="text-sm text-muted-foreground">
39 دریافت اعلان از طریق پیامک
40 </p>
41 </div>
42 </div>
43 <div className="flex flex-row-reverse items-center gap-2">
44 <RadioGroupItem value="push" id="push" />
45 <div className="flex flex-col items-end">
46 <Label htmlFor="push">اعلان فشاری</Label>
47 <p className="text-sm text-muted-foreground">
48 دریافت اعلان فشاری در مرورگر
49 </p>
50 </div>
51 </div>
52 </RadioGroup>
53 </div>
54 <button
55 type="submit"
56 className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors"
57 >
58 ذخیره تنظیمات
59 </button>
60 </form>
61 );
62}
63مثالهای پیشرفته (Advanced Examples)
استایل کارتی (Card Style)
سفارشیسازی ظاهر گزینهها به صورت کارت.
مشاهده کد
1import { useState } from "react";
2import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
3import { Label } from "@/components/ui/label";
4
5export default function CardStyleExample() {
6 const [plan, setPlan] = useState("free");
7
8 return (
9 <RadioGroup value={plan} onValueChange={setPlan}>
10 <div className="grid gap-4">
11 <div
12 className={`relative flex items-start flex-row-reverse gap-2 p-4 border-2 rounded-lg cursor-pointer transition-colors ${
13 plan === "free"
14 ? "border-primary bg-primary/5"
15 : "border-border hover:border-primary/50"
16 }`}
17 onClick={() => setPlan("free")}
18 >
19 <RadioGroupItem value="free" id="free" className="mt-1" />
20 <div className="flex-1">
21 <Label htmlFor="free" className="cursor-pointer flex flex-col items-end">
22 <div className="font-semibold">رایگان</div>
23 <p className="text-sm text-muted-foreground mt-1">
24 برای شروع کار و آزمایش ویژگیها
25 </p>
26 <p className="text-sm font-medium mt-2">۰ تومان / ماه</p>
27 </Label>
28 </div>
29 </div>
30 <div
31 className={`relative flex items-start flex-row-reverse gap-2 p-4 border-2 rounded-lg cursor-pointer transition-colors ${
32 plan === "pro"
33 ? "border-primary bg-primary/5"
34 : "border-border hover:border-primary/50"
35 }`}
36 onClick={() => setPlan("pro")}
37 >
38 <RadioGroupItem value="pro" id="pro" className="mt-1" />
39 <div className="flex-1">
40 <Label htmlFor="pro" className="cursor-pointer flex flex-col items-end">
41 <div className="font-semibold">حرفهای</div>
42 <p className="text-sm text-muted-foreground mt-1">
43 برای کسبوکارهای در حال رشد
44 </p>
45 <p className="text-sm font-medium mt-2">۲۹۹,۰۰۰ تومان / ماه</p>
46 </Label>
47 </div>
48 </div>
49 <div
50 className={`relative flex items-start flex-row-reverse gap-2 p-4 border-2 rounded-lg cursor-pointer transition-colors ${
51 plan === "enterprise"
52 ? "border-primary bg-primary/5"
53 : "border-border hover:border-primary/50"
54 }`}
55 onClick={() => setPlan("enterprise")}
56 >
57 <RadioGroupItem value="enterprise" id="enterprise" className="mt-1" />
58 <div className="flex-1">
59 <Label htmlFor="enterprise" className="cursor-pointer flex flex-col items-end">
60 <div className="font-semibold">سازمانی</div>
61 <p className="text-sm text-muted-foreground mt-1">
62 برای سازمانهای بزرگ با نیازهای سفارشی
63 </p>
64 <p className="text-sm font-medium mt-2">تماس بگیرید</p>
65 </Label>
66 </div>
67 </div>
68 </div>
69 </RadioGroup>
70 );
71}
72مرجع API (API Reference)
RadioGroup
پراپهای کامپوننت RadioGroup.
| پراپ (Prop) | نوع (Type) | پیشفرض (Default) | توضیحات (Description) |
|---|---|---|---|
value | string | undefined | مقدار کنترل شده |
defaultValue | string | undefined | مقدار پیشفرض (غیرکنترل شده) |
onValueChange | (value: string) => void | undefined | تابع فراخوانی هنگام تغییر مقدار |
disabled | boolean | false | غیرفعال کردن تمام گزینهها |
name | string | undefined | نام فیلد برای ارسال فرم |
required | boolean | false | الزامی بودن انتخاب |
orientation | "horizontal" | "vertical" | "vertical" | جهت نمایش گزینهها |
RadioGroupItem
پراپهای کامپوننت RadioGroupItem.
| پراپ (Prop) | نوع (Type) | پیشفرض (Default) | توضیحات (Description) |
|---|---|---|---|
value | string | - | مقدار این گزینه (الزامی) |
disabled | boolean | false | غیرفعال کردن این گزینه |
id | string | undefined | شناسه برای ارتباط با Label |
دسترسیپذیری (Accessibility)
کیبورد (Keyboard)
Tab- ورود به گروه یا خروج از آنSpace- انتخاب گزینه فعلیArrow Keys- حرکت بین گزینهها و انتخاب خودکار
نقش ARIA (ARIA Role)
کامپوننت از نقش radiogroup و radio استفاده میکند
برچسبها (Labels)
همیشه از Label با ویژگی htmlFor برای هر RadioGroupItem استفاده کنید
مدیریت فوکوس (Focus Management)
از الگوی roving tabindex برای مدیریت فوکوس استفاده میشود که فقط یک آیتم در هر زمان قابل فوکوس است
بهترین شیوهها (Best Practices)
برچسب واضح (Clear Labels)
همیشه برچسبهای واضح و مختصر برای هر گزینه استفاده کنید تا کاربر بتواند به راحتی تصمیم بگیرد
تعداد محدود گزینهها (Limited Options)
برای بیش از ۵-۷ گزینه، از Select یا Combobox استفاده کنید. Radio Group برای تعداد محدود گزینه مناسب است
انتخاب انحصاری (Mutually Exclusive)
فقط برای انتخابهای انحصاری استفاده کنید. برای انتخابهای چندگانه از Checkbox استفاده کنید
مقدار پیشفرض (Default Value)
در بیشتر موارد، یک مقدار پیشفرض تنظیم کنید تا کاربر مجبور به انتخاب نباشد (مگر اینکه انتخاب آگاهانه ضروری باشد)