Skip to content

Commit 2b018bf

Browse files
nullcoderClaude
andauthored
feat: implement ShareDialog component for gist sharing (#85)
Add complete ShareDialog component with security features, accessibility support, and comprehensive testing. Includes visual URL fragment separation, copy-to-clipboard functionality, download capabilities, and mobile-responsive design. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude <claude@ghostpaste.dev>
1 parent fdb0f87 commit 2b018bf

File tree

4 files changed

+763
-0
lines changed

4 files changed

+763
-0
lines changed

app/demo/share-dialog/page.tsx

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
import { Button } from "@/components/ui/button";
5+
import { ShareDialog } from "@/components/share-dialog";
6+
7+
export default function ShareDialogDemo() {
8+
const [dialogOpen, setDialogOpen] = useState(false);
9+
const [scenario, setScenario] = useState<
10+
"simple" | "with-title" | "long-key"
11+
>("simple");
12+
13+
const scenarios = {
14+
simple: {
15+
url: "https://ghostpaste.dev/g/abc123#key=eyJhbGciOiJBMTI4R0NNIiwiZXhwIjoxNjg5MzM2MDAwfQ",
16+
title: undefined,
17+
},
18+
"with-title": {
19+
url: "https://ghostpaste.dev/g/def456#key=eyJhbGciOiJBMTI4R0NNIiwiZXhwIjoxNjg5MzM2MDAwfQ",
20+
title: "My Configuration Files",
21+
},
22+
"long-key": {
23+
url: "https://ghostpaste.dev/g/xyz789#key=eyJhbGciOiJBMTI4R0NNIiwiZXhwIjoxNjg5MzM2MDAwLCJpdiI6IjEyMzQ1Njc4OTBhYmNkZWYiLCJkYXRhIjoiZXlKaGJHY2lPaUZCTVRJNFIwTk5JaXdpWlhod0lqb3hOamc1TXpNMk1EQXdNSDAifQ",
24+
title: "React Component Library",
25+
},
26+
};
27+
28+
const handleCopy = () => {
29+
console.log("URL copied to clipboard");
30+
};
31+
32+
const handleDownload = () => {
33+
console.log("Text file downloaded");
34+
};
35+
36+
return (
37+
<div className="container mx-auto max-w-4xl p-6">
38+
<div className="space-y-8">
39+
<div>
40+
<h1 className="text-3xl font-bold tracking-tight">
41+
ShareDialog Demo
42+
</h1>
43+
<p className="text-muted-foreground mt-2">
44+
Demo of the ShareDialog component with different scenarios.
45+
</p>
46+
</div>
47+
48+
<div className="space-y-4">
49+
<h2 className="text-xl font-semibold">Test Scenarios</h2>
50+
51+
<div className="grid gap-4 md:grid-cols-3">
52+
<div className="space-y-2">
53+
<h3 className="font-medium">Simple Gist</h3>
54+
<p className="text-muted-foreground text-sm">
55+
Basic gist without title
56+
</p>
57+
<Button
58+
onClick={() => {
59+
setScenario("simple");
60+
setDialogOpen(true);
61+
}}
62+
className="w-full"
63+
>
64+
Open Dialog
65+
</Button>
66+
</div>
67+
68+
<div className="space-y-2">
69+
<h3 className="font-medium">Gist with Title</h3>
70+
<p className="text-muted-foreground text-sm">
71+
Gist with a descriptive title
72+
</p>
73+
<Button
74+
onClick={() => {
75+
setScenario("with-title");
76+
setDialogOpen(true);
77+
}}
78+
className="w-full"
79+
>
80+
Open Dialog
81+
</Button>
82+
</div>
83+
84+
<div className="space-y-2">
85+
<h3 className="font-medium">Long Encryption Key</h3>
86+
<p className="text-muted-foreground text-sm">
87+
Gist with very long encryption key
88+
</p>
89+
<Button
90+
onClick={() => {
91+
setScenario("long-key");
92+
setDialogOpen(true);
93+
}}
94+
className="w-full"
95+
>
96+
Open Dialog
97+
</Button>
98+
</div>
99+
</div>
100+
</div>
101+
102+
<div className="space-y-4">
103+
<h2 className="text-xl font-semibold">Features Demonstrated</h2>
104+
<div className="grid gap-4 md:grid-cols-2">
105+
<div className="space-y-2">
106+
<h3 className="font-medium">✅ Core Features</h3>
107+
<ul className="text-muted-foreground space-y-1 text-sm">
108+
<li>• Visual URL fragment separation</li>
109+
<li>• Copy to clipboard with feedback</li>
110+
<li>• Download as text file</li>
111+
<li>• Security warning display</li>
112+
<li>• Success animation on creation</li>
113+
<li>• Mobile-friendly responsive layout</li>
114+
</ul>
115+
</div>
116+
<div className="space-y-2">
117+
<h3 className="font-medium">🔒 Security Features</h3>
118+
<ul className="text-muted-foreground space-y-1 text-sm">
119+
<li>• Fragment key highlighting</li>
120+
<li>• Clear security warnings</li>
121+
<li>• Complete URL copy requirement</li>
122+
<li>• No URL logging or analytics</li>
123+
<li>• Fallback copy for older browsers</li>
124+
</ul>
125+
</div>
126+
</div>
127+
</div>
128+
129+
<div className="space-y-4">
130+
<h2 className="text-xl font-semibold">Accessibility Features</h2>
131+
<ul className="text-muted-foreground space-y-1 text-sm">
132+
<li>• Keyboard navigation support</li>
133+
<li>• Focus trap within dialog</li>
134+
<li>• Escape key to close</li>
135+
<li>• Screen reader friendly labels</li>
136+
<li>• Auto-focus on primary action</li>
137+
</ul>
138+
</div>
139+
</div>
140+
141+
<ShareDialog
142+
open={dialogOpen}
143+
onOpenChange={setDialogOpen}
144+
shareUrl={scenarios[scenario].url}
145+
gistTitle={scenarios[scenario].title}
146+
onCopy={handleCopy}
147+
onDownload={handleDownload}
148+
/>
149+
</div>
150+
);
151+
}

0 commit comments

Comments
 (0)