Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 1x 1x 1x 1x 1x 15x 15x 15x 15x 15x 10x 6x 6x 6x 10x 10x 10x 10x 15x 15x 3x 3x 3x 3x 3x 15x 3x 3x 2x 3x 2x 2x 2x 3x 15x 15x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 15x | import { useState, useEffect } from 'react';
// Icons
import { ArrowBoxUpIcon } from '../icons/reacts';
// Utils
import { combineClasses } from '@shared/utils';
// Constants
import { KEYBOARD_EVENT } from '@shared/constants';
interface ScrollToTopButtonProps {
className?: string;
showAfterScrollY?: number;
}
export const ScrollToTopButton = ({
className,
showAfterScrollY = 100,
}: ScrollToTopButtonProps) => {
const [shouldShow, setShouldShow] = useState(false);
useEffect(() => {
const handleScroll = () => {
const scrollY = window.scrollY;
setShouldShow(scrollY > showAfterScrollY);
};
window.addEventListener('scroll', handleScroll, { passive: true });
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [showAfterScrollY]);
const handleScrollToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth',
});
};
const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {
if (
event.key === KEYBOARD_EVENT.ENTER ||
event.key === KEYBOARD_EVENT.SPACE
) {
event.preventDefault();
handleScrollToTop();
}
};
return (
shouldShow && (
<button
tabIndex={0}
aria-label="Scroll to top of page"
title="Scroll to top"
className={combineClasses(
'flex size-fit rounded-[12px]',
'focus:border-none focus:outline-none',
'focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2',
'transition-all duration-200 ease-in-out',
'hover:scale-105 active:scale-95',
'disabled:opacity-50 disabled:cursor-not-allowed',
className,
)}
onClick={handleScrollToTop}
onKeyDown={handleKeyDown}
>
<ArrowBoxUpIcon dataTestId="arrow-icon" aria-hidden="true" />
</button>
)
);
};
|