diff --git a/src/components/Actions.tsx b/src/components/Actions.tsx index 6afc487f1..917308cf1 100644 --- a/src/components/Actions.tsx +++ b/src/components/Actions.tsx @@ -23,6 +23,7 @@ import { } from "../utils"; import Stack from "./Stack"; import { ToolButton } from "./ToolButton"; +import { SubtypeToggles } from "./SubtypeButton"; import { hasStrokeColor } from "../scene/comparisons"; import { trackEvent } from "../analytics"; import { hasBoundTextElement } from "../element/typeChecks"; @@ -270,6 +271,7 @@ export const ShapesSwitcher = ({ /> ); })} + ); diff --git a/src/components/App.tsx b/src/components/App.tsx index 92e3c7dd6..eb4dd5e17 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -235,8 +235,6 @@ import { actionToggleViewMode } from "../actions/actionToggleViewMode"; import { SubtypeRecord, SubtypePrepFn, - getSubtypeNames, - hasAlwaysEnabledActions, prepareSubtype, selectSubtype, } from "../subtypes"; @@ -616,14 +614,6 @@ class App extends React.Component { value={this.actionManager} > - this.actionManager.renderAction( - subtype, - hasAlwaysEnabledActions(subtype) - ? { onContextMenu: this.handleCustomContextMenu } - : {}, - ), - )} canvas={this.canvas} appState={this.state} files={this.files} @@ -6047,28 +6037,6 @@ class App extends React.Component { } }; - private handleCustomContextMenu = ( - event: React.MouseEvent, - source: string, - ) => { - event.preventDefault(); - - const container = this.excalidrawContainerRef.current!; - const { top: offsetTop, left: offsetLeft } = - container.getBoundingClientRect(); - const left = event.clientX - offsetLeft; - const top = event.clientY - offsetTop; - this.setState({}, () => { - this.setState({ - contextMenu: { - top, - left, - items: this.getContextMenuItems("custom", source), - }, - }); - }); - }; - private handleCanvasContextMenu = ( event: React.PointerEvent, ) => { diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index 912e4f6f3..8aa8809fb 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -64,7 +64,6 @@ interface LayerUIProps { showExitZenModeBtn: boolean; langCode: Language["code"]; isCollaborating: boolean; - renderShapeToggles?: (JSX.Element | null)[]; renderTopRightUI?: ExcalidrawProps["renderTopRightUI"]; renderCustomStats?: ExcalidrawProps["renderCustomStats"]; renderCustomSidebar?: ExcalidrawProps["renderSidebar"]; @@ -90,7 +89,6 @@ const LayerUI = ({ onInsertElements, showExitZenModeBtn, isCollaborating, - renderShapeToggles, renderTopRightUI, renderCustomStats, renderCustomSidebar, @@ -327,7 +325,6 @@ const LayerUI = ({ {/* {actionManager.renderAction("eraser", { // size: "small", })} */} - {renderShapeToggles} @@ -414,7 +411,6 @@ const LayerUI = ({ onLockToggle={() => onLockToggle()} onPenModeToggle={onPenModeToggle} canvas={canvas} - renderShapeToggles={renderShapeToggles} onImageAction={onImageAction} renderTopRightUI={renderTopRightUI} renderCustomStats={renderCustomStats} diff --git a/src/components/MobileMenu.tsx b/src/components/MobileMenu.tsx index 6d630f75d..549292436 100644 --- a/src/components/MobileMenu.tsx +++ b/src/components/MobileMenu.tsx @@ -33,7 +33,6 @@ type MobileMenuProps = { onLockToggle: () => void; onPenModeToggle: () => void; canvas: HTMLCanvasElement | null; - renderShapeToggles?: (JSX.Element | null)[]; onImageAction: (data: { insertOnCanvasDirectly: boolean }) => void; renderTopRightUI?: ( @@ -55,7 +54,6 @@ export const MobileMenu = ({ onLockToggle, onPenModeToggle, canvas, - renderShapeToggles, onImageAction, renderTopRightUI, renderCustomStats, @@ -86,7 +84,6 @@ export const MobileMenu = ({ }); }} /> - {renderShapeToggles} {renderTopRightUI && renderTopRightUI(true, appState)} diff --git a/src/components/SubtypeButton.tsx b/src/components/SubtypeButton.tsx index dd64f2e89..6cf8d6e4c 100644 --- a/src/components/SubtypeButton.tsx +++ b/src/components/SubtypeButton.tsx @@ -3,8 +3,20 @@ import { t } from "../i18n"; import { Action } from "../actions/types"; import { ToolButton } from "./ToolButton"; import clsx from "clsx"; -import { Subtype, isValidSubtype, subtypeCollides } from "../subtypes"; +import { + Subtype, + getSubtypeNames, + hasAlwaysEnabledActions, + isValidSubtype, + subtypeCollides, +} from "../subtypes"; import { ExcalidrawElement, Theme } from "../element/types"; +import { + useExcalidrawActionManager, + useExcalidrawContainer, + useExcalidrawSetAppState, +} from "./App"; +import { ContextMenuItems } from "./ContextMenu"; export const SubtypeButton = ( subtype: Subtype, @@ -101,3 +113,44 @@ export const SubtypeButton = ( } return subtypeAction; }; + +export const SubtypeToggles = () => { + const am = useExcalidrawActionManager(); + const { container } = useExcalidrawContainer(); + const setAppState = useExcalidrawSetAppState(); + + const onContextMenu = ( + event: React.MouseEvent, + source: string, + ) => { + event.preventDefault(); + + const { top: offsetTop, left: offsetLeft } = + container!.getBoundingClientRect(); + const left = event.clientX - offsetLeft; + const top = event.clientY - offsetTop; + + const items: ContextMenuItems = []; + am.getCustomActions({ data: { source } }).forEach((action) => + items.push(action), + ); + setAppState({}, () => { + setAppState({ + contextMenu: { top, left, items }, + }); + }); + }; + + return ( + <> + {getSubtypeNames().map((subtype) => + am.renderAction( + subtype, + hasAlwaysEnabledActions(subtype) ? { onContextMenu } : {}, + ), + )} + + ); +}; + +SubtypeToggles.displayName = "SubtypeToggles";