ExportSheet
StableExport a deck as PDF, PowerPoint, images or a link: what the file holds, what needs fixing first (amber) and what will change, then progress, the file name, or Retry.
Also known as export dialog, download options, export
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Export with checks
<ExportSheet
open={open}
onClose={() => setOpen(false)}
deckTitle="Q3 churn review"
format={format}
onFormatChange={(f) => { setFormat(f); runChecks(f); }}
state={state} // "choosing" | "checking" | "exporting" | "done" | "failed"
includes={["8 slides, 16:9", "Speaker notes on 6 slides"]}
includeNotes={notes}
onIncludeNotesChange={setNotes}
checks={[
{ id: "ai", severity: "fix", message: "3 AI changes on slides 4, 6 and 7 have not been reviewed.", slideId: "s4", slideLabel: "slide 4" },
{ id: "font", severity: "info", message: "2 fonts will be replaced: Fieldwork becomes Arial, Lumen Serif becomes Georgia." },
]}
onJumpTo={goToSlide}
progress={{ done, total: 8 }}
fileName="q3-churn-review.pptx"
fileSize="3.8 MB"
onExport={startExport}
onStopExport={stopExport}
onDownload={download}
/>Open it, switch format and watch the checks change. PowerPoint fails the first time at slide 6, to show Try again. Go to slide 4 closes the sheet and jumps there.
When to use it
Stops people finding out after they sent a deck that fonts changed, descriptions went missing or AI changes were never checked.
Made of: Title · Format choice · What the file holds · Speaker notes switch · Before you export (checks) · Progress · Result (file name and size) · Footer actions
Use it for
- The Export or Share action in a deck editor.
- Making a view-only link to a deck.
- An export panel inside a side bar or settings page, with inline.
Not for
- Reviewing AI changes slide by slide: use DeckChangeReview.
- A plain confirm before one action: use Dialog.
- Progress for a single generated file: use GenerationProgress.
Do and avoid
Export Spring range review
Before you export
- Needs you: The photo has no description.
- Note: Content credentials are kept in PDF.
Export Spring range review
Before you export
- Needs you: The photo has no description.
- Needs you: Content credentials are kept in PDF.
Do
- Run the checks per format: a font swap matters in PowerPoint, not in PDF.
- Put things a person must act on first, in amber, each with a link to its slide.
- Let people export anyway, and say so on the button.
- Name the file after the deck and show it when done.
Avoid
- Do not use amber for notes that need no action, such as "Credentials are kept in PDF".
- Do not block the export until every check is fixed.
- Do not let font swaps, missing image descriptions or removed content credentials go unmentioned.
- Do not share or send the file without a press from the person.
On a phone
- Opens as a bottom sheet under the sm breakpoint, with the actions stacked at the bottom where a thumb reaches.
- Format options and the notes switch grow to 44px rows on touch screens.
- "Go to slide" links drop under their message on narrow screens and keep a 44px touch area.
Seen in products
- Gamma exports to PPTX, PDF and Google Slides; reviewers report fonts and layouts that need clean-up after export.
- Reviewers list export fidelity among the most common complaints about AI presentation tools.
- Google keeps SynthID and C2PA on Gemini images, but no product found says whether credentials survive a deck export.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Whether the dialog shows. Ignored when inline. |
| onClose | () => void | none | Closes it. Also used by Cancel and Close. |
| inline | boolean | false | Draws the same content as a card in the page. |
| deckTitle | string | none | Shown in the title: "Export Q3 churn review". |
| formats | ("pdf" | "pptx" | "png" | "link")[] | ["pdf", "pptx", "png", "link"] | Formats on offer, in order. |
| formatrequired | "pdf" | "pptx" | "png" | "link" | none | The chosen format. |
| onFormatChangerequired | (format: ExportFormat) => void | none | Called when the person picks a format. Run the checks for it. |
| staterequired | "choosing" | "checking" | "exporting" | "done" | "failed" | none | Where the export is. |
| includes | string[] | none | What the file will hold, worked out by your app. |
| includeNotes | boolean | none | Whether speaker notes go in. |
| onIncludeNotesChange | (value: boolean) => void | none | Shows the speaker notes switch. Leave out for formats that cannot carry notes. |
| checks | ExportCheck[] | none | { id, severity: "fix" | "info", message, slideId?, slideLabel? }. Fix items are amber and come first. |
| onJumpTo | (slideId: string) => void | none | Adds a Go to slide link to checks that name a slide. |
| progress | { done: number; total: number } | none | Real progress in slides while exporting. |
| fileName | string | none | The file made, or the link. |
| fileSize | string | none | Size of the file, such as "3.8 MB". |
| error | string | none | Why the export failed, in plain words. |
| onExportrequired | () => void | none | Starts the export. Never blocked. |
| onStopExport | () => void | none | Stops a running export. |
| onRetry | () => void | none | Try again after a failure. Defaults to onExport. |
| onDownload | () => void | none | Download button when a file is done. |
| onCopyLink | () => void | none | Copy link button when a link is done. The sheet then says "Link copied". |
| headingLevel | 2 | 3 | 4 | 5 | 6 | 3 | Heading level when inline. |
| className | string | none | Extra classes for the panel. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one ExportSheet switches all of this from its properties panel, across 40 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Format | format | Pdf, Pptx, Png, Link |
| Status | state | Choosing, Checking, Exporting, Done, Failed |
| Include notes | includeNotes | On or off |
| FileName | fileName | Any text |
| FileSize | fileSize | Any text |
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- checking
- Spinner and "Checking the deck for PowerPoint…". Format and notes are disabled for the moment.
- choosing
- Format, what the file holds and the check results. Export anyway when fix items remain.
- nothing to fix
- "Nothing to fix. It should look the same as PDF." with a check icon.
- exporting
- "Making PowerPoint: slide 5 of 8" with a meter and Stop export.
- done
- "Export done" with the file name and size, and Download or Copy link.
- failed
- Red panel with the reason and Try again. The format choice stays, so the person can pick another.
Tokens
Change one of these and every part that uses it follows.
--raised--surface--sunken--border--fg--fg-muted--fg-subtle--attention-soft--attention-fg--danger-soft--danger-fg--success-fg--radius-card--radius-overlay--radius-control--dur-fast
Built in
- In dialog mode it is a native modal dialog: the page behind is inert, Tab stays inside, Escape closes it and focus returns to the opener.
- Formats are a native radio group, so arrow keys move between them.
- Each check starts with the words "Needs you" or "Note" and an icon, so the meaning does not rest on colour.
- A polite live region speaks when checking ends ("Checks done. 2 things to fix before you send it."), when the export starts, ends or fails. Progress is not read out slide by slide.
- Export progress is a meter with value text such as "Slide 5 of 8".
- The check list fades in at --dur-fast, and not at all under reduced motion.
What you need to do
- Run the checks in your app for the chosen format and pass them in plain words. The model must not write them.
- Return focus to the right slide when onJumpTo is used, and close the sheet if the slide is hidden behind it.
- Make the file name readable: the deck title and the format, such as "q3-churn-review.pdf".
- Never send or share the file from code. Download and Copy link happen only when the person presses them.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide