قائمة الأوامر
Menu (Dropdown Menu and Context Menu)role="menu" + role="menuitem"
اسمه كمانمنيو، قائمة السياق، قائمة كليك يمين، قائمة الثلاث نقاط، قائمة الأوامر المنسدلة، دروب داون منيو، dropdown menu، context menu، right-click menu، action menu، overflow menu، kebab menu
قائمة الأوامر لوحة صغيرة تنفتح فوق الواجهة وتعرض أوامر جاهزة للتنفيذ، فما إن يضغط المستخدم سطراً منها حتى يقع الأمر وتُغلق اللوحة. ولها شكلان يتشاركان البنية نفسها: القائمة المنسدلة التي يفتحها زرّ ظاهر مثل زرّ الثلاث نقاط، وقائمة السياق التي يفتحها زرّ الفأرة الأيمن أو مفتاح ContextMenu على العنصر الذي يقف عليه المستخدم. ولا يخزّن أي بند فيها قيمة، ولهذا لا يقبل menuitem خاصّية aria-selected أصلاً. وهي ليست قائمة اختيار: عنصر select يحمل قيمة تبقى ظاهرة على الزرّ وتُرسَل مع النموذج، و listbox يعلّم اختياره بـ aria-selected ويبقيه بعد الإغلاق، والفيصل ما يحدث بعد الضغط: تنفيذ أمر أم تثبيت قيمة يقرأها شيء لاحقاً. وليست popover، فالـ popover صندوق عائم يقبل أي محتوى بلا دلالة، بينما role="menu" عقد صارم: أبناء من menuitem وما يشبهه، وتنقّل بالأسهم، ومحطّة Tab واحدة للقائمة كلّها. وليست قائمة روابط: شريط تنقّل الموقع عنصر <ul> فيه <a>، ووضع role="menu" على القائمة و role="menuitem" على الروابط يسلبها دور link فتسقط من قائمة الروابط في قارئ الشاشة، ويَعِد المستخدم بتنقّل بالأسهم لم يكتبه أحد. القاعدة العملية: role="menu" لأوامر التطبيق مثل «تحرير» و«ترتيب حسب»، والروابط تبقى روابط داخل <nav>.
لو قلت عليه…
العيّنة الحيّة
تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.
اضغط بالزرّ الأيمن في أي مكان هنا لفتح قائمة السياق.
آخر أمر: فتح · الشبكة: ظاهرة
تشريح العنصر: كل جزء واسمه
مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.
برومبت البناء
سلوكه في الاتجاه من اليمين لليسار
الجزء ده حصري عندنا.
جهة القائمة الفرعية
ينعكسالقائمة الفرعية تتابع اتجاه القراءة: تفتح عن يمين البند في الإنجليزية وعن يساره في العربية، أي عند نهايته المنطقية. والجهة تُحسب لحظة الفتح ولا تُكتب مرّة واحدة في CSS، لأنها تنقلب إلى الجهة المقابلة متى ضاق ما تبقّى من عرض النافذة. وانتبه إلى أن Floating UI منطقية في المحاذاة وحدها: لاحقتا -start و -end تقرآن direction من العنصر نفسه، أمّا الجهة الأساسية في placement فأسماؤها فيزيائية (top و right و bottom و left)، فإمّا أن تختار "left-start" بنفسك عند rtl، وإمّا أن تسلّم الأمر لمكوّن يقرأ الاتجاه مثل Radix: خاصّية dir تُوضع على DropdownMenu.Root أو على DirectionProvider يلفّ الشجرة، لا على DropdownMenu.Sub الذي لا يقبلها.
سهم القائمة الفرعية
ينعكسالسهم في طرف البند يشير إلى الجهة التي ستنفتح فيها القائمة الفرعية، فهو اتجاهيّ بحت ولا بدّ أن ينقلب مع الصفحة. ولو رسمته حرفاً نصّياً فلا تفترض أن محرّك bidi سيتكفّل به: خاصّية Bidi_Mirrored قيمتها Yes في › (U+203A) فينقلب من تلقاء نفسه، وقيمتها No في → (U+2192) و ▸ (U+25B8) فيبقيان كما رُسما مهما كان الاتجاه. اجعل الانعكاس صنفاً مخصّصاً مثل .flip-x { transform: scaleX(-1) } داخل [dir="rtl"] وضعه على هذا السهم وحده، فالقاعدة العامّة على svg ستقلب معه علامة الصح وأيقونتَي «نسخ» و«حذف».
عمود العلامة وعمود الاختصار
ينعكسكل بند صفّ من ثلاث خانات: علامة الحالة عند البداية المنطقية، والنصّ في الوسط، وتلميح الاختصار عند النهاية المنطقية، فتتبادل الخانتان الطرفيتين مكانيهما مع اتجاه الصفحة. احجز خانة العلامة في كل البنود بـ padding-inline-start أو بعنصر فارغ بنفس العرض، وادفع الاختصار إلى الطرف بـ margin-inline-start: auto. والفخّ الجاهز هنا مكوّن DropdownMenuShortcut في shadcn/ui: صنفه ml-auto، وهو يعمل في الإنجليزية ويترك الاختصار ملتصقاً بالجهة الخطأ في العربية حتى تستبدله بـ ms-auto.
نصّ الاختصار نفسه
لا ينعكسموضع الاختصار ينتقل مع الصفحة، أمّا ترتيب حروفه فلا يمسّه شيء: Ctrl+K تُقرأ كما هي في الاتجاهين. والخطر في الرموز التي تتصدّره، فـ ⌘ (U+2318) و ⇧ (U+21E7) صنفهما في bidi هو ON أي محرف محايد، والمحايد الواقف على حافّة النصّ يأخذ اتجاه الفقرة المحيطة به فيقفز إلى الطرف الآخر من الحرف وتقرأ العين K⌘ بدل ⌘K. اعزل النصّ كتلة واحدة بـ dir="ltr" مع unicode-bidi: isolate على العنصر أو بلفّه في <bdi>، ولا تعالج الأمر بمسافة زائدة ولا بمحرف تحكّم تكتبه بيدك داخل النصّ.
مفتاحا ArrowRight و ArrowLeft
ينعكسالمفتاحان يتبادلان وظيفتيهما مع الاتجاه: في العربية يفتح ArrowLeft القائمة الفرعية ويغلقها ArrowRight، وفي الإنجليزية العكس. اقرأ الاتجاه مرّة واحدة من getComputedStyle(el).direction واشتقّ منه openKey و closeKey، بدل نثر شرط rtl في كل فرع من معالج المفاتيح. وما عدا هذين المفتاحين لا يتبدّل شيء: ArrowDown و ArrowUp و Home و End تعمل على ترتيب البنود في الـ DOM، و Escape يغلق ويعيد التركيز، والقفز بالحرف الأوّل لا علاقة له بالاتجاه إطلاقاً.
أسماؤه في الكود
كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.
شوف كمان
آخر تحديث · 2026-08-19