1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2025-02-14 21:10:41 +01:00

project nav refactor

This commit is contained in:
Matthias Kretschmann 2021-03-13 17:42:21 +01:00
parent fbd0f39d71
commit 04f51eb0d7
Signed by: m
GPG Key ID: 606EEEF3C479A91F
4 changed files with 53 additions and 74 deletions

View File

@ -23,6 +23,7 @@
grid-column: main; grid-column: main;
} }
/* Projects Grid */
.grid { .grid {
display: grid; display: grid;
gap: calc(var(--spacer) * 2); gap: calc(var(--spacer) * 2);
@ -31,6 +32,7 @@
@media (min-width: 55rem) { @media (min-width: 55rem) {
.grid { .grid {
gap: calc(var(--spacer) * 3);
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr)); grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
} }
} }

View File

@ -33,3 +33,9 @@ export const projectImageTeaser = graphql`
gatsbyImageData(layout: CONSTRAINED, width: 740, quality: 85) gatsbyImageData(layout: CONSTRAINED, width: 740, quality: 85)
} }
` `
export const projectImageNav = graphql`
fragment ProjectImageNav on ImageSharp {
gatsbyImageData(layout: CONSTRAINED, width: 500, quality: 85)
}
`

View File

@ -1,9 +1,8 @@
import React, { PureComponent } from 'react' import React, { useEffect } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Link, graphql, StaticQuery } from 'gatsby' import { Link, graphql, useStaticQuery } from 'gatsby'
import shortid from 'shortid'
import ProjectImage from '../atoms/ProjectImage' import ProjectImage from '../atoms/ProjectImage'
import { item, link, title, projectNav } from './ProjectNav.module.css' import { item, projectNav } from './ProjectNav.module.css'
const query = graphql` const query = graphql`
query { query {
@ -14,7 +13,7 @@ const query = graphql`
slug slug
img { img {
childImageSharp { childImageSharp {
gatsbyImageData(layout: CONSTRAINED, width: 500, quality: 85) ...ProjectImageNav
} }
} }
} }
@ -24,15 +23,12 @@ const query = graphql`
` `
const Project = ({ node, refCurrentItem }) => ( const Project = ({ node, refCurrentItem }) => (
<div className={item} ref={refCurrentItem}> <Link className={item} to={node.slug} title={node.title} ref={refCurrentItem}>
<Link className={link} to={node.slug}> <ProjectImage
<ProjectImage image={node.img.childImageSharp.gatsbyImageData}
image={node.img.childImageSharp.gatsbyImageData} alt={node.title}
alt={node.title} />
/> </Link>
<h1 className={title}>{node.title}</h1>
</Link>
</div>
) )
Project.propTypes = { Project.propTypes = {
@ -40,67 +36,50 @@ Project.propTypes = {
refCurrentItem: PropTypes.any refCurrentItem: PropTypes.any
} }
export default class ProjectNav extends PureComponent { export default function ProjectNav({ currentSlug }) {
static propTypes = { const data = useStaticQuery(query)
currentSlug: PropTypes.string.isRequired const projects = data.allProjectsYaml.edges
}
state = { // Always keep the scroll position centered
scrollLeftPosition: 0 // to currently viewed project on mount.
} const scrollContainer = React.createRef()
const currentItem = React.createRef()
scrollContainer = React.createRef() function scrollToCurrent() {
currentItem = React.createRef() const activeItem = currentItem.current
const scrollRect = scrollContainer.current.getBoundingClientRect()
componentDidMount() {
this.scrollToCurrent()
}
componentDidUpdate() {
this.scrollToCurrent()
}
scrollToCurrent = () => {
const scrollContainer = this.scrollContainer.current
const activeItem = this.currentItem.current
const scrollRect = scrollContainer.getBoundingClientRect()
const activeRect = activeItem && activeItem.getBoundingClientRect() const activeRect = activeItem && activeItem.getBoundingClientRect()
const scrollLeftPosition = const newScrollLeftPosition =
activeRect && activeRect &&
activeRect.left - activeRect.left -
scrollRect.left - scrollRect.left -
scrollRect.width / 2 + scrollRect.width / 2 +
activeRect.width / 2 activeRect.width / 2
scrollContainer.scrollLeft += this.state.scrollLeftPosition scrollContainer.current.scrollLeft += newScrollLeftPosition
this.setState({ scrollLeftPosition })
} }
render() { useEffect(() => {
const { currentSlug } = this.props scrollToCurrent()
return ( }, [])
<StaticQuery
query={query}
render={(data) => {
const projects = data.allProjectsYaml.edges
return ( return (
<nav className={projectNav} ref={this.scrollContainer}> <nav className={projectNav} ref={scrollContainer}>
{projects.map(({ node }) => { {projects.map(({ node }) => {
const isCurrent = node.slug === currentSlug const isCurrent = node.slug === currentSlug
return ( return (
<Project <Project
key={shortid.generate()} key={node.slug}
node={node} node={node}
refCurrentItem={isCurrent ? this.currentItem : null} refCurrentItem={isCurrent ? currentItem : null}
/> />
) )
})} })}
</nav> </nav>
) )
}} }
/>
) ProjectNav.propTypes = {
} currentSlug: PropTypes.string.isRequired
} }

View File

@ -4,6 +4,7 @@
overflow-y: hidden; overflow-y: hidden;
overflow-x: auto; overflow-x: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
padding-bottom: var(--spacer);
} }
.projectNav::-webkit-scrollbar, .projectNav::-webkit-scrollbar,
@ -17,7 +18,7 @@
} }
.projectNav::-webkit-scrollbar-thumb { .projectNav::-webkit-scrollbar-thumb {
background: var(--brand-grey-dimmed); background: var(--text-color);
} }
.projectNav::-webkit-scrollbar-track { .projectNav::-webkit-scrollbar-track {
@ -41,12 +42,3 @@
margin-left: calc(var(--spacer) * 2); margin-left: calc(var(--spacer) * 2);
} }
} }
.title {
visibility: hidden;
font-size: 0;
}
.link {
display: block;
}