mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 09:15:58 +02:00
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:
committed by
Jean-Philippe Sirois
parent
5ba1e86672
commit
8a5970107f
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user