From 38e1a4ba564f62c9a770ef4e0bebf6f7db364918 Mon Sep 17 00:00:00 2001 From: jumpyapple <70656949+jumpyapple@users.noreply.github.com> Date: Wed, 3 Mar 2021 02:17:10 -0500 Subject: [PATCH] feat: add a proof of concept Using debouncing idea described in https://css-tricks.com/styling-based-on-scroll-position/ to record scrollY value and render the `BoxedTitle` base on the value. The box is hidden when scrollY is greater than 30. The class-style React component is used to register an event listener for scrolling event. --- src/components/HeaderBarebone/index.tsx | 76 +++++++++++++++++++------ 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/src/components/HeaderBarebone/index.tsx b/src/components/HeaderBarebone/index.tsx index c6a4456..edd4210 100644 --- a/src/components/HeaderBarebone/index.tsx +++ b/src/components/HeaderBarebone/index.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { Component } from "react" import cx from "classnames" import * as SC from "./styles" @@ -16,6 +16,10 @@ interface IBoxedTitleProps { content?: React.ReactNode } +type HeaderBareboneState = { + scrollY: Number +} + const BoxedTitle: React.FC = (props) => { return ( @@ -35,22 +39,58 @@ const BoxedTitle: React.FC = (props) => { ) } -export const HeaderBarebone: React.FC = (props) => { - const isBoxed = props.above || props.content - return ( - - - - - {isBoxed && ( - - {props.title} - - )} - - {!isBoxed && {props.title}} - - - ) +const debounce = (fn) => { + let frame + return (...params) => { + if (frame) { + cancelAnimationFrame(frame) + } + frame = requestAnimationFrame(() => { + fn(...params) + }) + } +} + +export class HeaderBarebone extends Component { + + constructor(props) { + super(props) + this.tick = this.tick.bind(this) + } + + tick() { + this.setState({ + scrollY: window.scrollY + }) + } + + componentWillMount() { + this.tick() + } + + componentDidMount() { + document.addEventListener('scroll', debounce(this.tick), { passive: true }) + } + + render() { + const props = this.props; + const isBoxed = props.above || props.content + + return ( + + + + + {(isBoxed && this.state.scrollY < 30) && ( + + {props.title} + + )} + + {!isBoxed && {props.title}} + + + ) + } }