Sunflower UI
Search
Copy Code
Light Mode
Workspace created
dialog-demo.tsx
dialog.tsx
alert-dialog.tsx
Collapse
Reset
Copy Code
Download
Run
1
"use client"
2
3
import * as React from "react"
4
import { Globe, Upload, CheckCircle2, FileUp, X } from "lucide-react"
5
6
import {
7
Dialog,
8
DialogContent,
9
DialogHeader,
10
DialogTitle,
11
DialogTrigger,
12
} from "@/components/ui/dialog"
13
14
import {
15
AlertDialog,
16
AlertDialogAction,
17
AlertDialogCancel,
18
AlertDialogContent,
19
AlertDialogDescription,
20
AlertDialogFooter,
21
AlertDialogHeader,
22
AlertDialogTitle,
23
AlertDialogTrigger,
24
} from "@/components/ui/alert-dialog"
25
26
export default function DialogDemo() {
27
const [dialogType, setDialogType] = React.useState<"multi" | "alert">("multi")
28
29
// Multi-step state
30
const [open, setOpen] = React.useState(false)
31
const [step, setStep] = React.useState(1)
32
const [showToast, setShowToast] = React.useState(false)
33
34
const handleNext = () => setStep((s) => s + 1)
35
const handleBack = () => setStep((s) => s - 1)
36
37
const handleCreate = () => {
38
setOpen(false)
39
setTimeout(() => {
40
setShowToast(true)
41
setTimeout(() => setShowToast(false), 3000)
42
}, 300)
43
}
44
45
React.useEffect(() => {
46
if (!open) {
47
setTimeout(() => setStep(1), 300)
48
}
49
}, [open])
50
51
return (
52
<div className="flex w-full min-h-[500px] border border-black/10 dark:border-white/10 rounded-xl overflow-hidden bg-white dark:bg-[#111111]">
53
{/* Left Preview Area */}
54
<div className="flex-1 flex items-center justify-center relative bg-zinc-50 dark:bg-[#111111]">
55
{/* Fake Toast */}
56
<div
57
className={"absolute top-4 transition-all duration-300 ease-[cubic-bezier(0.16,1,0.3,1)] flex items-center gap-2 rounded-full border border-black/10 dark:border-white/10 bg-white dark:bg-[#161616] px-4 py-2 shadow-sm z-50 " + (showToast ? "translate-y-0 opacity-100" : "-translate-y-8 opacity-0")}
58
>
59
<div className="rounded-full bg-blue-500 flex items-center justify-center h-4 w-4">
60
<CheckCircle2 className="h-3 w-3 text-white" />
61
</div>
62
<span className="text-sm font-medium dark:text-zinc-50">Workspace created</span>
63
</div>
64
65
{dialogType === "multi" ? (
66
<Dialog open={open} onOpenChange={setOpen}>
67
<DialogTrigger className="inline-flex h-9 items-center justify-center rounded-full border border-black/10 bg-transparent px-4 py-2 text-sm font-medium transition-colors hover:bg-black/5 dark:border-white/10 dark:text-white dark:hover:bg-white/5">
68
Create workspace
69
</DialogTrigger>
70
<DialogContent className="sm:max-w-[425px]">
71
{step === 1 && (
72
<div className="animate-in fade-in-0 slide-in-from-left-2 duration-300">
73
<DialogHeader className="mb-6">
74
<DialogTitle>Create your workspace</DialogTitle>
75
</DialogHeader>
76
<div className="grid gap-4 py-2">
77
<div className="grid gap-2">
78
<label className="text-[13px] font-medium text-zinc-950 dark:text-zinc-50">
79
Workspace name
80
</label>
81
<input
82
defaultValue="Acme Design"
83
className="flex h-9 w-full rounded-md border border-black/10 bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-zinc-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/10 dark:placeholder:text-zinc-400 dark:focus-visible:ring-white/20 dark:text-white"
84
/>
85
</div>
86
<div className="grid gap-2">
87
<label className="text-[13px] font-medium text-zinc-950 dark:text-zinc-50">
88
Workspace URL
89
</label>
90
<div className="relative flex items-center">
91
<Globe className="absolute left-3 h-4 w-4 text-zinc-500" />
92
<input
93
defaultValue="sunflower.design/acme"
94
className="flex h-9 w-full rounded-md border border-black/10 bg-transparent pl-9 pr-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-zinc-500 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/10 dark:placeholder:text-zinc-400 dark:focus-visible:ring-white/20 dark:text-white"
95
/>
96
</div>
97
</div>
98
</div>
99
<div className="mt-6 flex justify-end gap-2">
100
<button
101
onClick={() => setOpen(false)}
102
className="inline-flex h-9 items-center justify-center rounded-lg bg-black/5 dark:bg-white/10 px-4 py-2 text-sm font-medium transition-colors hover:bg-black/10 dark:hover:bg-white/20 dark:text-white"
103
>
104
Cancel
105
</button>
106
<button
107
onClick={handleNext}
108
className="inline-flex h-9 items-center justify-center rounded-lg bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-50 transition-colors hover:bg-zinc-900/90 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90 shadow-sm"
109
>
110
Continue
111
</button>
112
</div>
113
</div>
114
)}
115
116
{step === 2 && (
117
<div className="animate-in fade-in-0 slide-in-from-right-2 duration-300">
118
<DialogHeader className="mb-6">
119
<DialogTitle>Add sources</DialogTitle>
120
</DialogHeader>
121
<div className="py-2">
122
<div className="flex flex-col items-center justify-center gap-2 rounded-xl border border-dashed border-black/20 dark:border-white/20 p-8 text-center cursor-pointer hover:bg-black/5 dark:hover:bg-white/5 transition-colors group">
123
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-black/5 dark:bg-white/5 transition-colors group-hover:bg-black/10 dark:group-hover:bg-white/10">
124
<FileUp className="h-5 w-5 text-zinc-500 dark:text-zinc-400" />
125
</div>
126
<div className="flex flex-col gap-1">
127
<span className="text-sm font-medium dark:text-zinc-50">Upload sources</span>
128
<span className="text-[13px] text-zinc-500 dark:text-zinc-400">Drop files or click to browse</span>
129
</div>
130
</div>
131
</div>
132
<div className="mt-6 flex justify-end gap-2">
133
<button
134
onClick={handleBack}
135
className="inline-flex h-9 items-center justify-center rounded-lg bg-black/5 dark:bg-white/10 px-4 py-2 text-sm font-medium transition-colors hover:bg-black/10 dark:hover:bg-white/20 dark:text-white"
136
>
137
Back
138
</button>
139
<button
140
onClick={handleNext}
141
className="inline-flex h-9 items-center justify-center rounded-lg bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-50 transition-colors hover:bg-zinc-900/90 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90 shadow-sm"
142
>
143
Continue
144
</button>
145
</div>
146
</div>
147
)}
148
149
{step === 3 && (
150
<div className="animate-in fade-in-0 slide-in-from-right-2 duration-300">
151
<DialogHeader className="mb-6">
152
<DialogTitle>Review</DialogTitle>
153
</DialogHeader>
154
<div className="py-2">
155
<div className="rounded-xl border border-black/10 dark:border-white/10 divide-y divide-black/10 dark:divide-white/10 overflow-hidden text-[13px]">
156
<div className="flex items-center justify-between p-3 bg-black/[0.02] dark:bg-white/[0.02]">
157
<span className="text-zinc-500 dark:text-zinc-400 font-medium">Name</span>
158
<span className="font-medium dark:text-zinc-100">Acme Design</span>
159
</div>
160
<div className="flex items-center justify-between p-3 bg-black/[0.02] dark:bg-white/[0.02]">
161
<span className="text-zinc-500 dark:text-zinc-400 font-medium">URL</span>
162
<span className="font-medium dark:text-zinc-100">sunflower.design/acme</span>
163
</div>
164
<div className="flex items-center justify-between p-3 bg-black/[0.02] dark:bg-white/[0.02]">
165
<span className="text-zinc-500 dark:text-zinc-400 font-medium">Sources</span>
166
<span className="font-medium dark:text-zinc-100">None yet</span>
167
</div>
168
<div className="flex items-center justify-between p-3 bg-black/[0.02] dark:bg-white/[0.02]">
169
<span className="text-zinc-500 dark:text-zinc-400 font-medium">Members</span>
170
<span className="font-medium dark:text-zinc-100">Just you</span>
171
</div>
172
</div>
173
</div>
174
<div className="mt-6 flex justify-end gap-2">
175
<button
176
onClick={handleBack}
177
className="inline-flex h-9 items-center justify-center rounded-lg bg-black/5 dark:bg-white/10 px-4 py-2 text-sm font-medium transition-colors hover:bg-black/10 dark:hover:bg-white/20 dark:text-white"
178
>
179
Back
180
</button>
181
<button
182
onClick={handleCreate}
183
className="inline-flex h-9 items-center justify-center rounded-lg bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-50 transition-colors hover:bg-zinc-900/90 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90 shadow-sm"
184
>
185
Create workspace
186
</button>
187
</div>
188
</div>
189
)}
190
</DialogContent>
191
</Dialog>
192
) : (
193
<AlertDialog>
194
<AlertDialogTrigger className="inline-flex h-9 items-center justify-center rounded-full border border-black/10 bg-transparent px-4 py-2 text-sm font-medium transition-colors hover:bg-black/5 dark:border-white/10 dark:text-white dark:hover:bg-white/5">
195
Delete workspace
196
</AlertDialogTrigger>
197
<AlertDialogContent className="sm:max-w-[425px]">
198
<AlertDialogCancel className="absolute right-4 top-4 rounded-full bg-black/5 dark:bg-white/5 p-1.5 opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-zinc-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-zinc-100 data-[state=open]:text-zinc-500 dark:ring-offset-zinc-950 dark:focus:ring-zinc-300 dark:data-[state=open]:bg-zinc-800 dark:data-[state=open]:text-zinc-400 border-none h-auto w-auto hover:bg-black/10 dark:hover:bg-white/10">
199
<X className="h-4 w-4" />
200
<span className="sr-only">Close</span>
201
</AlertDialogCancel>
202
203
<AlertDialogHeader>
204
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
205
<AlertDialogDescription>
206
This cannot be undone.
207
</AlertDialogDescription>
208
</AlertDialogHeader>
209
<AlertDialogFooter>
210
<AlertDialogCancel className="border-none bg-black/5 hover:bg-black/10 dark:bg-white/10 dark:hover:bg-white/20 dark:text-white">Cancel</AlertDialogCancel>
211
<AlertDialogAction className="bg-red-500 hover:bg-red-600 dark:bg-red-500 dark:text-white dark:hover:bg-red-600">Delete</AlertDialogAction>
212
</AlertDialogFooter>
213
</AlertDialogContent>
214
</AlertDialog>
215
)}
216
</div>
217
218
{/* Right Sidebar Control Panel (matching screenshot) */}
219
<div className="w-[340px] border-l border-black/10 dark:border-white/10 bg-white dark:bg-[#161616] p-6 flex flex-col gap-8">
220
<div>
221
<h3 className="text-sm font-medium dark:text-zinc-50 mb-4">Preview</h3>
222
<div className="flex flex-col gap-3">
223
<label className="flex items-center justify-between cursor-pointer group">
224
<span className="text-sm text-zinc-600 dark:text-zinc-400 group-hover:text-zinc-900 dark:group-hover:text-zinc-300 transition-colors">Multi step</span>
225
<input
226
type="radio"
227
name="dialog-type"
228
className="sr-only"
229
checked={dialogType === "multi"}
230
onChange={() => setDialogType("multi")}
231
/>
232
<div className={"h-4 w-4 rounded-[4px] border flex items-center justify-center transition-colors " + (dialogType === "multi" ? "bg-zinc-900 border-zinc-900 dark:bg-zinc-50 dark:border-zinc-50" : "border-black/20 dark:border-white/20 group-hover:border-black/40 dark:group-hover:border-white/40")}>
233
{dialogType === "multi" && <CheckCircle2 className="h-3 w-3 text-white dark:text-zinc-900" />}
234
</div>
235
</label>
236
<label className="flex items-center justify-between cursor-pointer group">
237
<span className="text-sm text-zinc-600 dark:text-zinc-400 group-hover:text-zinc-900 dark:group-hover:text-zinc-300 transition-colors">Alert dialog</span>
238
<input
239
type="radio"
240
name="dialog-type"
241
className="sr-only"
242
checked={dialogType === "alert"}
243
onChange={() => setDialogType("alert")}
244
/>
245
<div className={"h-4 w-4 rounded-[4px] border flex items-center justify-center transition-colors " + (dialogType === "alert" ? "bg-zinc-900 border-zinc-900 dark:bg-zinc-50 dark:border-zinc-50" : "border-black/20 dark:border-white/20 group-hover:border-black/40 dark:group-hover:border-white/40")}>
246
{dialogType === "alert" && <CheckCircle2 className="h-3 w-3 text-white dark:text-zinc-900" />}
247
</div>
248
</label>
249
</div>
250
</div>
251
252
<div className="flex-1">
253
<table className="w-full text-left text-sm text-zinc-500 dark:text-zinc-400">
254
<thead>
255
<tr className="border-b border-black/10 dark:border-white/10">
256
<th className="pb-2 font-medium">Prop</th>
257
<th className="pb-2 font-medium">Type</th>
258
<th className="pb-2 font-medium">Default</th>
259
</tr>
260
</thead>
261
<tbody className="divide-y divide-black/10 dark:divide-white/10">
262
<tr>
263
<td className="py-3 font-mono text-[12px] text-zinc-800 dark:text-zinc-300">children</td>
264
<td className="py-3">ReactNode</td>
265
<td className="py-3 text-[13px]">Component<br/>content</td>
266
</tr>
267
<tr>
268
<td className="py-3 font-mono text-[12px] text-zinc-800 dark:text-zinc-300">className</td>
269
<td className="py-3">string</td>
270
<td className="py-3 text-[13px]">Optional<br/>CSS<br/>classes</td>
271
</tr>
272
<tr>
273
<td className="py-3 font-mono text-[12px] text-zinc-800 dark:text-zinc-300">open</td>
274
<td className="py-3">boolean</td>
275
<td className="py-3 text-[13px]">Controlled<br/>visibility</td>
276
</tr>
277
<tr>
278
<td className="py-3 font-mono text-[12px] text-zinc-800 dark:text-zinc-300">defaultOpen</td>
279
<td className="py-3">boolean</td>
280
<td className="py-3 font-mono text-[12px]">false</td>
281
</tr>
282
</tbody>
283
</table>
284
</div>
285
</div>
286
</div>
287
)
288
}
289