diff options
| author | 2021-01-04 02:33:35 +0300 | |
|---|---|---|
| committer | 2021-01-06 09:35:54 +0300 | |
| commit | c8046900fd94baa5264e15a527c24346be024b73 (patch) | |
| tree | ff7734db04282a9503c06f8240a433c2e1cc33cd /src | |
| 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')
| -rw-r--r-- | src/components/ScrollToTop.tsx | 87 | ||||
| -rw-r--r-- | src/pages/LandingPage.tsx | 7 | 
2 files changed, 91 insertions, 3 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; diff --git a/src/pages/LandingPage.tsx b/src/pages/LandingPage.tsx index 124bbcf..af968ad 100644 --- a/src/pages/LandingPage.tsx +++ b/src/pages/LandingPage.tsx @@ -4,10 +4,11 @@ import { useEffect, useState } from "react";  import HeaderBar from "../components/HeaderBar";  import FormListing from "../components/FormListing"; - -import { getForms, Form } from "../api/forms";  import OAuth2Button from "../components/OAuth2Button";  import Loading from "../components/Loading"; +import ScrollToTop from "../components/ScrollToTop"; + +import { getForms, Form } from "../api/forms";  function LandingPage(): JSX.Element {      const [forms, setForms] = useState<Form[]>(); @@ -25,8 +26,8 @@ function LandingPage(): JSX.Element {      return <div>          <HeaderBar/> +        <ScrollToTop/>          <div> -              <div css={css`          display: flex;          align-items: center; | 
