Explorar o código

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
Aakansha Doshi %!s(int64=4) %!d(string=hai) anos
pai
achega
7c5481b877

+ 16 - 11
src/components/App.tsx

@@ -672,19 +672,24 @@ class App extends React.Component<ExcalidrawProps, AppState> {
 
     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({

+ 1 - 0
src/data/types.ts

@@ -15,6 +15,7 @@ export interface ImportedDataState {
   source?: string;
   elements?: DataState["elements"] | null;
   appState?: Partial<DataState["appState"]> | null;
+  scrollToCenter?: boolean;
 }
 
 export interface LibraryData {

+ 5 - 1
src/excalidraw-app/collab/CollabWrapper.tsx

@@ -256,6 +256,7 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
         if (elements) {
           scenePromise.resolve({
             elements,
+            scrollToCenter: true,
           });
         }
       } catch (error) {
@@ -307,7 +308,10 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
                 init: true,
               });
               // noop if already resolved via init from firebase
-              scenePromise.resolve({ elements: reconciledElements });
+              scenePromise.resolve({
+                elements: reconciledElements,
+                scrollToCenter: true,
+              });
             }
             break;
           }

+ 7 - 2
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);
       }

+ 2 - 0
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

+ 5 - 4
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
 {

+ 1 - 0
src/tests/scroll.test.tsx

@@ -30,6 +30,7 @@ describe("appState", () => {
               height: ELEM_HEIGHT,
             }),
           ],
+          scrollToCenter: true,
         }}
       />,
     );