diff --git a/src/components/ActiveConfirmDialog.tsx b/src/components/ActiveConfirmDialog.tsx new file mode 100644 index 00000000..3c79a519 --- /dev/null +++ b/src/components/ActiveConfirmDialog.tsx @@ -0,0 +1,35 @@ +import { atom, useAtom } from "jotai"; +import { actionClearCanvas } from "../actions"; +import { t } from "../i18n"; +import { useExcalidrawActionManager } from "./App"; +import ConfirmDialog from "./ConfirmDialog"; + +export const activeConfirmDialogAtom = atom<"clearCanvas" | null>(null); + +export const ActiveConfirmDialog = () => { + const [activeConfirmDialog, setActiveConfirmDialog] = useAtom( + activeConfirmDialogAtom, + ); + const actionManager = useExcalidrawActionManager(); + + if (!activeConfirmDialog) { + return null; + } + + if (activeConfirmDialog === "clearCanvas") { + return ( + { + actionManager.executeAction(actionClearCanvas); + setActiveConfirmDialog(null); + }} + onCancel={() => setActiveConfirmDialog(null)} + title={t("clearCanvasDialog.title")} + > +

{t("alerts.clearReset")}

+
+ ); + } + + return null; +}; diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index 140f28e9..3defb294 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -50,6 +50,7 @@ import { hostSidebarCountersAtom } from "./Sidebar/Sidebar"; import { jotaiScope } from "../jotai"; import { useAtom } from "jotai"; import MainMenu from "./main-menu/MainMenu"; +import { ActiveConfirmDialog } from "./ActiveConfirmDialog"; import { HandButton } from "./HandButton"; import { isHandToolActive } from "../appState"; @@ -394,6 +395,7 @@ const LayerUI = ({ }} /> )} + {renderImageExportDialog()} {renderJSONExportDialog()} {appState.pasteDialog.shown && ( diff --git a/src/components/LibraryMenuHeaderContent.tsx b/src/components/LibraryMenuHeaderContent.tsx index beeb8dd1..43ea9689 100644 --- a/src/components/LibraryMenuHeaderContent.tsx +++ b/src/components/LibraryMenuHeaderContent.tsx @@ -187,6 +187,7 @@ export const LibraryMenuHeader: React.FC<{ setIsLibraryMenuOpen(false)} + onSelect={() => setIsLibraryMenuOpen(false)} className="library-menu" > {!itemsSelected && ( diff --git a/src/components/dropdownMenu/DropdownMenuContent.tsx b/src/components/dropdownMenu/DropdownMenuContent.tsx index 873a99d8..8ec2b6e6 100644 --- a/src/components/dropdownMenu/DropdownMenuContent.tsx +++ b/src/components/dropdownMenu/DropdownMenuContent.tsx @@ -4,16 +4,23 @@ import { Island } from "../Island"; import { useDevice } from "../App"; import clsx from "clsx"; import Stack from "../Stack"; +import React from "react"; +import { DropdownMenuContentPropsContext } from "./common"; const MenuContent = ({ children, onClickOutside, className = "", + onSelect, style, }: { children?: React.ReactNode; onClickOutside?: () => void; className?: string; + /** + * Called when any menu item is selected (clicked on). + */ + onSelect?: (event: Event) => void; style?: React.CSSProperties; }) => { const device = useDevice(); @@ -24,28 +31,32 @@ const MenuContent = ({ const classNames = clsx(`dropdown-menu ${className}`, { "dropdown-menu--mobile": device.isMobile, }).trim(); + return ( -
- {/* the zIndex ensures this menu has higher stacking order, + +
+ {/* the zIndex ensures this menu has higher stacking order, see https://github.com/excalidraw/excalidraw/pull/1445 */} - {device.isMobile ? ( - {children} - ) : ( - - {children} - - )} -
+ {device.isMobile ? ( + {children} + ) : ( + + {children} + + )} +
+ ); }; -export default MenuContent; MenuContent.displayName = "DropdownMenuContent"; + +export default MenuContent; diff --git a/src/components/dropdownMenu/DropdownMenuItem.tsx b/src/components/dropdownMenu/DropdownMenuItem.tsx index 4f8db982..9a8e9246 100644 --- a/src/components/dropdownMenu/DropdownMenuItem.tsx +++ b/src/components/dropdownMenu/DropdownMenuItem.tsx @@ -1,10 +1,10 @@ import React from "react"; +import { + getDrodownMenuItemClassName, + useHandleDropdownMenuItemClick, +} from "./common"; import MenuItemContent from "./DropdownMenuItemContent"; -export const getDrodownMenuItemClassName = (className = "") => { - return `dropdown-menu-item dropdown-menu-item-base ${className}`.trim(); -}; - const DropdownMenuItem = ({ icon, onSelect, @@ -14,15 +14,17 @@ const DropdownMenuItem = ({ ...rest }: { icon?: JSX.Element; - onSelect: () => void; + onSelect: (event: Event) => void; children: React.ReactNode; shortcut?: string; className?: string; -} & React.ButtonHTMLAttributes) => { +} & Omit, "onSelect">) => { + const handleClick = useHandleDropdownMenuItemClick(rest.onClick, onSelect); + return (