رفع الملفات
File Upload / Dropzone<input type="file">
اسمه كمانمنطقة الإفلات، حقل رفع الملف، دروب زون، أبلود، سحب وإفلات الملفات، حقل المرفقات، dropzone، file picker، file input، upload field، drag and drop upload، attachment field
رفع الملفات هو الطريق الذي يسلّم به المستخدم ملفاً من جهازه إلى التطبيق، وأساسه في الويب عنصر واحد: <input type="file">. الضغط عليه يفتح نافذة اختيار الملفات التابعة لنظام التشغيل، وهي نافذة لا تملك عليها الصفحة أي سلطة: لا تُفتح إلا بإيماءة من المستخدم، ولا تكشف مسار الملف على القرص، ولا يصل الصفحة منها إلا كائن File. وثلاثة أشياء تُخلط به. منطقة الإفلات (dropzone) هدف سحب لا حقل، أي مستطيل يستمع لحدثَي dragover و drop، وهي طريق ثانٍ إلى نفس الملفات ولا تنوب عن الحقل، لأن الإفلات لا وجود له أصلاً على شاشة اللمس ولا في لوحة المفاتيح. وزرّ «اختر ملفاً» ليس عنصراً مستقلاً في الغالب، وإنما <label> مربوطة بالحقل تنقل إليه ضغطة المؤشّر، ويبقى التركيز والتفعيل بلوحة المفاتيح في الحقل نفسه لأن الـ <label> لا تدخل ترتيب Tab. أما الرافع الكامل (uploader) فطبقة فوق ذلك كله: طابور، وتقدّم لكل ملف، وإلغاء، وإعادة محاولة. والحقل نفسه لا يرفع شيئاً، إنما يختار فقط، وإرسال البايتات مسؤولية fetch أو XMLHttpRequest، إلا أن يكون الحقل داخل <form> يحمل enctype="multipart/form-data" فيتولّى المتصفّح الإرسال عند التسليم.
لو قلت عليه…
العيّنة الحيّة
تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.
تشريح العنصر: كل جزء واسمه
مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.
برومبت البناء
سلوكه في الاتجاه من اليمين لليسار
الجزء ده حصري عندنا.
صفّ الملف
ينعكسترتيب الصفّ منطقي بالكامل: الأيقونة والاسم عند البداية، ثم الحجم وزرّ الإزالة عند النهاية، فينقلب الصفّ كله في العربية ويصير زرّ الإزالة عند اليسار. نفّذه بصفّ flex مع margin-inline-start: auto على الزرّ، ولا تكتب margin-left: auto ولا float: right. وإن رسمت حافّة ملوّنة تدلّ على حالة الملف فاجعلها border-inline-start لا border-left، وإلا وقفت الحافّة في الطرف المخالف للاسم بعد الانعكاس.
شريط تقدّم كل ملف
ينعكسالشريط يمتلئ من البداية المنطقية، أي من اليمين في العربية. نفّذ الامتلاء بعنصر داخلي مثبّت بـ inset-inline-start: 0 يتغيّر فيه inline-size من صفر إلى ١٠٠٪، فينعكس وحده لأن الحافّة التي رُسِي عليها هي التي تبدّلت. وابتعد عن transform: scaleX() لأن transform-origin لا تقبل أي كلمة منطقية، وعن linear-gradient(to right, …) لأن التدرّجات كذلك بلا كلمات منطقية. أما عنصر <progress> الأصلي فيأخذ اتجاهه من قيمة direction الموروثة، ومعنى ذلك أن dir="ltr" الذي تضعه على الصفّ لإصلاح اسم الملف يقلب معه اتجاه الامتلاء.
اسم ملف لاتيني في صفّ عربي
لا ينعكساسم الملف نصّ يأتي من المستخدم ولا تعرف اتجاهه سلفاً، فالعلاج عزله لا تثبيت اتجاهه: <bdi> أو unicode-bidi: plaintext على العنصر الحامل له. ولا وجود لقيمة direction: auto في CSS، فالخاصية لا تقبل غير ltr و rtl، والسلوك التلقائي مكانه سمة dir="auto" أو كلمة plaintext التي تعزل وتأخذ الاتجاه من أول محرف قويّ. وبدون عزل تلتحق المحارف المحايدة الملاصقة للأرقام (الشرطة والشرطة السفلية والنقطة) باتجاه الفقرة العربية، فينقسم الاسم إلى جزر يُعاد ترتيبها من اليمين، ويظهر invoice_2026.pdf على الشاشة هكذا: pdf.2026_invoice. والقوسان يزيدان الأمر سوءاً لأن قيمة Bidi_Mirrored لهما Yes فينقلب شكلهما. ولا تعالج ذلك بـ dir="ltr" على الصفّ، فهو يقلب التخطيط والشريط معاً ويسيء إلى الأسماء العربية التي تحمل أرقاماً مثل «تقرير 2026.pdf».
الحجم ونظام الأرقام
لا ينعكسحجم الملف رقم ووحدة، وهما لا ينعكسان، فالأرقام تُقرأ من اليسار إلى اليمين في العربية أيضاً. المشكلة في الخلط: صفحة تطبع ٢٫٤ بالأرقام الهندية ثم تكتب MB بحروف لاتينية، أو تبني السلسلة بـ toFixed(1) ثم تلصق بها وحدة عربية، فيقف «2.4 ميجابايت» في القائمة إلى جوار «٨٦٠ كيلوبايت». اختر نظام ترقيم واحداً للمنتج كله ونسّق من خلاله: Intl.NumberFormat("ar-EG", { style: "unit", unit: "megabyte", unitDisplay: "short" }) يعطيك الرقم والفاصل والوحدة من مصدر واحد، والفاصل العشري العربي هو U+066B لا النقطة. ولو أردت أرقاماً لاتينية داخل صفحة عربية فاطلبها صراحة بـ ar-EG-u-nu-latn.
نافذة النظام
لا ينعكسنافذة اختيار الملفات ليست جزءاً من صفحتك: يرسمها نظام التشغيل، ويتبع اتجاهها ولغتها إعدادات الجهاز لا سمة dir ولا لغة واجهتك. فلا تَعِد المستخدم بنافذة عربية ولا تحاول تنسيقها. وكذلك النصّ الافتراضي داخل الحقل نفسه (Choose File و No file chosen) يأتي من لغة المتصفّح ولا يُترجَم ولا يُستبدَل، و::file-selector-button ينسّق الزرّ ولا يمسّ كلماته. وهذا وحده سبب كافٍ لإخفاء الحقل خلف <label> تكتب نصّها بنفسك بالعربية.
أسماؤه في الكود
كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.
شوف كمان
آخر تحديث · 2026-08-19