Select
اختيار خيار واحد من قائمة (في DGA: Dropdown Input أي القائمة المنسدلة). حجمان وثلاث تعبئات ومجموعات وكل الحالات، على Base UI Select.
الإصدار 0.4.1 ·
التثبيت
bunx --bun shadcn@latest add @dga/selectويثبّت Field أيضًا. هذا هو Dropdown Input في DGA (القائمة المنسدلة)؛ وسمّيناه Select تيمّنًا بجزء Base UI.
الاستخدام
import { Field, FieldLabel } from "@/components/ui/field";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
const services = [
{ value: "issue", label: "إصدار رخصة" },
{ value: "renew", label: "تجديد رخصة" },
];
export function ServiceField() {
return (
<Field name="service">
<FieldLabel required>الخدمة</FieldLabel>
<Select items={services} required>
<SelectTrigger>
<SelectValue placeholder="اختر خدمة" />
</SelectTrigger>
<SelectContent>
{services.map((s) => (
<SelectItem key={s.value} value={s.value}>
{s.label}
</SelectItem>
))}
</SelectContent>
</Select>
</Field>
);
}استخدم Select لاختيار خيار واحد من خمسة إلى خمسة عشر. وللأقل من ذلك يعرض Radio كل الخيارات معًا؛ وللأكثر أضف حقل بحث. مرّر items ليعرض الزر تسمية القيمة المختارة، وplaceholder يوضح ما المطلوب اختياره.
البنية
- الزر (
<button>): الحد والتسمية المختارة أو النص التلميحي وسهم. - المحتوى: القائمة المنبثقة على سطح البطاقة وبعرض الزر.
- الخيار: خيار واحد، وعليه علامة صح في جهة النهاية عند اختياره.
- المجموعة والتسمية والفاصل (اختيارية): تجمع الخيارات المترابطة.
أمثلة
الأساسي
انقر للفتح، أو ركّز عليه واضغط Enter أو Space أو ArrowDown.
الحالات
الافتراضية والمعبأة وللقراءة فقط والمعطّلة وحالة الخطأ، والحجم المتوسط مع التعبئة الأغمق.
المجموعات
لفّ الخيارات المترابطة في SelectGroup مع SelectLabel، وافصل بين المجموعات بـ SelectSeparator.
RTL
يبدأ نص الزر من اليمين ويقع السهم على اليسار. وتفتح القائمة أسفل الزر وتُحاذى بحافة بدايته (اليمنى)؛ وتقع علامة الصح على اليسار.
إمكانية الوصول
| المفتاح | الإجراء |
|---|---|
| Tab | ينقل التركيز إلى الزر. |
| Enter أو Space أو ArrowDown | يفتح القائمة. |
| ArrowUp / ArrowDown | ينتقل بين الخيارات. |
| Home / End | يقفز إلى أول خيار أو آخره. |
| كتابة حرف | يقفز إلى الخيار الذي يبدأ به. |
| Enter | يختار الخيار المميّز ويغلق القائمة. |
| Esc | يغلق القائمة ويعيد التركيز إلى الزر. |
- للزر الدور
comboboxمعaria-expanded؛ وللقائمة الدورlistboxولكل خيار الدورoptionمعaria-selected. - تأتي التسمية من Field. ويرتبط النص المساعد والأخطاء عبر
aria-describedby. - للخيار المميّز شريط بسمك 2px مع تظليل، لا تظليل وحده (WCAG 2.4.7). وللخيار المختار علامة صح.
- تحتفظ كل الحالات بحد بنسبة 3:1 ونص بنسبة 4.5:1، فاتحًا وداكنًا.
مرجع API
Select
يتيح اختيار خيار واحد من قائمة (في DGA: Dropdown Input، أي القائمة المنسدلة). ركّبه من SelectTrigger وSelectValue وSelectContent. مرّر `items` ليعرض الزر تسمية القيمة المختارة، وسمّه بـ Field.
| الخاصية | النوع | القيمة الافتراضية |
|---|---|---|
{ value, label }[] | Record<string, ReactNode>الخيارات مع تسمياتها، ليعرض الزر تسمية القيمة المختارة قبل فتح القائمة. | لا توجد قيمة افتراضية | |
| ||
Valueقيمة متحكَّم بها. | لا توجد قيمة افتراضية | |
| ||
Valueالقيمة الابتدائية عند عدم التحكم. | لا توجد قيمة افتراضية | |
| ||
booleanيعطّل القائمة المنسدلة. | لا توجد قيمة افتراضية | |
| ||
booleanيتيح اختيار عدة خيارات. وتكون القيمة حينئذٍ مصفوفة. | لا توجد قيمة افتراضية | |
| ||
stringاسم الحقل عند إرسال النموذج. | لا توجد قيمة افتراضية | |
| ||
(value: Value, details) => voidتُستدعى عند اختيار المستخدم خيارًا. من Base UI. | لا توجد قيمة افتراضية | |
| ||
booleanيعرض الاختيار دون فتح القائمة. | لا توجد قيمة افتراضية | |
| ||
booleanلا يمكن إرسال النموذج دون اختيار. | لا توجد قيمة افتراضية | |
| ||
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectContent
القائمة المنبثقة. تفتح أسفل الزر افتراضيًا وبعرضه.
| الخاصية | النوع | القيمة الافتراضية |
|---|---|---|
"top" | "bottom" | "inline-start" | "inline-end"أي جهة من الزر تفتح عليها القائمة. الافتراضي `bottom`. | "bottom" | |
| ||
"start" | "center" | "end"المحاذاة مع الزر. و`start` هي الحافة اليمنى في RTL. | "start" | |
| ||
numberالفجوة بين الزر والقائمة بالبكسل. الافتراضي 4. | 4 | |
| ||
booleanيجعل الخيار المختار فوق الزر تمامًا، كالقائمة الأصلية في macOS. الافتراضي `false`. | false | |
| ||
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectGroup
يجمع خيارات مترابطة تحت SelectLabel.
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectItem
خيار واحد. يظهر على الخيار المختار علامة صح في جهة النهاية.
| الخاصية | النوع | القيمة الافتراضية |
|---|---|---|
Valueالقيمة التي يمثلها هذا الخيار. | لا توجد قيمة افتراضية | |
| ||
booleanيعطّل الخيار. | لا توجد قيمة افتراضية | |
| ||
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectLabel
عنوان SelectGroup.
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectSeparator
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectTrigger
الزر الذي يعرض الخيار المختار ويفتح القائمة.
| الخاصية | النوع | القيمة الافتراضية |
|---|---|---|
"md" | "lg"الارتفاع: `md` 32px، و`lg` 40px. | "lg" | |
| ||
"default" | "lighter" | "darker"التعبئة: `default` (أبيض) أو `lighter` أو `darker`. وتحتفظ الثلاث بحد ظاهر. | "default" | |
| ||
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
SelectValue
الخيار المختار، أو `placeholder` ما دام لا يوجد اختيار.
| الخاصية | النوع | القيمة الافتراضية |
|---|---|---|
ReactNodeيظهر ما دام لم يُختر شيء. | لا توجد قيمة افتراضية | |
| ||
يقبل أيضًا جميع خصائص Base UI Select (يفتح في نافذة جديدة).
الاختلافات عن DGA
- سمّيناه Select (في Figma: Dropdown Input). يرسم Figma القائمة المفتوحة فقط؛ وسطح القائمة المنبثقة من عندنا.
- للخيار المميّز شريط مع التظليل، لأن التظليل وحده بنسبة 1.1:1.
- الحالات نفسها كما في Input: لا حد خارجي، وخط سفلي كامل عند التركيز أو الفتح، ويعرض الضغط نصف الخط السفلي. والضغط بالفأرة يفتح القائمة فورًا، فينتقل من السكون إلى الفتح.
| التغيير | السبب |
|---|---|
Select: popup | The tint alone is 1.1:1 against the popup, so keyboard users could not see which option is highlighted (WCAG 2.4.7). |
Select: name | Named after the Base UI part and the shadcn convention, so it is found when people search for it. The docs page says it is DGA's Dropdown Input. |
عرض جميع الاختلافات (2) لهذا المكوّن أسباب الاختلافات مكتوبة بالإنجليزية.
التباين
282 زوجًا لونيًا فُحص · جميعها تجتاز WCAG 2.1 AAعرض 51 حالةإخفاء
| النمط / الحالة | الفاتح | الداكن |
|---|---|---|
| filled text | 18.09:1 AAA | 15.87:1 AAA |
| hovered text | 18.09:1 AAA | 15.87:1 AAA |
| focused text | 10.17:1 AAA | 12.04:1 AAA |
| pressed text | 9.24:1 AAA | 9.64:1 AAA |
| pressed placeholder | 6.69:1 AA | 5.06:1 AA |
| pressed prefix and suffix text | 9.24:1 AAA | 9.64:1 AAA |
| underline, focused and pressed | 18.74:1 3:1 | 16.80:1 3:1 |
| placeholder | 4.77:1 AA | 6.32:1 AA |
| prefix and suffix text | 10.17:1 AAA | 12.04:1 AAA |
| icon | 4.77:1 3:1 | 9.38:1 3:1 |
| border, default | 4.57:1 3:1 | 3.80:1 3:1 |
| border, hovered | 9.73:1 3:1 | 12.04:1 3:1 |
| border, focused and pressed | 17.93:1 3:1 | 16.80:1 3:1 |
| underline, error | 4.62:1 3:1 | 4.65:1 3:1 |
| border, error | 4.62:1 3:1 | 4.65:1 3:1 |
| filled text (lighter) | 17.64:1 AAA | 14.42:1 AAA |
| hovered text (lighter) | 17.64:1 AAA | 14.42:1 AAA |
| focused text (lighter) | 10.17:1 AAA | 12.04:1 AAA |
| pressed text (lighter) | 9.24:1 AAA | 9.64:1 AAA |
| pressed placeholder (lighter) | 6.69:1 AA | 5.06:1 AA |
| pressed prefix and suffix text (lighter) | 9.24:1 AAA | 9.64:1 AAA |
| underline, focused and pressed (lighter) | 18.28:1 3:1 | 15.27:1 3:1 |
| placeholder (lighter) | 4.65:1 AA | 5.75:1 AA |
| prefix and suffix text (lighter) | 9.92:1 AAA | 10.95:1 AAA |
| icon (lighter) | 4.65:1 3:1 | 8.52:1 3:1 |
| border, hovered (lighter) | 9.73:1 3:1 | 12.04:1 3:1 |
| border, focused and pressed (lighter) | 17.93:1 3:1 | 16.80:1 3:1 |
| underline, error (lighter) | 4.62:1 3:1 | 4.65:1 3:1 |
| border, error (lighter) | 4.62:1 3:1 | 4.65:1 3:1 |
| filled text (darker) | 16.44:1 AAA | 17.04:1 AAA |
| hovered text (darker) | 16.44:1 AAA | 17.04:1 AAA |
| focused text (darker) | 10.17:1 AAA | 12.04:1 AAA |
| pressed text (darker) | 9.24:1 AAA | 9.64:1 AAA |
| pressed placeholder (darker) | 6.69:1 AA | 5.06:1 AA |
| pressed prefix and suffix text (darker) | 9.24:1 AAA | 9.64:1 AAA |
| underline, focused and pressed (darker) | 17.03:1 3:1 | 18.03:1 3:1 |
| placeholder (darker) | 6.69:1 AA | 6.79:1 AA |
| prefix and suffix text (darker) | 9.24:1 AAA | 12.93:1 AAA |
| icon (darker) | 4.34:1 3:1 | 10.07:1 3:1 |
| border, hovered (darker) | 9.73:1 3:1 | 12.04:1 3:1 |
| border, focused and pressed (darker) | 17.93:1 3:1 | 16.80:1 3:1 |
| underline, error (darker) | 4.62:1 3:1 | 4.65:1 3:1 |
| border, error (darker) | 4.62:1 3:1 | 4.65:1 3:1 |
| border, hover and focus (lighter and darker) | 4.57:1 3:1 | 3.80:1 3:1 |
| read-only text | 18.09:1 AAA | 15.87:1 AAA |
| option text | 18.09:1 AAA | 15.87:1 AAA |
| option text, highlighted | 16.44:1 AAA | 12.71:1 AAA |
| group label | 4.77:1 AA | 6.32:1 AA |
| selected check | 4.74:1 3:1 | 10.38:1 3:1 |
| selected check, highlighted | 4.31:1 3:1 | 8.31:1 3:1 |
| highlight bar | 18.09:1 3:1 | 17.49:1 3:1 |
يحتاج النص إلى تباين 4.5:1، والأيقونات وحلقات التركيز إلى 3:1. الحالات المعطّلة مستثناة. تقرير التباين الكامل