Attachment
@vincisys/eyesonAttachment
Anexo de arquivo ou imagem com mídia, metadados, estado de upload e ações.
import { Attachment } from "@vincisys/eyeson";
import { FileText, X } from "lucide-react";
export function AttachmentBasicDemo() {
return (
<div className="flex flex-wrap gap-3">
<Attachment>
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>relatorio-vendas.pdf</Attachment.Title>
<Attachment.Description>
PDF · 2.4 MB
</Attachment.Description>
</Attachment.Content>
<Attachment.Actions>
<Attachment.Action
icon={X}
label="Remover relatorio-vendas.pdf"
/>
</Attachment.Actions>
</Attachment>
</div>
);
} Instalação
import { Attachment } from '@vincisys/eyeson'; Uso
import { Attachment } from '@vincisys/eyeson';
import { FileText, X } from 'lucide-react';
export function Example() {
return (
<Attachment>
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>relatorio.pdf</Attachment.Title>
<Attachment.Description>PDF · 2.4 MB</Attachment.Description>
</Attachment.Content>
<Attachment.Actions>
<Attachment.Action icon={X} label="Remover relatorio.pdf" />
</Attachment.Actions>
</Attachment>
);
} Composição
Attachment
├── Attachment.Media
├── Attachment.Content
│ ├── Attachment.Title
│ └── Attachment.Description
├── Attachment.Actions
│ └── Attachment.Action
└── Attachment.Trigger Exemplos
Básico
import { Attachment } from "@vincisys/eyeson";
import { FileText, X } from "lucide-react";
export function AttachmentBasicDemo() {
return (
<div className="flex flex-wrap gap-3">
<Attachment>
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>relatorio-vendas.pdf</Attachment.Title>
<Attachment.Description>
PDF · 2.4 MB
</Attachment.Description>
</Attachment.Content>
<Attachment.Actions>
<Attachment.Action
icon={X}
label="Remover relatorio-vendas.pdf"
/>
</Attachment.Actions>
</Attachment>
</div>
);
} Estados
Use state para refletir o ciclo de upload: idle, uploading, processing,
error e done. Em progresso, o título usa shimmer azul.
import { Attachment } from "@vincisys/eyeson";
import { FileText, Loader2, X } from "lucide-react";
export function AttachmentStatesDemo() {
return (
<div className="flex flex-col gap-3">
<Attachment state="idle">
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>arquivo-selecionado.pdf</Attachment.Title>
<Attachment.Description>
Pronto para enviar
</Attachment.Description>
</Attachment.Content>
</Attachment>
<Attachment state="uploading">
<Attachment.Media>
<Loader2 className="animate-eds-spin" data-slot="spinner" />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>design-system.zip</Attachment.Title>
<Attachment.Description>
Enviando · 64%
</Attachment.Description>
</Attachment.Content>
<Attachment.Actions>
<Attachment.Action icon={X} label="Cancelar envio" />
</Attachment.Actions>
</Attachment>
<Attachment state="processing">
<Attachment.Media>
<Loader2 className="animate-eds-spin" data-slot="spinner" />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>pesquisa-mercado.pdf</Attachment.Title>
<Attachment.Description>
Processando documento
</Attachment.Description>
</Attachment.Content>
</Attachment>
<Attachment state="error">
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>modelo-financeiro.xlsx</Attachment.Title>
<Attachment.Description>
Falha no envio. Tente novamente.
</Attachment.Description>
</Attachment.Content>
<Attachment.Actions>
<Attachment.Action
icon={X}
label="Remover modelo-financeiro.xlsx"
color="red-main"
/>
</Attachment.Actions>
</Attachment>
<Attachment state="done">
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>relatorio-enviado.pdf</Attachment.Title>
<Attachment.Description>
Enviado · 1.8 MB
</Attachment.Description>
</Attachment.Content>
</Attachment>
</div>
);
} Tamanhos
size aceita default, sm e xs.
import { Attachment } from "@vincisys/eyeson";
import { FileText } from "lucide-react";
export function AttachmentSizesDemo() {
return (
<div className="flex flex-col gap-3">
<Attachment size="default">
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>Tamanho padrão</Attachment.Title>
<Attachment.Description>
PDF · 2.4 MB
</Attachment.Description>
</Attachment.Content>
</Attachment>
<Attachment size="sm">
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>Tamanho pequeno</Attachment.Title>
<Attachment.Description>
PDF · 2.4 MB
</Attachment.Description>
</Attachment.Content>
</Attachment>
<Attachment size="xs">
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>Extra pequeno</Attachment.Title>
</Attachment.Content>
</Attachment>
</div>
);
} Grupo
Attachment.Group organiza anexos em uma linha com scroll horizontal.
import { Attachment } from "@vincisys/eyeson";
import { FileCode, FileText } from "lucide-react";
export function AttachmentGroupDemo() {
return (
<Attachment.Group className="max-w-lg">
<Attachment>
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>briefing.pdf</Attachment.Title>
<Attachment.Description>
PDF · 1.4 MB
</Attachment.Description>
</Attachment.Content>
</Attachment>
<Attachment>
<Attachment.Media>
<FileCode />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>renderer.tsx</Attachment.Title>
<Attachment.Description>TSX · 12 KB</Attachment.Description>
</Attachment.Content>
</Attachment>
<Attachment>
<Attachment.Media>
<FileText />
</Attachment.Media>
<Attachment.Content>
<Attachment.Title>clientes.csv</Attachment.Title>
<Attachment.Description>CSV · 18 KB</Attachment.Description>
</Attachment.Content>
</Attachment>
</Attachment.Group>
);
}