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.
This commit is contained in:
jumpyapple
2021-06-01 00:02:56 -04:00
committed by Jean-Philippe Sirois
parent 47f811373c
commit 38e1a4ba56
+58 -18
View File
@@ -1,4 +1,4 @@
import React from "react" import React, { Component } from "react"
import cx from "classnames" import cx from "classnames"
import * as SC from "./styles" import * as SC from "./styles"
@@ -16,6 +16,10 @@ interface IBoxedTitleProps {
content?: React.ReactNode content?: React.ReactNode
} }
type HeaderBareboneState = {
scrollY: Number
}
const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => { const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
return ( return (
<SC.Box> <SC.Box>
@@ -35,22 +39,58 @@ const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
) )
} }
export const HeaderBarebone: React.FC<IHeaderBareboneProps> = (props) => {
const isBoxed = props.above || props.content
return ( const debounce = (fn) => {
<SC.HeaderWrapper className={props.className}> let frame
<SC.Background /> return (...params) => {
if (frame) {
<Container> cancelAnimationFrame(frame)
{isBoxed && ( }
<BoxedTitle above={props.above} content={props.content}> frame = requestAnimationFrame(() => {
{props.title} fn(...params)
</BoxedTitle> })
)} }
}
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
</Container> export class HeaderBarebone extends Component<IHeaderBareboneProps, HeaderBareboneState> {
</SC.HeaderWrapper>
) 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 (
<SC.HeaderWrapper className={props.className}>
<SC.Background />
<Container>
{(isBoxed && this.state.scrollY < 30) && (
<BoxedTitle above={props.above} content={props.content}>
{props.title}
</BoxedTitle>
)}
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
</Container>
</SC.HeaderWrapper>
)
}
} }