feat: create sticky version of components involved

Notices problems are
- Links in content area are higher (in terms of z value) than the sticky header.
- The sidebar header for table of contents seems to be positioned higher than it should.
- Text size of breadcrumb and title are too big.
- Flickering problem on pages that are short (less content/one page content).
This commit is contained in:
jumpyapple
2021-06-01 00:02:56 -04:00
committed by Jean-Philippe Sirois
parent 5ba1e86672
commit 8a5970107f
2 changed files with 122 additions and 13 deletions
+59 -13
View File
@@ -17,7 +17,7 @@ interface IBoxedTitleProps {
}
type HeaderBareboneState = {
scrollY: Number
scrollY: number
}
const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
@@ -39,6 +39,29 @@ const BoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
)
}
const StickyBoxedTitle: React.FC<IBoxedTitleProps> = (props) => {
return (
<SC.StickyBox>
{props.above}
<SC.Title
className={cx({
"has-content-above": props.above,
"has-content-below": props.content,
})}
>
{props.children}
</SC.Title>
{props.content}
</SC.StickyBox>
)
}
const StickyContainer: React.FC = ({ children, ...restProps }) => {
return <SC.StickyContainerWrapper {...restProps}>{children}</SC.StickyContainerWrapper>
}
const debounce = (fn) => {
let frame
return (...params) => {
@@ -52,11 +75,15 @@ const debounce = (fn) => {
}
export class HeaderBarebone extends Component<IHeaderBareboneProps, HeaderBareboneState> {
controller: AbortController
state: HeaderBareboneState = {
scrollY: 0
}
constructor(props) {
super(props)
this.tick = this.tick.bind(this)
this.state = { scrollY: 0 }
this.controller = new AbortController()
}
tick() {
@@ -67,32 +94,51 @@ export class HeaderBarebone extends Component<IHeaderBareboneProps, HeaderBarebo
}
}
componentWillMount() {
componentDidMount() {
document.addEventListener('scroll', debounce(this.tick), { passive: true, signal: this.controller.signal })
this.tick()
}
componentDidMount() {
document.addEventListener('scroll', debounce(this.tick), { passive: true })
componentWillUnmount() {
this.controller.abort()
}
render() {
const props = this.props;
const isBoxed = props.above || props.content
return (
if (this.state.scrollY <= 250) {
return (
<SC.HeaderWrapper className={props.className}>
<SC.Background />
<SC.Background />
<Container>
{(isBoxed && this.state.scrollY < 30) && (
<BoxedTitle above={props.above} content={props.content}>
<Container>
{isBoxed && (
<BoxedTitle above={props.above} content={props.content}>
{props.title}
</BoxedTitle>
</BoxedTitle>
)}
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
</Container>
</Container>
</SC.HeaderWrapper>
)
)
} else {
return (
<SC.HeaderWrapperSticky className={props.className}>
<SC.Background />
<StickyContainer>
{isBoxed && (
<StickyBoxedTitle above={props.above}>
{props.title}
</StickyBoxedTitle>
)}
{!isBoxed && <SC.SingleTitle>{props.title}</SC.SingleTitle>}
</StickyContainer>
</SC.HeaderWrapperSticky>
)
}
}
}
+63
View File
@@ -9,6 +9,11 @@ import HeaderMobile from "../../images/header-mobile-375x300.png"
const spaceAbove = 67
const height = 300 - spaceAbove
export const StickyContainerWrapper = styled.div`
margin: 0;
width: 100%;
`
export const HeaderWrapper = styled.div`
display: flex;
width: 100%;
@@ -34,6 +39,31 @@ export const HeaderWrapper = styled.div`
}
`
export const HeaderWrapperSticky = styled.div`
display: flex;
width: 100%;
height: 7px;
padding-top: ${spaceAbove}px;
position: fixed;
&.shifted {
width: calc(100% - 305px);
padding-right: 305px;
}
@media screen and (max-width: 1200px) {
width: 100% !important;
padding-right: 0 !important;
}
@media screen and (max-width: 767px) {
display: flex;
align-items: flex-end;
height: auto;
min-height: ${height}px;
}
`
export const Background = styled.div`
position: absolute;
top: 0;
@@ -99,6 +129,39 @@ export const Box = styled.div`
}
`
export const StickyBox = styled.div`
display: inline-flex;
flex-direction: column;
position: absolute;
bottom: 0;
background: ${(props) => transparentize(0.3, props.theme.main.background)};
padding: 16px;
backdrop-filter: blur(14px);
width: 100%;
@media screen and (max-width: 1200px) {
max-width: 100%;
left: 32px;
right: 32px;
margin-left: 0;
}
@media screen and (max-width: 767px) {
position: static;
bottom: auto;
top: auto;
margin: 32px 0;
left: 0px;
right: 0px;
@-moz-document url-prefix() {
& {
position: relative;
}
}
}
`
const title = css`
font-family: ${fontFamily.header};
font-size: 34px;