Skip to content
Statecraft

All patterns

  • Bulk Actions

    Let users perform one action across many records safely, with clear scope, eligibility and recovery.

    Data
  • Advanced Filters

    Help users narrow large datasets with filters they can see, edit, share and recover from.

    Data
  • Autosave

    Save changes continuously without a Save button, while keeping users certain their work is safe.

    Forms
  • Approval Workflow

    Route a request through one or more reviewers with clear status, accountability and an auditable history.

    Workflow
  • AI Response

    Present generated answers with streaming, sources, control and recovery, so users can trust and verify them.

    AI
  • File Upload

    Let users add files with visible progress, early validation and recovery that never loses what already uploaded.

    Files
  • Command Palette

    Give users one keyboard-first entry point to jump anywhere and run any action without hunting through menus.

    Navigation
  • Subscription Management

    Let customers upgrade, downgrade, change billing cycles and cancel with exact prices, dates and consequences shown before they confirm.

    Payments
  • Refunds

    Let support staff or customers return money with the exact amount, destination, timing and consequences stated before it's irreversible.

    Payments
  • Checkout

    Take a customer from plan choice to paid with the fewest fields, a total that never surprises, and errors that keep what they typed.

    Payments
  • Failed Payment Recovery

    Recover failed renewals with timely, specific prompts and a grace period, before customers lose access they still want.

    Payments
  • Usage & Limits

    Show customers how much of their plan they've used and handle the moment they hit a limit without breaking their work.

    Payments
  • App Sidebar

    Organise a product's main navigation so users always know where they are, reach frequent places in one click, and keep their place on small screens.

    Navigation
  • Tabs

    Split one object's content into peer views that users switch between without losing their place, state or URL.

    Navigation
  • Breadcrumbs & Back

    Show users where they are in a hierarchy and get them back to exactly where they came from — filters, scroll and all.

    Navigation
  • File Preview

    Let users look inside a file without downloading it, with a predictable fallback for every type the product can't render.

    Files
  • Attachments

    Attach files to records and comments with clear ownership, visibility and deletion rules that match the record they belong to.

    Files
  • CSV Import

    Bring spreadsheet data into the product with column mapping, row-level validation and a preview, so nothing is imported by surprise.

    Files
  • Confirmation

    Ask for confirmation only when an action is hard to undo, and make the dialog state exactly what will happen.

    Workflow
  • Partial Failure

    Report operations where some items succeed and some fail, so users know exactly what happened and what to do about the rest.

    Workflow
  • Permissions

    Show people what they can do, explain what they can't, and give them a way forward instead of a dead end.

    Workflow
  • Notifications

    Tell people about things that need them, in the right channel and at the right volume, without burying what matters.

    Workflow
  • Activity History

    Show who changed what and when on a record, in a timeline people can scan, filter and trust.

    Data
  • Empty States

    Design what users see when there's nothing to show, so every empty screen explains why and offers the next useful step.

    Data
  • Version History

    Let users see earlier versions of a document or record, compare them, and restore safely without losing current work.

    Forms
  • Human Review

    Put a person between AI output and real-world consequences, with review that's fast for good output and careful for risky output.

    AI
  • Feedback

    Collect quick, specific feedback on AI output that users actually give, and that the team can actually use.

    AI
  • Inline Validation

    Tell users about input problems at the right moment — not while they're still typing, and not only after they submit.

    Forms
  • Unsaved Changes

    Protect work in forms that save explicitly, warning only when something would actually be lost.

    Forms
  • Offline Mode

    Keep users working when the connection drops, with an honest view of what's synced, what's pending and what can't be done offline.

    Forms
  • Pagination

    Split long lists into pages or progressive loads in a way that keeps position, counts and selection predictable.

    Data
  • Saved Views

    Let users save a combination of filters, sorting and columns as a named view they and their team can return to.

    Data
  • Comments

    Let people discuss work where it happens — on the record or the exact part of it — with mentions, threads and resolution.

    Workflow
  • Error Recovery

    When something fails, say what happened in plain language, protect the user's work, and offer the most useful next step.

    Workflow
  • Keyboard Shortcuts

    Give frequent users fast keyboard paths that are discoverable, consistent and never get in the way of typing.

    Navigation
  • Prompt Input

    Design the box where users ask AI for things — with context, attachments and controls visible — so prompts start strong and never get lost.

    AI
  • AI Suggestions

    Offer AI-generated values, completions and next steps inline, so users accept good ones in one action and ignore the rest at no cost.

    AI
  • Agent Progress

    Show what an AI agent is doing during long, multi-step tasks — steps, tool use and decisions — so users can follow, steer and stop it.

    AI
  • AI Onboarding

    Introduce an AI feature by showing what it can do with the user's own data, setting honest expectations about limits and privacy.

    AI
  • Export

    Let users take their data out in the format they need, with a clear scope and no surprises about what's included.

    Files
  • Storage Limits

    Show how much storage is used and by what, and handle a full quota without blocking work or deleting anything.

    Files
FilesFree

File Upload

Let users add files with visible progress, early validation and recovery that never loses what already uploaded.

8 states7 edge casesDesktop + Mobile

01The problem

Users need to get files from their device into the product: receipts, contracts, images, datasets. Uploads are slow, fail on bad networks, and get rejected for size or type. When they fail, users usually can't tell which files made it, and often start over.

02When to use

Use when

  • Attaching documents to records: invoices, contracts, tickets
  • Uploading images or media for content
  • Importing data files for processing
  • Any flow where users bring several files at once

Avoid when

  • The content is short text — a paste field is faster than a file round trip.
  • Files live in a cloud drive the user already uses. Offer a picker integration instead of download-then-upload.
  • A file must be processed before the user can continue. That is an import flow, with mapping and validation steps.

03Recommended UX

Statecraft recommendation

Start uploading the moment files are chosen, show per-file progress in a list, and validate type and size before any bytes are sent. A failed file must never block or discard the files that succeeded.

Uploading on selection removes a pointless “Upload” click and uses the time the user spends filling other fields.

Per-file rows turn one opaque operation into many small ones, each with its own status, retry and remove. This is what makes partial failure recoverable.

Checking type and size on the client gives instant feedback. A 200 MB file rejected after a 3-minute upload is the worst possible outcome.

04Interaction flow

  1. 01

    Empty drop zone

    States accepted types and maximum size up front.

  2. 02

    Choose or drop files

    Browse button, drag and drop, or paste.

  3. 03

    Validate locally

    Type, size and count checked before upload.

  4. 04

    Upload per file

    Each file gets a row with progress and Cancel.

  5. 05

    Server processing

    Virus scan, thumbnail or parsing where needed.

  6. Result

    • Uploaded
    • Rejected
    • Failed — retry

05Desktop behaviour

On desktop, drag and drop is the expected shortcut, but never the only way in. The drop zone sits where the files will live, and the file list grows below it.

Desktop rules

  • Always pair the drop zone with a visible “Browse files” button. Drag and drop is not discoverable or accessible on its own.
  • Highlight the drop zone only while a file is dragged over the window, not permanently.
  • Show accepted types and the size limit inside the drop zone: “PDF, PNG or JPG · up to 25 MB”.
  • Support paste (Cmd/Ctrl+V) for screenshots where images are accepted.
Validation happens before upload, each file has its own row and status, and one failure never blocks the others.

06Mobile behaviour

Mobile users don't drag files. They pick from photos, the camera or a files app, often on a weak connection.

Mobile rules

  • Replace the drop zone with one clear “Add files” button that opens the native picker.
  • Offer the camera directly when documents or receipts are expected.
  • Keep uploads running if the user scrolls or moves to another field, and keep the list visible.
  • Show remaining time or size for large files: “12 of 48 MB”.
No drop zone on phones: one Add button opening the native picker, with the camera offered directly for receipts.

07States

  • Empty

    Drop zone with accepted types, size limit and a Browse button.

  • Drag over

    Drop zone highlights only while a file is dragged over the window.

  • Uploading

    Per-file progress bar with percentage and Cancel.

  • Processing

    Bytes are uploaded, server work continues: “Scanning…”, “Generating preview…”.

  • Uploaded

    File name, size, thumbnail if available, and Remove.

  • Rejected

    Failed validation before upload. Explains the rule: “Larger than 25 MB”.

  • Failed

    Network or server failure during upload. Retry on the row, other files unaffected.

  • Limit reached

    Maximum file count reached. Drop zone disabled with the reason.

08Edge cases

  1. EC-01

    Mixed valid and invalid files

    The user drops 6 files; 2 are over the size limit.

    Recommendation

    Upload the 4 valid files and list the 2 rejected ones with the reason. Never reject the whole batch because of one file.

  2. EC-02

    Submitting while uploads are in progress

    The user clicks Save on the form while 2 files are still uploading.

    Recommendation

    Disable Save with the reason (“Waiting for 2 uploads”) or queue the save until uploads finish. Never save a record that silently drops in-flight files.

  3. EC-03

    Connection drops mid-upload

    A 40 MB video is 70% uploaded when the network drops.

    Recommendation

    Mark the file as failed with Retry, keep everything else intact, and resume from the last chunk if the backend supports resumable uploads.

  4. EC-04

    Leaving the page

    The user navigates away with uploads still running.

    Recommendation

    Warn before leaving only while uploads are in progress. After they finish, leave freely.

  5. EC-05

    Duplicate file names

    The user uploads “invoice.pdf” to a record that already has one.

    Recommendation

    Keep both and disambiguate the display name (“invoice (2).pdf”). Ask about replacing only when the product versions files.

  6. EC-06

    File type spoofing

    A file named “report.pdf” is actually an executable.

    Recommendation

    Treat the client check as a convenience only. Verify the real type on the server and show a clear rejection: “This file isn’t a valid PDF.”

  7. EC-07

    Server-side rejection after upload

    A virus scan flags a file after it uploaded.

    Recommendation

    Move the row to a rejected state with the reason, and make sure the file was never visible to other users in the meantime.

09Microcopy

  • Drop zone

    Avoid

    “Drag files here”

    Prefer

    “Drop files or browse · PDF, PNG or JPG up to 25 MB”

  • Too large

    Avoid

    “Invalid file”

    Prefer

    “contract-final.pdf is 38 MB. The limit is 25 MB.”

  • Network failure

    Avoid

    “Upload error”

    Prefer

    “Upload interrupted. Retry”

  • Blocked save

    Prefer

    “Waiting for 2 uploads to finish…”

  • Count limit

    Avoid

    “Limit exceeded”

    Prefer

    “You can attach up to 10 files. Remove one to add another.”

10Accessibility

  • The Browse button is the primary control. The drop zone is an enhancement and needs no keyboard handling of its own.
  • Each file row exposes its status in text, with a progress element that has an accessible name: “Uploading invoice.pdf, 45%”.
  • Announce completion and failures in a polite live region; don't announce every progress tick.
  • Remove and Retry buttons must name the file: “Remove invoice.pdf”.
  • After a file is removed, move focus to the next row, or back to Browse when the list is empty.

11Developer notes

  1. 01

    Upload directly to object storage with short-lived signed URLs rather than streaming through the app server.

  2. 02

    Use chunked or resumable uploads for anything over ~10 MB so that retries resume rather than restart.

  3. 03

    Give each file a client-generated ID at selection time; progress, retry and removal all key off it.

  4. 04

    Create the attachment record only after the upload is confirmed, and clean up orphaned uploads on a schedule.

  5. 05

    Validate type by inspecting file content on the server; never trust the extension or the browser-reported MIME type.

12Implementation prompt

For Claude Code, Codex or Cursor

Implement a production-quality file upload component for the existing form.

Requirements:
- Drop zone with a visible "Browse files" button; show accepted types and size limit inside it.
- Highlight the drop zone only while files are dragged over the window. Support paste for images.
- Validate type, size and count on the client before uploading; list rejected files with a specific reason.
- Start uploading immediately on selection. One row per file: name, size, progress, Cancel.
- States per file: uploading, processing, uploaded, rejected, failed (with Retry). Failures never affect other files.
- Upload directly to storage via signed URLs; use chunked/resumable uploads above 10 MB.
- Client-generated file IDs for progress, retry and removal.
- Disable form submission while uploads are in progress, with a "Waiting for N uploads" message.
- Warn before leaving the page only while uploads are running.
- Verify file type on the server by content; surface server-side rejections on the row.
- Accessibility: labelled progress per file, polite live region for completion/failure, Remove/Retry labelled with the file name, sensible focus after removal.
- Mobile: replace the drop zone with an "Add files" button; offer the camera when documents are expected.

Do not redesign the existing interface.
Keep upload state management in a hook, separate from presentation.

React + TypeScript reference code for this pattern — logic, hook, component and tests — is included in Statecraft Pro.