File Upload
منطقة إفلات تعمل بلوحة المفاتيح، وقائمة بالملفات المختارة، مع حالات الإزالة والتقدم والخطأ والتحقق من الملفات.
الإصدار 0.4.1 ·
التثبيت
bunx --bun shadcn@latest add @dga/file-uploadويثبّت Field أيضًا.
الاستخدام
import { Field, FieldLabel } from "@/components/ui/field";
import { FileUpload } from "@/components/ui/file-upload";
export function DocumentsField() {
return (
<Field name="documents">
<FieldLabel>المستندات الداعمة</FieldLabel>
<FileUpload
accept=".pdf,.jpg,.png"
maxSize={5 * 1024 * 1024}
maxFiles={3}
hint="PDF أو JPG أو PNG، حتى 5 MB للملف."
onFilesAdded={(files) => files.forEach(upload)}
/>
</Field>
);
}استخدم File Upload لإرفاق المستندات والصور بطلب. يختار المكوّن الملفات ويفحصها، وأنت ترفعها. مرّر onFilesAdded لبدء الرفع، ثم احتفظ بالقائمة في حالتك (files) وحدّث status وprogress لكل ملف. اذكر الصيغ المقبولة وحد الحجم في hint.
البنية
- منطقة الإفلات (
<label>حول<input>للملفات): المنطقة المنقطة. والحقل هو عنصر التحكم القابل للتركيز. - التلميح: الصيغ وحد الحجم.
- قائمة الملفات (
<ul>): صف لكل ملف فيه أيقونة والاسم والحجم أو الحالة وزر إزالة. - شريط التقدم (
role="progressbar") أثناء رفع الملف.
أمثلة
التحقق
تُفحص الملفات مقابل accept وmaxSize وmaxFiles. ويبقى الملف المرفوض في القائمة مع السبب، فلا يضيع بصمت. جرّب ملفًا أكبر من 5 MB أو ملف .exe. والدالة validateFiles() مصدَّرة إن احتجت الفحص نفسه في مكان آخر.
الحالات
تعرض القائمة ملفًا انتهى رفعه وملفًا يُرفع مع التقدم وملفًا مرفوضًا وملفًا ينتظر الرفع. ويمكن تعطيل منطقة الإفلات أو جعلها في حالة خطأ.
إظهار التقدم
تحكّم في القائمة عبر files وonFilesChange، وحدّث الملف أثناء رفعه.
const [files, setFiles] = useState<UploadFile[]>([]);
<FileUpload
files={files}
onFilesChange={setFiles}
onFilesAdded={(added) =>
added.forEach((file) =>
upload(file.file, (progress) =>
setFiles((current) =>
current.map((f) =>
f.id === file.id
? { ...f, status: progress < 100 ? "uploading" : "done", progress }
: f,
),
),
),
)
}
/>RTL
يبدأ رمز كل صف ونصه من اليمين، ويقع زر الإزالة على اليسار، ويمتلئ شريط التقدم من اليمين إلى اليسار. وتحتفظ أسماء الملفات باتجاهها (dir="auto" داخل <bdi>): الاسم العربي يُقرأ من اليمين إلى اليسار وreport.pdf من اليسار إلى اليمين. والأحجام والنسب المئوية بأرقام غربية من اليسار إلى اليمين.
إمكانية الوصول
| المفتاح | الإجراء |
|---|---|
| Tab | ينقل التركيز إلى منطقة الإفلات، ثم عبر أزرار الإزالة. |
| Space أو Enter | يفتح منتقي الملفات. |
| Enter أو Space على زر الإزالة | يزيل ذلك الملف. |
- منطقة الإفلات حقل ملفات أصلي، فهي قابلة للتركيز وتعمل بلوحة المفاتيح وتقنيات المساعدة. والسحب إضافة وليس الطريقة الوحيدة (WCAG 2.1.1).
- يحيط حد التركيز بالمنطقة كلها. والحد المتقطع بنسبة 3:1 أو أفضل؛ والسحب فوقها يضيف حدًا مصمتًا بلون العلامة وتظليلًا.
- يحمل كل زر إزالة اسم الملف («إزالة report.pdf»). وتُعلَن حالات الرفض في منطقة حيّة وتظهر في القائمة بأيقونة ونص.
- لشريط التقدم
role="progressbar"معaria-valuenow؛ وتُكتب النسبة المئوية بجانبه أيضًا. - ترجم
messagesفي الصفحات العربية.
مرجع API
FileUpload
منطقة إفلات وقائمة بالملفات المختارة. المنطقة حقل ملف حقيقي، فتعمل بلوحة المفاتيح (Tab ثم Space أو Enter) وبالسحب والإفلات. الملفات التي تفشل في التحقق تبقى في القائمة مع سبب الرفض. سمّها بـ Field.
| الخاصية | النوع | القيمة الافتراضية |
|---|---|---|
stringاسم الحقل عند إرسال النموذج. | لا توجد قيمة افتراضية | |
| ||
UploadFile[]الملفات في القائمة (متحكَّم بها). حدّث `status` و`progress` أثناء الرفع. | لا توجد قيمة افتراضية | |
| ||
stringالصيغ المقبولة كما في سمة HTML `accept`: `.pdf,image/*`. | لا توجد قيمة افتراضية | |
| ||
numberأكبر حجم للملف الواحد بالبايت. | لا توجد قيمة افتراضية | |
| ||
numberأكبر عدد من الملفات في القائمة. تكون `multiple` مفعّلة افتراضيًا ما دام العدد أكبر من 1. | لا توجد قيمة افتراضية | |
| ||
UploadFile[]الملفات التي تبدأ بها القائمة (عند عدم التحكم). | [] | |
| ||
(files: UploadFile[]) => voidتُستدعى بالقائمة كاملة كلما أُضيف ملف أو أُزيل. | لا توجد قيمة افتراضية | |
| ||
(files: UploadFile[]) => voidتُستدعى بالملفات التي اجتازت التحقق، لتبدأ رفعها. | لا توجد قيمة افتراضية | |
| ||
booleanيتيح عدة ملفات. مفعّل افتراضيًا ما لم تكن `maxFiles` تساوي 1. | لا توجد قيمة افتراضية | |
| ||
string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<AwaitedReactNode>يعرض الصيغ المقبولة والحجم تحت منطقة الإفلات. | لا توجد قيمة افتراضية | |
| ||
Partial<FileUploadMessages>نصوص منطقة الإفلات وحالات الرفع والأخطاء. ترجمها في الصفحات العربية. | لا توجد قيمة افتراضية | |
| ||
booleanيعطّل منطقة الإفلات. | لا توجد قيمة افتراضية | |
| ||
booleanلا يمكن إرسال النموذج دون ملف. | لا توجد قيمة افتراضية | |
| ||
يقبل أيضًا جميع خصائص Base UI Field (يفتح في نافذة جديدة).
الاختلافات عن DGA
- مكوّن واحد لنسختي الملف الواحد والملفات المتعددة في Figma، ومنطقة الإفلات فيه حقل ملفات حقيقي.
- تبقى الملفات المرفوضة في القائمة مع السبب.
- تحتفظ أسماء الملفات العربية باتجاهها.
| التغيير | السبب |
|---|---|
File Upload: drop zone | A drop zone that only accepts a mouse drag is not keyboard accessible (WCAG 2.1.1). Rejected files stay in the list with the reason. |
File Upload: Arabic file names | A name mixing Arabic and Latin text must not be reordered around its extension. |
عرض جميع الاختلافات (2) لهذا المكوّن أسباب الاختلافات مكتوبة بالإنجليزية.
التباين
70 زوجًا لونيًا فُحص · جميعها تجتاز WCAG 2.1 AAعرض 23 حالةإخفاء
| النمط / الحالة | الفاتح | الداكن |
|---|---|---|
| drop zone border | 4.57:1 3:1 | 3.80:1 3:1 |
| drop zone border, hovered | 9.73:1 3:1 | 12.04:1 3:1 |
| drop zone border, drag over | 4.54:1 3:1 | 7.73:1 3:1 |
| drop zone border, error | 4.62:1 3:1 | 4.65:1 3:1 |
| focus ring | 17.31:1 3:1 | 17.49:1 3:1 |
| hint | 4.57:1 AA | 6.32:1 AA |
| drop zone text | 18.09:1 AAA | 15.87:1 AAA |
| drop zone text, hovered | 17.31:1 AAA | 17.04:1 AAA |
| drop zone text, drag over | 17.29:1 AAA | 13.36:1 AAA |
| drop zone icon | 4.74:1 3:1 | 10.38:1 3:1 |
| drop zone icon, drag over | 4.53:1 3:1 | 8.74:1 3:1 |
| drag over border | 4.53:1 3:1 | 6.50:1 3:1 |
| file name | 18.09:1 AAA | 15.87:1 AAA |
| file size | 4.77:1 AA | 6.32:1 AA |
| error text | 6.57:1 AA | 9.01:1 AAA |
| error icon | 6.57:1 3:1 | 9.01:1 3:1 |
| error border | 4.83:1 3:1 | 4.65:1 3:1 |
| done text | 5.69:1 AA | 10.80:1 AAA |
| done icon | 5.69:1 3:1 | 10.80:1 3:1 |
| progress bar | 3.83:1 3:1 | 8.31:1 3:1 |
| file icon | 4.77:1 3:1 | 9.38:1 3:1 |
| remove button icon | 18.09:1 3:1 | 15.87:1 3:1 |
| remove button icon, hovered | 16.44:1 3:1 | 12.71:1 3:1 |
يحتاج النص إلى تباين 4.5:1، والأيقونات وحلقات التركيز إلى 3:1. الحالات المعطّلة مستثناة. تقرير التباين الكامل