mirror of
https://github.com/BradNut/awesome-uses
synced 2025-09-08 17:40:31 +00:00
make the scroll to top better
This commit is contained in:
parent
9dab2205f1
commit
124bdd6434
7 changed files with 80 additions and 18 deletions
|
|
@ -56,7 +56,6 @@ function sourceNodes({ actions, createNodeId, createContentDigest }) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add Devices to GraphQL API
|
// Add Devices to GraphQL API
|
||||||
console.log(devices());
|
|
||||||
devices().forEach(device => {
|
devices().forEach(device => {
|
||||||
const nodeMeta = {
|
const nodeMeta = {
|
||||||
id: createNodeId(`device-${device.name}`),
|
id: createNodeId(`device-${device.name}`),
|
||||||
|
|
|
||||||
56
src/components/BackToTop.js
Normal file
56
src/components/BackToTop.js
Normal file
|
|
@ -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 (
|
||||||
|
<BackToTopLink href="#top" title="Back To Top" percent={percent}>
|
||||||
|
↑
|
||||||
|
</BackToTopLink>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,31 @@
|
||||||
import React from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { name } from 'country-emoji';
|
import { name } from 'country-emoji';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Tag, Tags } from './Topics';
|
import { Tag, Tags } from './Topics';
|
||||||
import * as icons from '../util/icons';
|
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 }) {
|
export default function Person({ person, currentTag }) {
|
||||||
const url = new URL(person.url);
|
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`;
|
const img = `https://images.weserv.nl/?url=https://unavatar.now.sh/${url.host}&w=100&l=9&af&il&n=-1`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PersonWrapper>
|
<PersonWrapper>
|
||||||
<PersonInner>
|
<PersonInner>
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ const GlobalStyle = createGlobalStyle`
|
||||||
font-family: 'Fira Mono', monospace;
|
font-family: 'Fira Mono', monospace;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { createContext, useState } from 'react';
|
import React, { createContext, useState } from 'react';
|
||||||
import { useStaticQuery, graphql } from 'gatsby';
|
import { useStaticQuery, graphql } from 'gatsby';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const FilterContext = createContext();
|
const FilterContext = createContext();
|
||||||
|
|
||||||
|
|
@ -45,7 +46,7 @@ const FilterProvider = function({ children }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterProvider.propTypes = {
|
FilterProvider.propTypes = {
|
||||||
children: React.Children,
|
children: PropTypes.element,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FilterContext;
|
export default FilterContext;
|
||||||
|
|
|
||||||
|
|
@ -2727,7 +2727,6 @@ module.exports = [
|
||||||
'YouTuber',
|
'YouTuber',
|
||||||
'JavaScript',
|
'JavaScript',
|
||||||
'TypeScript',
|
'TypeScript',
|
||||||
'Node',
|
|
||||||
'React',
|
'React',
|
||||||
'Node',
|
'Node',
|
||||||
'CSS',
|
'CSS',
|
||||||
|
|
@ -3699,7 +3698,6 @@ module.exports = [
|
||||||
'React',
|
'React',
|
||||||
'TypeScript',
|
'TypeScript',
|
||||||
'JavaScript',
|
'JavaScript',
|
||||||
'React',
|
|
||||||
'Node',
|
'Node',
|
||||||
'CSS',
|
'CSS',
|
||||||
],
|
],
|
||||||
|
|
@ -4065,7 +4063,6 @@ module.exports = [
|
||||||
phone: 'iphone',
|
phone: 'iphone',
|
||||||
tags: [
|
tags: [
|
||||||
'Architect',
|
'Architect',
|
||||||
'Developer',
|
|
||||||
'SitecoreJSS',
|
'SitecoreJSS',
|
||||||
'Sitecore',
|
'Sitecore',
|
||||||
'React',
|
'React',
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,7 @@ import FilterContext from '../context/FilterContext';
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
import Person from '../components/Person';
|
import Person from '../components/Person';
|
||||||
import Topics from '../components/Topics';
|
import Topics from '../components/Topics';
|
||||||
|
import BackToTop from '../components/BackToTop';
|
||||||
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;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function IndexPage() {
|
function IndexPage() {
|
||||||
const { currentTag } = useContext(FilterContext);
|
const { currentTag } = useContext(FilterContext);
|
||||||
|
|
@ -54,7 +44,7 @@ function IndexPage() {
|
||||||
<Person key={person.name} person={person} currentTag={currentTag} />
|
<Person key={person.name} person={person} currentTag={currentTag} />
|
||||||
))}
|
))}
|
||||||
</People>
|
</People>
|
||||||
<BackToTopLink href="#top">↑ Back to top</BackToTopLink>
|
<BackToTop />
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue