cover-shot.png1.8 MB
PDF
brand-guidelines.pdf248 KB
P
series-a-deck.pptx4.2 MB
W
contract-v3.docx86 KB
X
q3-forecast.xlsx312 KB
attachment-demo.tsx
prompt.md
Collapse
Reset
Copy Code
Download
Run
1
"use client";
2
3
import { X } from "lucide-react";
4
import { cn } from "@/lib/utils";
5
6
const ATTACHMENTS = [
7
{
8
name: "cover-shot.png",
9
size: "1.8 MB",
10
type: "image",
11
src: "https://images.unsplash.com/photo-1707343843437-caacff5cfa74?q=80&w=150&auto=format&fit=crop",
12
},
13
{
14
name: "brand-guidelines.pdf",
15
size: "248 KB",
16
type: "pdf",
17
},
18
{
19
name: "series-a-deck.pptx",
20
size: "4.2 MB",
21
type: "presentation",
22
},
23
{
24
name: "contract-v3.docx",
25
size: "86 KB",
26
type: "document",
27
},
28
{
29
name: "q3-forecast.xlsx",
30
size: "312 KB",
31
type: "spreadsheet",
32
}
33
];
34
35
function FileIcon({ type, src }: { type: string, src?: string }) {
36
if (type === "image" && src) {
37
return (
38
<img src={src} alt="thumbnail" className="w-8 h-8 rounded-md object-cover border border-black/10 dark:border-white/10" />
39
);
40
}
41
42
const iconConfig: Record<string, { bg: string, text: string, color: string }> = {
43
pdf: { bg: "bg-red-500", text: "PDF", color: "text-white" },
44
presentation: { bg: "bg-[#F26422]", text: "P", color: "text-white" },
45
document: { bg: "bg-[#2B579A]", text: "W", color: "text-white" },
46
spreadsheet: { bg: "bg-[#217346]", text: "X", color: "text-white" },
47
};
48
49
const config = iconConfig[type];
50
51
return (
52
<div className={cn("w-8 h-8 rounded-md flex items-center justify-center text-[10px] font-bold tracking-tighter shadow-sm", config.bg, config.color)}>
53
{config.text}
54
</div>
55
);
56
}
57
58
export function AttachmentDemo() {
59
return (
60
<div className="flex flex-wrap items-center justify-center gap-3 w-full max-w-[600px] p-4 bg-transparent">
61
{ATTACHMENTS.map((file, i) => (
62
<div
63
key={i}
64
className="group relative flex items-center gap-3 p-3 pr-7 rounded-xl border border-zinc-200/80 dark:border-white/5 bg-white dark:bg-gradient-to-b dark:from-[#1C1C1E] dark:to-[#0A0A0C] hover:border-zinc-300 dark:hover:border-white/15 dark:hover:shadow-[0_8px_30px_rgba(0,0,0,0.6),inset_0_1px_0_rgba(255,255,255,0.12)] transition-all duration-200 cursor-pointer shadow-sm dark:shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] w-[215px]"
65
>
66
<FileIcon type={file.type} src={file.src} />
67
<div className="flex flex-col gap-0.5 overflow-hidden">
68
<span className="text-[12.5px] font-matter font-medium text-zinc-900 dark:text-[#F5F5F7] truncate">{file.name}</span>
69
<span className="text-[11px] font-mono uppercase tracking-wider text-zinc-500 dark:text-[#86868B]">{file.size}</span>
70
</div>
71
<button
72
className="absolute top-2 right-2 w-5 h-5 flex items-center justify-center rounded-full bg-black/5 dark:bg-white/10 text-zinc-500 dark:text-[#86868B] opacity-0 group-hover:opacity-100 focus:opacity-100 transition-all hover:bg-black/10 dark:hover:bg-white/20 hover:text-zinc-900 dark:hover:text-[#F5F5F7] outline-none"
73
aria-label="Remove attachment"
74
onClick={(e) => {
75
e.stopPropagation();
76
// Remove logic here
77
}}
78
>
79
<X className="w-3 h-3" />
80
</button>
81
</div>
82
))}
83
</div>
84
);
85
}
86

