From ea4f653c442096f0d74cccce3bb669a90ad15e65 Mon Sep 17 00:00:00 2001 From: Ryan Di Date: Fri, 21 Mar 2025 14:12:44 +1100 Subject: [PATCH] refactor --- packages/excalidraw/components/App.tsx | 49 ++++++++++++------- .../excalidraw/components/ShapeSwitch.tsx | 49 ++++++++----------- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 15b3617d7..65f7788c7 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -391,7 +391,11 @@ import { getMinTextElementWidth, } from "../element/textMeasurements"; -import ShapeSwitch, { shapeSwitchAtom } from "./ShapeSwitch"; +import ShapeSwitch, { + GENERIC_SWITCHABLE_SHAPES, + LINEAR_SWITCHABLE_SHAPES, + shapeSwitchAtom, +} from "./ShapeSwitch"; import { activeConfirmDialogAtom } from "./ActiveConfirmDialog"; import BraveMeasureTextError from "./BraveMeasureTextError"; @@ -4116,25 +4120,29 @@ class App extends React.Component { if (event.key === KEYS.ESCAPE) { editorJotaiStore.set(shapeSwitchAtom, null); } else if (event.key === KEYS.SLASH || event.key === KEYS.TAB) { - if (editorJotaiStore.get(shapeSwitchAtom) === "panel") { - if (isGenericSwitchable) { - const index = ["rectangle", "diamond", "ellipse"].indexOf( - selectedElements[0].type, - ); - const nextType = ["rectangle", "diamond", "ellipse"][ - (index + 1) % 3 - ] as ToolType; - this.setActiveTool({ type: nextType }); - } else if (isLinearSwitchable) { - const index = ["arrow", "line"].indexOf( - selectedElements[0].type, - ); - const nextType = ["arrow", "line"][(index + 1) % 2] as ToolType; - this.setActiveTool({ type: nextType }); - } + event.preventDefault(); + + if (editorJotaiStore.get(shapeSwitchAtom)?.type === "panel") { + const index = isGenericSwitchable + ? GENERIC_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type) + : LINEAR_SWITCHABLE_SHAPES.indexOf(selectedElements[0].type); + + const nextType = ( + isGenericSwitchable + ? GENERIC_SWITCHABLE_SHAPES[ + (index + 1) % GENERIC_SWITCHABLE_SHAPES.length + ] + : LINEAR_SWITCHABLE_SHAPES[ + (index + 1) % LINEAR_SWITCHABLE_SHAPES.length + ] + ) as ToolType; + + this.setActiveTool({ type: nextType }); } - editorJotaiStore.set(shapeSwitchAtom, "panel"); + editorJotaiStore.set(shapeSwitchAtom, { + type: "panel", + }); } } @@ -4700,7 +4708,10 @@ class App extends React.Component { }); } - editorJotaiStore.set(shapeSwitchAtom, "hint"); + editorJotaiStore.set(shapeSwitchAtom, { + type: "hint", + id: firstNode.id, + }); } this.flowChartCreator.clear(); diff --git a/packages/excalidraw/components/ShapeSwitch.tsx b/packages/excalidraw/components/ShapeSwitch.tsx index 75dbe1607..0ffd4a12c 100644 --- a/packages/excalidraw/components/ShapeSwitch.tsx +++ b/packages/excalidraw/components/ShapeSwitch.tsx @@ -31,7 +31,20 @@ import type { ToolType } from "../types"; const GAP_HORIZONTAL = 8; const GAP_VERTICAL = 10; -export const shapeSwitchAtom = atom<"hint" | "panel" | null>(null); +export const GENERIC_SWITCHABLE_SHAPES = ["rectangle", "diamond", "ellipse"]; + +export const LINEAR_SWITCHABLE_SHAPES = ["line", "arrow"]; + +export const shapeSwitchAtom = atom< + | { + type: "hint"; + id: string; + } + | { + type: "panel"; + } + | null +>(null); const ShapeSwitch = ({ app }: { app: App }) => { const [shapeSwitch, setShapeSwitch] = useAtom(shapeSwitchAtom); @@ -46,8 +59,13 @@ const ShapeSwitch = ({ app }: { app: App }) => { ); const firstElement = selectedElements[0]; + if (shapeSwitch.type === "hint" && firstElement.id !== shapeSwitch.id) { + setShapeSwitch(null); + return null; + } + if (firstElement && selectedElements.length === 1) { - switch (shapeSwitch) { + switch (shapeSwitch.type) { case "hint": return ; case "panel": @@ -64,13 +82,6 @@ const ShapeSwitch = ({ app }: { app: App }) => { const Hint = ({ app, element }: { app: App; element: ExcalidrawElement }) => { const [, setShapeSwitch] = useAtom(shapeSwitchAtom); const hintRef = useRef(null); - const initialElementRef = useRef(element); - - useEffect(() => { - if (element !== initialElementRef.current) { - setShapeSwitch(null); - } - }, [element, setShapeSwitch]); useEffect(() => { const hint = hintRef.current; @@ -90,10 +101,6 @@ const Hint = ({ app, element }: { app: App; element: ExcalidrawElement }) => { }; }, [setShapeSwitch]); - if (element !== initialElementRef.current) { - return null; - } - const [x1, y1, , , cx, cy] = getElementAbsoluteCoords( element, app.scene.getNonDeletedElementsMap(), @@ -140,22 +147,6 @@ const Hint = ({ app, element }: { app: App; element: ExcalidrawElement }) => { }; const Panel = ({ app, element }: { app: App; element: ExcalidrawElement }) => { - const [shapeSwitch, setShapeSwitch] = useAtom(shapeSwitchAtom); - - const isMounted = useRef(true); - useEffect(() => { - isMounted.current = true; - - return () => { - isMounted.current = false; - requestAnimationFrame(() => { - if (!isMounted.current && shapeSwitch === "panel") { - setShapeSwitch(null); - } - }); - }; - }, [shapeSwitch, setShapeSwitch]); - const [x1, , , y2, cx, cy] = getElementAbsoluteCoords( element, app.scene.getNonDeletedElementsMap(),