feat: Add scroll listener to the nearest scrollable container and allow consumer to disable it (#3408)

* fix: Add scroll listener to the nearest scrollable container

* fix

* use loop instead of recursion

* fix

* return document

* calculate nearest scrollable container in settimeout to unblock main thread

* Add prop detectNearestScroll and clear timeout on unmount

* disable scroll listener on excal app

* update prop name to detectScroll

* update docs

* remove settimeout

* tweak docs

Co-authored-by: David Luzar <luzar.david@gmail.com>

* tweak changelog

Co-authored-by: David Luzar <luzar.david@gmail.com>

* lint

Co-authored-by: David Luzar <luzar.david@gmail.com>
This commit is contained in:
Aakansha Doshi 2021-04-09 20:44:54 +05:30 committed by GitHub
parent d91950bd03
commit c19c8ecd27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 47 additions and 8 deletions

View file

@ -168,6 +168,7 @@ import { AppProps, AppState, Gesture, GestureEvent, SceneData } from "../types";
import {
debounce,
distance,
getNearestScrollableContainer,
isInputLike,
isToolIcon,
isWritableElement,
@ -303,6 +304,7 @@ class App extends React.Component<AppProps, AppState> {
private scene: Scene;
private resizeObserver: ResizeObserver | undefined;
private nearestScrollableContainer: HTMLElement | Document | undefined;
constructor(props: AppProps) {
super(props);
const defaultAppState = getDefaultAppState();
@ -841,6 +843,10 @@ class App extends React.Component<AppProps, AppState> {
document.removeEventListener(EVENT.COPY, this.onCopy);
document.removeEventListener(EVENT.PASTE, this.pasteFromClipboard);
document.removeEventListener(EVENT.CUT, this.onCut);
this.nearestScrollableContainer?.removeEventListener(
EVENT.SCROLL,
this.onScroll,
);
document.removeEventListener(EVENT.KEYDOWN, this.onKeyDown, false);
document.removeEventListener(
@ -907,8 +913,15 @@ class App extends React.Component<AppProps, AppState> {
document.addEventListener(EVENT.PASTE, this.pasteFromClipboard);
document.addEventListener(EVENT.CUT, this.onCut);
document.addEventListener(EVENT.SCROLL, this.onScroll);
if (this.props.detectScroll) {
this.nearestScrollableContainer = getNearestScrollableContainer(
this.excalidrawContainerRef.current!,
);
this.nearestScrollableContainer.addEventListener(
EVENT.SCROLL,
this.onScroll,
);
}
window.addEventListener(EVENT.RESIZE, this.onResize, false);
window.addEventListener(EVENT.UNLOAD, this.onUnload, false);
window.addEventListener(EVENT.BLUR, this.onBlur, false);