120k

附件

显示带有媒体、元数据、上传状态和操作的文件或图片附件。

Workspace
workspace.pngPNG · 820 KB
Desk
desk-reference.jpgJPG · 1.1 MB
Office
office-reference.jpgJPG · 940 KB
sales-dashboard.pdfUploading · 64%
message-renderer.tsxTypeScript · 12 KB
import { FileCodeIcon, XIcon } from "lucide-react"

import {

Attachment 组件显示文件或图片附件及其媒体、名称和元数据,并可选地包含操作和上传状态。可将其用于聊天编辑器、消息线程和上传列表中的文件和图片。

安装

pnpm dlx shadcn@latest add attachment

用法

import {
  Attachment,
  AttachmentAction,
  AttachmentActions,
  AttachmentContent,
  AttachmentDescription,
  AttachmentMedia,
  AttachmentTitle,
} from "@/components/ui/attachment"
<Attachment>
  <AttachmentMedia>
    <FileTextIcon />
  </AttachmentMedia>
  <AttachmentContent>
    <AttachmentTitle>sales-dashboard.pdf</AttachmentTitle>
    <AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>
  </AttachmentContent>
  <AttachmentActions>
    <AttachmentAction aria-label="移除 sales-dashboard.pdf">
      <XIcon />
    </AttachmentAction>
  </AttachmentActions>
</Attachment>

组合

使用以下组合来构建一个附件:

Attachment
├── AttachmentMedia
├── AttachmentContent
│   ├── AttachmentTitle
│   └── AttachmentDescription
├── AttachmentActions
│   └── AttachmentAction
└── AttachmentTrigger

使用 AttachmentGroup 以可滚动的行布局多个附件:

AttachmentGroup
├── Attachment
└── Attachment

功能

  • 通过 AttachmentMedia 支持图标和图片媒体
  • 上传状态:idleuploadingprocessingerrordone,内置样式,并在进行中时带有闪烁效果
  • 三种尺寸以及水平或垂直布局
  • 全卡片式 AttachmentTrigger,可打开链接或对话框,同时各个操作仍可独立点击
  • 可滚动、可吸附的 AttachmentGroup,带有边缘渐隐效果
  • 可通过每个部分的 className 属性自定义样式

示例

图片

AttachmentMedia 上设置 variant="image",并在其中渲染一个 <img>。使用 orientation="vertical" 将媒体置于内容上方堆叠显示。

Workspace
workspace.pngPNG · 820 KB
Desk
desk-reference.jpgJPG · 1.1 MB
Office
office-reference.jpgJPG · 940 KB
import { XIcon } from "lucide-react"

import {

状态

设置 state 以反映上传生命周期。uploadingprocessing 会让标题呈现闪烁效果,而 error 会切换为破坏性样式。

selected-file.pdfReady to upload
design-system.zipUploading · 64%
market-research.pdfProcessing document
financial-model.xlsxUpload failed. Try again.
uploaded-report.pdfUploaded · 1.8 MB
import {
  CheckIcon,
  ClockIcon,

大小

使用 sizedefaultsmxs 之间切换。

Default attachmentPDF · 2.4 MB
Small attachmentPDF · 2.4 MB
Extra small attachment
import { FileTextIcon } from "lucide-react"

import {

将附件包裹在 AttachmentGroup 中,以水平可滚动、带吸附效果的行布局显示,并带有边缘渐隐效果。

briefing-notes.pdfPDF · 1.4 MB
workspace.png
workspace.pngPNG · 820 KB
customers.csvCSV · 18 KB
renderer.tsxTSX · 12 KB
import {
  FileCodeIcon,
  FileTextIcon,

触发器

添加一个 AttachmentTrigger,让整个卡片打开链接或对话框。它会填充在操作按钮后方的卡片区域,因此这些操作仍然可以点击。

research-summary.pdfOpen preview dialog
import { CopyIcon, FileSearchIcon, XIcon } from "lucide-react"

import {
<Dialog>
  <Attachment>
    {/* 媒体、内容、操作 */}
    <DialogTrigger
      render={<AttachmentTrigger aria-label="预览 research-summary.pdf" />}
    />
  </Attachment>
  <DialogContent>{/* ... */}</DialogContent>
</Dialog>

无障碍

AttachmentAction 会渲染一个 Button,而 AttachmentTrigger 会渲染一个真正的 <button>(或者通过 render 渲染你的元素)。请遵循下面的指导,以确保两者都可操作且可被正确播报。

为仅图标操作添加标签

AttachmentAction 通常只有图标,因此请为每个操作提供一个描述该动作及其目标的 aria-label

<AttachmentAction aria-label="移除 sales-dashboard.pdf">
  <XIcon />
</AttachmentAction>

为触发器添加标签

AttachmentTrigger 会覆盖整个卡片,本身没有文字,因此请为它提供一个 aria-label,说明激活它会执行什么操作。

<AttachmentTrigger
  render={
    <a
      href={url}
      target="_blank"
      rel="noreferrer"
      aria-label="打开 workspace.png"
    />
  }
/>

触发器在层叠顺序中位于操作按钮后面,因此 AttachmentActionAttachmentTrigger 不会相互遮挡——两者仍然可以分别获得焦点并被点击。

键盘滚动

AttachmentGroup 会水平滚动。当其中的附件是可交互元素时:无论是触发器还是操作按钮,键盘用户都可以通过 Tab 键切换到屏幕外的项目。对于仅用于展示的一排附件,请通过添加 tabIndex={0}role="group"aria-label,让该组本身可聚焦且可滚动。

不仅仅依赖颜色

error 状态使用的是一种危险色。请将失败原因写入 AttachmentDescription 中,这样状态就不会只通过颜色来传达。

API 参考

Attachment

根附件容器。

属性类型默认值描述
state"idle" | "uploading" | "processing" | "error" | "done""done"上传状态。驱动样式和闪烁效果。
size"default" | "sm" | "xs""default"附件尺寸。
orientation"horizontal" | "vertical""horizontal"将媒体放在内容旁边或上方。
classNamestring-应用于根元素的额外类名。

AttachmentMedia

用于图标或图片预览的媒体槽位。

属性类型默认值描述
variant"icon" | "image""icon"媒体包含的是图标还是 <img>
classNamestring-应用于媒体槽位的额外类名。

AttachmentContent

包裹标题和描述。

属性类型默认值描述
classNamestring-应用于内容槽位的额外类名。

AttachmentTitle

附件名称。当附件处于 uploadingprocessing 状态时会显示闪烁效果。

属性类型默认值描述
classNamestring-应用于标题的额外类名。

AttachmentDescription

文件类型、大小或上传状态等次要元数据。

属性类型默认值描述
classNamestring-应用于描述的额外类名。

AttachmentActions

一个或多个操作的容器,靠齐附件末端。

属性类型默认值描述
classNamestring-应用于操作区域的额外类名。

AttachmentAction

一个操作按钮。渲染为 Button 并接受其全部属性。

属性类型默认值描述
sizeButton["size"]"icon-xs"按钮尺寸。
...propsReact.ComponentProps<typeof Button>-传递给底层 Button 的属性。

AttachmentTrigger

一个覆盖整个卡片的触发层,用于激活附件。默认渲染为 <button>

属性类型默认值描述
renderReactElement | function-渲染为其他元素,例如链接。
...propsReact.ComponentProps<"button">-传递给触发元素的属性。

AttachmentGroup

将附件以可横向滚动、可吸附的行进行布局。

属性类型默认值描述
classNamestring-应用于组的额外类名。