Style updates and misc fixes
Other fixes: - disable scroll behavior for cli version selections - close mobile search after successful navigation
Luke Karrys committed
Oct 23, 2023 at 15:55 UTC
53dbeda756cc5ec1dcd458b683386b3a55c92656
18 files changed
+244
-200
.eslintrc.js
+5
-3
@@ -46,7 +46,7 @@ module.exports = {
46
},
47
},
48
{
49
- files: ['*.mdx', 'shared.js'],
49
+ files: ['*.mdx', 'shared.js', 'src/**/*.js'],
50
rules: {
51
'react/forbid-elements': [
52
'error',
@@ -109,7 +109,8 @@ module.exports = {
109
'header',
110
'hgroup',
111
'hr',
112
- 'html',
112
+ // used in head
113
+ // 'html',
114
'i',
115
'input',
116
'ins',
@@ -170,7 +171,8 @@ module.exports = {
171
'th',
172
'thead',
173
'time',
173
- 'title',
174
+ // used in head
175
+ // 'title',
176
'tr',
177
'track',
178
'tt',
gatsby-browser.js
+5
@@ -1,2 +1,7 @@
1
export {default as wrapPageElement} from './src/page'
2
export {default as wrapRootElement} from './src/root'
3
+
4
+export const shouldUpdateScroll = ({routerProps}) => {
5
+ const {scrollUpdate = true} = routerProps.location.state ?? {}
6
+ return scrollUpdate
7
+}
src/components/container.js
deleted
-6
@@ -1,6 +0,0 @@
1
-import {Box} from '@primer/react'
2
-import React from 'react'
3
-
4
-const Container = ({children}) => <Box sx={{width: '100%', maxWidth: 960, p: 5, mx: 'auto'}}>{children}</Box>
5
-
6
-export default Container
src/components/drawer.js
deleted
-61
@@ -1,61 +0,0 @@
1
-import React from 'react'
2
-import {Box} from '@primer/react'
3
-import {AnimatePresence, motion} from 'framer-motion'
4
-import {FocusOn} from 'react-focus-on'
5
-
6
-const Drawer = ({isOpen, onDismiss, children}) => (
7
- <AnimatePresence>
8
- {isOpen ? (
9
- // These event handlers fix a bug that caused links below the fold
10
- // to be unclickable in macOS Safari.
11
- // Reference: https://github.com/theKashey/react-focus-lock/issues/79
12
- <div
13
- onMouseDown={event => event.preventDefault()}
14
- onKeyDown={event => event.target.focus()}
15
- onClick={event => event.target.focus()}
16
- role="button"
17
- tabIndex="0"
18
- >
19
- <FocusOn returnFocus={true} onEscapeKey={onDismiss}>
20
- <Box
21
- sx={{
22
- position: 'fixed',
23
- top: 0,
24
- right: 0,
25
- bottom: 0,
26
- left: 0,
27
- bg: 'overlay.backdrop',
28
- }}
29
- key="overlay"
30
- as={motion.div}
31
- initial={{opacity: 0}}
32
- animate={{opacity: 1}}
33
- exit={{opacity: 0}}
34
- transition={{type: 'tween'}}
35
- onClick={onDismiss}
36
- />
37
- <Box
38
- sx={{
39
- position: 'fixed',
40
- top: 0,
41
- right: 0,
42
- bottom: 0,
43
- width: 300,
44
- zIndex: 1,
45
- }}
46
- key="drawer"
47
- as={motion.div}
48
- initial={{x: '100%'}}
49
- animate={{x: 0}}
50
- exit={{x: '100%'}}
51
- transition={{type: 'tween', duration: 0.2}}
52
- >
53
- {children}
54
- </Box>
55
- </FocusOn>
56
- </div>
57
- ) : null}
58
- </AnimatePresence>
59
-)
60
-
61
-export default Drawer
src/components/header.js
+3
-25
@@ -6,26 +6,16 @@ import NavDrawer from './nav-drawer'
6
import Link from './link'
7
import useSearch from '../hooks/use-search'
8
import {HEADER_HEIGHT, HEADER_BAR} from '../constants'
9
-import useSiteMetadata from '../hooks/use-site-metadata'
9
import headerNavItems from '../../content/header-nav.yml'
10
import {DarkTheme} from '../theme'
11
+import SiteTitle from './site-title'
12
13
const NpmHeaderBar = styled(Box)`
14
height: ${HEADER_BAR}px;
15
background-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff);
16
`
17
18
-const NpmLogo = ({size, sx}) => (
19
- <Box sx={{...sx, color: 'logoBg'}} role="banner">
20
- <svg height={size} width={size} viewBox="0 0 700 700" fill="currentColor" aria-hidden="true">
21
- <polygon fill="currentColor" points="0,700 700,700 700,0 0,0" />
22
- <polygon fill="#ffffff" points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150 " />
23
- </svg>
24
- </Box>
25
-)
26
-
18
function Header() {
28
- const siteMetadata = useSiteMetadata()
19
const search = useSearch()
20
21
return (
@@ -35,7 +25,7 @@ function Header() {
25
as="header"
26
sx={{
27
display: 'flex',
38
- height: HEADER_HEIGHT,
28
+ height: `${HEADER_HEIGHT}px`,
29
px: [3, null, null, 4],
30
alignItems: 'center',
31
justifyContent: 'space-between',
@@ -47,19 +37,7 @@ function Header() {
37
}}
38
>
39
<Box sx={{display: 'flex', alignItems: 'center'}}>
50
- <Link
51
- to="/"
52
- sx={{
53
- mr: 4,
54
- fontWeight: 'bold',
55
- color: 'fg.default',
56
- display: 'flex',
57
- alignItems: 'center',
58
- }}
59
- >
60
- <NpmLogo size="32" sx={{display: 'flex', mr: 3}} />
61
- {siteMetadata.title}
62
- </Link>
40
+ <SiteTitle logo={true} sx={{mr: 4}} />
41
<Box sx={{display: ['none', null, null, 'block'], ml: 4}}>
42
<Search.Desktop {...search} />
43
</Box>
src/components/link.js
+12
-5
@@ -2,6 +2,16 @@ import React from 'react'
2
import {Link as PrimerLink} from '@primer/react'
3
import {Link as GatsbyLink} from 'gatsby'
4
5
+const omit = (obj, ...keys) => {
6
+ const res = {}
7
+ for (const k of Object.keys(obj)) {
8
+ if (!keys.includes(k)) {
9
+ res[k] = obj[k]
10
+ }
11
+ }
12
+ return res
13
+}
14
+
15
const FALLBACK = `http://_${Math.random().toString().slice(2)}._${Math.random().toString().slice(2)}`
16
17
const getLocalPath = href => {
@@ -21,11 +31,8 @@ const getLocalPath = href => {
31
return null
32
}
33
24
-const GatsbyLinkWithoutSxProps = React.forwardRef(function GatsbyLinkWithoutSxProps(
25
- {sx, underline, hoverColor, muted, ...props},
26
- ref,
27
-) {
28
- return <GatsbyLink ref={ref} {...props} />
34
+const GatsbyLinkWithoutSxProps = React.forwardRef(function GatsbyLinkWithoutSxProps(props, ref) {
35
+ return <GatsbyLink ref={ref} {...omit(props, 'sx', 'underline', 'hoverColor', 'muted')} />
36
})
37
38
const Link = React.forwardRef(function Link({to, href, ...props}, ref) {
src/components/nav-drawer.js
+75
-41
@@ -1,38 +1,85 @@
1
import React from 'react'
2
import {Button, Box} from '@primer/react'
3
import {XIcon, ThreeBarsIcon} from '@primer/octicons-react'
4
-import Link from './link'
5
-import Drawer from './drawer'
4
import NavItems from './nav-items'
7
-import useSiteMetadata from '../hooks/use-site-metadata'
5
import {useIsMobile} from '../hooks/use-breakpoint'
6
import {DarkTheme, LightTheme} from '../theme'
7
+import {AnimatePresence, motion} from 'framer-motion'
8
+import {FocusOn} from 'react-focus-on'
9
+import {HEADER_BAR, HEADER_HEIGHT} from '../constants'
10
+import SiteTitle from './site-title'
11
11
-const useDrawerIsOpen = () => {
12
+const Drawer = ({isOpen, onDismiss, children}) => (
13
+ <AnimatePresence>
14
+ {isOpen ? (
15
+ // These event handlers fix a bug that caused links below the fold
16
+ // to be unclickable in macOS Safari.
17
+ // Reference: https://github.com/theKashey/react-focus-lock/issues/79
18
+ <Box
19
+ onMouseDown={event => event.preventDefault()}
20
+ onKeyDown={event => event.target.focus()}
21
+ onClick={event => event.target.focus()}
22
+ role="button"
23
+ tabIndex="0"
24
+ >
25
+ <FocusOn returnFocus={true} onEscapeKey={onDismiss}>
26
+ <Box
27
+ sx={{
28
+ position: 'fixed',
29
+ top: 0,
30
+ right: 0,
31
+ bottom: 0,
32
+ left: 0,
33
+ bg: 'overlay.backdrop',
34
+ }}
35
+ key="overlay"
36
+ as={motion.div}
37
+ initial={{opacity: 0}}
38
+ animate={{opacity: 1}}
39
+ exit={{opacity: 0}}
40
+ transition={{type: 'tween'}}
41
+ onClick={onDismiss}
42
+ />
43
+ <Box
44
+ sx={{
45
+ position: 'fixed',
46
+ top: `${HEADER_BAR}px`,
47
+ right: 0,
48
+ bottom: 0,
49
+ width: 300,
50
+ zIndex: 1,
51
+ }}
52
+ key="drawer"
53
+ as={motion.div}
54
+ initial={{x: '100%'}}
55
+ animate={{x: 0}}
56
+ exit={{x: '100%'}}
57
+ transition={{type: 'tween', duration: 0.2}}
58
+ >
59
+ {children}
60
+ </Box>
61
+ </FocusOn>
62
+ </Box>
63
+ ) : null}
64
+ </AnimatePresence>
65
+)
66
+
67
+function NavDrawer() {
68
const isMobile = useIsMobile()
13
- const [isOpen, setIsOpen] = React.useState(false)
14
- const setOpen = React.useCallback(() => setIsOpen(true), [])
15
- const setClose = React.useCallback(() => setIsOpen(false), [])
69
+ const [open, setOpen] = React.useState(false)
70
71
React.useEffect(() => {
18
- if (!isMobile && isOpen) {
19
- setIsOpen(false)
72
+ if (!isMobile && open) {
73
+ setOpen(false)
74
}
21
- }, [isMobile, isOpen])
22
-
23
- return [isOpen, {setOpen, setClose}]
24
-}
25
-
26
-function NavDrawer() {
27
- const siteMetadata = useSiteMetadata()
28
- const [isOpen, {setOpen, setClose}] = useDrawerIsOpen()
75
+ }, [isMobile, open])
76
77
return (
78
<>
32
- <Button aria-label="Menu" aria-expanded={isOpen} onClick={setOpen} sx={{ml: 3}}>
79
+ <Button aria-label="Menu" aria-expanded={open} onClick={() => setOpen(true)} sx={{ml: 3}}>
80
<ThreeBarsIcon />
81
</Button>
35
- <LightTheme as={Drawer} isOpen={isOpen} onDismiss={setClose}>
82
+ <LightTheme as={Drawer} isOpen={open} onDismiss={() => setOpen(false)}>
83
<Box
84
sx={{
85
display: 'flex',
@@ -54,32 +101,19 @@ function NavDrawer() {
101
>
102
<DarkTheme
103
sx={{
57
- borderWidth: 0,
58
- borderRadius: 0,
59
- borderBottomWidth: 1,
60
- borderColor: 'border.muted',
61
- borderStyle: 'solid',
104
color: 'fg.default',
105
bg: 'canvas.default',
106
+ height: `${HEADER_HEIGHT}px`,
107
+ px: 3,
108
+ alignItems: 'center',
109
+ justifyContent: 'space-between',
110
+ display: 'flex',
111
}}
112
>
66
- <Box
67
- sx={{
68
- py: 3,
69
- pl: 4,
70
- pr: 3,
71
- alignItems: 'center',
72
- justifyContent: 'space-between',
73
- display: 'flex',
74
- }}
75
- >
76
- <Link to="/" sx={{fontSize: 2, color: 'fg.default'}}>
77
- {siteMetadata.title}
78
- </Link>
79
- <Button aria-label="Close" onClick={setClose}>
80
- <XIcon />
81
- </Button>
82
- </Box>
113
+ <SiteTitle />
114
+ <Button aria-label="Close" onClick={() => setOpen(false)}>
115
+ <XIcon />
116
+ </Button>
117
</DarkTheme>
118
<Box sx={{display: 'flex', flexDirection: 'column'}}>
119
<NavItems />
src/components/nav-items.js
+1
-3
@@ -59,9 +59,7 @@ const Navigation = () => {
59
60
return (
61
<>
62
- <VisuallyHidden>
63
- <h3>Site navigation</h3>
64
- </VisuallyHidden>
62
+ <VisuallyHidden as="h3">Site navigation</VisuallyHidden>
63
<NavList aria-label="Site">
64
<NavItems items={items} path={pathname} />
65
<NavList.Divider />
src/components/page-footer.js
+2
-2
@@ -29,7 +29,7 @@ const Contributors = ({contributors = [], latestCommit}) => {
29
}
30
31
return (
32
- <div>
32
+ <>
33
<Box sx={{display: 'flex', alignItems: 'center'}}>
34
<Text sx={{mr: 2}}>
35
{contributors.length} {pluralize('contributor', contributors.length)}
@@ -48,7 +48,7 @@ const Contributors = ({contributors = [], latestCommit}) => {
48
<Link href={latestCommit.url}>{format(new Date(latestCommit.date))}</Link>
49
</Text>
50
) : null}
51
- </div>
51
+ </>
52
)
53
}
54
src/components/search-results.js
+8
-12
@@ -26,17 +26,17 @@ const SearchItem = ({item}) => {
26
)
27
}
28
29
+const Result = React.forwardRef(function Result({sx, ...props}, ref) {
30
+ return <Box ref={ref} sx={{px: 3, py: 2, color: 'fg.default', fontSize: 1, ...sx}} {...props} />
31
+})
32
+
33
function SearchResults({results, getItemProps, highlightedIndex}) {
30
- if (results.length === 0) {
31
- return (
32
- <Text as="div" sx={{px: 3, py: 2, color: 'fg.default', fontSize: 1}}>
33
- No results
34
- </Text>
35
- )
34
+ if (!results || results.length === 0) {
35
+ return <Result>No results</Result>
36
}
37
38
return results.map((item, index) => (
39
- <Box
39
+ <Result
40
{...getItemProps({item, index})}
41
as={LinkNoUnderline}
42
to={item.path}
@@ -45,15 +45,11 @@ function SearchResults({results, getItemProps, highlightedIndex}) {
45
display: 'flex',
46
flexDirection: 'column',
47
flex: '0 0 auto',
48
- px: 3,
49
- py: 2,
50
- color: 'fg.default',
51
- fontSize: 1,
48
bg: highlightedIndex === index ? 'neutral.muted' : 'transparent',
49
}}
50
>
51
<SearchItem item={item} />
56
- </Box>
52
+ </Result>
53
))
54
}
55
src/components/search.js
+17
-2
@@ -8,6 +8,7 @@ import SearchResults from './search-results'
8
import useSiteMetadata from '../hooks/use-site-metadata'
9
import {HEADER_BAR, HEADER_HEIGHT} from '../constants'
10
import {LightTheme} from '../theme'
11
+import useLocationChange from '../hooks/use-location-change'
12
13
export const Desktop = props => {
14
const siteMetadata = useSiteMetadata()
@@ -44,10 +45,24 @@ export const Desktop = props => {
45
)
46
}
47
47
-export const Mobile = props => {
48
+export const Mobile = ({
49
+ reset,
50
+ results,
51
+ isOpen: resultsOpen,
52
+ getInputProps,
53
+ getItemProps,
54
+ getMenuProps,
55
+ highlightedIndex,
56
+}) => {
57
const [open, setOpen] = React.useState(false)
58
const siteMetadata = useSiteMetadata()
50
- const {reset, results, isOpen: resultsOpen, getInputProps, getItemProps, getMenuProps, highlightedIndex} = props
59
+ const locationChange = useLocationChange()
60
+
61
+ React.useEffect(() => {
62
+ if (locationChange.change) {
63
+ setOpen(false)
64
+ }
65
+ }, [locationChange])
66
67
// Fixes focus behavior on iOS where the input gets focus styles but not the
68
// actual focus after animating open.
src/components/site-title.js
new
+36
@@ -0,0 +1,36 @@
1
+import React from 'react'
2
+import {Box} from '@primer/react'
3
+import Link from './link'
4
+import useSiteMetadata from '../hooks/use-site-metadata'
5
+
6
+const NpmLogo = ({size, sx}) => (
7
+ <Box sx={{...sx, color: 'logoBg'}} role="banner">
8
+ <svg height={size} width={size} viewBox="0 0 700 700" fill="currentColor" aria-hidden="true">
9
+ <polygon fill="currentColor" points="0,700 700,700 700,0 0,0" />
10
+ <polygon fill="#ffffff" points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150 " />
11
+ </svg>
12
+ </Box>
13
+)
14
+
15
+const SiteTitle = ({logo, sx}) => {
16
+ const siteMetadata = useSiteMetadata()
17
+
18
+ return (
19
+ <Link
20
+ to="/"
21
+ sx={{
22
+ fontWeight: 'bold',
23
+ fontSize: 2,
24
+ color: 'fg.default',
25
+ display: 'flex',
26
+ alignItems: 'center',
27
+ ...sx,
28
+ }}
29
+ >
30
+ {logo ? <NpmLogo size="32" sx={{display: 'flex', mr: 3}} /> : null}
31
+ {siteMetadata.title}
32
+ </Link>
33
+ )
34
+}
35
+
36
+export default SiteTitle
src/components/table-of-contents.js
+25
-6
@@ -18,8 +18,8 @@ const TableOfContentsItems = ({items, depth}) => (
18
</>
19
)
20
21
-const TableOfContents = ({'aria-labelledby': ariaLabelledBy, items, depth = 1}) => (
22
- <NavList {...(depth === 1 ? {'aria-labelledby': ariaLabelledBy, sx: {ml: -2}} : {})}>
21
+const TableOfContents = ({'aria-labelledby': ariaLabelledBy, items, depth = 1, ...props}) => (
22
+ <NavList aria-labelledby={ariaLabelledBy} {...props}>
23
<TableOfContentsItems items={items} depth={depth} />
24
</NavList>
25
)
@@ -35,9 +35,28 @@ const withTableOfContents = Component => {
35
export const Mobile = withTableOfContents(({items}) => {
36
const {getDetailsProps, open} = useDetails({defaultOpen: true})
37
return (
38
- <Box sx={{display: ['block', null, 'none'], mb: 3}}>
39
- <Details {...getDetailsProps()}>
40
- <Button as="summary" sx={{display: 'inline-flex'}} leadingIcon={open ? ChevronDownIcon : ChevronRightIcon}>
38
+ <Box sx={{display: ['block', null, 'none'], mb: 3, mt: 4}}>
39
+ <Details
40
+ {...getDetailsProps()}
41
+ sx={{
42
+ borderStyle: 'solid',
43
+ borderWidth: 1,
44
+ borderColor: 'border.muted',
45
+ borderRadius: 2,
46
+ }}
47
+ >
48
+ <Button
49
+ as="summary"
50
+ sx={{
51
+ borderTopWidth: 0,
52
+ borderLeftWidth: 0,
53
+ borderRightWidth: 0,
54
+ borderBottomWidth: open ? 1 : 0,
55
+ borderBottomLeftRadius: open ? 0 : 2,
56
+ borderBottomRightRadius: open ? 0 : 2,
57
+ }}
58
+ leadingIcon={open ? ChevronDownIcon : ChevronRightIcon}
59
+ >
60
Table of contents
61
</Button>
62
<TableOfContents items={items} />
@@ -68,7 +87,7 @@ export const Desktop = withTableOfContents(({items}) => (
87
overflowY: 'scroll',
88
}}
89
>
71
- <TableOfContents aria-labelledby="toc-heading" items={items} />
90
+ <TableOfContents aria-labelledby="toc-heading" items={items} sx={{ml: -2}} />
91
</Box>
92
</Box>
93
))
src/components/variant-select.js
+13
-19
@@ -3,38 +3,30 @@ import {ActionList, ActionMenu, Box} from '@primer/react'
3
import * as getNav from '../util/get-nav'
4
import usePage from '../hooks/use-page'
5
import {LinkNoUnderline} from './link'
6
+import useLocationChange from '../hooks/use-location-change'
7
8
const VariantItem = ({title, shortName, url, active}) => (
8
- <ActionList.Item as={LinkNoUnderline} to={url} id={shortName} active={active}>
9
+ <ActionList.Item as={LinkNoUnderline} to={url} state={{scrollUpdate: false}} id={shortName} active={active}>
10
{title}
11
</ActionList.Item>
12
)
13
13
-const useVariantFocus = path => {
14
+const useVariantFocus = () => {
15
+ const locationChange = useLocationChange()
16
const anchorRef = React.useRef(null)
15
- const pathRef = React.useRef(null)
17
18
React.useEffect(() => {
18
- const previousPath = pathRef.current
19
- pathRef.current = path
20
-
21
- if (getNav.didVariantChange(previousPath, path)) {
22
- const anchor = anchorRef.current
23
- const onBlur = () => {
24
- anchor.removeEventListener('blur', onBlur)
25
- anchor.focus()
26
- }
27
- anchor.addEventListener('blur', onBlur)
28
- return () => anchor.removeEventListener('blur', onBlur)
19
+ if (locationChange.change && getNav.didVariantChange(locationChange.previous, locationChange.current)) {
20
+ anchorRef.current.focus()
21
}
30
- }, [path])
22
+ }, [locationChange])
23
24
return anchorRef
25
}
26
35
-const VariantMenu = ({title, latest, current, prerelease, legacy, path}) => {
27
+const VariantMenu = ({title, latest, current, prerelease, legacy}) => {
28
const [open, setOpen] = React.useState(false)
37
- const anchorRef = useVariantFocus(path)
29
+ const anchorRef = useVariantFocus()
30
const labelId = 'label-versions-list-item'
31
32
return (
@@ -43,7 +35,9 @@ const VariantMenu = ({title, latest, current, prerelease, legacy, path}) => {
35
Select CLI Version:
36
</Box>
37
<ActionMenu anchorRef={anchorRef} open={open} onOpenChange={setOpen}>
46
- <ActionMenu.Button aria-describedby={labelId}>{title}</ActionMenu.Button>
38
+ <ActionMenu.Button aria-describedby={labelId} sx={{width: ['100%', null, 'auto']}}>
39
+ {title}
40
+ </ActionMenu.Button>
41
<ActionMenu.Overlay width="auto" onEscape={() => setOpen(false)}>
42
<ActionList aria-labelledby={labelId}>
43
<ActionList.Group title="Current">
@@ -73,7 +67,7 @@ const useVariants = () => {
67
return null
68
}
69
76
- const result = {path, latest: null, current: null, prerelease: null, legacy: []}
70
+ const result = {latest: null, current: null, prerelease: null, legacy: []}
71
72
for (const {variant, page} of variantPages) {
73
const item = {...variant, url: page.url, active: page.url === path}
src/hooks/use-location-change.js
new
+19
@@ -0,0 +1,19 @@
1
+import React from 'react'
2
+import usePage from './use-page'
3
+
4
+const useLocationChange = () => {
5
+ const {pathname} = usePage().location
6
+ const pathRef = React.useRef(null)
7
+ const [pathChange, setPathChange] = React.useState({change: false})
8
+
9
+ React.useEffect(() => {
10
+ if (pathRef.current && pathRef.current !== pathname) {
11
+ setPathChange({change: true, current: pathname, previous: pathRef.current})
12
+ }
13
+ pathRef.current = pathname
14
+ }, [pathname])
15
+
16
+ return pathChange
17
+}
18
+
19
+export default useLocationChange
src/layout.js
+7
-6
@@ -5,19 +5,20 @@ import PageFooter from './components/page-footer'
5
import * as TableOfContents from './components/table-of-contents'
6
import VariantSelect from './components/variant-select'
7
import Breadcrumbs from './components/breadcrumbs'
8
-import Container from './components/container'
8
import useSiteMetadata from './hooks/use-site-metadata'
9
import usePage from './hooks/use-page'
10
import {DarkTheme} from './theme'
11
import {SkipNav} from './components/skip-nav'
12
13
+const Container = ({sx, ...props}) => <Box sx={{width: '100%', maxWidth: '960px', ...sx}} {...props} />
14
+
15
const HeroLayout = ({children}) => {
16
const {title, description} = useSiteMetadata()
17
18
return (
19
<Box as="main" sx={{width: '100%'}}>
19
- <DarkTheme sx={{bg: 'canvas.inset', py: 6}}>
20
- <Container>
20
+ <DarkTheme sx={{bg: 'canvas.inset', py: [0, 4, 5, 6]}}>
21
+ <Container sx={{p: 5, mx: 'auto'}}>
22
<Heading as="h1" sx={{color: 'fg.default', fontSize: 7, m: 0}}>
23
{title}
24
</Heading>
@@ -27,7 +28,7 @@ const HeroLayout = ({children}) => {
28
</Container>
29
</DarkTheme>
30
<SkipNav />
30
- <Container>{children}</Container>
31
+ <Container sx={{p: 5, mx: 'auto'}}>{children}</Container>
32
</Box>
33
)
34
}
@@ -47,7 +48,7 @@ const DefaultLayout = ({children}) => {
48
}}
49
>
50
<TableOfContents.Desktop />
50
- <Box as="main" sx={{width: '100%', maxWidth: '960px'}}>
51
+ <Container as="main">
52
<Box sx={{mb: 4}}>
53
<Breadcrumbs />
54
<H1 autolink={false}>{title}</H1>
@@ -58,7 +59,7 @@ const DefaultLayout = ({children}) => {
59
<TableOfContents.Mobile />
60
{children}
61
<PageFooter />
61
- </Box>
62
+ </Container>
63
</Box>
64
)
65
}
src/mdx/code.js
+2
-2
@@ -112,11 +112,11 @@ function Code({className = '', prompt, children}) {
112
{({className: highlightClassName, style, tokens, getLineProps, getTokenProps}) => (
113
<CodeBlock className={highlightClassName} style={style} code={code}>
114
{tokens.map((line, i) => (
115
- <div key={i} {...getLineProps({line, key: i})}>
115
+ <Box key={i} {...getLineProps({line, key: i})}>
116
{line.map((token, key) => (
117
<MonoText key={key} {...getTokenProps({token, key})} />
118
))}
119
- </div>
119
+ </Box>
120
))}
121
</CodeBlock>
122
)}
src/theme.js
+14
-7
@@ -39,11 +39,18 @@ export const npmTheme = deepmerge(theme, {
39
40
export const ThemeProvider = props => <Provider theme={npmTheme} {...props} />
41
42
-export const Theme = ({theme: colorMode, as = Box, ...props}) => (
43
- <Provider colorMode={colorMode} nightScheme="dark_dimmed">
44
- {React.createElement(as, props)}
45
- </Provider>
46
-)
42
+export const Theme = React.forwardRef(function Theme({theme: colorMode, as = Box, ...props}, ref) {
43
+ return (
44
+ <Provider colorMode={colorMode} nightScheme="dark_dimmed">
45
+ {React.createElement(as, {...props, ref})}
46
+ </Provider>
47
+ )
48
+})
49
+
50
+export const LightTheme = React.forwardRef(function LightTheme(props, ref) {
51
+ return <Theme ref={ref} theme="light" {...props} />
52
+})
53
48
-export const LightTheme = props => <Theme theme="light" {...props} />
49
-export const DarkTheme = props => <Theme theme="dark" {...props} />
54
+export const DarkTheme = React.forwardRef(function DarkTheme(props, ref) {
55
+ return <Theme ref={ref} theme="dark" {...props} />
56
+})