본문으로 건너뛰기
언어

Attachmentstandard

첨부 파일 한 개를 보여 주는 카드(첨부, attachment)입니다. 그림 또는 아이콘, 이름, 설명, 동작 버튼을 조합하고 올리는 중·실패 같은 상태를 색과 테두리로 구분합니다. shadcn base-nova 의 원본을 그대로 담은 아이템입니다. 업스트림 메타데이터에 문서 링크가 없습니다.

설치

pnpm
pnpm dlx shadcn@4.23.0 add @uikit/attachment

의존 아이템button

Default

attachment-example.tsx
"use client"
import * as React from "react"
import {  Example,  ExampleWrapper,} from "@/components/example"import {  Attachment,  AttachmentAction,  AttachmentActions,  AttachmentContent,  AttachmentDescription,  AttachmentGroup,  AttachmentMedia,  AttachmentTitle,  AttachmentTrigger,} from "@/components/ui/attachment"import { Button } from "@/components/ui/button"import {  Dialog,  DialogContent,  DialogDescription,  DialogHeader,  DialogTitle,  DialogTrigger,} from "@/components/ui/dialog"import { Spinner } from "@/components/ui/spinner"import { CheckIcon, ClockIcon, CopyIcon, DownloadIcon, FileArchiveIcon, FileCodeIcon, FileSearchIcon, FileTextIcon, FileWarningIcon, PresentationIcon, RefreshCwIcon, TableIcon, XIcon } from "lucide-react"
export default function AttachmentExample() {  return (    <ExampleWrapper>      <AttachmentFiles />      <AttachmentContentOnly />      <AttachmentStates />      <AttachmentImages />      <AttachmentImageStates />      <AttachmentSizes />      <AttachmentScrollableGroup />      <AttachmentTriggers />    </ExampleWrapper>  )}
function AttachmentFiles() {  return (    <Example title="Files" className="gap-8">      <div className="flex w-full flex-col gap-2">        <div className="px-1 text-xs font-medium text-muted-foreground">          Horizontal        </div>        <div className="flex flex-col gap-3">          <Attachment className="w-full">            <AttachmentMedia>              <FileTextIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>sales-dashboard.pdf</AttachmentTitle>              <AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove sales-dashboard.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment className="w-full">            <AttachmentMedia>              <TableIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>customer-import.csv</AttachmentTitle>              <AttachmentDescription>CSV · 18 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove customer-import.csv">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment className="w-full">            <AttachmentMedia>              <FileCodeIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>message-renderer.tsx</AttachmentTitle>              <AttachmentDescription>TypeScript · 12 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove message-renderer.tsx">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>        </div>      </div>      <div className="flex w-full flex-col gap-2">        <div className="px-1 text-xs font-medium text-muted-foreground">          Vertical        </div>        <AttachmentGroup className="w-full">          <Attachment orientation="vertical">            <AttachmentMedia>              <FileTextIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>sales-dashboard.pdf</AttachmentTitle>              <AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove sales-dashboard.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia>              <TableIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>customer-import.csv</AttachmentTitle>              <AttachmentDescription>CSV · 18 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove customer-import.csv">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia>              <FileCodeIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>message-renderer.tsx</AttachmentTitle>              <AttachmentDescription>TypeScript · 12 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove message-renderer.tsx">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia>              <FileArchiveIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>source-assets.zip</AttachmentTitle>              <AttachmentDescription>ZIP · 4.2 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove source-assets.zip">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia>              <PresentationIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>quarterly-review.key</AttachmentTitle>              <AttachmentDescription>Keynote · 9 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove quarterly-review.key">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>        </AttachmentGroup>      </div>    </Example>  )}
function AttachmentContentOnly() {  return (    <Example title="Content Only" className="gap-8">      <div className="flex w-full flex-col gap-2">        <div className="px-1 text-xs font-medium text-muted-foreground">          Title        </div>        <div className="flex flex-col gap-3">          <Attachment className="w-full">            <AttachmentContent>              <AttachmentTitle>React Documentation</AttachmentTitle>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove React Documentation">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment className="w-full">            <AttachmentContent>              <AttachmentTitle>Tailwind CSS</AttachmentTitle>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove Tailwind CSS">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment size="sm" className="w-48">            <AttachmentContent>              <AttachmentTitle>shadcn/ui</AttachmentTitle>            </AttachmentContent>            <AttachmentTrigger              render={                <a                  href="https://ui.shadcn.com"                  target="_blank"                  rel="noopener noreferrer"                  aria-label="Open shadcn/ui"                />              }            />          </Attachment>        </div>      </div>      <div className="flex w-full flex-col gap-2">        <div className="px-1 text-xs font-medium text-muted-foreground">          Title and Description        </div>        <div className="flex flex-col gap-3">          <Attachment className="w-full">            <AttachmentContent>              <AttachmentTitle>Building accessible components</AttachmentTitle>              <AttachmentDescription>                react.dev · 8 min read              </AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove Building accessible components">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment className="w-full">            <AttachmentContent>              <AttachmentTitle>Utility-first CSS framework</AttachmentTitle>              <AttachmentDescription>tailwindcss.com</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove Utility-first CSS framework">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment size="sm" className="w-full max-w-80">            <AttachmentContent>              <AttachmentTitle>Compound components in React</AttachmentTitle>              <AttachmentDescription>ui.shadcn.com/docs</AttachmentDescription>            </AttachmentContent>            <AttachmentTrigger              render={                <a                  href="https://ui.shadcn.com/docs"                  target="_blank"                  rel="noopener noreferrer"                  aria-label="Open Compound components in React"                />              }            />          </Attachment>        </div>      </div>    </Example>  )}
function AttachmentStates() {  return (    <Example title="States" className="gap-8">      <div className="flex w-full flex-col gap-3">        <div className="px-1 text-xs font-medium text-muted-foreground">          Horizontal        </div>        <div className="flex flex-col gap-2">          <Attachment state="idle" className="w-full">            <AttachmentMedia>              <ClockIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>selected-file.pdf</AttachmentTitle>              <AttachmentDescription>Ready to upload</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove selected-file.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="uploading" className="w-full">            <AttachmentMedia>              <Spinner />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>design-system.zip</AttachmentTitle>              <AttachmentDescription>Uploading · 64%</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove design-system.zip">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="processing" className="w-full">            <AttachmentMedia>              <FileTextIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>market-research.pdf</AttachmentTitle>              <AttachmentDescription>Processing document</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove market-research.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="error" className="w-full">            <AttachmentMedia>              <FileWarningIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>financial-model.xlsx</AttachmentTitle>              <AttachmentDescription>                Upload failed. Try again.              </AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Retry upload">                <RefreshCwIcon />              </AttachmentAction>              <AttachmentAction aria-label="Remove attachment">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="done" className="w-full">            <AttachmentMedia>              <CheckIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>uploaded-report.pdf</AttachmentTitle>              <AttachmentDescription>Uploaded · 1.8 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove uploaded-report.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>        </div>      </div>      <div className="flex w-full flex-col gap-3">        <div className="px-1 text-xs font-medium text-muted-foreground">          Vertical        </div>        <AttachmentGroup className="w-full">          <Attachment state="idle" orientation="vertical">            <AttachmentMedia>              <ClockIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>selected-file.pdf</AttachmentTitle>              <AttachmentDescription>Ready</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove selected-file.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="uploading" orientation="vertical">            <AttachmentMedia>              <Spinner />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>design-system.zip</AttachmentTitle>              <AttachmentDescription>Uploading</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove design-system.zip">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="processing" orientation="vertical">            <AttachmentMedia>              <FileTextIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>market-research.pdf</AttachmentTitle>              <AttachmentDescription>Processing</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove market-research.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="error" orientation="vertical">            <AttachmentMedia>              <FileWarningIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>financial-model.xlsx</AttachmentTitle>              <AttachmentDescription>Failed</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Retry financial-model.xlsx">                <RefreshCwIcon />              </AttachmentAction>              <AttachmentAction aria-label="Remove financial-model.xlsx">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="done" orientation="vertical">            <AttachmentMedia>              <CheckIcon />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>uploaded-report.pdf</AttachmentTitle>              <AttachmentDescription>Done</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove uploaded-report.pdf">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>        </AttachmentGroup>      </div>    </Example>  )}
function AttachmentImages() {  return (    <Example title="Images" className="gap-8">      <div className="flex w-full flex-col gap-3">        <div className="px-1 text-xs font-medium text-muted-foreground">          Horizontal        </div>        <div className="flex flex-col gap-2">          <Attachment className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"                alt="Workspace"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>workspace.png</AttachmentTitle>              <AttachmentDescription>PNG · 820 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove workspace.png">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open workspace.png"                />              }            />          </Attachment>          <Attachment className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2394a3b8'/%3E%3C/svg%3E"                alt="Desk"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>desk-reference.jpg</AttachmentTitle>              <AttachmentDescription>JPG · 1.1 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove desk-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open desk-reference.jpg"                />              }            />          </Attachment>          <Attachment className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"                alt="Office"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>office-reference.jpg</AttachmentTitle>              <AttachmentDescription>JPG · 940 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove office-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open office-reference.jpg"                />              }            />          </Attachment>        </div>      </div>      <div className="flex w-full flex-col gap-2">        <div className="px-1 text-xs font-medium text-muted-foreground">          Vertical        </div>        <AttachmentGroup className="w-full">          <Attachment orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"                alt="Workspace"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>workspace.png</AttachmentTitle>              <AttachmentDescription>PNG · 820 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove workspace.png">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open workspace.png"                />              }            />          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2394a3b8'/%3E%3C/svg%3E"                alt="Desk"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>desk-reference.jpg</AttachmentTitle>              <AttachmentDescription>JPG · 1.1 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove desk-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open desk-reference.jpg"                />              }            />          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"                alt="Office"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>office-reference.jpg</AttachmentTitle>              <AttachmentDescription>JPG · 940 KB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove office-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open office-reference.jpg"                />              }            />          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23737373'/%3E%3C/svg%3E"                alt="Outdoor patio"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>patio-reference.jpg</AttachmentTitle>              <AttachmentDescription>JPG · 1.6 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove patio-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open patio-reference.jpg"                />              }            />          </Attachment>          <Attachment orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%236b7280'/%3E%3C/svg%3E"                alt="House exterior"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>house-exterior.jpg</AttachmentTitle>              <AttachmentDescription>JPG · 1.4 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove house-exterior.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>            <AttachmentTrigger              render={                <a                  href="https://images.unsplash.com/photo-1494526585095-c41746248156?w=900&auto=format&fit=crop&q=80"                  target="_blank"                  rel="noreferrer"                  aria-label="Open house-exterior.jpg"                />              }            />          </Attachment>        </AttachmentGroup>      </div>    </Example>  )}
function AttachmentImageStates() {  return (    <Example title="Image States" className="gap-8">      <div className="flex w-full flex-col gap-3">        <div className="px-1 text-xs font-medium text-muted-foreground">          Horizontal        </div>        <div className="flex flex-col gap-2">          <Attachment state="idle" className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"                alt="Office"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>office-reference.jpg</AttachmentTitle>              <AttachmentDescription>Ready to upload</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove office-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="uploading" className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"                alt="Workspace"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>workspace.png</AttachmentTitle>              <AttachmentDescription>Uploading · 72%</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove workspace.png">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="processing" className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2394a3b8'/%3E%3C/svg%3E"                alt="Desk"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>desk-reference.jpg</AttachmentTitle>              <AttachmentDescription>Processing image</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove desk-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="error" className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"                alt="Office"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>office-reference.jpg</AttachmentTitle>              <AttachmentDescription>Upload failed</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Retry image upload">                <RefreshCwIcon />              </AttachmentAction>              <AttachmentAction aria-label="Remove attachment">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="done" className="w-full">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"                alt="Workspace"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>workspace.png</AttachmentTitle>              <AttachmentDescription>Uploaded · 1.2 MB</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove workspace.png">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>        </div>      </div>      <div className="flex w-full flex-col gap-2">        <div className="px-1 text-xs font-medium text-muted-foreground">          Vertical        </div>        <AttachmentGroup className="w-full">          <Attachment state="idle" orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"                alt="Office"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>office-reference.jpg</AttachmentTitle>              <AttachmentDescription>Ready</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove office-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="uploading" orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"                alt="Workspace"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>workspace.png</AttachmentTitle>              <AttachmentDescription>Uploading</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove workspace.png">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="processing" orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2394a3b8'/%3E%3C/svg%3E"                alt="Desk"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>desk-reference.jpg</AttachmentTitle>              <AttachmentDescription>Processing</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove desk-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="error" orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"                alt="Office"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>office-reference.jpg</AttachmentTitle>              <AttachmentDescription>Failed</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Retry office-reference.jpg">                <RefreshCwIcon />              </AttachmentAction>              <AttachmentAction aria-label="Remove office-reference.jpg">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>          <Attachment state="done" orientation="vertical">            <AttachmentMedia variant="image">              <img                src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"                alt="Workspace"              />            </AttachmentMedia>            <AttachmentContent>              <AttachmentTitle>workspace.png</AttachmentTitle>              <AttachmentDescription>Done</AttachmentDescription>            </AttachmentContent>            <AttachmentActions>              <AttachmentAction aria-label="Remove workspace.png">                <XIcon />              </AttachmentAction>            </AttachmentActions>          </Attachment>        </AttachmentGroup>      </div>    </Example>  )}
function AttachmentSizes() {  return (    <Example title="Sizes" className="gap-3">      <Attachment size="default" className="w-full">        <AttachmentMedia>          <FileTextIcon />        </AttachmentMedia>        <AttachmentContent>          <AttachmentTitle>Default attachment</AttachmentTitle>          <AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>        </AttachmentContent>      </Attachment>      <Attachment size="sm" className="w-full">        <AttachmentMedia>          <FileTextIcon />        </AttachmentMedia>        <AttachmentContent>          <AttachmentTitle>Small attachment</AttachmentTitle>          <AttachmentDescription>PDF · 2.4 MB</AttachmentDescription>        </AttachmentContent>      </Attachment>      <Attachment size="xs" className="w-full">        <AttachmentMedia>          <FileTextIcon />        </AttachmentMedia>        <AttachmentContent>          <AttachmentTitle>Extra small attachment</AttachmentTitle>        </AttachmentContent>      </Attachment>    </Example>  )}
function AttachmentScrollableGroup() {  return (    <Example title="Scrollable Group" className="gap-4">      <AttachmentGroup className="w-full">        <Attachment className="w-64">          <AttachmentMedia>            <FileTextIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>briefing-notes.pdf</AttachmentTitle>            <AttachmentDescription>PDF · 1.4 MB</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove briefing-notes.pdf">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment className="w-64">          <AttachmentMedia variant="image">            <img              src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%23a3a3a3'/%3E%3C/svg%3E"              alt="Workspace"            />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>workspace.png</AttachmentTitle>            <AttachmentDescription>PNG · 820 KB</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove workspace.png">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment className="w-64">          <AttachmentMedia>            <TableIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>customers.csv</AttachmentTitle>            <AttachmentDescription>CSV · 18 KB</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove customers.csv">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment className="w-64">          <AttachmentMedia>            <FileCodeIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>renderer.tsx</AttachmentTitle>            <AttachmentDescription>TSX · 12 KB</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove renderer.tsx">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>      </AttachmentGroup>      <AttachmentGroup className="w-full">        <Attachment orientation="vertical">          <AttachmentMedia>            <FileTextIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>invoice.pdf</AttachmentTitle>            <AttachmentDescription>PDF</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove invoice.pdf">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment orientation="vertical">          <AttachmentMedia variant="image" className="aspect-square w-full">            <img              src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2394a3b8'/%3E%3C/svg%3E"              alt="Desk"            />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>desk.jpg</AttachmentTitle>            <AttachmentDescription>JPG</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove desk.jpg">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment orientation="vertical">          <AttachmentMedia>            <FileArchiveIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>assets.zip</AttachmentTitle>            <AttachmentDescription>ZIP</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove assets.zip">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment orientation="vertical">          <AttachmentMedia variant="image" className="aspect-square w-full">            <img              src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%206'%3E%3Crect%20width='8'%20height='6'%20fill='%2378716c'/%3E%3C/svg%3E"              alt="Office"            />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>office.jpg</AttachmentTitle>            <AttachmentDescription>JPG</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove office.jpg">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>        <Attachment orientation="vertical">          <AttachmentMedia>            <FileTextIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>notes.pdf</AttachmentTitle>            <AttachmentDescription>PDF</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Remove notes.pdf">              <XIcon />            </AttachmentAction>          </AttachmentActions>        </Attachment>      </AttachmentGroup>    </Example>  )}
function AttachmentTriggers() {  const [isVisible, setIsVisible] = React.useState(true)
  return (    <Example title="Triggers" className="gap-3">      {isVisible ? (        <Attachment className="w-full">          <AttachmentMedia>            <FileTextIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>contract-review.pdf</AttachmentTitle>            <AttachmentDescription>PDF · 820 KB</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Download attachment">              <DownloadIcon />            </AttachmentAction>            <AttachmentAction              aria-label="Remove attachment"              onClick={() => setIsVisible(false)}            >              <XIcon />            </AttachmentAction>          </AttachmentActions>          <AttachmentTrigger            render={              <a                href="#"                target="_blank"                rel="noreferrer"                aria-label="Open contract-review.pdf"              />            }          />        </Attachment>      ) : (        <Button variant="outline" onClick={() => setIsVisible(true)}>          Restore attachment        </Button>      )}      <Dialog>        <Attachment className="w-full">          <AttachmentMedia>            <FileSearchIcon />          </AttachmentMedia>          <AttachmentContent>            <AttachmentTitle>research-summary.pdf</AttachmentTitle>            <AttachmentDescription>Open preview dialog</AttachmentDescription>          </AttachmentContent>          <AttachmentActions>            <AttachmentAction aria-label="Copy link">              <CopyIcon />            </AttachmentAction>            <AttachmentAction aria-label="Remove research-summary.pdf">              <XIcon />            </AttachmentAction>          </AttachmentActions>          <DialogTrigger            render={              <AttachmentTrigger aria-label="Preview research-summary.pdf" />            }          />        </Attachment>        <DialogContent className="sm:max-w-md">          <DialogHeader>            <DialogTitle>research-summary.pdf</DialogTitle>            <DialogDescription>              Attachment triggers can open dialogs while actions remain              independently reachable.            </DialogDescription>          </DialogHeader>        </DialogContent>      </Dialog>    </Example>  )}