Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Media Upload Dialog Block for React

A video library with its upload dialog shown open: a drop zone for images, video and audio that names the files it turns away and why, tiles for the ones that pass with a check each, bulk removal, a total and an Add button that puts the clips in the library.

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

Check files before they join a library, with this upload dialog for React with Base UI. It opens from the Library of Clipcellar, a creator's video library: the page's header holds an outline Upload Button, and the library, a search bar and six drawn tiles, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog holds the catalog File Upload drop zone for images, video and audio, up to 8 files of 25 MB each. A file that is the wrong kind or too large is named with its reason, "Not a media file" or "Too large", and is not added. The files that pass become tiles, each with a glyph for its kind (an image shows the visitor's own picture), the name, the size and the kind in words, and a check to select it; Remove selected and Remove all take tiles out, and a total reads "5 files, 38 MB". Add 5 files is the only Shine Button: the clips appear first in the drawn library, named after the files. Nothing is uploaded, so there is no progress bar. For preview the dialog is drawn open in place when the page loads, with five typed sample files already listed so there is something to check; the header button opens the real Dialog.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the library: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Upload button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same UploadFields component and share the block's state, so the files you chose in the copy are there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

How are the files checked?

By the files' own properties, in words. The picker takes only images, video and audio; a file of another kind, or one over 25 MB, is refused and named with its reason in the drop zone's own line, such as "notes.txt: Not a media file" or "huge.mov: Too large, 26 MB against 25 MB". The block adds two checks of its own: a file with the same name and size as one already listed is turned away, and the list takes eight files at a time, so a ninth is named too. Dismiss clears the lines. Nothing is read beyond the name, the size and the type.

Does anything upload, and what is an object URL doing here?

Nothing uploads: the files are read on this device and stay in the tab, and there is no progress bar because there is no transfer. An image tile shows the visitor's own picture through an object URL, made when the tile appears and revoked when it goes, so the browser lets the memory go; audio and video get a drawn glyph and are never played. In your app send each file to your storage from addThem, and show the real progress then.

How do selecting and removing work?

Each tile is one checkbox: press anywhere on it, or move to it with Tab and press Space. Remove selected names its count and takes the ticked tiles out, Remove all empties the list, and both move focus to Browse files so a keyboard user is never left on a control that is gone. With nothing ticked the buttons stay in place and answer in words instead of doing nothing. The eight places are always drawn, the free ones dashed, so the dialog keeps its height whatever is chosen.

Why are files listed before I choose any?

So the preview shows the dialog at work. On load the list holds five typed sample files (a tour, a room tone, a cover frame, a cut and a voiceover, 38 MB in all); they are only names and sizes, with a drawn glyph and no picture, and Remove all clears them. Files you choose join them, up to eight. Once the dialog closes the samples are gone until a reload. In your app start with an empty list and remove SAMPLES.

What does Add do to the library?

It moves the tiles to the front of the drawn library as real text, named after the files with their kind and size, and says "5 files added to the library, 38 MB" in a polite message. The count in the page header follows. Cancel, Close and Escape let the chosen files go.

Is it accessible from the keyboard?

Yes. The real dialog is named Add to the library, focus starts on Browse files and stays inside until the dialog closes, and Escape and the close button return focus to Upload. The drop zone is a labelled group, so dragging is an extra and Browse files is the way in for everyone. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the button.

  • Pro

    Profile Picture Dialog

    Account and security

    A profile page with its picture dialog shown open: a large preview over an Upload tab that checks one PNG, JPG or WebP up to 2 MB and shows it without cropping, and a Drawings tab of eight greyscale patterns, with Remove picture and Save picture.

  • Pro

    A shared drive's document list with a full-screen viewer shown open: three drawn pages that turn with buttons or arrow keys, a Fit, 125% and 150% zoom, a details list, activity, a Copy link button and a Download that saves a text file.

  • Pro

    A file-sync folder with its conflict alert shown open: the two copies of a spreadsheet side by side with when, who and how big, four ways to settle it, an Apply to all option, and the next conflict loading after each answer.

  • Pro

    A profile page with its cover-crop dialog shown open: a drawn landscape in an image cropper with shape, zoom, turn and reset controls, and the same crop shown live as an avatar, a card thumbnail and a banner strip.

  • Pro

    Quick Note Dialog

    Notes and editing

    A sticky-note wall with its dialog shown open: a title, a note of up to 280 characters, an Idea, To-do, Reference or Later label, a reminder day on a calendar and a pin switch, and a new card that lands first on the wall.

  • Pro

    A stock spreadsheet with its copy-as dialog shown open: the same four selected rows as Markdown, CSV, JSON or plain text, a preview that shows exactly what lands on the clipboard, a header-row option and a button that writes it.