瀏覽代碼

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
vanilla_orig
Aakansha Doshi 3 年之前
父節點
當前提交
0f0244224d
沒有連結到貢獻者的電子郵件帳戶。
共有 5 個檔案被更改,包括 123 行新增21 行删除
  1. 7
    20
      src/actions/actionCanvas.tsx
  2. 42
    0
      src/components/ClearCanvas.scss
  3. 67
    0
      src/components/ClearCanvas.tsx
  4. 1
    0
      src/components/LayerUI.tsx
  5. 6
    1
      src/locales/en.json

+ 7
- 20
src/actions/actionCanvas.tsx 查看文件

1
-import { getDefaultAppState } from "../appState";
2
 import { ColorPicker } from "../components/ColorPicker";
1
 import { ColorPicker } from "../components/ColorPicker";
3
-import { trash, zoomIn, zoomOut } from "../components/icons";
2
+import { zoomIn, zoomOut } from "../components/icons";
4
 import { ToolButton } from "../components/ToolButton";
3
 import { ToolButton } from "../components/ToolButton";
5
 import { DarkModeToggle } from "../components/DarkModeToggle";
4
 import { DarkModeToggle } from "../components/DarkModeToggle";
6
 import { THEME, ZOOM_STEP } from "../constants";
5
 import { THEME, ZOOM_STEP } from "../constants";
7
 import { getCommonBounds, getNonDeletedElements } from "../element";
6
 import { getCommonBounds, getNonDeletedElements } from "../element";
8
-import { newElementWith } from "../element/mutateElement";
9
 import { ExcalidrawElement } from "../element/types";
7
 import { ExcalidrawElement } from "../element/types";
10
 import { t } from "../i18n";
8
 import { t } from "../i18n";
11
-import { useIsMobile } from "../components/App";
12
 import { CODES, KEYS } from "../keys";
9
 import { CODES, KEYS } from "../keys";
13
 import { getNormalizedZoom, getSelectedElements } from "../scene";
10
 import { getNormalizedZoom, getSelectedElements } from "../scene";
14
 import { centerScrollOn } from "../scene/scroll";
11
 import { centerScrollOn } from "../scene/scroll";
17
 import { getShortcutKey } from "../utils";
14
 import { getShortcutKey } from "../utils";
18
 import { register } from "./register";
15
 import { register } from "./register";
19
 import { Tooltip } from "../components/Tooltip";
16
 import { Tooltip } from "../components/Tooltip";
17
+import { newElementWith } from "../element/mutateElement";
18
+import { getDefaultAppState } from "../appState";
19
+import ClearCanvas from "../components/ClearCanvas";
20
 
20
 
21
 export const actionChangeViewBackgroundColor = register({
21
 export const actionChangeViewBackgroundColor = register({
22
   name: "changeViewBackgroundColor",
22
   name: "changeViewBackgroundColor",
47
 
47
 
48
 export const actionClearCanvas = register({
48
 export const actionClearCanvas = register({
49
   name: "clearCanvas",
49
   name: "clearCanvas",
50
-  perform: (elements, appState: AppState) => {
50
+  perform: (elements, appState) => {
51
     return {
51
     return {
52
       elements: elements.map((element) =>
52
       elements: elements.map((element) =>
53
         newElementWith(element, { isDeleted: true }),
53
         newElementWith(element, { isDeleted: true }),
65
       commitToHistory: true,
65
       commitToHistory: true,
66
     };
66
     };
67
   },
67
   },
68
-  PanelComponent: ({ updateData }) => (
69
-    <ToolButton
70
-      type="button"
71
-      icon={trash}
72
-      title={t("buttons.clearReset")}
73
-      aria-label={t("buttons.clearReset")}
74
-      showAriaLabel={useIsMobile()}
75
-      onClick={() => {
76
-        if (window.confirm(t("alerts.clearReset"))) {
77
-          updateData(null);
78
-        }
79
-      }}
80
-      data-testid="clear-canvas-button"
81
-    />
82
-  ),
68
+
69
+  PanelComponent: ({ updateData }) => <ClearCanvas onConfirm={updateData} />,
83
 });
70
 });
84
 
71
 
85
 export const actionZoomIn = register({
72
 export const actionZoomIn = register({

+ 42
- 0
src/components/ClearCanvas.scss 查看文件

1
+@import "../css/variables.module";
2
+
3
+.excalidraw {
4
+  .clear-canvas {
5
+    &-buttons {
6
+      display: flex;
7
+      padding: 0.2rem 0;
8
+      justify-content: flex-end;
9
+
10
+      .ToolIcon__icon {
11
+        min-width: 2.5rem;
12
+        width: auto;
13
+        font-size: 1rem;
14
+      }
15
+
16
+      .ToolIcon_type_button {
17
+        margin-left: 1.5rem;
18
+        padding: 0 0.5rem;
19
+      }
20
+    }
21
+
22
+    &__content {
23
+      font-size: 1rem;
24
+    }
25
+
26
+    &--confirm.ToolIcon_type_button {
27
+      background-color: $oc-red-6;
28
+
29
+      &:hover {
30
+        background-color: $oc-red-8;
31
+      }
32
+
33
+      .ToolIcon__icon {
34
+        color: $oc-white;
35
+      }
36
+    }
37
+
38
+    &--cancel.ToolIcon_type_button {
39
+      background-color: $oc-gray-2;
40
+    }
41
+  }
42
+}

+ 67
- 0
src/components/ClearCanvas.tsx 查看文件

1
+import { useState } from "react";
2
+import { t } from "../i18n";
3
+import { useIsMobile } from "./App";
4
+import { Dialog } from "./Dialog";
5
+import { trash } from "./icons";
6
+import { ToolButton } from "./ToolButton";
7
+
8
+import "./ClearCanvas.scss";
9
+
10
+const ClearCanvas = ({ onConfirm }: { onConfirm: () => void }) => {
11
+  const [showDialog, setShowDialog] = useState(false);
12
+  const toggleDialog = () => {
13
+    setShowDialog(!showDialog);
14
+  };
15
+
16
+  return (
17
+    <>
18
+      <ToolButton
19
+        type="button"
20
+        icon={trash}
21
+        title={t("buttons.clearReset")}
22
+        aria-label={t("buttons.clearReset")}
23
+        showAriaLabel={useIsMobile()}
24
+        onClick={toggleDialog}
25
+        data-testid="clear-canvas-button"
26
+      />
27
+
28
+      {showDialog && (
29
+        <Dialog
30
+          onCloseRequest={toggleDialog}
31
+          title={t("clearCanvasDialog.title")}
32
+          className="clear-canvas"
33
+          small={true}
34
+        >
35
+          <>
36
+            <p className="clear-canvas__content"> {t("alerts.clearReset")}</p>
37
+            <div className="clear-canvas-buttons">
38
+              <ToolButton
39
+                type="button"
40
+                title={t("buttons.clear")}
41
+                aria-label={t("buttons.clear")}
42
+                label={t("buttons.clear")}
43
+                onClick={() => {
44
+                  onConfirm();
45
+                  toggleDialog();
46
+                }}
47
+                data-testid="confirm-clear-canvas-button"
48
+                className="clear-canvas--confirm"
49
+              />
50
+              <ToolButton
51
+                type="button"
52
+                title={t("buttons.cancel")}
53
+                aria-label={t("buttons.cancel")}
54
+                label={t("buttons.cancel")}
55
+                onClick={toggleDialog}
56
+                data-testid="cancel-clear-canvas-button"
57
+                className="clear-canvas--cancel"
58
+              />
59
+            </div>
60
+          </>
61
+        </Dialog>
62
+      )}
63
+    </>
64
+  );
65
+};
66
+
67
+export default ClearCanvas;

+ 1
- 0
src/components/LayerUI.tsx 查看文件

468
       </Section>
468
       </Section>
469
     );
469
     );
470
   };
470
   };
471
+
471
   const renderCanvasActions = () => (
472
   const renderCanvasActions = () => (
472
     <Section
473
     <Section
473
       heading="canvasActions"
474
       heading="canvasActions"

+ 6
- 1
src/locales/en.json 查看文件

136
     "darkMode": "Dark mode",
136
     "darkMode": "Dark mode",
137
     "lightMode": "Light mode",
137
     "lightMode": "Light mode",
138
     "zenMode": "Zen mode",
138
     "zenMode": "Zen mode",
139
-    "exitZenMode": "Exit zen mode"
139
+    "exitZenMode": "Exit zen mode",
140
+    "cancel": "Cancel",
141
+    "clear": "Clear"
140
   },
142
   },
141
   "alerts": {
143
   "alerts": {
142
     "clearReset": "This will clear the whole canvas. Are you sure?",
144
     "clearReset": "This will clear the whole canvas. Are you sure?",
256
     "zoomToFit": "Zoom to fit all elements",
258
     "zoomToFit": "Zoom to fit all elements",
257
     "zoomToSelection": "Zoom to selection"
259
     "zoomToSelection": "Zoom to selection"
258
   },
260
   },
261
+  "clearCanvasDialog": {
262
+    "title": "Clear Canvas"
263
+  },
259
   "encrypted": {
264
   "encrypted": {
260
     "tooltip": "Your drawings are end-to-end encrypted so Excalidraw's servers will never see them.",
265
     "tooltip": "Your drawings are end-to-end encrypted so Excalidraw's servers will never see them.",
261
     "link": "Blog post on end-to-end encryption in Excalidraw"
266
     "link": "Blog post on end-to-end encryption in Excalidraw"

Loading…
取消
儲存