Merge pull request #553 from ONLYOFFICE/feature/edge-scrolling
Web: Components: added scrolling around edges
This commit is contained in:
commit
d300a0fec3
@ -35,7 +35,13 @@ import EmptyContainer from "../../../../components/EmptyContainer";
|
|||||||
import withLoader from "../../../../HOCs/withLoader";
|
import withLoader from "../../../../HOCs/withLoader";
|
||||||
import TableView from "./TableView/TableContainer";
|
import TableView from "./TableView/TableContainer";
|
||||||
import withHotkeys from "../../../../HOCs/withHotkeys";
|
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 { isElementInViewport } from "@docspace/shared/utils/common";
|
||||||
|
|
||||||
import { DeviceType } from "@docspace/shared/enums";
|
import { DeviceType } from "@docspace/shared/enums";
|
||||||
@ -197,6 +203,7 @@ const SectionBodyContent = (props) => {
|
|||||||
setDragging(true);
|
setDragging(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEdgeScrolling(e);
|
||||||
setTooltipPosition(e.pageX, e.pageY);
|
setTooltipPosition(e.pageX, e.pageY);
|
||||||
const wrapperElement = document.elementFromPoint(e.clientX, e.clientY);
|
const wrapperElement = document.elementFromPoint(e.clientX, e.clientY);
|
||||||
if (!wrapperElement) {
|
if (!wrapperElement) {
|
||||||
@ -240,6 +247,7 @@ const SectionBodyContent = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onMouseUp = (e) => {
|
const onMouseUp = (e) => {
|
||||||
|
clearEdgeScrollingTimer();
|
||||||
setStartDrag(false);
|
setStartDrag(false);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -30,6 +30,7 @@ import { useTheme } from "styled-components";
|
|||||||
import { StyledSelectionArea } from "./SelectionArea.styled";
|
import { StyledSelectionArea } from "./SelectionArea.styled";
|
||||||
import { frames } from "./SelectionArea.utils";
|
import { frames } from "./SelectionArea.utils";
|
||||||
import { SelectionAreaProps, TArrayTypes } from "./SelectionArea.types";
|
import { SelectionAreaProps, TArrayTypes } from "./SelectionArea.types";
|
||||||
|
import { onEdgeScrolling, clearEdgeScrollingTimer } from "../../utils";
|
||||||
|
|
||||||
const SelectionArea = ({
|
const SelectionArea = ({
|
||||||
onMove,
|
onMove,
|
||||||
@ -298,6 +299,8 @@ const SelectionArea = ({
|
|||||||
areaLocation.current.x2 = e.clientX;
|
areaLocation.current.x2 = e.clientX;
|
||||||
areaLocation.current.y2 = e.clientY;
|
areaLocation.current.y2 = e.clientY;
|
||||||
|
|
||||||
|
onEdgeScrolling(e);
|
||||||
|
|
||||||
frame().next();
|
frame().next();
|
||||||
},
|
},
|
||||||
[frame],
|
[frame],
|
||||||
@ -358,6 +361,7 @@ const SelectionArea = ({
|
|||||||
}, [onMoveAction, onScroll, onTapMove]);
|
}, [onMoveAction, onScroll, onTapMove]);
|
||||||
|
|
||||||
const onTapStop = React.useCallback(() => {
|
const onTapStop = React.useCallback(() => {
|
||||||
|
clearEdgeScrollingTimer();
|
||||||
removeListeners();
|
removeListeners();
|
||||||
document.removeEventListener("mouseup", onTapStop);
|
document.removeEventListener("mouseup", onTapStop);
|
||||||
window.removeEventListener("blur", onTapStop);
|
window.removeEventListener("blur", onTapStop);
|
||||||
|
62
packages/shared/utils/edgeScrolling.ts
Normal file
62
packages/shared/utils/edgeScrolling.ts
Normal 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();
|
||||||
|
}
|
||||||
|
};
|
@ -77,6 +77,7 @@ import {
|
|||||||
} from "./common";
|
} from "./common";
|
||||||
import { DeviceType } from "../enums";
|
import { DeviceType } from "../enums";
|
||||||
import { TFile } from "../api/files/types";
|
import { TFile } from "../api/files/types";
|
||||||
|
import { onEdgeScrolling, clearEdgeScrollingTimer } from "./edgeScrolling";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
isBetaLanguage,
|
isBetaLanguage,
|
||||||
@ -127,6 +128,8 @@ export {
|
|||||||
ObjectUtils,
|
ObjectUtils,
|
||||||
getLogoUrl,
|
getLogoUrl,
|
||||||
isMobileDevice,
|
isMobileDevice,
|
||||||
|
onEdgeScrolling,
|
||||||
|
clearEdgeScrollingTimer,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getModalType = () => {
|
export const getModalType = () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user