1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

added experimental scroll helper

This commit is contained in:
Fedor Katurov 2022-01-10 16:47:29 +07:00
parent c2154e930c
commit 8d1e6989c2
8 changed files with 105 additions and 4 deletions

View file

@ -0,0 +1,27 @@
import React, { VFC } from 'react';
import styles from './styles.module.scss';
import { useScrollTop } from '~/hooks/dom/useScrollTop';
import { useScrollHeight } from '~/hooks/dom/useScrollHeight';
import classNames from 'classnames';
import { useScrollToBottom } from '~/hooks/dom/useScrollToBottom';
interface ScrollHelperBottomProps {}
const ScrollHelperBottom: VFC<ScrollHelperBottomProps> = () => {
const top = useScrollTop();
const scrollHeight = useScrollHeight();
const scrollToBottom = useScrollToBottom();
const isVisible = scrollHeight > 2000 && top < scrollHeight * 0.25;
return (
<div
className={classNames(styles.helper, { [styles.visible]: isVisible })}
onClick={scrollToBottom}
>
Вниз
</div>
);
};
export { ScrollHelperBottom };

View file

@ -0,0 +1,26 @@
@import "src/styles/variables";
.helper {
position: fixed;
bottom: 0;
background: radial-gradient($red, transparent) 50% 24px no-repeat;
background-size: 100% 48px;
display: none;
width: calc(100% - 20px);
z-index: 4;
text-align: center;
max-width: 500px;
height: 64px;
align-items: flex-end;
justify-content: center;
padding: $gap;
text-transform: uppercase;
font: $font_16_medium;
border-radius: $radius $radius 0 0;
user-select: none;
cursor: pointer;
&.visible {
display: flex;
}
}

View file

@ -19,7 +19,7 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
opacity: 0; opacity: 1;
} }
&:hover { &:hover {

View file

@ -0,0 +1,35 @@
import { useEffect, useState } from 'react';
const getHeight = () => {
if (typeof document === 'undefined') {
return 0;
}
const body = document.body;
const html = document.documentElement;
return Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
);
};
export const useScrollHeight = () => {
const [scrollHeight, setScrollHeight] = useState(getHeight());
useEffect(() => {
const measure = () => setScrollHeight(getHeight());
window.addEventListener('scroll', measure);
window.addEventListener('resize', measure);
return () => {
window.removeEventListener('scroll', measure);
window.removeEventListener('resize', measure);
};
}, []);
return scrollHeight;
};

View file

@ -0,0 +1,10 @@
import { useCallback } from 'react';
import { useScrollHeight } from '~/hooks/dom/useScrollHeight';
export const useScrollToBottom = () => {
const top = useScrollHeight();
return useCallback(() => {
window.scrollTo({ top });
}, [top]);
};

View file

@ -14,7 +14,6 @@ export const useScrollToTop = (deps?: any[]) => {
const bounds = targetElement.getBoundingClientRect(); const bounds = targetElement.getBoundingClientRect();
window.scrollTo({ window.scrollTo({
top: bounds.top - 100, top: bounds.top - 100,
behavior: 'smooth',
}); });
}, },
deps && Array.isArray(deps) ? deps : [] deps && Array.isArray(deps) ? deps : []

View file

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
export const useScrollTop = () => { export const useScrollTop = () => {
const [top, setTop] = useState(0); const [top, setTop] = useState(typeof window !== 'undefined' ? window.scrollY : 0);
useEffect(() => { useEffect(() => {
const onScroll = () => { const onScroll = () => {

View file

@ -17,6 +17,8 @@ import { useNodeContext } from '~/utils/context/NodeContextProvider';
import { useNodePermissions } from '~/hooks/node/useNodePermissions'; import { useNodePermissions } from '~/hooks/node/useNodePermissions';
import { useNodeActions } from '~/hooks/node/useNodeActions'; import { useNodeActions } from '~/hooks/node/useNodeActions';
import { NodeTitle } from '~/components/node/NodeTitle'; import { NodeTitle } from '~/components/node/NodeTitle';
import { ScrollHelperBottom } from '~/components/common/ScrollHelperBottom';
import { Superpower } from '~/components/boris/Superpower';
type IProps = {}; type IProps = {};
@ -65,7 +67,9 @@ const NodeLayout: FC<IProps> = () => {
<SidebarRouter prefix="/post:id" /> <SidebarRouter prefix="/post:id" />
<Route path={URLS.NODE_EDIT_URL(':id')} component={EditorEditDialog} /> <Superpower>
<ScrollHelperBottom />
</Superpower>
</div> </div>
); );
}; };