2.0 beta — new releases can include breaking changes. Stable 1.x docs
dimah-s3v2.0.0-beta.0
ComponentsFiles

Attachment

File cards, status rows, progress rings, and type glyphs for upload, download, and delete feedback.

FileAttachment and StatusAttachment are the cards the upload family renders, built on shadcn Attachment. Use them, with the smaller pieces on this page, when you build your own parts.

Preview

Layout
State
quarterly-report.pdf2.3 MB
avatar.png175.8 KB
budget.xlsx82.0 KB

Install

Complete UI Setup first: the stylesheet and one <Toaster />. Then add this component:

import { FileAttachment, StatusAttachment } from "@dimah-s3/ui";

Usage

UploadStatus, UploadFileList, and UploadFieldValue already render these cards. Reach for them when you render a file yourself:

"use client";

import { UploadFileList, FileAttachment } from "@dimah-s3/ui";

export function CompactFiles() {
  return (
    <UploadFileList className="flex-row flex-wrap">
      {(file) => (
        <FileAttachment
          className="w-32"
          state={
            file.phase === "success"
              ? "done"
              : file.phase === "error"
                ? "error"
                : "uploading"
          }
          fileName={file.fileName}
          fileSize={file.fileSize}
          contentType={file.contentType}
          previewUrl={file.previewUrl}
          percent={file.progress.percent}
          error={file.error}
        />
      )}
    </UploadFileList>
  );
}

Render UploadFileList inside Upload. UploadFileItem maps every phase and adds cancel for you.

Layout

Set the width with className. The card is a size container: below a 9rem content width, such as className="w-32", the media stacks above the text. Wider, it is a row. StatusAttachment is always a row and fills its parent unless you set a width.

state is idle, uploading, processing, done, or error. The ring shows percent while the card is idle or uploading; processing shows a spinner instead.

Actions

  • onCancel adds a Cancel {name} action while the card is idle (queued), uploading, or processing.
  • onRetry adds a Retry {name} action while it is error. It is the same button as cancel, so focus stays on it when the file goes back in flight.
  • onDismiss adds a Dismiss {name} action once it is done or error.
  • actions takes your own AttachmentActions, placed before those.

The title is a FileName: a long name ends its stem in an ellipsis and keeps the extension visible, and title holds the whole name.

  • trigger takes an AttachmentTrigger that makes the whole card one control, such as opening the file. Give it an accessible name.
<FileAttachment
  state="done"
  fileName={file.name}
  fileSize={file.size}
  trigger={
    <AttachmentTrigger aria-label={`Open ${file.name}`} onClick={open} />
  }
  actions={
    <AttachmentAction aria-label={`Share ${file.name}`} onClick={share}>
      <Share2Icon />
    </AttachmentAction>
  }
/>

Wrap several cards in AttachmentGroup for a scrolling row.

Examples

Every state

FileAttachment for one file in each state, and StatusAttachment for a result that has no single file.

FileAttachment

waiting-in-queue.pdf1.1 MB
holiday-video.mp448 MB · 9s left
dataset.csvFinishing…
avatar.png175.8 KB
too-large-archive.zipThe file is larger than the 75 MB limit.

StatusAttachment

Preparing 4 files…
All 4 files uploaded12.6 MB
Upload failed2 of 4 files could not be uploaded.

Glyphs and progress

FileTypeGlyph picks a colored glyph from the content type, else the extension. FolderGlyph is the object list's folder, and CircleProgress the ring a card shows while its file uploads.

  • Folder
  • report.pdf
  • notes.docx
  • budget.xlsx
  • slides.pptx
  • data.csv
  • archive.zip
  • photo.jpg
  • song.mp3
  • clip.mp4
  • app.ts
  • README.md
  • unknown.bin
0%
25%
50%
75%
100%

Building blocks

ExportRenders
CircleProgressA progress ring with role="progressbar", named Progress for {name}
FileNameA name that fits its width and keeps the extension (report-for-q….pdf)
FileTypeGlyphA colored glyph for the file type, from the content type or the extension
FolderGlyphThe folder glyph the object list uses
DismissAttachmentActionThe dismiss icon button. label sets its accessible name
AttachmentGroupA horizontal, scrolling group of cards, from shadcn Attachment
AttachmentActionAn icon button in the card's actions, from shadcn Attachment
AttachmentTriggerA button over the whole card, from shadcn Attachment

For chrome that does not fit these, compose shadcn Attachment with the headless hooks; see Custom UI.


Props

import type {
  FileAttachmentProps,
  StatusAttachmentProps,
  CircleProgressProps,
  FileNameProps,
  FileTypeGlyphProps,
  DismissAttachmentActionProps,
} from "@dimah-s3/ui";

FileAttachment

Prop

Type

StatusAttachment

Prop

Type

CircleProgress

Prop

Type

FileName

Prop

Type

FileTypeGlyph

Prop

Type

DismissAttachmentAction

Prop

Type

On this page