gatsby-theme-try-ghost
Version:
A Gatsby theme for building flaring fast blogs from headless Ghost CMS.
79 lines (62 loc) • 2.23 kB
JavaScript
import React from 'react'
import PropTypes from 'prop-types'
const throttle = require(`lodash.throttle`)
export default class StickyNavContainer extends React.Component {
constructor(props) {
super(props)
this.scrollHandler = this.scrollHandler.bind(this)
this.resizeHandler = this.resizeHandler.bind(this)
this.anchorRef = React.createRef()
this.activeClass = this.props.activeClass,
this.isPost = this.props.isPost || false,
this.state = {
ticking: false,
}
}
scrollHandler = () => {}
resizeHandler = () => {}
componentDidMount() {
this.scrollHandler = throttle(this.onScroll, this.props.throttle)
this.resizeHandler = throttle(this.onScroll, this.props.throttle)
window.addEventListener(`scroll`, this.scrollHandler, { passive: true })
window.addEventListener(`resize`, this.resizeHandler, { passive: true })
}
componentWillUnmount() {
window.removeEventListener(`scroll`, this.scrollHandler)
window.removeEventListener(`resize`, this.resizeHandler)
}
onScroll = () => {
this.setState({ lastScrollY: window.scrollY })
this.requestTick()
}
requestTick = () => {
if (!this.state.ticking) {
requestAnimationFrame(this.update)
}
this.setState({ ticking: false })
}
update = () => {
const current = this.anchorRef && this.anchorRef.current
var top = current && current.getBoundingClientRect().top
var trigger = top + window.scrollY
var triggerOffset = -20
if (this.isPost){
triggerOffset = current && current.offsetHeight + 35
}
if (this.state.lastScrollY >= trigger + triggerOffset) {
this.setState({ currentClass: this.activeClass })
} else {
this.setState({ currentClass: `` })
}
this.setState({ ticking: false })
}
render() {
return this.props.render(this)
}
}
StickyNavContainer.propTypes = {
render: PropTypes.func.isRequired,
activeClass: PropTypes.string.isRequired,
throttle: PropTypes.number.isRequired,
isPost: PropTypes.bool,
}