import "./ExportDialog.css"; import React, { useState, useEffect, useRef } from "react"; import { Modal } from "./Modal"; import { ToolIcon } from "./ToolIcon"; import { clipboard, exportFile, downloadFile, link } from "./icons"; import { Island } from "./Island"; import { ExcalidrawElement } from "../element/types"; import { AppState } from "../types"; import { getExportCanvasPreview } from "../scene/getExportCanvasPreview"; import { ActionsManagerInterface, UpdaterFn } from "../actions/types"; import Stack from "./Stack"; const probablySupportsClipboard = "toBlob" in HTMLCanvasElement.prototype && "clipboard" in navigator && "write" in navigator.clipboard && "ClipboardItem" in window; const scales = [1, 2, 3]; const defaultScale = scales.includes(devicePixelRatio) ? devicePixelRatio : 1; type ExportCB = (elements: readonly ExcalidrawElement[], scale: number) => void; export function ExportDialog({ elements, appState, exportPadding = 10, actionManager, syncActionResult, onExportToPng, onExportToClipboard, onExportToBackend }: { appState: AppState; elements: readonly ExcalidrawElement[]; exportPadding?: number; actionManager: ActionsManagerInterface; syncActionResult: UpdaterFn; onExportToPng: ExportCB; onExportToClipboard: ExportCB; onExportToBackend: ExportCB; }) { const someElementIsSelected = elements.some(element => element.isSelected); const [modalIsShown, setModalIsShown] = useState(false); const [scale, setScale] = useState(defaultScale); const [exportSelected, setExportSelected] = useState(someElementIsSelected); const previeRef = useRef(null); const { exportBackground, viewBackgroundColor } = appState; const exportedElements = exportSelected ? elements.filter(element => element.isSelected) : elements; useEffect(() => { setExportSelected(someElementIsSelected); }, [someElementIsSelected]); useEffect(() => { const previewNode = previeRef.current; const canvas = getExportCanvasPreview(exportedElements, { exportBackground, viewBackgroundColor, exportPadding, scale }); previewNode?.appendChild(canvas); return () => { previewNode?.removeChild(canvas); }; }, [ modalIsShown, exportedElements, exportBackground, exportPadding, viewBackgroundColor, scale ]); function handleClose() { setModalIsShown(false); setExportSelected(someElementIsSelected); } return ( <> setModalIsShown(true)} icon={exportFile} type="button" aria-label="Show export dialog" title="Export" /> {modalIsShown && (

Export

onExportToPng(exportedElements, scale)} /> {probablySupportsClipboard && ( onExportToClipboard(exportedElements, scale) } /> )} onExportToBackend(exportedElements, 1)} /> {actionManager.renderAction( "changeProjectName", elements, appState, syncActionResult )}
{scales.map(s => ( setScale(s)} /> ))}
{actionManager.renderAction( "changeExportBackground", elements, appState, syncActionResult )} {someElementIsSelected && (
)}
)} ); }