diff options
| author | 2021-01-04 02:33:35 +0300 | |
|---|---|---|
| committer | 2021-01-06 09:35:54 +0300 | |
| commit | c8046900fd94baa5264e15a527c24346be024b73 (patch) | |
| tree | ff7734db04282a9503c06f8240a433c2e1cc33cd /src/components | |
| parent | Updates HeaderBar (diff) | |
Implements Scroll Button
Adds a scroll to top button to the landing page, and form pages to make
navigation easier on long pages.
Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/ScrollToTop.tsx | 87 | 
1 files changed, 87 insertions, 0 deletions
diff --git a/src/components/ScrollToTop.tsx b/src/components/ScrollToTop.tsx new file mode 100644 index 0000000..6af938d --- /dev/null +++ b/src/components/ScrollToTop.tsx @@ -0,0 +1,87 @@ +/** @jsx jsx */ +import { jsx, css } from "@emotion/react"; +import React from "react"; + +const styles = css` +  width: 2.5rem; +  height: 2.5rem; + +  position: fixed; +  bottom: 3rem; +  right: 3rem; +   +  background-color: #7289DA; /* Blurple */ +  border-radius: 50%; + +  opacity: 0; +  transition: opacity 300ms; +   +  :after { +    display: inline-block; +    content: ""; + +    position: fixed; +    bottom: 3.5rem; +    right: 3.65rem; +     +    border: solid whitesmoke; +    border-width: 0.35rem 0.35rem 0 0; +    padding: 0.4rem; + +    transform: rotate(-45deg); +  } +   +  @media (max-width: 800px) { +    bottom: 1.5rem; +    right: 1.5rem; +     +    :after { +      bottom: 2rem; +      right: 2.15rem; +    } +  } +`; + +let last_ref: React.RefObject<HTMLDivElement>; + +class ScrollToTop extends React.Component { +    constructor(props: Record<string, never>) { +        super(props); +        last_ref = React.createRef(); +    } + +    handleScroll(): void { +        if (!last_ref.current) return; + +        if (window.pageYOffset > 250) { +            last_ref.current.style.opacity = "1"; +        } else { +            last_ref.current.style.opacity = "0"; +        } +    } + +    componentDidMount(): void { +        // Register event handler +        window.addEventListener("scroll", this.handleScroll, {passive: true}); +    } + +    componentDidUpdate(): void { +        // Hide previous iterations, and register handler for current one +        if (last_ref.current) { +            last_ref.current.style.opacity = "0"; +        } + +        window.addEventListener("scroll", this.handleScroll, {passive: true}); +    } + +    componentWillUnmount(): void { +        // Unregister handler +        window.removeEventListener("scroll", this.handleScroll); +    } + +    render(): JSX.Element { +        return <div css={styles} key={Date.now()} ref={last_ref} onClick={() => window.scrollTo({top: 0, behavior: "smooth"})}/>; +    } +} + +export default ScrollToTop;  |