File Upload 2
Dropzone-style file input. A native file input stretched across a dashed drop area — click anywhere or drag files onto it. Five sizes, five colour intents, five corner radii, RTL support, composed header/subheader/CTA lines, drag-over feedback, and a disabled state.
Playground
Installation
pnpm add @tessinaui/uiUsage
import { FileUpload2, FileUpload2Header, FileUpload2Subheader } from "@tessinaui/ui";{/* Default */}
<FileUpload2 onFilesSelected={(files) => console.log(files)}>
<FileUpload2Header>Upload your files</FileUpload2Header>
<FileUpload2Subheader>Supported formats: .jpg, .png</FileUpload2Subheader>
<span>Click or drag files here to upload</span>
</FileUpload2>
{/* Multiple files */}
<FileUpload2 multiple onFilesSelected={setFiles}>
<FileUpload2Header>Multiple files</FileUpload2Header>
<span>Browse files</span>
</FileUpload2>
{/* Restrict file types */}
<FileUpload2 accept=".jpg,.png">
<FileUpload2Header>Images only</FileUpload2Header>
<span>Click or drag files here to upload</span>
</FileUpload2>
{/* Size + intent + rounded */}
<FileUpload2 size="lg" intent="error" rounded="md">
<FileUpload2Header>Upload failed</FileUpload2Header>
<FileUpload2Subheader>File was too large</FileUpload2Subheader>
<span>Click or drag files here to retry</span>
</FileUpload2>
{/* Right-to-left */}
<FileUpload2 dir="rtl">
<FileUpload2Header>ارفع ملفاتك</FileUpload2Header>
<span>انقر أو اسحب الملفات هنا للرفع</span>
</FileUpload2>
{/* Without the icon bubble */}
<FileUpload2 hideIcon>
<FileUpload2Header>Custom header</FileUpload2Header>
<span>Click or drag files here to upload</span>
</FileUpload2>
{/* Disabled */}
<FileUpload2 disabled>
<FileUpload2Header>Upload your files</FileUpload2Header>
<span>Click or drag files here to upload</span>
</FileUpload2>Examples
Default
Header, subheader, and an underlined call-to-action. Clicking anywhere in the zone — or dropping a file onto it — opens the native picker / accepts the file.
Multiple
Set multiple to accept more than one file at a time.
Sizes
Five sizes from xs to xl scale the padding, icon, and text together.
Intents
Colour intents tint the fill and border — none, error, warning, success, and info.
Rounded
Five corner radii from none to full.
Direction
Set dir="rtl" to mirror the icon and text for right-to-left languages.
States
Disabled, icon-less, and loading placeholder.
Anatomy
<FileUpload2>
<FileUpload2Header /> {/* bold first line */}
<FileUpload2Subheader /> {/* muted second line */}
<span>…</span> {/* any other children become the underlined CTA */}
</FileUpload2>The component renders a real <input type="file"> stretched across the entire zone in the same grid cell, so click-to-browse and drag-and-drop are both native browser behavior — no synthetic drop handling, no hidden buttons.
Props
FileUpload2
Extends React.InputHTMLAttributes<HTMLInputElement> — accept, multiple, name, form, capture, etc. all pass through to the native input.
| Prop | Type | Default | Description |
|---|---|---|---|
onFilesSelected | (files: File[], event) => void | — | Fired when file(s) are picked or dropped |
size | xs | sm | md | lg | xl | md | Scales padding, icon, and text |
intent | none | error | warning | success | info | none | Fill tint and border colour |
rounded | none | sm | md | lg | full | lg | Corner radius |
dir | ltr | rtl | — | Text/layout direction; mirrors icon and text |
disabled | boolean | false | Disables the input and dims the zone |
hideIcon | boolean | false | Hides the leading upload-icon bubble |
className | string | — | Class for the native file input |
wrapperClassName | string | — | Class for the outer grid wrapper |
containerClassName | string | — | Class for the visible dropzone container |
After each selection the input's value is cleared so picking the same file again still fires onFilesSelected. When a name prop is set (native form usage) the value is kept so the FileList survives until submit.
The size, intent, rounded, and dir props also accept containerClassName / wrapperClassName for further overrides.
FileUpload2Header / FileUpload2Subheader
Styled <span>s that read the parent's size from context, so their text scales automatically. Accept all HTMLSpanElement props.
FileUpload2Skeleton
Loading placeholder — accepts size, rounded, dir, and hideIcon to match the zone it stands in for.
Accessibility
- The interactive element is a real
<input type="file">— full keyboard support (focus withTab, open withEnter/Space) and screen-reader semantics for free - The call-to-action is wrapped in a
<label htmlFor>tied to the input, giving it its accessible name; when no CTA children are passed the input falls back toaria-label="Upload files"(override by passing your ownaria-label) - A visible focus ring is drawn around the zone when the input has keyboard focus, with a transparent-outline fallback that stays visible in forced-colors (high-contrast) modes
- The upload icon is
aria-hidden— decorative only - The disabled state uses the native
disabledattribute
File Upload
Drag-and-drop file upload with file list, progress, validation, four visual variants, five sizes, intent colours, and per-file status (idle/uploading/success/error).
Flex
A low-level flexbox layout primitive that exposes the full flex API — four directions, three wrap modes, independent row and column gap, align-items, justify-content, align-content, inline mode, polymorphic render, and LTR/RTL. Ships with FlexItem for per-child grow, shrink, basis, order, and alignSelf control.