From 124bdd64345bc64eb84879929f0e57cbb8752e34 Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Wed, 22 Jan 2020 12:14:25 -0500 Subject: [PATCH] make the scroll to top better --- gatsby-node.js | 1 - src/components/BackToTop.js | 56 ++++++++++++++++++++++++++++++++++++ src/components/Person.js | 20 ++++++++++++- src/components/layout.js | 1 + src/context/FilterContext.js | 3 +- src/data.js | 3 -- src/pages/index.js | 14 ++------- 7 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 src/components/BackToTop.js diff --git a/gatsby-node.js b/gatsby-node.js index f28b49d8..8f64c729 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -56,7 +56,6 @@ function sourceNodes({ actions, createNodeId, createContentDigest }) { }); // Add Devices to GraphQL API - console.log(devices()); devices().forEach(device => { const nodeMeta = { id: createNodeId(`device-${device.name}`), diff --git a/src/components/BackToTop.js b/src/components/BackToTop.js new file mode 100644 index 00000000..faaab8a1 --- /dev/null +++ b/src/components/BackToTop.js @@ -0,0 +1,56 @@ +import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; + +const BackToTopLink = styled.a` + position: fixed; + bottom: 1%; + right: 1%; + background: var(--pink); + color: white; + background: rgba(0, 0, 0, 0.5); + cursor: pointer; + border-radius: 3px; + padding: 1rem; + transition: opacity 0.2s; + opacity: 0; + text-decoration: none; + ${props => + props.percent > 0.25 && + ` + opacity: 1; + `} + @media screen and (max-width: 500px) { + display: none; + } +`; + +function useScrollPosition() { + const [percent, setPercent] = useState(0); + + function handleScroll(event) { + console.log(document.documentElement.scrollTop); + const howFar = + document.documentElement.scrollTop / + document.documentElement.scrollTopMax; + setPercent(howFar); + } + + useEffect(() => { + // listen for window scroll event + document.addEventListener('scroll', handleScroll); + return () => { + document.removeEventListener('scroll', handleScroll); + }; + }); + + return percent; +} + +export default function BackToTop() { + const percent = useScrollPosition(); + return ( + + ↑ + + ); +} diff --git a/src/components/Person.js b/src/components/Person.js index baddbbdb..9c9cef83 100644 --- a/src/components/Person.js +++ b/src/components/Person.js @@ -1,13 +1,31 @@ -import React from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import { name } from 'country-emoji'; import styled from 'styled-components'; import { Tag, Tags } from './Topics'; import * as icons from '../util/icons'; +function useIntersectionObserver(ref) { + const [isIntersecting, setIntersecting] = useState(false); + + useEffect(function() { + const observer = new IntersectionObserver(function([entry]) { + console.log('Run once for every time its on screen'); + console.log(entry); + }); + // Observe the element we want to observve + observer.observe(ref.current); + + return () => { + observer.unobserve(ref.current); + }; + }); +} + export default function Person({ person, currentTag }) { const url = new URL(person.url); const img = `https://images.weserv.nl/?url=https://unavatar.now.sh/${url.host}&w=100&l=9&af&il&n=-1`; + return ( diff --git a/src/components/layout.js b/src/components/layout.js index bef6c484..17e50fdf 100644 --- a/src/components/layout.js +++ b/src/components/layout.js @@ -85,6 +85,7 @@ const GlobalStyle = createGlobalStyle` font-family: 'Fira Mono', monospace; font-weight: 100; font-size: 10px; + scroll-behavior: smooth; } body { font-size: 2rem; diff --git a/src/context/FilterContext.js b/src/context/FilterContext.js index e3f32206..c1d9b98e 100644 --- a/src/context/FilterContext.js +++ b/src/context/FilterContext.js @@ -1,5 +1,6 @@ import React, { createContext, useState } from 'react'; import { useStaticQuery, graphql } from 'gatsby'; +import PropTypes from 'prop-types'; const FilterContext = createContext(); @@ -45,7 +46,7 @@ const FilterProvider = function({ children }) { }; FilterProvider.propTypes = { - children: React.Children, + children: PropTypes.element, }; export default FilterContext; diff --git a/src/data.js b/src/data.js index 9a1754bb..03752bd2 100644 --- a/src/data.js +++ b/src/data.js @@ -2727,7 +2727,6 @@ module.exports = [ 'YouTuber', 'JavaScript', 'TypeScript', - 'Node', 'React', 'Node', 'CSS', @@ -3699,7 +3698,6 @@ module.exports = [ 'React', 'TypeScript', 'JavaScript', - 'React', 'Node', 'CSS', ], @@ -4065,7 +4063,6 @@ module.exports = [ phone: 'iphone', tags: [ 'Architect', - 'Developer', 'SitecoreJSS', 'Sitecore', 'React', diff --git a/src/pages/index.js b/src/pages/index.js index 0519dd91..14a6d27f 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -6,17 +6,7 @@ import FilterContext from '../context/FilterContext'; import Layout from '../components/layout'; import Person from '../components/Person'; import Topics from '../components/Topics'; - -const BackToTopLink = styled.a` - position: fixed; - bottom: 1%; - right: 1%; - background: var(--pink); - cursor: pointer; - border-radius: 3px; - padding: 1rem; - transition: background-color 0.2s ease 0s; -`; +import BackToTop from '../components/BackToTop'; function IndexPage() { const { currentTag } = useContext(FilterContext); @@ -54,7 +44,7 @@ function IndexPage() { ))} - ↑ Back to top + ); }