الحالة الفارغة
Empty State<Empty> / noRowsOverlay
اسمه كمانإمبتي ستيت، شاشة فارغة، حالة لا توجد نتائج، الحالة الصفرية، رسالة لا توجد بيانات، شاشة البداية الفارغة، blank state، zero state، no results state، no data placeholder، first-run screen، null state
الحالة الفارغة هي ما تعرضه الواجهة حين ينتهي الطلب بنجاح ولا يوجد شيء يُعرض: جدول بلا صفوف، أو بريد بلا رسائل، أو بحث بلا نتائج. وهي ليست حالة تحميل: هيكل التحميل (skeleton) يقول «البيانات في الطريق»، أمّا الحالة الفارغة فتقول «وصل الجواب، والجواب صفر». والخلط بينهما يترك المستخدم ينتظر شيئاً لن يصل. وصفحة ٤٠٤ شيء آخر، لأنها تقول إنّ العنوان نفسه لا يقابله شيء، بينما هنا العنوان صحيح والحاوية موجودة لكنها خالية. ولا هي رسالة خطأ، لأن الخطأ يعني أنّنا لا نعرف أصلاً هل توجد بيانات أم لا. والسؤال الذي يحسم التصميم كلّه هو «لماذا خلا المكان؟»، وله ثلاث إجابات لا تُخلط: المستخدم لم يُنشئ شيئاً بعد، أو مرشِّح أو بحث استبعد كل النتائج، أو الطلب فشل، والأخيرة تستعير نفس المساحة دون أن تكون حالة فارغة، فتأخذ نصّها الخاصّ وزرّ «أعد المحاولة». لكلّ إجابة عنوان مختلف وزرّ مختلف، ومَن يعرض الثلاث برسالة واحدة «لا توجد بيانات» يكون قد أضاع أفضل فرصة يشرح فيها المنتج نفسه للمستخدم.
لو قلت عليه…
العيّنة الحيّة
تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.
لا نتائج مطابقة
لا توجد فاتورة تطابق «INV-2025» في هذه الفترة. جرّب كلمة أقصر أو امسح البحث.
تشريح العنصر: كل جزء واسمه
مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.
برومبت البناء
سلوكه في الاتجاه من اليمين لليسار
الجزء ده حصري عندنا.
الرسم الاتجاهي وحده هو الذي ينعكس
ينعكسالرسم الذي يحمل اتجاهاً (سهم يشير إلى زرّ في الشريط العلوي، أو يد تسحب ملفاً، أو مسار يمشي مع ترتيب القراءة) ينعكس مع الصفحة لأن معناه مربوط بذلك الترتيب. أمّا رسم الشيء نفسه، كصندوق فارغ أو مجلّد أو عدسة مكبّرة أو كوب، فلا ينعكس: القلب لا يضيف إليه معنى، بل يعكس مصدر الضوء واتجاه الظلّ معه. لا تكتب قاعدة شاملة مثل [dir="rtl"] svg { transform: scaleX(-1) }: اقصر القلب على صنف صريح مثل .illus-directional تضعه بيدك على الأصول الاتجاهية وحدها.
الرسم الذي يحمل نصّاً لاتينياً يُستبدل لا يُقلب
لا ينعكسقلب صورة تحتوي على كلمات يجعل الحروف مقلوبة كما في المرآة، وحتى لو قلبتَ عقدة <text> وحدها مرّة ثانية بـ scaleX(-1) لتعود الحروف مقروءة، ستبقى الكلمة في الموضع الخطأ من التركيب. ونفس الحكم على الرسم الذي يصوّر واجهة مصغّرة (جدول أو بريد وهمي): تلك الواجهة الصغيرة يجب أن تُعاد رسمها بترتيب عربي لا أن تُعكس ككتلة واحدة. اربط مصدر الأصل باللغة: { ar: empty-ar.svg, en: empty-en.svg }[locale]، وعامله كنصّ قابل للترجمة في ملفّات اللغة لا كأصل ثابت في الكود.
كتلة النصّ الوسطى ونصّ البحث المقتبس
لا ينعكسالكتلة الوسطى نفسها لا تحتاج انعكاساً: text-align: center مع margin-inline: auto و max-inline-size تعطي النتيجة ذاتها في الاتجاهين. والفخّ يظهر في السطر المساعد حين يقتبس نصّ بحث لاتينياً داخل جملة عربية، فخوارزمية bidi تدفع علامة التنصيص الأخيرة أو النقطة إلى الطرف الخطأ في «لا نتائج لـ INV-2025». لفّ كل نصّ قادم من المستخدم بـ <bdi>، وهي تعادل unicode-bidi: isolate مع السمة dir="auto"، لأن direction في CSS لا تقبل إلا ltr أو rtl ولا تعرف auto، ولا تستعمل <span dir="ltr"> لأنها تفرض اتجاهاً ثابتاً على نصّ قد يكون عربياً في المرّة القادمة.
صفّ الأزرار
ينعكسالمحور المضمّن لحاوية flex يتبع direction، فترتيب الـ DOM وحده يحدّد الترتيب البصري وينعكس من تلقاء نفسه: ضع الزرّ الأساسي أخيراً في الـ markup ليجلس عند النهاية المنطقية، وهي أقصى اليسار في العربية وأقصى اليمين في الإنجليزية. لا تضف flex-direction: row-reverse ولا خاصية order داخل [dir="rtl"]، فهي تعكس الانعكاس وتعيد الأساسي إلى الجهة الخطأ. وباعد بين الزرّين بـ gap لا بـ margin-left، واستبدل أي margin-left: auto بـ margin-inline-start: auto.
الحالة الفارغة داخل جدول
ينعكسفي جدول HTML يتبع ترتيب الأعمدة اتجاه الجدول: العمود الأول يجلس في أقصى اليمين تحت dir="rtl". لذلك لا تعلّق الحالة الفارغة على مؤشّر عمود ثابت، بل ضعها في صفّ <tr> واحد بخلية <td colspan={columns.length}> تغطّي العرض كلّه فتبقى في المنتصف بعد الانعكاس. وأبقِ <thead> ظاهراً فوقها ليعرف المستخدم أنه ما زال داخل الجدول نفسه، ولا توسّط الرسالة بـ position: absolute مع قيم left أو right.
أسماؤه في الكود
كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.
شوف كمان
آخر تحديث · 2026-08-19