Преглед изворни кода

feat: Use dialog component for clear canvas instead of window confirm (#4075)

* feat: Use dialog component for clear canvas instead of window confirm

* reduce font weight

* fix specs

* update button name and use action

* export clearCanvas from actions
Aakansha Doshi пре 3 година
родитељ
комит
0f0244224d

+ 7 - 20
src/actions/actionCanvas.tsx

@@ -1,14 +1,11 @@
-import { getDefaultAppState } from "../appState";
 import { ColorPicker } from "../components/ColorPicker";
-import { trash, zoomIn, zoomOut } from "../components/icons";
+import { zoomIn, zoomOut } from "../components/icons";
 import { ToolButton } from "../components/ToolButton";
 import { DarkModeToggle } from "../components/DarkModeToggle";
 import { THEME, ZOOM_STEP } from "../constants";
 import { getCommonBounds, getNonDeletedElements } from "../element";
-import { newElementWith } from "../element/mutateElement";
 import { ExcalidrawElement } from "../element/types";
 import { t } from "../i18n";
-import { useIsMobile } from "../components/App";
 import { CODES, KEYS } from "../keys";
 import { getNormalizedZoom, getSelectedElements } from "../scene";
 import { centerScrollOn } from "../scene/scroll";
@@ -17,6 +14,9 @@ import { AppState, NormalizedZoomValue } from "../types";
 import { getShortcutKey } from "../utils";
 import { register } from "./register";
 import { Tooltip } from "../components/Tooltip";
+import { newElementWith } from "../element/mutateElement";
+import { getDefaultAppState } from "../appState";
+import ClearCanvas from "../components/ClearCanvas";
 
 export const actionChangeViewBackgroundColor = register({
   name: "changeViewBackgroundColor",
@@ -47,7 +47,7 @@ export const actionChangeViewBackgroundColor = register({
 
 export const actionClearCanvas = register({
   name: "clearCanvas",
-  perform: (elements, appState: AppState) => {
+  perform: (elements, appState) => {
     return {
       elements: elements.map((element) =>
         newElementWith(element, { isDeleted: true }),
@@ -65,21 +65,8 @@ export const actionClearCanvas = register({
       commitToHistory: true,
     };
   },
-  PanelComponent: ({ updateData }) => (
-    <ToolButton
-      type="button"
-      icon={trash}
-      title={t("buttons.clearReset")}
-      aria-label={t("buttons.clearReset")}
-      showAriaLabel={useIsMobile()}
-      onClick={() => {
-        if (window.confirm(t("alerts.clearReset"))) {
-          updateData(null);
-        }
-      }}
-      data-testid="clear-canvas-button"
-    />
-  ),
+
+  PanelComponent: ({ updateData }) => <ClearCanvas onConfirm={updateData} />,
 });
 
 export const actionZoomIn = register({

+ 42 - 0
src/components/ClearCanvas.scss

@@ -0,0 +1,42 @@
+@import "../css/variables.module";
+
+.excalidraw {
+  .clear-canvas {
+    &-buttons {
+      display: flex;
+      padding: 0.2rem 0;
+      justify-content: flex-end;
+
+      .ToolIcon__icon {
+        min-width: 2.5rem;
+        width: auto;
+        font-size: 1rem;
+      }
+
+      .ToolIcon_type_button {
+        margin-left: 1.5rem;
+        padding: 0 0.5rem;
+      }
+    }
+
+    &__content {
+      font-size: 1rem;
+    }
+
+    &--confirm.ToolIcon_type_button {
+      background-color: $oc-red-6;
+
+      &:hover {
+        background-color: $oc-red-8;
+      }
+
+      .ToolIcon__icon {
+        color: $oc-white;
+      }
+    }
+
+    &--cancel.ToolIcon_type_button {
+      background-color: $oc-gray-2;
+    }
+  }
+}

+ 67 - 0
src/components/ClearCanvas.tsx

@@ -0,0 +1,67 @@
+import { useState } from "react";
+import { t } from "../i18n";
+import { useIsMobile } from "./App";
+import { Dialog } from "./Dialog";
+import { trash } from "./icons";
+import { ToolButton } from "./ToolButton";
+
+import "./ClearCanvas.scss";
+
+const ClearCanvas = ({ onConfirm }: { onConfirm: () => void }) => {
+  const [showDialog, setShowDialog] = useState(false);
+  const toggleDialog = () => {
+    setShowDialog(!showDialog);
+  };
+
+  return (
+    <>
+      <ToolButton
+        type="button"
+        icon={trash}
+        title={t("buttons.clearReset")}
+        aria-label={t("buttons.clearReset")}
+        showAriaLabel={useIsMobile()}
+        onClick={toggleDialog}
+        data-testid="clear-canvas-button"
+      />
+
+      {showDialog && (
+        <Dialog
+          onCloseRequest={toggleDialog}
+          title={t("clearCanvasDialog.title")}
+          className="clear-canvas"
+          small={true}
+        >
+          <>
+            <p className="clear-canvas__content"> {t("alerts.clearReset")}</p>
+            <div className="clear-canvas-buttons">
+              <ToolButton
+                type="button"
+                title={t("buttons.clear")}
+                aria-label={t("buttons.clear")}
+                label={t("buttons.clear")}
+                onClick={() => {
+                  onConfirm();
+                  toggleDialog();
+                }}
+                data-testid="confirm-clear-canvas-button"
+                className="clear-canvas--confirm"
+              />
+              <ToolButton
+                type="button"
+                title={t("buttons.cancel")}
+                aria-label={t("buttons.cancel")}
+                label={t("buttons.cancel")}
+                onClick={toggleDialog}
+                data-testid="cancel-clear-canvas-button"
+                className="clear-canvas--cancel"
+              />
+            </div>
+          </>
+        </Dialog>
+      )}
+    </>
+  );
+};
+
+export default ClearCanvas;

+ 1 - 0
src/components/LayerUI.tsx

@@ -468,6 +468,7 @@ const LayerUI = ({
       </Section>
     );
   };
+
   const renderCanvasActions = () => (
     <Section
       heading="canvasActions"

+ 6 - 1
src/locales/en.json

@@ -136,7 +136,9 @@
     "darkMode": "Dark mode",
     "lightMode": "Light mode",
     "zenMode": "Zen mode",
-    "exitZenMode": "Exit zen mode"
+    "exitZenMode": "Exit zen mode",
+    "cancel": "Cancel",
+    "clear": "Clear"
   },
   "alerts": {
     "clearReset": "This will clear the whole canvas. Are you sure?",
@@ -256,6 +258,9 @@
     "zoomToFit": "Zoom to fit all elements",
     "zoomToSelection": "Zoom to selection"
   },
+  "clearCanvasDialog": {
+    "title": "Clear Canvas"
+  },
   "encrypted": {
     "tooltip": "Your drawings are end-to-end encrypted so Excalidraw's servers will never see them.",
     "link": "Blog post on end-to-end encryption in Excalidraw"