From 07ebd7c68ce6ff92ddbc22d1c3d215f2b21328d6 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Fri, 20 May 2022 18:43:38 +0530 Subject: [PATCH] feat: support setting/resetting cursor from host (#5215) * Support setting/resetting cursor type from host * add docs * minor --- src/components/App.tsx | 11 +++++++- src/packages/excalidraw/CHANGELOG.md | 2 ++ src/packages/excalidraw/README_NEXT.md | 14 ++++++++++ src/packages/excalidraw/example/App.js | 38 ++++++++++++++++++++++---- src/types.ts | 2 ++ src/utils.ts | 3 +- 6 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 34389700..ec25b129 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -383,6 +383,8 @@ class App extends React.Component { setToastMessage: this.setToastMessage, id: this.id, setActiveTool: this.setActiveTool, + setCursor: this.setCursor, + resetCursor: this.resetCursor, } as const; if (typeof excalidrawRef === "function") { excalidrawRef(api); @@ -1921,6 +1923,13 @@ class App extends React.Component { } }; + private setCursor = (cursor: string) => { + setCursor(this.canvas, cursor); + }; + + private resetCursor = () => { + resetCursor(this.canvas); + }; /** * returns whether user is making a gesture with >= 2 fingers (points) * on o touch screen (not on a trackpad). Currently only relates to Darwin @@ -3013,7 +3022,7 @@ class App extends React.Component { pointerDownState, ); } else if (this.state.activeTool.type === "custom") { - setCursor(this.canvas, CURSOR_TYPE.CROSSHAIR); + setCursor(this.canvas, CURSOR_TYPE.AUTO); } else if (this.state.activeTool.type !== "eraser") { this.createGenericElementOnPointerDown( this.state.activeTool.type, diff --git a/src/packages/excalidraw/CHANGELOG.md b/src/packages/excalidraw/CHANGELOG.md index 822467f5..b6ab7443 100644 --- a/src/packages/excalidraw/CHANGELOG.md +++ b/src/packages/excalidraw/CHANGELOG.md @@ -17,6 +17,8 @@ Please add the latest change on the top under the correct section. #### Features +- Export API to [set](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#setCursor) and [reset](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#resetCursor) mouse cursor on the canvas [#5215](https://github.com/excalidraw/excalidraw/pull/5215). + - Export [`sceneCoordsToViewportCoords`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#onPointerDown) and [`viewportCoordsToSceneCoords`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#onPointerDown) utilities [#5187](https://github.com/excalidraw/excalidraw/pull/5187). - Added [`useHandleLibrary`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#useHandleLibrary) hook to automatically handle importing of libraries when `#addLibrary` URL hash key is present, and potentially for initializing library as well [#5115](https://github.com/excalidraw/excalidraw/pull/5115). diff --git a/src/packages/excalidraw/README_NEXT.md b/src/packages/excalidraw/README_NEXT.md index d9e31dd3..58d8ea6f 100644 --- a/src/packages/excalidraw/README_NEXT.md +++ b/src/packages/excalidraw/README_NEXT.md @@ -495,6 +495,8 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the | [id](#id) | string | Unique ID for the excalidraw component. | | [getFiles](#getFiles) | () => files | This API can be used to get the files present in the scene. It may contain files that aren't referenced by any element, so if you're persisting the files to a storage, you should compare them against stored elements. | | [setActiveTool](#setActiveTool) | (tool: { type: typeof SHAPES[number]["value"] | "eraser" } | { type: "custom"; customType: string }) => void | This API can be used to set the active tool | +| [setCursor](#setCursor) | (cursor: string) => void | This API can be used to set customise the mouse cursor on the canvas | +| [resetCursor](#resetCursor) | () => void | This API can be used to reset to default mouse cursor on the canvas | #### `readyPromise` @@ -707,6 +709,18 @@ This API has the below signature. It sets the `tool` passed in param as the acti (tool: { type: typeof SHAPES[number]["value"] | "eraser" } | { type: "custom"; customType: string }) => void +#### `setCursor` + +This API can be used to customise the mouse cursor on the canvas and has the below signature. It sets the mouse cursor to the cursor passed in param. + +
+(cursor: string) => void
+
+ +#### `resetCursor` + +This API can be used to reset to default mouse cursor. + #### `detectScroll` Indicates whether Excalidraw should listen for `scroll` event on the nearest scrollable container in the DOM tree and recompute the coordinates (e.g. to correctly handle the cursor) when the component's position changes. You can disable this when you either know this doesn't affect your app or you want to take care of it yourself (calling the [`refresh()`](#ref) method). diff --git a/src/packages/excalidraw/example/App.js b/src/packages/excalidraw/example/App.js index 0df9cb9b..99cc66e1 100644 --- a/src/packages/excalidraw/example/App.js +++ b/src/packages/excalidraw/example/App.js @@ -31,8 +31,19 @@ const { } = window.ExcalidrawLib; const COMMENT_SVG = ( - - + + ); const COMMENT_ICON_DIMENSION = 32; @@ -119,12 +130,29 @@ export default function App() { {" "} diff --git a/src/types.ts b/src/types.ts index f4af48d9..0eb01d57 100644 --- a/src/types.ts +++ b/src/types.ts @@ -466,6 +466,8 @@ export type ExcalidrawImperativeAPI = { ready: true; id: string; setActiveTool: InstanceType["setActiveTool"]; + setCursor: InstanceType["setCursor"]; + resetCursor: InstanceType["resetCursor"]; }; export type DeviceType = { diff --git a/src/utils.ts b/src/utils.ts index 7cfe1309..d81ddfec 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -301,7 +301,8 @@ export const setCursorForShape = ( setEraserCursor(canvas, appState.theme); // do nothing if image tool is selected which suggests there's // a image-preview set as the cursor - } else if (appState.activeTool.type !== "image") { + // Ignore custom type as well and let host decide + } else if (!["image", "custom"].includes(appState.activeTool.type)) { canvas.style.cursor = CURSOR_TYPE.CROSSHAIR; } };