رفع الملفات
منطقة إفلات هي حقل ملفات حقيقي، فتعمل وتُرسل قبل تشغيل أي سكربت. والملفات المختارة تظهر في قائمة.
client - الحجم لم يُقَس بعد
رفع الملفات
client - الحجم لم يُقَس بعدمنطقة إفلات هي حقل ملفات حقيقي، فتعمل وتُرسل قبل تشغيل أي سكربت. والملفات المختارة تظهر في قائمة.
جرّبه
maxFiles
maxSize
invalid
visibleRows
الشيفرة
file-upload.tsx
import { FileUpload } from 'topclassui/file-upload'
<div className="grid gap-1.5">
<label htmlFor="file-upload-playground" className="text-sm font-medium text-body">Attachment</label>
<FileUpload id="file-upload-playground" name="attachment" accept=".png,.jpg,.jpeg,.pdf">
PNG, JPG or PDF
</FileUpload>
</div>maxSize بالبايت، ويُتحقق منه في المتصفح فقط: تحقّق منه مجددًا في الإجراء.
كل الحالات، بدون تمرير الفأرة
حالتانأفلت الملفات هناتصفّحA file is required
أفلت الملفات هناتصفّحUploads are closed
أو استورده من الحزمة
topclassui/file-upload
import { FileUpload } from 'topclassui/file-upload'ثبّت مرة واحدة:npm i topclassui@beta zod
أمثلة
- العناصر الأبناء هي التلميح داخل المنطقة، مثل «PDF أو PNG، حتى 5 ميغابايت»، وهي تصف الحقل.
maxFiles(من 1 إلى 100، والافتراضي 1) هو وحده ما يقرر إن كان الحقل يقبل عدة ملفات دفعة واحدة؛ ومع 1 يحل الملف الجديد محل القديم.maxSizeيرفض الملف الأكبر لأنه كبير جدًا؛ ويُعلن كل رفض، ولا يُرسل الملف المرفوض أبدًا.- لا يستطيع الحقل ضبط encType لنموذجه: النموذج ذو الإجراء النصي يحتاج multipart/form-data، وإلا أرسل أسماء الملفات فقط.
- تتراكم القائمة عبر الاختيارات والإفلاتات، وتعرض
visibleRowsصفوف قبل التمرير. وonValueChangeيستقبل الملفات المحفوظة بعد كل تغيير.
basic
أفلت الملفات هناتصفّحPNG, JPG or PDF, up to 10 MB
basic.tsx
import { FileUpload } from 'topclassui/file-upload'
/** One file, named by its label. The hint inside the zone describes the input. */
export default function Demo() {
return (
<div className="grid gap-1.5">
<label htmlFor="file-upload-basic" className="text-sm font-medium text-body">Attachment</label>
<FileUpload id="file-upload-basic" name="attachment" accept=".png,.jpg,.jpeg,.pdf" maxSize={10 * 1024 * 1024}>
PNG, JPG or PDF, up to 10 MB
</FileUpload>
</div>
)
}
multiple
أفلت الملفات هناتصفّحPDF or PNG, up to 5 files
multiple.tsx
import { FileUpload } from 'topclassui/file-upload'
/** The limits of the card's sample: up to five files, PDF or PNG, 5 MB each. maxFiles above 1 makes the input multiple. */
export default function Demo() {
return (
<div className="grid gap-1.5">
<label htmlFor="file-upload-multiple" className="text-sm font-medium text-body">Attachments</label>
<FileUpload id="file-upload-multiple" name="attachments" accept="application/pdf,image/png" maxFiles={5} maxSize={5 * 1024 * 1024}>
PDF or PNG, up to 5 files
</FileUpload>
</div>
)
}
in-field
أفلت الملفات هناتصفّحDrop them here, 5 MB each
PDF or PNG, up to 5 files
in-field.tsx
import { Field } from 'topclassui/field'
import { FileUpload } from 'topclassui/file-upload'
/** The card's sample: a Field names the input, and its hint describes it after the zone's own. */
export default function Demo() {
return (
<Field name="attachments" label="Attachments" hint="PDF or PNG, up to 5 files">
{(control) => (
<FileUpload {...control} accept="application/pdf,image/png" maxFiles={5} maxSize={5 * 1024 * 1024}>
Drop them here, 5 MB each
</FileUpload>
)}
</Field>
)
}
form
form.tsx
import { Button } from 'topclassui/button'
import { FileUpload } from 'topclassui/file-upload'
/** A multipart form that posts with no script: the input sends one part per file. An input cannot set the form's
* encType, so the form writes it. Required: an empty input blocks the submit. */
export default function Demo() {
return (
<form method="post" encType="multipart/form-data" className="grid gap-3">
<div className="grid gap-1.5">
<label htmlFor="file-upload-form" className="text-sm font-medium text-body">Attachments</label>
<FileUpload id="file-upload-form" name="attachments" maxFiles={5} required>Up to 5 files</FileUpload>
</div>
<div><Button type="submit">Send</Button></div>
</form>
)
}
بالعربية، من اليمين إلى اليسار
أفلت الملفات هناتصفّحPDF أو PNG، حتى 5 ملفات
rtl.tsx
import { TopClassProvider } from 'topclassui/provider'
import { FileUpload } from 'topclassui/file-upload'
/** Arabic, inside TopClassProvider as the root layout would mount it: the zone's words, the sizes and the reasons
* come from the Arabic labels, and each file name takes its own direction. */
export default function Demo() {
return (
<TopClassProvider direction="rtl" locale="ar">
<div dir="rtl" lang="ar" className="grid gap-1.5">
<label htmlFor="file-upload-rtl" className="text-sm font-medium text-body">المرفقات</label>
<FileUpload id="file-upload-rtl" name="attachments" accept="application/pdf,image/png" maxFiles={5} maxSize={5 * 1024 * 1024}>
PDF أو PNG، حتى 5 ملفات
</FileUpload>
</div>
</TopClassProvider>
)
}
الخصائص
لوحة المفاتيح وإمكانية الوصول
- الاسم مطلوب:
idلتسمية<label htmlFor>، أوaria-label، أوaria-labelledby. - لكل ملف زر إزالة يحمل اسمه، مثل «إزالة brief.pdf»؛ وبعد الإزالة ينتقل التركيز إلى الملف التالي، أو السابق، أو إلى الحقل.
- سحب الملفات يميّز المنطقة بخط أساسي متصل؛ وفي وضع الألوان القسرية يصبح الخط Highlight. و
invalidيحوّله إلى لون الخطر.
من اليمين إلى اليسار
تتوسط المنطقة، وتنعكس الصفوف، ويأخذ كل اسم ملف اتجاهه الخاص. وتُكتب الأحجام بأرقام القارئ.
الخادم والمتصفح
مكوّن متصفح: يُعرض على الخادم ثم يُرطَّب في المتصفح.
الملفات: index.tsx, client.tsx.
على الشارة: client - الحجم لم يُقَس بعد.