Skip to content

Commit

Permalink
Merge pull request #2168 from system-ui/docs-header-scroll-shadow
Browse files Browse the repository at this point in the history
fix(docs): make layout more consistent
  • Loading branch information
hasparus committed Mar 20, 2022
2 parents bbd808b + 84b424d commit baec10c
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 20 deletions.
96 changes: 76 additions & 20 deletions packages/docs/src/components/layout.js
@@ -1,6 +1,6 @@
/** @jsx jsx */
import { jsx, Themed, useColorMode } from 'theme-ui'
import { useState, useRef } from 'react'
import { css, jsx, Themed, useColorMode } from 'theme-ui'
import { useState, useRef, useEffect } from 'react'
import { Flex, Box } from '@theme-ui/components'
import { AccordionNav } from '@theme-ui/sidenav'
import { Link } from 'gatsby'
Expand Down Expand Up @@ -45,10 +45,12 @@ export default function DocsLayout(props) {
const nav = useRef(null)
const [mode, setMode] = useColorMode()

const { pathname } = props.location
const isLanding = pathname === '/'

const fullwidth =
(props.pageContext.frontmatter &&
props.pageContext.frontmatter.fullwidth) ||
props.location.pathname === '/'
isLanding ||
(props.pageContext.frontmatter && props.pageContext.frontmatter.fullwidth)

const showNav = !props.pageContext?.frontmatter?.hidenav

Expand All @@ -62,16 +64,22 @@ export default function DocsLayout(props) {
sx={{
flexDirection: 'column',
minHeight: '100vh',
}}>
}}
>
{showNav && (
<Flex
as="header"
sx={{
zIndex: 1,
height: 64,
px: 3,
alignItems: 'center',
justifyContent: 'space-between',
}}>
position: isLanding ? 'initial' : 'sticky',
top: 0,
background: 'background',
}}
>
<Flex sx={{ alignItems: 'center' }}>
<MenuButton
onClick={(e) => {
Expand Down Expand Up @@ -99,7 +107,8 @@ export default function DocsLayout(props) {
ml: 2,
whiteSpace: 'pre',
}}
onClick={() => setMode(nextColorMode)}>
onClick={() => setMode(nextColorMode)}
>
{getModeName(mode)}
</Button>
</Flex>
Expand All @@ -112,7 +121,8 @@ export default function DocsLayout(props) {
alignItems: 'flex-start',
display: ['block', 'flex'],
height: '100%',
}}>
}}
>
<Sidebar
ref={nav}
role="navigation"
Expand All @@ -130,8 +140,9 @@ export default function DocsLayout(props) {
}}
open={menuOpen}
components={sidebar}
pathname={props.location.pathname}
pathname={pathname}
sx={{
background: 'background',
display: [null, fullwidth ? 'none' : 'block'],
width: 256,
flex: 'none',
Expand All @@ -141,23 +152,68 @@ export default function DocsLayout(props) {
pt: 3,
pb: 4,
mt: [64, 0],
position: [null, 'sticky'],
top: [null, '64px'],
}}
/>
<main
id="content"
<div
sx={{
width: '100%',
minWidth: 0,
maxWidth: fullwidth ? 'none' : 768,
mx: 'auto',
px: fullwidth ? 0 : 3,
}}>
{props.children}
<EditLink />
{!fullwidth && <Pagination />}
</main>

position: 'relative',
}}
>
{!isLanding && <HeaderScrollShadow />}
<main
id="content"
sx={{
maxWidth: fullwidth ? 'none' : 768,
mx: 'auto',
px: fullwidth ? 0 : 3,
}}
>
{props.children}
<EditLink />
{!fullwidth && <Pagination />}
</main>
</div>
</Box>
</Flex>
</Themed.root>
)
}

function HeaderScrollShadow() {
const ref = useRef()

useEffect(() => {
const onScroll = () => {
const { current } = ref
if (current) {
current.style.opacity = window.scrollY > 0 ? 1 : 0
}
}

window.addEventListener('scroll', onScroll)
return () => window.removeEventListener('scroll', onScroll)
}, [])

return (
<div
ref={ref}
sx={{
content: "''",
top: '64px',
transform: 'translateY(-64px)',
left: 0,
right: 0,
height: '64px',
position: 'sticky',
boxShadow: '0 12px 18px -3px rgb(0 0 0 / 0.03)',
transition: 'opacity 250ms linear',
opacity: 0,
}}
/>
)
}
73 changes: 73 additions & 0 deletions packages/e2e/integration/docs-navigation.ts
@@ -0,0 +1,73 @@
describe('docs navigation', () => {
it('works without 404', () => {
cy.visit('/')
cy.findByText('Documentation').click()
cy.location().should('have.property', 'pathname', '/getting-started')
cy.findByText('Theming').click()
cy.get('h1').should('have.text', 'Theming')
cy.findAllByRole('link').then(($links) => {
const links = $links.get()
const texts = links.map((link) => link.textContent)

const expectedLinkTexts = [
'Hooks',
'API',
'Theme Specification',
'Demo',
'Resources',
'Components',
'Packages',
'Guides',
'Recipes',
'Migrating',
'Edit the page on GitHub',
'Previous:Getting Started with Gatsby',
]

for (const s of expectedLinkTexts) {
expect(texts).to.include(s)
}

const nextChapterLink = links.find(
(link) => link.textContent === 'Next:The sx Prop'
)!

nextChapterLink.click()

const packagesLink = links.find(
(link) => link.textContent === 'Packages'
)!

packagesLink.click()
})

for (const packageName of [
'css',
'core',
'components',
'presets',
'color',
]) {
cy.findAllByText('@theme-ui/' + packageName, { selector: 'li > a' })
.first()
.click()
cy.location().should(
'have.property',
'pathname',
`/packages/${packageName}`
)
}

cy.window().then((win) => win.scrollTo(0, 200))

cy.percySnapshot('@theme-ui/color docs')
})

it('displays 404 page', () => {
cy.visit(`/not-found-${Math.random()}`, { failOnStatusCode: false })
cy.findByRole('heading').should('have.text', '404')
cy.findByText('Page not found')
})
})

export {}

0 comments on commit baec10c

Please sign in to comment.