Skip to main content
Graphite UI

File uploader

Lets the reader pick files from their device, or drop them, and shows each one’s progress. It picks and lists files; uploading and checking them is the page’s, which reports back through each file’s status.

Contract 1.0.0Kit · 4 sets · 41 variantsOpen in Figma

Live preview

Rendered by the component itself from the same generated tokens as the rest of the site.

Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

Installation

Install it with the shadcn CLI, along with everything it uses. New project? Set it up first, as Quick start shows.

npx shadcn@latest add https://www.graphite-ui.com/r/file-uploader.json
import { FileUploader } from '@/components/ui/file-uploader'
import type { UploaderFile } from '@/components/ui/file-uploader'

Anatomy

The label and a description of what may be uploaded, the trigger, then a list of the files, each with its name and a remove button. The list sits 16 under the trigger, its items 8 apart.

Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg
  1. LabelRequiredInput Label in on-surface (the kit's text-primary). Names the group.
  2. DescriptionOptionalThe kit's Desc. text, Body/3 in on-surface-variant, 8 under the label. Says what may be uploaded; the trigger is described by it.
  3. TriggerRequiredThe kit's Type. Default is the governed primary Button at the uploader's size; Drag and drop is a 100-tall drop box with a dashed edge, which is itself the file input's label.
  4. File listOptionalThe kit's Files. One item per file, 8 apart, each the private _File uploader file item.

Variants

Type is the trigger: a primary Button, or a drop box that also opens the picker. Size sets the Button and the file items, 48, 40 or 32; the drop box is 100 at every size.

Default: Large
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg
Default: Medium
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg
Default: Small
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg
Drag and drop
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg
Drag and drop: Small
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg

States

Each file shows where it is: uploaded and removable, uploading, complete, or an error with its message, short or with a second line of detail. The drop box takes a 2px primary edge while files are over it or it has focus.

File states
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • banner.jpg
  • logo.png
  • photo.jpg
    File exceeds size limit.
  • scan.png
    File exceeds size limit.500kb max file size. Select a new file and try again.
File states: Small
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • banner.jpg
  • logo.png
  • photo.jpg
    File exceeds size limit.
  • scan.png
    File exceeds size limit.500kb max file size. Select a new file and try again.
Disabled
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

  • cover.png
  • portrait-of-the-team-at-the-offsite.jpg
Drag and drop: Disabled
Upload files

Max file size is 500kb. Supported file types are .jpg and .png.

API reference

Generated from the contract, versioned with it, and checked by drift-check. This table cannot describe props the component does not have.

File uploader props
PropTypeDefaultNotes
type'button' | 'dropzone'—The kit's Default and Drag and drop.
size'sm' | 'md' | 'lg'—The kit's Size. Sets the Button (32, 40, 48) and the file items (32, 40, 48). The drop box is 100 at every size, as the kit draws it.
label / description——The label is required.
buttonLabel / dropLabel——The trigger's copy. "Add file" and the kit's "Drag and drop files here or click to upload" by default.
accept / multiple——Passed to the file input. Multiple by default.
disabledboolean—
files / onAdd / onRemove——Controlled. onAdd receives the files picked or dropped; uploading and validating them is the caller's, reported back through each file's status (uploaded, uploading, complete, error) and, for an error, error and errorDetail.

Design tokens

Every swatch is live. Change the source color in the header and this table repaints, because it reads the same roles the component does.

  • on-surfaceThe label, file names and the remove glyph (Text/text-primary, Icon/icon-primary), and an Error long's first line.
  • on-surface-variantThe description (Text/text-secondary).
  • outlineThe drop box's dashed edge through the strong step (Border/border-strong-01), and the rule over an error message through the subtle step (Border/border-subtle-00).
  • primaryThe drop box's copy (Link/link-primary), its drag-over and focus edge (Miscellaneous/interactive), the spinner, the remove glyph's focus ring through primary-focus, and the disabled family through primary-disabled and primary-disabled-content.
  • elevationFile items, elevation-01 (Layer/layer-01).
  • infoThe success mark (Support/support-info).
  • dangerAn errored item's 2px edge, its status glyph and its message (Support/support-error, Text/text-error).
  • backgroundThe mark inside the error glyph.
  • textInput Label, Body/3, and Caption/1 for error messages.
  • spacingThe 16 and 8 gaps, item padding and the drop box's padding.
  • motionThe spinner's turn, through the indeterminate duration and its linear ease, as Modal's inline loading turns.

Usage

The contract's prohibitions, written as the choices you will actually face.

Do

  • Say what may be uploaded in the description: size, type and how many.
  • Show each file’s progress, and say what went wrong in the error, with what to do next in the detail.
  • Use the drop box where uploading is the main task on the page.
  • Let the reader remove a file they picked by mistake.

Don’t

  • Show an error edge without its message.
  • Upload on the reader’s behalf before they have chosen; picking is theirs.
  • Restyle the Button. It is the governed primary Button.
  • Hide the file types the picker accepts. Put them in the description too.

Accessibility

What the component does for you, and what it leaves to you.

Roles
A labelled group. The Default trigger is a Button that opens the native file picker; the drop box is the file input’s label, so clicking or pressing it opens the same picker.
Keyboard
Tab reaches the trigger and each remove button. Enter or Space on the trigger, or on the focused drop box, opens the picker.
Names
The trigger is described by the description. Each remove button is “Remove file”, described by the file’s error; uploading announces as a status.
Focus
The drop box takes a 2px --graphite-primary edge; the remove glyph a 2px --graphite-primary-focus ring, 4 out.
Errors
An errored file always shows its message, so the edge and the glyph never carry the meaning alone.

Figma parity

The kit’s File uploader page has one public set, with three private ones that draw the drop box and the file items. The code is one component; its file list is the private item, built in.

Kit axes and how they map to code
Kit axisValuesCodeHow it maps
TypeDefault · Drag and droptypebutton and dropzone.
SizeLarge · Medium · SmallsizeThe Button at 48, 40 or 32 (the kit draws Large and Medium 2 over, as Button carries); the items at 48, 40 or 32.
StateEnabled · DisableddisabledThe kit’s Disabled hides the file list, which reads as Files switched off; the code keeps the files, their remove buttons disabled.
StateSkeleton—No counterpart by rule.
FilesBooleanfilesThe list shows when there are files.
Item stateUploaded · Loading · Success · Focus · Error short · Error longfiles[].statusuploaded, uploading, complete and error; error with errorDetail is Error long. Focus is the remove button’s pseudo-class.
Drop boxEnabled · Drag + Hover · Focus · Disabled—Drag-over is tracked while files are over it; focus is the file input’s. Disabled copy takes the disabled content tone, not the kit’s fill tone.
Remove glyphDrop shadow—Read as a stray and not drawn.