Merge pull request #553 from ONLYOFFICE/feature/edge-scrolling

Web: Components: added scrolling around edges
This commit is contained in:
Alexey Safronov 2024-07-19 16:57:47 +04:00 committed by GitHub
commit d300a0fec3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 78 additions and 1 deletions

View File

@ -35,7 +35,13 @@ import EmptyContainer from "../../../../components/EmptyContainer";
import withLoader from "../../../../HOCs/withLoader";
import TableView from "./TableView/TableContainer";
import withHotkeys from "../../../../HOCs/withHotkeys";
import { Consumer, isMobile, isTablet } from "@docspace/shared/utils";
import {
clearEdgeScrollingTimer,
Consumer,
isMobile,
isTablet,
onEdgeScrolling,
} from "@docspace/shared/utils";
import { isElementInViewport } from "@docspace/shared/utils/common";
import { DeviceType } from "@docspace/shared/enums";
@ -197,6 +203,7 @@ const SectionBodyContent = (props) => {
setDragging(true);
}
onEdgeScrolling(e);
setTooltipPosition(e.pageX, e.pageY);
const wrapperElement = document.elementFromPoint(e.clientX, e.clientY);
if (!wrapperElement) {
@ -240,6 +247,7 @@ const SectionBodyContent = (props) => {
};
const onMouseUp = (e) => {
clearEdgeScrollingTimer();
setStartDrag(false);
setTimeout(() => {

View File

@ -30,6 +30,7 @@ import { useTheme } from "styled-components";
import { StyledSelectionArea } from "./SelectionArea.styled";
import { frames } from "./SelectionArea.utils";
import { SelectionAreaProps, TArrayTypes } from "./SelectionArea.types";
import { onEdgeScrolling, clearEdgeScrollingTimer } from "../../utils";
const SelectionArea = ({
onMove,
@ -298,6 +299,8 @@ const SelectionArea = ({
areaLocation.current.x2 = e.clientX;
areaLocation.current.y2 = e.clientY;
onEdgeScrolling(e);
frame().next();
},
[frame],
@ -358,6 +361,7 @@ const SelectionArea = ({
}, [onMoveAction, onScroll, onTapMove]);
const onTapStop = React.useCallback(() => {
clearEdgeScrollingTimer();
removeListeners();
document.removeEventListener("mouseup", onTapStop);
window.removeEventListener("blur", onTapStop);

View File

@ -0,0 +1,62 @@
const edgeSize = 200;
const maxStep = 50;
let timer: null | ReturnType<typeof setTimeout> = null;
export const clearEdgeScrollingTimer = () => {
if (timer) clearTimeout(timer);
};
export const onEdgeScrolling = (e: React.MouseEvent) => {
const bodyScroll = document.querySelector(".section-scroll");
if (bodyScroll) {
const viewportY = e.clientY;
const viewportHeight = document.documentElement.clientHeight;
const edgeTop = edgeSize;
const edgeBottom = viewportHeight - edgeSize;
const isInTopEdge = viewportY < edgeTop;
const isInBottomEdge = viewportY > edgeBottom;
if (!(isInTopEdge || isInBottomEdge)) {
clearEdgeScrollingTimer();
return;
}
const maxScrollY = bodyScroll.scrollHeight - viewportHeight;
const adjustWindowScroll = () => {
const currentScrollY = bodyScroll.scrollTop;
const canScrollUp = currentScrollY > 0;
const canScrollDown = currentScrollY < maxScrollY;
let nextScrollY = currentScrollY;
if (isInTopEdge && canScrollUp) {
const intensity = (edgeTop - viewportY) / edgeSize;
nextScrollY -= maxStep * intensity;
} else if (isInBottomEdge && canScrollDown) {
const intensity = (viewportY - edgeBottom) / edgeSize;
nextScrollY += maxStep * intensity;
}
nextScrollY = Math.max(0, Math.min(maxScrollY, nextScrollY));
if (nextScrollY !== currentScrollY) {
bodyScroll.scrollTo(0, nextScrollY);
return true;
}
return false;
};
const checkForWindowScroll = () => {
clearEdgeScrollingTimer();
if (adjustWindowScroll()) {
timer = setTimeout(checkForWindowScroll, 30);
}
};
checkForWindowScroll();
}
};

View File

@ -77,6 +77,7 @@ import {
} from "./common";
import { DeviceType } from "../enums";
import { TFile } from "../api/files/types";
import { onEdgeScrolling, clearEdgeScrollingTimer } from "./edgeScrolling";
export {
isBetaLanguage,
@ -127,6 +128,8 @@ export {
ObjectUtils,
getLogoUrl,
isMobileDevice,
onEdgeScrolling,
clearEdgeScrollingTimer,
};
export const getModalType = () => {