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; |