11import React , { useState , useEffect } from "react" ;
2- import { FaArrowUp } from "react-icons/fa" ;
2+ import { FaArrowDown , FaArrowUp } from "react-icons/fa" ;
33
44export default function ScrollBottomToTop ( ) {
5- const [ isVisible , setIsVisible ] = useState ( false ) ;
6-
7- const toggleVisibility = ( ) => {
8- if ( window . pageYOffset > 300 ) {
9- setIsVisible ( true ) ;
10- } else {
11- setIsVisible ( false ) ;
12- }
5+ const [ showTopButton , setShowTopButton ] = useState ( false ) ;
6+ const [ showBottomButton , setShowBottomButton ] = useState ( false ) ;
7+
8+ const updateVisibility = ( ) => {
9+ const scrollTop = window . pageYOffset ;
10+ const documentHeight = document . documentElement . scrollHeight ;
11+ const viewportHeight = window . innerHeight ;
12+
13+ setShowTopButton ( scrollTop > 300 ) ;
14+ setShowBottomButton ( scrollTop + viewportHeight < documentHeight - 300 ) ;
1315 } ;
1416
1517 const scrollToTop = ( ) => {
@@ -19,26 +21,50 @@ export default function ScrollBottomToTop() {
1921 } ) ;
2022 } ;
2123
24+ const scrollToBottom = ( ) => {
25+ window . scrollTo ( {
26+ top : document . documentElement . scrollHeight ,
27+ behavior : "smooth" ,
28+ } ) ;
29+ } ;
30+
2231 useEffect ( ( ) => {
23- window . addEventListener ( "scroll" , toggleVisibility ) ;
32+ updateVisibility ( ) ;
33+ window . addEventListener ( "scroll" , updateVisibility ) ;
34+ window . addEventListener ( "resize" , updateVisibility ) ;
2435
2536 return ( ) => {
26- window . removeEventListener ( "scroll" , toggleVisibility ) ;
37+ window . removeEventListener ( "scroll" , updateVisibility ) ;
38+ window . removeEventListener ( "resize" , updateVisibility ) ;
2739 } ;
2840 } , [ ] ) ;
2941
42+ if ( ! showTopButton && ! showBottomButton ) {
43+ return null ;
44+ }
45+
3046 return (
31- < div className = "scroll-to-top" >
32- { isVisible && (
47+ < div className = "scroll-to-top fixed right-5 bottom-5 z-50 flex flex-col gap-3 " >
48+ { showTopButton && (
3349 < button
34- aria-label = "Scroll to top"
50+ aria-label = "Scroll to top"
3551 onClick = { scrollToTop }
36- className = "fixed right-5 bottom-5 z-50 cursor-pointer rounded-full border-none bg-gray-700 p-3 text-white shadow-lg transition-opacity duration-300 hover:bg-gray-800 dark:bg-gray-600 dark:hover:bg-gray-700"
52+ className = "cursor-pointer rounded-full border-none bg-gray-700 p-3 text-white shadow-lg transition-opacity duration-300 hover:bg-gray-800 dark:bg-gray-600 dark:hover:bg-gray-700"
3753 style = { { backgroundColor : "var(--ifm-color-primary)" } }
3854 >
3955 < FaArrowUp />
4056 </ button >
4157 ) }
58+ { showBottomButton && (
59+ < button
60+ aria-label = "Scroll to bottom"
61+ onClick = { scrollToBottom }
62+ className = "cursor-pointer rounded-full border-none bg-gray-700 p-3 text-white shadow-lg transition-opacity duration-300 hover:bg-gray-800 dark:bg-gray-600 dark:hover:bg-gray-700"
63+ style = { { backgroundColor : "var(--ifm-color-primary)" } }
64+ >
65+ < FaArrowDown />
66+ </ button >
67+ ) }
4268 </ div >
4369 ) ;
4470}
0 commit comments