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 1/8] 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}} + + + ) + } } From 5ba1e86672d1fcfe48660024312eaacc532bd82f Mon Sep 17 00:00:00 2001 From: jumpyapple <70656949+jumpyapple@users.noreply.github.com> Date: Wed, 3 Mar 2021 02:46:47 -0500 Subject: [PATCH 2/8] fix: window is not available during gatsby build Check if window is available, and set initial value for `state.scrollY`. --- src/components/HeaderBarebone/index.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/HeaderBarebone/index.tsx b/src/components/HeaderBarebone/index.tsx index edd4210..17bc6e4 100644 --- a/src/components/HeaderBarebone/index.tsx +++ b/src/components/HeaderBarebone/index.tsx @@ -39,7 +39,6 @@ const BoxedTitle: React.FC = (props) => { ) } - const debounce = (fn) => { let frame return (...params) => { @@ -57,12 +56,15 @@ export class HeaderBarebone extends Component Date: Fri, 12 Mar 2021 17:44:15 -0500 Subject: [PATCH 3/8] 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). --- src/components/HeaderBarebone/index.tsx | 72 +++++++++++++++++++----- src/components/HeaderBarebone/styles.tsx | 63 +++++++++++++++++++++ 2 files changed, 122 insertions(+), 13 deletions(-) diff --git a/src/components/HeaderBarebone/index.tsx b/src/components/HeaderBarebone/index.tsx index 17bc6e4..a0fe2db 100644 --- a/src/components/HeaderBarebone/index.tsx +++ b/src/components/HeaderBarebone/index.tsx @@ -17,7 +17,7 @@ interface IBoxedTitleProps { } type HeaderBareboneState = { - scrollY: Number + scrollY: number } const BoxedTitle: React.FC = (props) => { @@ -39,6 +39,29 @@ const BoxedTitle: React.FC = (props) => { ) } +const StickyBoxedTitle: React.FC = (props) => { + return ( + + {props.above} + + + {props.children} + + + {props.content} + + ) +} + +const StickyContainer: React.FC = ({ children, ...restProps }) => { + return {children} +} + const debounce = (fn) => { let frame return (...params) => { @@ -52,11 +75,15 @@ const debounce = (fn) => { } export class HeaderBarebone extends Component { + 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 - + - - {(isBoxed && this.state.scrollY < 30) && ( - + + {isBoxed && ( + {props.title} - + )} {!isBoxed && {props.title}} - + - ) + ) + } else { + return ( + + + + + {isBoxed && ( + + {props.title} + + )} + + {!isBoxed && {props.title}} + + + ) + } } } diff --git a/src/components/HeaderBarebone/styles.tsx b/src/components/HeaderBarebone/styles.tsx index 95c4207..ecce209 100644 --- a/src/components/HeaderBarebone/styles.tsx +++ b/src/components/HeaderBarebone/styles.tsx @@ -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; From fdb6083c6b00331c0530670d03f449b3d82b63ca Mon Sep 17 00:00:00 2001 From: jumpyapple <70656949+jumpyapple@users.noreply.github.com> Date: Fri, 12 Mar 2021 20:40:58 -0500 Subject: [PATCH 4/8] fix: AbortController not found, resize text in Box --- src/components/HeaderBarebone/index.tsx | 6 +++--- src/components/HeaderBarebone/styles.tsx | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/HeaderBarebone/index.tsx b/src/components/HeaderBarebone/index.tsx index a0fe2db..d5e3e7e 100644 --- a/src/components/HeaderBarebone/index.tsx +++ b/src/components/HeaderBarebone/index.tsx @@ -44,14 +44,14 @@ const StickyBoxedTitle: React.FC = (props) => { {props.above} - {props.children} - + {props.content} @@ -83,7 +83,6 @@ export class HeaderBarebone extends Component transparentize(0.3, props.theme.main.background)}; - padding: 16px; + padding: 0px 0px 16px 30px; backdrop-filter: blur(14px); width: 100%; + font-size: 16px @media screen and (max-width: 1200px) { max-width: 100%; @@ -183,6 +184,15 @@ export const Title = styled.h1` } ` +export const StickyTitle = styled.h1` + ${title}; + font-size: 20px; + + &.has-content-below { + margin-bottom: 16px; + px; +` + export const SingleTitle = styled(Title)` ${title}; color: #fff; From cc740502e9d90b7317919b52ed6d9e15ef10f84e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Mon, 31 May 2021 23:19:41 -0400 Subject: [PATCH 5/8] fix: move to a more stable scroll API to avoid jumping --- package-lock.json | 216 ++++++++++++++++++++++++ package.json | 1 + src/components/HeaderBarebone/index.tsx | 142 +++++++--------- src/components/PageContent/styles.tsx | 2 +- 4 files changed, 276 insertions(+), 85 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8296b0a..2696807 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3060,6 +3060,11 @@ "@types/istanbul-lib-report": "*" } }, + "@types/js-cookie": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.6.tgz", + "integrity": "sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==" + }, "@types/js-yaml": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.1.tgz", @@ -3749,6 +3754,11 @@ "@xtuc/long": "4.2.2" } }, + "@xobotyi/scrollbar-width": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6691,6 +6701,14 @@ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, + "copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "copyfiles": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", @@ -6912,6 +6930,15 @@ "timsort": "^0.3.0" } }, + "css-in-js-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", + "requires": { + "hyphenate-style-name": "^1.0.2", + "isobject": "^3.0.1" + } + }, "css-loader": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", @@ -9275,11 +9302,21 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, + "fast-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", + "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" + }, "fastest-levenshtein": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" }, + "fastest-stable-stringify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==" + }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -12233,6 +12270,11 @@ "ms": "^2.0.0" } }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -12619,6 +12661,14 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, + "inline-style-prefixer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz", + "integrity": "sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg==", + "requires": { + "css-in-js-utils": "^2.0.0" + } + }, "inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", @@ -13471,6 +13521,11 @@ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" }, + "js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -15276,6 +15331,47 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" }, + "nano-css": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.1.tgz", + "integrity": "sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==", + "requires": { + "css-tree": "^1.1.2", + "csstype": "^3.0.6", + "fastest-stable-stringify": "^2.0.2", + "inline-style-prefixer": "^6.0.0", + "rtl-css-js": "^1.14.0", + "sourcemap-codec": "^1.4.8", + "stacktrace-js": "^2.0.2", + "stylis": "^4.0.6" + }, + "dependencies": { + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -18146,6 +18242,44 @@ "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==" }, + "react-universal-interface": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", + "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==" + }, + "react-use": { + "version": "17.2.4", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.2.4.tgz", + "integrity": "sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==", + "requires": { + "@types/js-cookie": "^2.2.6", + "@xobotyi/scrollbar-width": "^1.9.5", + "copy-to-clipboard": "^3.3.1", + "fast-deep-equal": "^3.1.3", + "fast-shallow-equal": "^1.0.0", + "js-cookie": "^2.2.1", + "nano-css": "^5.3.1", + "react-universal-interface": "^0.6.2", + "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.1.0", + "set-harmonic-interval": "^1.0.1", + "throttle-debounce": "^3.0.1", + "ts-easing": "^0.2.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + } + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -19019,6 +19153,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -19130,6 +19269,14 @@ "inherits": "^2.0.1" } }, + "rtl-css-js": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.14.1.tgz", + "integrity": "sha512-G9N1s/6329FpJr8k9e1U/Lg0IDWThv99sb7k0IrXHjSnubxe01h52/ajsPRafJK1/2Vqrhz3VKLe3E1dx6jS9Q==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -19219,6 +19366,11 @@ "ajv-keywords": "^3.5.2" } }, + "screenfull": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.1.0.tgz", + "integrity": "sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA==" + }, "scuid": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", @@ -19459,6 +19611,11 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "set-harmonic-interval": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", + "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==" + }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -19974,6 +20131,11 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, "space-separated-tokens": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", @@ -20161,6 +20323,14 @@ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" }, + "stack-generator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.5.tgz", + "integrity": "sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q==", + "requires": { + "stackframe": "^1.1.1" + } + }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -20171,6 +20341,32 @@ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" }, + "stacktrace-gps": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz", + "integrity": "sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg==", + "requires": { + "source-map": "0.5.6", + "stackframe": "^1.1.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + } + } + }, + "stacktrace-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", + "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "requires": { + "error-stack-parser": "^2.0.6", + "stack-generator": "^2.0.5", + "stacktrace-gps": "^3.0.4" + } + }, "state-toggle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", @@ -20533,6 +20729,11 @@ } } }, + "stylis": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", + "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + }, "subscriptions-transport-ws": { "version": "0.9.18", "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz", @@ -20958,6 +21159,11 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, + "throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -21115,6 +21321,11 @@ "repeat-string": "^1.6.1" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -21167,6 +21378,11 @@ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" }, + "ts-easing": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" + }, "ts-log": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.3.tgz", diff --git a/package.json b/package.json index 2f65b73..ce672f6 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "react-particles-js": "^3.4.1", "react-perfect-scrollbar": "^1.5.8", "react-scrollspy": "^3.4.3", + "react-use": "^17.2.4", "styled-components": "^5.2.1", "typescript": "^3.9.3", "uuid": "^8.3.1" diff --git a/src/components/HeaderBarebone/index.tsx b/src/components/HeaderBarebone/index.tsx index d5e3e7e..c979fd0 100644 --- a/src/components/HeaderBarebone/index.tsx +++ b/src/components/HeaderBarebone/index.tsx @@ -1,4 +1,5 @@ -import React, { Component } from "react" +import React, { useEffect, useState } from "react" +import { useDebounce, useWindowScroll } from "react-use" import cx from "classnames" import * as SC from "./styles" @@ -16,10 +17,6 @@ interface IBoxedTitleProps { content?: React.ReactNode } -type HeaderBareboneState = { - scrollY: number -} - const BoxedTitle: React.FC = (props) => { return ( @@ -59,86 +56,63 @@ const StickyBoxedTitle: React.FC = (props) => { } const StickyContainer: React.FC = ({ children, ...restProps }) => { - return {children} + return ( + + {children} + + ) } -const debounce = (fn) => { - let frame - return (...params) => { - if (frame) { - cancelAnimationFrame(frame) +export const HeaderBarebone = (props: IHeaderBareboneProps) => { + const { y } = useWindowScroll() + const [scrollY, setScrollY] = useState(0) + + const [, cancel] = useDebounce( + () => { + setScrollY(y) + }, + 10, + [y] + ) + + useEffect(() => { + return () => { + cancel() } - frame = requestAnimationFrame(() => { - fn(...params) - }) - } -} - -export class HeaderBarebone extends Component { - controller: AbortController - state: HeaderBareboneState = { - scrollY: 0 - } - - constructor(props) { - super(props) - this.tick = this.tick.bind(this) - } - - tick() { - if (typeof window !== 'undefined') { - this.setState({ - scrollY: window.scrollY - }) - } - } - - componentDidMount() { - this.controller = new AbortController() - document.addEventListener('scroll', debounce(this.tick), { passive: true, signal: this.controller.signal }) - this.tick() - } - - componentWillUnmount() { - this.controller.abort() - } - - render() { - const props = this.props; - const isBoxed = props.above || props.content - - if (this.state.scrollY <= 250) { - return ( - - - - - {isBoxed && ( - - {props.title} - - )} - - {!isBoxed && {props.title}} - - - ) - } else { - return ( - - - - - {isBoxed && ( - - {props.title} - - )} - - {!isBoxed && {props.title}} - - - ) - } - } + }, [cancel]) + + const isBoxed = props.above || props.content + + const stickyHeader = ( + + + + + {isBoxed && ( + {props.title} + )} + + {!isBoxed && {props.title}} + + + ) + + return ( + <> + + + + + {isBoxed && ( + + {props.title} + + )} + + {!isBoxed && {props.title}} + + + {scrollY >= 270 && stickyHeader} + + ) } diff --git a/src/components/PageContent/styles.tsx b/src/components/PageContent/styles.tsx index e86cd2a..35b7650 100644 --- a/src/components/PageContent/styles.tsx +++ b/src/components/PageContent/styles.tsx @@ -21,7 +21,7 @@ export const Sidebar = styled.div` margin: 64px 0; padding: 0 32px; position: sticky; - top: 32px; + top: 119px; &:empty { display: none; From e7307a0893d58567d201c53a2844bfcf012663d1 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Mon, 31 May 2021 23:22:31 -0400 Subject: [PATCH 6/8] fix: invalid css --- src/components/HeaderBarebone/styles.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/HeaderBarebone/styles.tsx b/src/components/HeaderBarebone/styles.tsx index af22809..e6d31b6 100644 --- a/src/components/HeaderBarebone/styles.tsx +++ b/src/components/HeaderBarebone/styles.tsx @@ -138,7 +138,7 @@ export const StickyBox = styled.div` padding: 0px 0px 16px 30px; backdrop-filter: blur(14px); width: 100%; - font-size: 16px + font-size: 16px; @media screen and (max-width: 1200px) { max-width: 100%; @@ -190,7 +190,7 @@ export const StickyTitle = styled.h1` &.has-content-below { margin-bottom: 16px; - px; + } ` export const SingleTitle = styled(Title)` From fd7005c9df8caf04e75013981943572cda7bcb56 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Tue, 1 Jun 2021 00:02:09 -0400 Subject: [PATCH 7/8] ui: tweak sticky header styles to match figma sketch --- src/components/HeaderBarebone/styles.tsx | 42 +++++++++++++++++++----- src/components/PageContent/styles.tsx | 2 +- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/components/HeaderBarebone/styles.tsx b/src/components/HeaderBarebone/styles.tsx index e6d31b6..c55c69e 100644 --- a/src/components/HeaderBarebone/styles.tsx +++ b/src/components/HeaderBarebone/styles.tsx @@ -42,9 +42,21 @@ export const HeaderWrapper = styled.div` export const HeaderWrapperSticky = styled.div` display: flex; width: 100%; - height: 7px; - padding-top: ${spaceAbove}px; + height: 74px; position: fixed; + overflow: hidden; + + &::before { + content: ""; + display: block; + width: 1px; + height: 48px; + background: rgba(255, 255, 255, 0.7); + position: absolute; + top: 14px; + left: 0; + z-index: 1; + } &.shifted { width: calc(100% - 305px); @@ -73,25 +85,36 @@ export const Background = styled.div` background-repeat: no-repeat; background-position: 50% 50%; background-size: cover; + background-image: var(--headerImage); + + // Overlaid gradient for a sticky header + ${HeaderWrapperSticky} & { + background-image: linear-gradient( + to left, + ${transparentize(1, "#263440")} 0, + #263440 100% + ), + var(--headerImage); + } // 2560x1400 screens @media screen and (min-width: 2500px) { - background-image: url("${Header2560}"); + --headerImage: url("${Header2560}"); } // 1920x1080 screens @media screen and (min-width: 1800px) and (max-width: 2499px) { - background-image: url("${Header1920}"); + --headerImage: url("${Header1920}"); } // 1440x900 screens @media screen and (min-width: 768px) and (max-width: 1799px) { - background-image: url("${Header1440}"); + --headerImage: url(${Header1440}); } // mobile screens @media screen and (max-width: 767px) { - background-image: url("${HeaderMobile}"); + --headerImage: url(${HeaderMobile}); } ` @@ -131,11 +154,12 @@ export const Box = styled.div` export const StickyBox = styled.div` display: inline-flex; + justify-content: center; flex-direction: column; position: absolute; top: 0; - background: ${(props) => transparentize(0.3, props.theme.main.background)}; - padding: 0px 0px 16px 30px; + bottom: 0; + padding-left: 64px; backdrop-filter: blur(14px); width: 100%; font-size: 16px; @@ -187,6 +211,8 @@ export const Title = styled.h1` export const StickyTitle = styled.h1` ${title}; font-size: 20px; + line-height: 1; + margin-bottom: 8px; &.has-content-below { margin-bottom: 16px; diff --git a/src/components/PageContent/styles.tsx b/src/components/PageContent/styles.tsx index 35b7650..0cea025 100644 --- a/src/components/PageContent/styles.tsx +++ b/src/components/PageContent/styles.tsx @@ -21,7 +21,7 @@ export const Sidebar = styled.div` margin: 64px 0; padding: 0 32px; position: sticky; - top: 119px; + top: 100px; &:empty { display: none; From efb1fe724b5eb838ceeedc70c5782893b3145a72 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Sirois Date: Tue, 1 Jun 2021 00:18:01 -0400 Subject: [PATCH 8/8] fix: correctly show header on generic content pages --- src/components/HeaderBarebone/index.tsx | 6 +----- src/components/HeaderBarebone/styles.tsx | 5 ++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/HeaderBarebone/index.tsx b/src/components/HeaderBarebone/index.tsx index c979fd0..05d7fe8 100644 --- a/src/components/HeaderBarebone/index.tsx +++ b/src/components/HeaderBarebone/index.tsx @@ -88,11 +88,7 @@ export const HeaderBarebone = (props: IHeaderBareboneProps) => { - {isBoxed && ( - {props.title} - )} - - {!isBoxed && {props.title}} + {props.title} ) diff --git a/src/components/HeaderBarebone/styles.tsx b/src/components/HeaderBarebone/styles.tsx index c55c69e..f2ec57a 100644 --- a/src/components/HeaderBarebone/styles.tsx +++ b/src/components/HeaderBarebone/styles.tsx @@ -212,7 +212,10 @@ export const StickyTitle = styled.h1` ${title}; font-size: 20px; line-height: 1; - margin-bottom: 8px; + + &.has-content-above { + margin-bottom: 8px; + } &.has-content-below { margin-bottom: 16px;