shadcn.io is an independent project built on shadcn/ui
The panel shows file size 2.4 MB and format PDF. Download File spins for a short timer, then the dialog closes. No file is fetched.
Show the spinner while a real request runs, and leave Cancel available. If it fails, keep the dialog open and show an Alert. In React, Base UI does not download the report.
Installation
Anatomy

Usage
<AlertDialog onOpenChange={setOpen} open={open}>
<AlertDialogTrigger render={<Button variant="outline" />}>
<DownloadIcon aria-hidden="true" data-icon="inline-start" />
Download
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Download Report</AlertDialogTitle>
<AlertDialogDescription>
Your report is ready to download. This file contains sensitive
information and should be handled securely.
</AlertDialogDescription>
</AlertDialogHeader>
<div className="flex flex-col gap-1 rounded-md bg-muted p-3 text-sm">
<div className="flex items-center justify-between">
<span>File size:</span>
<span className="font-medium">2.4 MB</span>
</div>
<div className="flex items-center justify-between">
<span>Format:</span>
<span className="font-medium">PDF</span>
</div>
</div>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction isLoading={downloading} onClick={handleDownload}>
<DownloadIcon aria-hidden="true" data-icon="inline-start" />
Download File
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>FAQ
How does the spinner work?
The Download File button sets isLoading while the download runs, which shows a spinner and disables it. The demo fakes the work with a timer; replace it with your request.
How does the dialog close when the download finishes?
Its open state is controlled, and the handler sets it to closed once the work settles. Pass open and onOpenChange.
What details should a download dialog show?
What helps people decide: size, format, and anything sensitive about the file. Two to four facts in a bg-muted panel, as label and value pairs, are enough.
Can people cancel while it's downloading?
AlertDialogCancel stays enabled and closes the dialog. If your download can be aborted, abort it when the dialog closes, for example with an AbortController.
How should I handle a failed download?
Keep the dialog open, clear the loading state and show the error inline, for example with an Alert, so people can retry or cancel.
Should I show progress for large files?
For long downloads, yes: add a Progress bar fed by your download's progress events. A spinner is enough for files that take a second or two.
API Reference
Alert Dialog
Sets onOpenChange={setOpen}, open={open}, isLoading={downloading} and onClick={handleDownload}. The rest is on the Alert Dialog page.
Button
Sets variant="outline". The rest is on the Button page.




