From c8046900fd94baa5264e15a527c24346be024b73 Mon Sep 17 00:00:00 2001
From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com>
Date: Mon, 4 Jan 2021 02:33:35 +0300
Subject: 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 <47495861+HassanAbouelela@users.noreply.github.com>
---
 src/components/ScrollToTop.tsx | 87 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 src/components/ScrollToTop.tsx

(limited to 'src/components/ScrollToTop.tsx')

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;
-- 
cgit v1.2.3

