From 830fb64a252a1c84709d3a68c5eef5e2700b258f Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Sun, 14 Feb 2021 18:18:34 +0530 Subject: [PATCH] fix: Support Excalidraw inside scrollable container (#3018) * refactor: remove position fixed from excalidraw container, modal and stats * remove unused css * remove position fixed from toast and scroll to content * Make excal interactable by fixing offsets and set popover as fixed since position needs to be calculate from viewport top * Assign 200px less than height of Excalidraw to the selected shapes actions o UI doesn't overflow * update changelog, readme and package.json --- src/components/App.tsx | 6 ++++ src/components/LayerUI.tsx | 34 ++++++++++++++--------- src/components/Modal.scss | 11 ++++++-- src/components/Modal.tsx | 2 +- src/components/Popover.scss | 10 +------ src/components/Stats.scss | 2 +- src/components/Toast.scss | 2 +- src/constants.ts | 2 ++ src/css/styles.scss | 4 +-- src/packages/excalidraw/CHANGELOG.md | 14 ++++++++++ src/packages/excalidraw/README.md | 26 +++++++++-------- src/packages/excalidraw/package-lock.json | 2 +- src/packages/excalidraw/package.json | 2 +- 13 files changed, 73 insertions(+), 44 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index b421f954..9a7a15c8 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -51,6 +51,7 @@ import { LINE_CONFIRM_THRESHOLD, MIME_TYPES, POINTER_BUTTON, + SCROLL_TIMEOUT, TAP_TWICE_TIMEOUT, TEXT_TO_CENTER_SNAP_THRESHOLD, TOUCH_CTX_MENU_TIMEOUT, @@ -825,6 +826,7 @@ class App extends React.Component { document.addEventListener(EVENT.PASTE, this.pasteFromClipboard); document.addEventListener(EVENT.CUT, this.onCut); + document.addEventListener(EVENT.SCROLL, this.onScroll); window.addEventListener(EVENT.RESIZE, this.onResize, false); window.addEventListener(EVENT.UNLOAD, this.onUnload, false); @@ -998,6 +1000,10 @@ class App extends React.Component { } } + private onScroll = debounce(() => { + this.setState({ ...this.getCanvasOffsets() }); + }, SCROLL_TIMEOUT); + // Copy/paste private onCut = withBatchedUpdates((event: ClipboardEvent) => { diff --git a/src/components/LayerUI.tsx b/src/components/LayerUI.tsx index cf9933d3..103b0ef8 100644 --- a/src/components/LayerUI.tsx +++ b/src/components/LayerUI.tsx @@ -442,7 +442,15 @@ const LayerUI = ({ "transition-left": zenModeEnabled, })} > - + {t("buttons.exitZenMode")} - {appState.scrolledOutside && ( - - )} ); @@ -677,6 +673,18 @@ const LayerUI = ({ {renderBottomAppMenu()} {renderGitHubCorner()} {renderFooter()} + {appState.scrolledOutside && ( + + )} ); }; diff --git a/src/components/Modal.scss b/src/components/Modal.scss index 2666f351..69d5e3ae 100644 --- a/src/components/Modal.scss +++ b/src/components/Modal.scss @@ -1,8 +1,13 @@ @import "../css/variables.module"; .excalidraw { + &.excalidraw-modal-container { + position: absolute; + z-index: 10; + } + .Modal { - position: fixed; + position: absolute; top: 0; left: 0; right: 0; @@ -15,7 +20,7 @@ } .Modal__background { - position: fixed; + position: absolute; top: 0; left: 0; right: 0; @@ -82,7 +87,7 @@ } .Modal__content { - position: fixed; + position: absolute; top: 0; left: 0; right: 0; diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index 01576082..9dcff1ad 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -54,7 +54,7 @@ const useBodyRoot = () => { ?.classList.contains("Appearance_dark"); const div = document.createElement("div"); - div.classList.add("excalidraw"); + div.classList.add("excalidraw", "excalidraw-modal-container"); if (isDarkTheme) { div.classList.add("Appearance_dark"); diff --git a/src/components/Popover.scss b/src/components/Popover.scss index c69c4679..0428f744 100644 --- a/src/components/Popover.scss +++ b/src/components/Popover.scss @@ -1,14 +1,6 @@ .excalidraw { .popover { - position: absolute; + position: fixed; z-index: 10; } - - .popover .cover { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - } } diff --git a/src/components/Stats.scss b/src/components/Stats.scss index 84864f93..3d0278cf 100644 --- a/src/components/Stats.scss +++ b/src/components/Stats.scss @@ -1,7 +1,7 @@ @import "../css/variables.module"; .Stats { - position: fixed; + position: absolute; top: 64px; right: 12px; font-size: 12px; diff --git a/src/components/Toast.scss b/src/components/Toast.scss index 70cc8018..4cf24115 100644 --- a/src/components/Toast.scss +++ b/src/components/Toast.scss @@ -11,7 +11,7 @@ left: 50%; margin-left: -150px; padding: 4px 0; - position: fixed; + position: absolute; text-align: center; width: 300px; z-index: 999999; diff --git a/src/constants.ts b/src/constants.ts index be74e938..acdfd273 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -47,6 +47,7 @@ export enum EVENT { TOUCH_END = "touchend", HASHCHANGE = "hashchange", VISIBILITY_CHANGE = "visibilitychange", + SCROLL = "scroll", } export const ENV = { @@ -92,6 +93,7 @@ export const TOUCH_CTX_MENU_TIMEOUT = 500; export const TITLE_TIMEOUT = 10000; export const TOAST_TIMEOUT = 5000; export const VERSION_TIMEOUT = 30000; +export const SCROLL_TIMEOUT = 500; export const ZOOM_STEP = 0.1; diff --git a/src/css/styles.scss b/src/css/styles.scss index f7dc0825..d8bf1c79 100644 --- a/src/css/styles.scss +++ b/src/css/styles.scss @@ -10,7 +10,6 @@ .excalidraw { color: var(--text-color-primary); display: flex; - position: fixed; top: 0; bottom: 0; left: 0; @@ -362,7 +361,6 @@ .App-menu__left { overflow-y: auto; - max-height: calc(100vh - 236px); } .dropdown-select { @@ -434,7 +432,7 @@ .scroll-back-to-content { color: var(--popup-text-color); - position: fixed; + position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%); diff --git a/src/packages/excalidraw/CHANGELOG.md b/src/packages/excalidraw/CHANGELOG.md index 367dd315..c8709648 100644 --- a/src/packages/excalidraw/CHANGELOG.md +++ b/src/packages/excalidraw/CHANGELOG.md @@ -12,6 +12,20 @@ The change should be grouped under one of the below section and must contain PR Please add the latest change on the top under the correct section. --> +## 0.3.1 + +## Excalidraw API + +### Fixes + +- Support Excalidraw inside scrollable container [#3018](https://github.com/excalidraw/excalidraw/pull/3018) + +## Excalidraw Library + +### Fixes + +- Allow to toggle between modes when view only mode to make UI consistent [#3009](https://github.com/excalidraw/excalidraw/pull/3009) + ## 0.3.0 ## Excalidraw API diff --git a/src/packages/excalidraw/README.md b/src/packages/excalidraw/README.md index 61e98721..620455ef 100644 --- a/src/packages/excalidraw/README.md +++ b/src/packages/excalidraw/README.md @@ -37,18 +37,18 @@ You can update the value of `PUBLIC_URL` if you want to serve it from a differen 1. If you are using a Web bundler (for instance, Webpack), you can import it as an ES6 module as shown below ```js -import React, { useEffect, useState, createRef } from "react"; +import React, { useEffect, useState, useRef } from "react"; import Excalidraw from "@excalidraw/excalidraw"; import InitialData from "./initialData"; -import "./styles.css"; +import "./styles.scss"; export default function App() { - const excalidrawRef = createRef(); - + const excalidrawRef = useRef(null); + const excalidrawWrapperRef = useRef(null); const [dimensions, setDimensions] = useState({ - width: window.innerWidth, - height: window.innerHeight, + width: undefined, + height: undefined, }); const [viewModeEnabled, setViewModeEnabled] = useState(false); @@ -56,17 +56,21 @@ export default function App() { const [gridModeEnabled, setGridModeEnabled] = useState(false); useEffect(() => { + setDimensions({ + width: excalidrawWrapperRef.current.getBoundingClientRect().width, + height: excalidrawWrapperRef.current.getBoundingClientRect().height, + }); const onResize = () => { setDimensions({ - width: window.innerWidth, - height: window.innerHeight, + width: excalidrawWrapperRef.current.getBoundingClientRect().width, + height: excalidrawWrapperRef.current.getBoundingClientRect().height, }); }; window.addEventListener("resize", onResize); return () => window.removeEventListener("resize", onResize); - }, []); + }, [excalidrawWrapperRef]); const updateScene = () => { const sceneData = { @@ -102,6 +106,7 @@ export default function App() { return (
+

Excalidraw Example

-
+
console.log("Elements :", elements, "State : ", state) } - user={{ name: "Excalidraw User" }} onPointerUpdate={(payload) => console.log(payload)} onCollabButtonClick={() => window.alert("You clicked on collab button") diff --git a/src/packages/excalidraw/package-lock.json b/src/packages/excalidraw/package-lock.json index 87eafc5d..2419c8c7 100644 --- a/src/packages/excalidraw/package-lock.json +++ b/src/packages/excalidraw/package-lock.json @@ -1,6 +1,6 @@ { "name": "@excalidraw/excalidraw", - "version": "0.3.0", + "version": "0.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/packages/excalidraw/package.json b/src/packages/excalidraw/package.json index 60637c75..370357d0 100644 --- a/src/packages/excalidraw/package.json +++ b/src/packages/excalidraw/package.json @@ -1,6 +1,6 @@ { "name": "@excalidraw/excalidraw", - "version": "0.3.0", + "version": "0.3.1", "main": "dist/excalidraw.min.js", "files": [ "dist/*"