From 7c5481b877d31080ce64ca24a6a8f51f941ffd78 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Sun, 21 Feb 2021 19:01:34 +0530 Subject: [PATCH] feat: Add support for scrollToCenter in initialData so host can control whether to scroll to center on mount (#3070) * feat: Add support for scrollToCenter in initialData so host can control whether to scroll to center on mount * fix * update changelog and readme * fix * Scroll to center only for collab and shareable links in excalidraw app * fix test * update readme * Update src/packages/excalidraw/README.md --- src/components/App.tsx | 27 ++++++++++++--------- src/data/types.ts | 1 + src/excalidraw-app/collab/CollabWrapper.tsx | 6 ++++- src/excalidraw-app/index.tsx | 9 +++++-- src/packages/excalidraw/CHANGELOG.md | 2 ++ src/packages/excalidraw/README.md | 9 ++++--- src/tests/scroll.test.tsx | 1 + 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 8094a7b303..b670ca1a2f 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -672,19 +672,24 @@ class App extends React.Component { scene.appState = { ...scene.appState, - ...calculateScrollCenter( - scene.elements, - { - ...scene.appState, - width: this.state.width, - height: this.state.height, - offsetTop: this.state.offsetTop, - offsetLeft: this.state.offsetLeft, - }, - null, - ), isLoading: false, }; + if (initialData?.scrollToCenter) { + scene.appState = { + ...scene.appState, + ...calculateScrollCenter( + scene.elements, + { + ...scene.appState, + width: this.state.width, + height: this.state.height, + offsetTop: this.state.offsetTop, + offsetLeft: this.state.offsetLeft, + }, + null, + ), + }; + } this.resetHistory(); this.syncActionResult({ diff --git a/src/data/types.ts b/src/data/types.ts index 34973f9da0..dd3354c217 100644 --- a/src/data/types.ts +++ b/src/data/types.ts @@ -15,6 +15,7 @@ export interface ImportedDataState { source?: string; elements?: DataState["elements"] | null; appState?: Partial | null; + scrollToCenter?: boolean; } export interface LibraryData { diff --git a/src/excalidraw-app/collab/CollabWrapper.tsx b/src/excalidraw-app/collab/CollabWrapper.tsx index e22f03986b..c6ffdf95e9 100644 --- a/src/excalidraw-app/collab/CollabWrapper.tsx +++ b/src/excalidraw-app/collab/CollabWrapper.tsx @@ -256,6 +256,7 @@ class CollabWrapper extends PureComponent { if (elements) { scenePromise.resolve({ elements, + scrollToCenter: true, }); } } catch (error) { @@ -307,7 +308,10 @@ class CollabWrapper extends PureComponent { init: true, }); // noop if already resolved via init from firebase - scenePromise.resolve({ elements: reconciledElements }); + scenePromise.resolve({ + elements: reconciledElements, + scrollToCenter: true, + }); } break; } diff --git a/src/excalidraw-app/index.tsx b/src/excalidraw-app/index.tsx index 96d8af30ff..926c2635b1 100644 --- a/src/excalidraw-app/index.tsx +++ b/src/excalidraw-app/index.tsx @@ -13,7 +13,7 @@ import { ExcalidrawImperativeAPI } from "../components/App"; import { ErrorDialog } from "../components/ErrorDialog"; import { TopErrorBoundary } from "../components/TopErrorBoundary"; import { APP_NAME, EVENT, TITLE_TIMEOUT, VERSION_TIMEOUT } from "../constants"; -import { ImportedDataState } from "../data/types"; +import { DataState, ImportedDataState } from "../data/types"; import { ExcalidrawElement, NonDeletedExcalidrawElement, @@ -75,7 +75,11 @@ const initializeScene = async (opts: { const initialData = importFromLocalStorage(); - let scene = await loadScene(null, null, initialData); + let scene: DataState & { scrollToCenter?: boolean } = await loadScene( + null, + null, + initialData, + ); let roomLinkData = getCollaborationLinkData(window.location.href); const isExternalScene = !!(id || jsonMatch || roomLinkData); @@ -94,6 +98,7 @@ const initializeScene = async (opts: { } else if (jsonMatch) { scene = await loadScene(jsonMatch[1], jsonMatch[2], initialData); } + scene.scrollToCenter = true; if (!roomLinkData) { window.history.replaceState({}, APP_NAME, window.location.origin); } diff --git a/src/packages/excalidraw/CHANGELOG.md b/src/packages/excalidraw/CHANGELOG.md index 7a37ae6d73..7fe4ffc3f4 100644 --- a/src/packages/excalidraw/CHANGELOG.md +++ b/src/packages/excalidraw/CHANGELOG.md @@ -18,6 +18,8 @@ Please add the latest change on the top under the correct section. ### Features +- Add support for `scrollToCenter` in [initialData](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L18) so host can control whether to scroll to center on mount [#3070](https://github.com/excalidraw/excalidraw/pull/3070). + - Export [`restore`](https://github.com/excalidraw/excalidraw/blob/master/src/data/restore.ts#L182), [`restoreAppState`](https://github.com/excalidraw/excalidraw/blob/master/src/data/restore.ts#L144) and [`restoreElements`](https://github.com/excalidraw/excalidraw/blob/master/src/data/restore.ts#L128) to host ### Fixes diff --git a/src/packages/excalidraw/README.md b/src/packages/excalidraw/README.md index ba2e3ecf2f..d72c61b52f 100644 --- a/src/packages/excalidraw/README.md +++ b/src/packages/excalidraw/README.md @@ -286,10 +286,11 @@ Here you can try saving the data to your backend or local storage for example. This helps to load Excalidraw with `initialData`. It must be an object or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to an object containing the below optional fields. -| name | type | -| --- | --- | -| elements | [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) | -| appState | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L37) | +| Name | Type | Descrption | +| --- | --- | --- | +| `elements` | [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78) | The elements with which Excalidraw should be mounted. | +| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L37) | The App state with which Excalidraw should be mounted. | +| `scrollToCenter` | boolean | This attribute implies whether to scroll to the center once Excalidraw is mounted. By default, it will not scroll to the center. | ```json { diff --git a/src/tests/scroll.test.tsx b/src/tests/scroll.test.tsx index 6ee4a2d348..2984e3c609 100644 --- a/src/tests/scroll.test.tsx +++ b/src/tests/scroll.test.tsx @@ -30,6 +30,7 @@ describe("appState", () => { height: ELEM_HEIGHT, }), ], + scrollToCenter: true, }} />, );