Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Mobile Responsive File Upload Block for React

A phone-first uploader drawn in a 360 px device frame: a large Choose files target, a Take photo camera shortcut, compact file chips and a bottom drawer quick look with Remove.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Design the upload for a thumb first, with this file upload panel for React with Base UI. It is the uploader of Snapfold, a field-notes scanning app for surveyors, drawn in a 360 px device frame on the panel's stage. Inside it, a large Choose files Shine Button opens the picker, and a Take photo Button is a second small File Upload root with accept="image/*" and capture="environment", so a phone opens its camera and a desktop opens the picker. The notes already added are compact chips with a glyph, name and size, and a Badge counts them. Tapping a chip opens a bottom Drawer with a quick look: a drawn stand-in page, the name, the size, Close and Remove. On a phone the frame drops its bezel and fills the width. The panel is ruled by Guides. It is built from File Upload, Drawer, Badge, Button, Shine Button and Guides, with a CSS entrance only. For field apps, mobile web uploaders and any flow used mostly on a phone.

FAQ

Does Take photo open a camera?

On a phone that supports it, yes: capture="environment" asks the browser to open the rear camera for an image, as the platform allows. On a desktop it opens the ordinary picker limited to images. The block never reads the photo; it lists its name and size.

What does the quick look show?

A stand-in, not the file. The page is drawn from a number made from the file's name, so the same name always draws the same page. The drawer shows the real name and size, a Close button and Remove, which takes the note out of the list and moves focus to the next chip.

How does the frame change on a phone?

Below the small breakpoint the frame loses its bezel, rounded corners and 360 px width and fills the panel, so the same screen is the real one. Every target is at least 44 px high: the Choose files button is 56 px, Take photo 44 and the chips 44.

Does it read my files?

No. Only the name and the size are kept, and files over 25 MB are refused with a message. The page holds twelve notes. Nothing is uploaded or saved, and a polite status line says so from load.

How does it work from the keyboard?

Both buttons and every chip are real buttons in the tab order. The drawer is a modal with a focus trap, named by the note's name; Escape or Close returns focus to the chip you opened.

How do I wire it to my app?

Send each file from the accepted handler to your storage and show its state on the chip. Keep the two roots: the camera shortcut is its own FileUpload because capture belongs to the whole root.

  • Pro

    A project folder's drop zone that folds into a slim Add more strip over its file list as files arrive, with a running total against 25 MB, Remove on each row and Clear all.

  • Pro

    A file drop zone that lists every file you pick or drop (name and size, never opened) beside a queue of four seeded files in their states, with Retry, Remove and a Send button.

  • Pro

    A deep inset drop zone whose 1 px edge lights up where the pointer is and glows evenly on focus, over a tray of attachment rows with Remove and Clear tray.

  • Pro

    A drawn project brief that is itself the drop zone: nothing shows until a file is dragged over it, then a full-bleed message appears, and dropped files join an attachments list with a short bar.

  • Pro

    An illustrated empty state whose drawn folder is the drop zone: a pick closes the folder and lists the file, with working Add files, Paste a link and New folder shortcuts.

  • Pro

    A format allow-list (PDF, PNG, JPG, DOCX, CSV, ZIP) that builds the drop zone's accept, checking each file by extension and by reported type, with an Accepted and a Refused list and the reason for each refusal.