From db9c9eb3d286060f4de9649d2ff7a80247a8e00a Mon Sep 17 00:00:00 2001 From: ad1992 Date: Fri, 22 Apr 2022 00:56:17 +0530 Subject: [PATCH] suppport disabling context menu in custom elements --- src/components/App.tsx | 15 ++++++++++++++- src/constants.ts | 1 + src/packages/excalidraw/example/App.js | 2 ++ src/scene/selection.ts | 4 ++-- src/scene/types.ts | 4 ++-- src/types.ts | 1 + src/utils.ts | 4 ++-- 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 0ecf4381e..71a2aa218 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -129,6 +129,7 @@ import { isBindingElement, isBindingElementType, isBoundToContainer, + isCustomElement, isImageElement, isInitializedImageElement, isLinearElement, @@ -3158,6 +3159,7 @@ class App extends React.Component { } if ( + event.button !== POINTER_BUTTON.SECONDARY && this.state.activeTool.type === "selection" && this.props.onElementClick && hitElement @@ -5416,7 +5418,6 @@ class App extends React.Component { event: React.PointerEvent, ) => { event.preventDefault(); - if ( (event.nativeEvent.pointerType === "touch" || (event.nativeEvent.pointerType === "pen" && @@ -5433,6 +5434,18 @@ class App extends React.Component { includeLockedElements: true, }); + let disableContextMenu = false; + if (element && isCustomElement(element)) { + const config = getCustomElementConfig( + this.props.customElementsConfig, + element.customType, + ); + disableContextMenu = !!config?.disableContextMenu; + } + if (disableContextMenu) { + this.contextMenuOpen = true; + return false; + } const type = element ? "element" : "canvas"; const container = this.excalidrawContainerRef.current!; diff --git a/src/constants.ts b/src/constants.ts index aea189b06..797eda501 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -161,6 +161,7 @@ export const DEFAULT_CUSTOM_ELEMENT_CONFIG: Required = { height: 40, stackedOnTop: false, onCreate: () => {}, + disableContextMenu: false, }; export const MQ_MAX_WIDTH_PORTRAIT = 730; export const MQ_MAX_WIDTH_LANDSCAPE = 1000; diff --git a/src/packages/excalidraw/example/App.js b/src/packages/excalidraw/example/App.js index ddffc4e43..a082ca5f6 100644 --- a/src/packages/excalidraw/example/App.js +++ b/src/packages/excalidraw/example/App.js @@ -211,6 +211,7 @@ export default function App() { `)}`, width: 60, height: 60, + disableContextMenu: true, }, { type: "custom", @@ -223,6 +224,7 @@ export default function App() { transformHandles: false, stackedOnTop: true, onCreate, + disableContextMenu: true, }, { type: "custom", diff --git a/src/scene/selection.ts b/src/scene/selection.ts index 847bed0e5..a0667d2f9 100644 --- a/src/scene/selection.ts +++ b/src/scene/selection.ts @@ -3,14 +3,14 @@ import { NonDeletedExcalidrawElement, } from "../element/types"; import { getElementAbsoluteCoords, getElementBounds } from "../element"; -import { AppState, ExcalidrawProps } from "../types"; +import { AppProps, AppState } from "../types"; import { isBoundToContainer } from "../element/typeChecks"; import { getCustomElementConfig } from "../utils"; export const getElementsWithinSelection = ( elements: readonly NonDeletedExcalidrawElement[], selection: NonDeletedExcalidrawElement, - customElementConfig: ExcalidrawProps["customElementsConfig"], + customElementConfig: AppProps["customElementsConfig"], ) => { const [selectionX1, selectionY1, selectionX2, selectionY2] = getElementAbsoluteCoords(selection); diff --git a/src/scene/types.ts b/src/scene/types.ts index 1fd2df4c4..886f6fd6b 100644 --- a/src/scene/types.ts +++ b/src/scene/types.ts @@ -1,5 +1,5 @@ import { ExcalidrawTextElement } from "../element/types"; -import { AppClassProperties, AppState, ExcalidrawProps } from "../types"; +import { AppClassProperties, AppProps, AppState } from "../types"; export type RenderConfig = { // AppState values @@ -27,7 +27,7 @@ export type RenderConfig = { /** when exporting the behavior is slightly different (e.g. we can't use CSS filters), and we disable render optimizations for best output */ isExporting: boolean; - customElementsConfig?: ExcalidrawProps["customElementsConfig"]; + customElementsConfig?: AppProps["customElementsConfig"]; }; export type SceneScroll = { diff --git a/src/types.ts b/src/types.ts index b54eb4146..2bb059c0d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -233,6 +233,7 @@ export type CustomElementConfig = { height?: number; stackedOnTop: boolean; onCreate?: (element: ExcalidrawElement) => void; + disableContextMenu: boolean; }; export type ExcalidrawInitialDataState = Merge< ImportedDataState, diff --git a/src/utils.ts b/src/utils.ts index 23e47817f..3c457e2bd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -11,7 +11,7 @@ import { WINDOWS_EMOJI_FALLBACK_FONT, } from "./constants"; import { FontFamilyValues, FontString } from "./element/types"; -import { AppState, DataURL, ExcalidrawProps, Zoom } from "./types"; +import { AppProps, AppState, DataURL, Zoom } from "./types"; import { unstable_batchedUpdates } from "react-dom"; import { isDarwin } from "./keys"; @@ -627,7 +627,7 @@ export const getFrame = () => { }; export const getCustomElementConfig = ( - customElementConfig: ExcalidrawProps["customElementsConfig"], + customElementConfig: AppProps["customElementsConfig"], customType: string, ) => { if (!customElementConfig) {