Convert primer colors to use new color names
Luke Karrys committed
Oct 16, 2023 at 10:43 UTC
a9c2e4477485c51111ab2a7101a48e28e0ae19cd
21 files changed
+279
-192
gatsby-browser.js
+2
-2
@@ -1,2 +1,2 @@
1
-export {default as wrapPageElement} from './src/page-element'
2
-export {default as wrapRootElement} from './src/root-element'
1
+export {default as wrapPageElement} from './src/page'
2
+export {default as wrapRootElement} from './src/root'
gatsby-config.js
+2
-3
@@ -1,7 +1,7 @@
1
const path = require('path')
2
const fs = require('fs')
3
4
-const {NODE_ENV, GATSBY_PARTIAL_CONTENT, GATSBY_CONTENT_DIR = 'content'} = process.env
4
+const {NODE_ENV, GATSBY_PARTIAL_CONTENT, GATSBY_CONTENT_IGNORE, GATSBY_CONTENT_DIR = 'content'} = process.env
5
const DEV = NODE_ENV === 'development'
6
const CONTENT_DIR = path.resolve(GATSBY_CONTENT_DIR)
7
@@ -15,7 +15,7 @@ const walkDirs = dir => {
15
}
16
17
const getContentOptions = () => {
18
- if (!DEV || !GATSBY_PARTIAL_CONTENT) {
18
+ if (!DEV || (!GATSBY_PARTIAL_CONTENT && !GATSBY_CONTENT_IGNORE)) {
19
return
20
}
21
@@ -47,7 +47,6 @@ module.exports = {
47
shortName: 'npm',
48
description: 'Documentation for the npm registry, website, and command-line interface',
49
lang: 'en',
50
- // eslint-disable-next-line max-len
50
imageUrl: 'https://user-images.githubusercontent.com/29712634/81721690-e2fb5d80-9445-11ea-8602-4b2294c964f3.png',
51
},
52
plugins: [
gatsby-ssr.js
+2
-2
@@ -1,2 +1,2 @@
1
-export {default as wrapPageElement} from './src/page-element'
2
-export {default as wrapRootElement} from './src/root-element'
1
+export {default as wrapPageElement} from './src/page'
2
+export {default as wrapRootElement} from './src/root'
src/components/clipboard-copy.js
+5
-11
@@ -1,16 +1,9 @@
1
import React from 'react'
2
-import {Button, Octicon, themeGet} from '@primer/react'
2
+import {Button, Octicon} from '@primer/react'
3
import {CheckIcon, CopyIcon} from '@primer/octicons-react'
4
-import styled from 'styled-components'
4
import copy from 'copy-to-clipboard'
5
import {announce} from '../util/aria-live'
6
8
-const CopyToClipboard = styled(Button)`
9
- &:focus {
10
- box-shadow: 0 0 0 3px ${themeGet('colors.blue.5')};
11
- }
12
-`
13
-
7
function ClipboardCopy({value}) {
8
const [copied, setCopied] = React.useState(false)
9
@@ -25,16 +18,17 @@ function ClipboardCopy({value}) {
18
}, [copied])
19
20
return (
28
- <CopyToClipboard
21
+ <Button
22
aria-label="Copy to clipboard"
23
onClick={() => {
24
copy(value)
25
setCopied(true)
26
announce(`Copied to clipboard`)
27
}}
28
+ sx={{px: 2}}
29
>
36
- <Octicon icon={copied ? CheckIcon : CopyIcon} sx={{color: copied ? 'green.5' : 'gray.7'}} />
37
- </CopyToClipboard>
30
+ <Octicon icon={copied ? CheckIcon : CopyIcon} sx={{color: copied ? 'success.fg' : 'fg.muted'}} />
31
+ </Button>
32
)
33
}
34
src/components/contributors.js
+1
-1
@@ -37,7 +37,7 @@ function Contributors({logins, latestCommit}) {
37
))}
38
</Box>
39
{latestCommit ? (
40
- <Text sx={{fontSize: 1, color: 'gray.7', mt: 1}}>
40
+ <Text sx={{fontSize: 1, color: 'fg.muted', mt: 1}}>
41
Last edited by <Link href={`https://github.com/${latestCommit.login}`}>{latestCommit.login}</Link> on{' '}
42
<Link href={latestCommit.url}>{format(new Date(latestCommit.date))}</Link>
43
</Text>
src/components/dark-text-input.js
deleted
-21
@@ -1,21 +0,0 @@
1
-import {TextInput, themeGet} from '@primer/react'
2
-import styled from 'styled-components'
3
-
4
-const DarkTextInput = styled(TextInput)`
5
- /* The font-size of inputs should never be less than 16px.
6
- * Otherwise, iOS browsers will zoom in when the input is focused.
7
- * TODO: Update font-size of TextInput in @primer/react.
8
- */
9
- font-size: ${themeGet('fontSizes.2')} !important;
10
- color: ${themeGet('colors.white')};
11
- background-color: rgba(255, 255, 255, 0.07);
12
- border: 1px solid transparent;
13
- box-shadow: none;
14
-
15
- &:focus {
16
- border: 1px solid rgba(255, 255, 255, 0.15);
17
- outline: none;
18
- box-shadow: none;
19
- }
20
-`
21
-export default DarkTextInput
src/components/drawer.js
+1
-1
@@ -43,8 +43,8 @@ const Drawer = ({isOpen, onDismiss, children}) => (
43
bottom: 0,
44
bg: 'gray.0',
45
width: 300,
46
- zIndex: 1,
46
}}
47
+ style={{zIndex: 1}}
48
key="drawer"
49
as={motion.div}
50
initial={{x: '100%'}}
src/components/header.js
+7
-4
@@ -37,13 +37,16 @@ function Header() {
37
<Box sx={{top: 0, position: 'sticky', zIndex: 1}} role="banner">
38
<NpmHeaderBar />
39
<Box
40
+ as="header"
41
sx={{
42
display: 'flex',
43
height: HEADER_HEIGHT,
44
px: [3, null, null, 4],
45
alignItems: 'center',
46
justifyContent: 'space-between',
46
- bg: '#333333',
47
+ bg: 'canvas.default',
48
+ border: '1px solid',
49
+ borderColor: 'border.muted',
50
}}
51
>
52
<Box sx={{display: 'flex', alignItems: 'center'}}>
@@ -52,8 +55,8 @@ function Header() {
55
to="/"
56
sx={{
57
mr: 4,
55
- color: '#dddddd',
56
- fontWeight: '600',
58
+ fontWeight: 'bold',
59
+ color: 'fg.default',
60
display: 'flex',
61
alignItems: 'center',
62
}}
@@ -69,7 +72,7 @@ function Header() {
72
<Box sx={{display: ['none', null, null, 'block']}}>
73
<Box sx={{display: 'flex', alignItems: 'center', color: 'gray.2'}}>
74
{headerNavItems.map((item, index) => (
72
- <Link key={index} href={item.url} sx={{display: 'block', color: 'inherit', ml: 4}}>
75
+ <Link key={index} href={item.url} sx={{display: 'block', ml: 4}}>
76
{item.title}
77
</Link>
78
))}
src/components/hero.js
+2
-2
@@ -10,10 +10,10 @@ function Hero() {
10
<ThemeProvider colorMode="night" nightScheme="dark_dimmed">
11
<Box sx={{bg: 'canvas.default', py: 6}}>
12
<Container>
13
- <Heading as="h1" sx={{color: 'fg.onEmphasis', fontSize: 7, m: 0}}>
13
+ <Heading as="h1" sx={{color: 'accent.fg', fontSize: 7, m: 0}}>
14
{title}
15
</Heading>
16
- <Text as="p" sx={{m: 0, color: 'fg.onEmphasis', fontSize: 4}}>
16
+ <Text as="p" sx={{m: 0, color: 'fg.default', fontSize: 4}}>
17
{description}
18
</Text>
19
</Container>
src/components/mobile-search.js
+20
-16
@@ -3,7 +3,7 @@ import {Button, Box} from '@primer/react'
3
import {XIcon, SearchIcon} from '@primer/octicons-react'
4
import {AnimatePresence, motion} from 'framer-motion'
5
import {FocusOn} from 'react-focus-on'
6
-import DarkTextInput from './dark-text-input'
6
+import TextInput from './text-input'
7
import SearchResults from './search-results'
8
import useSiteMetadata from '../hooks/use-site-metadata'
9
@@ -21,7 +21,7 @@ function MobileSearch({onDismiss, ...props}) {
21
<Box
22
sx={{
23
position: 'fixed',
24
- top: '10px',
24
+ top: '10px', // TODO: use constant
25
left: 0,
26
right: 0,
27
bottom: 0,
@@ -35,7 +35,7 @@ function MobileSearch({onDismiss, ...props}) {
35
left: 0,
36
right: 0,
37
bottom: 0,
38
- bg: 'rgba(0,0,0,0.5)',
38
+ bg: 'primer.canvas.backdrop',
39
zIndex: -1,
40
}}
41
as={motion.div}
@@ -45,7 +45,7 @@ function MobileSearch({onDismiss, ...props}) {
45
onClick={handleDismiss}
46
/>
47
<Box sx={{display: 'flex', flexDirection: 'column', height: isOpen ? '100%' : 'auto'}}>
48
- <Box sx={{display: 'flex', bg: 'gray.9', color: 'white', p: 3, flex: '0 0 auto'}}>
48
+ <Box sx={{display: 'flex', bg: 'canvas.default', color: 'fg.default', p: 3, flex: '0 0 auto'}}>
49
<motion.div
50
initial={{scaleX: 0.1}}
51
animate={{scaleX: 1}}
@@ -53,11 +53,12 @@ function MobileSearch({onDismiss, ...props}) {
53
transition={{type: 'tween', duration: 0.2}}
54
style={{width: '100%', originX: '100%'}}
55
>
56
- <DarkTextInput
56
+ <TextInput
57
+ leadingVisual={SearchIcon}
58
{...getInputProps({
59
placeholder: `Search ${siteMetadata.title}`,
60
'aria-label': `Search ${siteMetadata.title}`,
60
- width: '100%',
61
+ sx: {width: '100%'},
62
})}
63
/>
64
</motion.div>
@@ -66,16 +67,19 @@ function MobileSearch({onDismiss, ...props}) {
67
</Button>
68
</Box>
69
<Box
69
- {...getMenuProps()}
70
- sx={{
71
- display: 'flex',
72
- bg: 'white',
73
- py: isOpen ? 1 : 0,
74
- flexDirection: 'column',
75
- flex: '1 1 auto',
76
- overflow: 'auto',
77
- WebkitOverflowScrolling: 'touch',
78
- }}
70
+ {...getMenuProps({
71
+ sx: {
72
+ display: 'flex',
73
+ bg: 'canvas.default',
74
+ py: isOpen ? 1 : 0,
75
+ flexDirection: 'column',
76
+ flex: '1 1 auto',
77
+ },
78
+ style: {
79
+ overflow: 'auto',
80
+ WebkitOverflowScrolling: 'touch',
81
+ },
82
+ })}
83
>
84
{isOpen ? <SearchResults {...{results, getItemProps, highlightedIndex}} /> : null}
85
</Box>
src/components/nav-drawer.js
+19
-10
@@ -38,25 +38,31 @@ function NavDrawer() {
38
display: 'flex',
39
flexDirection: 'column',
40
height: '100%',
41
- bg: 'gray.0',
41
+ bg: 'canvas.default',
42
overflow: 'auto',
43
WebkitOverflowScrolling: 'touch',
44
}}
45
>
46
- <Box sx={{display: 'flex', flexDirection: 'column', flex: '1 0 auto', color: 'gray.7', bg: 'gray.0'}}>
46
+ <Box
47
+ sx={{display: 'flex', flexDirection: 'column', flex: '1 0 auto', color: 'fg.default', bg: 'canvas.default'}}
48
+ >
49
<Box
48
- sx={{borderStyle: 'solid', borderWidth: 0, borderRadius: 0, borderBottomWidth: 1, borderColor: 'gray.7'}}
50
+ sx={{
51
+ borderWidth: 0,
52
+ borderRadius: 0,
53
+ borderBottomWidth: 1,
54
+ borderColor: 'border.muted',
55
+ borderStyle: 'solid',
56
+ }}
57
>
58
<Box
59
sx={{
52
- display: 'flex',
60
py: 3,
61
pl: 4,
62
pr: 3,
63
alignItems: 'center',
64
justifyContent: 'space-between',
58
- color: 'gray.1',
59
- bg: 'gray.9',
65
+ display: 'flex',
66
}}
67
>
68
<Link as={GatsbyLink} to="/" sx={{display: 'inline-block', color: 'inherit'}}>
@@ -71,17 +77,20 @@ function NavDrawer() {
77
<NavItems />
78
</Box>
79
</Box>
74
- <Box sx={{display: 'flex', flexDirection: 'column', flex: '1 0 auto', color: 'gray.1', bg: 'gray.9'}}>
80
+ <Box
81
+ sx={{flexDirection: 'column', flex: '1 0 auto', color: 'fg.default', bg: 'canvas.default', display: 'flex'}}
82
+ >
83
{headerNavItems.map((item, index) => (
84
<Box
85
key={item.title}
86
sx={{
79
- borderStyle: 'solid',
87
borderWidth: 0,
88
borderRadius: 0,
89
borderTopWidth: index !== 0 ? 1 : 0,
83
- borderColor: 'gray.7',
84
- p: 4,
90
+ borderColor: 'border.muted',
91
+ px: 4,
92
+ py: 3,
93
+ borderStyle: 'solid',
94
}}
95
>
96
<Link key={index} href={item.url} sx={{color: 'inherit', display: 'block'}}>
src/components/page-footer.js
+3
-3
@@ -8,13 +8,13 @@ function PageFooter({editUrl, contributors = {}}) {
8
return editUrl || logins.length ? (
9
<Box
10
sx={{
11
- borderStyle: 'solid',
12
- borderColor: 'border.default',
13
- borderRadius: 2,
11
borderWidth: 0,
12
borderTopWidth: 1,
13
+ borderRadius: 0,
14
mt: 8,
15
py: 5,
16
+ borderStyle: 'solid',
17
+ borderColor: 'border.default',
18
}}
19
>
20
<Box sx={{display: 'grid', gap: 4}}>
src/components/search-results.js
+15
-11
@@ -29,17 +29,21 @@ function SearchResults({results, getItemProps, highlightedIndex}) {
29
return results.map((item, index) => (
30
<Box
31
key={item.path}
32
- sx={{
33
- display: 'flex',
34
- flexDirection: 'column',
35
- flex: '0 0 auto',
36
- px: 3,
37
- py: 2,
38
- color: highlightedIndex === index ? 'white' : 'gray.8',
39
- bg: highlightedIndex === index ? 'blue.5' : 'transparent',
40
- cursor: 'pointer',
41
- }}
42
- {...getItemProps({item})}
32
+ {...getItemProps({
33
+ item,
34
+ style: {cursor: 'pointer'},
35
+ sx: {
36
+ display: 'flex',
37
+ flexDirection: 'column',
38
+ flex: '0 0 auto',
39
+ px: 3,
40
+ py: 2,
41
+ color: 'fg.default',
42
+ fontSize: 1,
43
+ bg: highlightedIndex === index ? 'neutral.muted' : 'transparent',
44
+ cursor: 'pointer',
45
+ },
46
+ })}
47
>
48
<Breadcrumbs item={item} highlighted={highlightedIndex === index} />
49
{item.title}
src/components/search.js
+11
-11
@@ -1,6 +1,6 @@
1
import React from 'react'
2
import {Box} from '@primer/react'
3
-import DarkTextInput from './dark-text-input'
3
+import TextInput from './text-input'
4
import SearchResults from './search-results'
5
import useSiteMetadata from '../hooks/use-site-metadata'
6
@@ -10,7 +10,7 @@ function Search(props) {
10
11
return (
12
<Box sx={{position: 'relative'}}>
13
- <DarkTextInput
13
+ <TextInput
14
sx={{width: '240px'}}
15
{...getInputProps({
16
placeholder: `Search ${siteMetadata.title}`,
@@ -27,17 +27,17 @@ function Search(props) {
27
>
28
{isOpen ? (
29
<Box
30
+ style={{overflow: 'auto'}}
31
sx={{
31
- borderWidth: 1,
32
- borderStyle: 'solid',
33
- borderColor: 'border.default',
34
- borderRadius: 2,
35
- minWidth: '300px',
32
+ minWidth: 300,
33
maxHeight: '70vh',
37
- py: 1,
38
- boxShadow: 'medium',
39
- bg: 'white',
40
- overflow: 'auto',
34
+ p: 2,
35
+ boxShadow: 'shadow.large',
36
+ borderColor: 'border.muted',
37
+ bg: 'canvas.overlay',
38
+ borderRadius: '12px',
39
+ borderWidth: '1px',
40
+ borderStyle: 'solid',
41
}}
42
>
43
<SearchResults {...{results, getItemProps, highlightedIndex}} />
src/components/sidebar.js
+29
-5
@@ -3,6 +3,30 @@ import React from 'react'
3
import NavItems from './nav-items'
4
import {HEADER_HEIGHT} from '../constants'
5
6
+function usePersistentScroll(id) {
7
+ const ref = React.useRef()
8
+
9
+ const handleScroll = React.useCallback(
10
+ // Save scroll position in session storage on every scroll change
11
+ event => window.sessionStorage.setItem(id, event.target.scrollTop),
12
+ [id],
13
+ )
14
+
15
+ React.useLayoutEffect(() => {
16
+ // Restore scroll position when component mounts
17
+ const scrollPosition = window.sessionStorage.getItem(id)
18
+ if (scrollPosition && ref.current) {
19
+ ref.current.scrollTop = scrollPosition
20
+ }
21
+ }, [id])
22
+
23
+ // Return props to spread onto the scroll container
24
+ return {
25
+ ref,
26
+ onScroll: handleScroll,
27
+ }
28
+}
29
+
30
const Sidebar = () => (
31
<Box
32
role="navigation"
@@ -11,19 +35,19 @@ const Sidebar = () => (
35
top: `${HEADER_HEIGHT}px`,
36
height: `calc(100vh - ${HEADER_HEIGHT}px)`,
37
minWidth: 260,
14
- color: 'gray.8',
15
- bg: 'gray.0',
38
}}
39
>
40
<Box
41
+ {...usePersistentScroll('sidebar')}
42
+ style={{overflow: 'auto'}}
43
sx={{
20
- borderStyle: 'solid',
21
- borderColor: 'border.default',
44
borderWidth: 0,
45
borderRightWidth: 1,
46
borderRadius: 0,
47
height: '100%',
26
- overflow: 'auto',
48
+ borderStyle: 'solid',
49
+ borderColor: 'border.subtle',
50
+ px: 2,
51
}}
52
>
53
<Box sx={{display: 'flex', flexDirection: 'column'}} role="list">
src/components/table-of-contents.js
+20
-17
@@ -1,26 +1,29 @@
1
import React from 'react'
2
-import {Box, Link, Text, Octicon, Details, useDetails} from '@primer/react'
2
+import {Box, Text, Octicon, Details, useDetails} from '@primer/react'
3
import {ChevronDownIcon, ChevronRightIcon} from '@primer/octicons-react'
4
import {usePageContext} from '../layout'
5
import {HEADER_HEIGHT} from '../constants'
6
+import {NavList} from '@primer/react/drafts'
7
7
-const TableOfContents = ({items, depth = 0, labelId}) => (
8
- <Box
9
- key={items}
10
- as="ul"
11
- role="list"
12
- sx={{m: 0, p: 0, listStyle: 'none', lineHeight: '1.4em'}}
13
- aria-labelledby={labelId}
14
- >
8
+const TableOfContentsItems = ({items}) => (
9
+ <>
10
{items.map(item => (
16
- <Box as="li" role="listitem" key={item.url} sx={{pl: depth > 0 ? 3 : 0}}>
17
- <Link key={item.title} href={item.url} sx={{display: 'inline-block', py: 1, color: 'gray.6'}}>
18
- {item.title}
19
- </Link>
20
- {item.items ? <TableOfContents items={item.items} depth={depth + 1} /> : null}
21
- </Box>
11
+ <NavList.Item key={item.title} href={item.url}>
12
+ {item.title}
13
+ {item.items ? (
14
+ <NavList.SubNav>
15
+ <TableOfContentsItems items={item.items} />
16
+ </NavList.SubNav>
17
+ ) : null}
18
+ </NavList.Item>
19
))}
23
- </Box>
20
+ </>
21
+)
22
+
23
+const TableOfContents = ({'aria-labelledby': ariaLabelledBy, items}) => (
24
+ <NavList aria-labelledby={ariaLabelledBy}>
25
+ <TableOfContentsItems items={items} />
26
+ </NavList>
27
)
28
29
const withTableOfContents = Component => {
@@ -66,6 +69,6 @@ export const Desktop = withTableOfContents(({items}) => (
69
<Text id="table-of-content-label" sx={{display: 'inline-block', fontWeight: 'bold', mb: 1}}>
70
Table of contents
71
</Text>
69
- <TableOfContents items={items} labelId="table-of-content-label" />
72
+ <TableOfContents items={items} aria-labelledby="table-of-content-label" />
73
</Box>
74
))
src/components/text-input.js
new
+17
@@ -0,0 +1,17 @@
1
+import {TextInput as PrimerTextInput, themeGet} from '@primer/react'
2
+import styled from 'styled-components'
3
+
4
+const TextInput = styled(PrimerTextInput)`
5
+ /* The font-size of inputs should never be less than 16px.
6
+ * Otherwise, iOS browsers will zoom in when the input is focused.
7
+ * TODO: Update font-size of TextInput in @primer/react.
8
+ */
9
+ input {
10
+ font-size: ${themeGet('fontSizes.2')} !important;
11
+ }
12
+
13
+ input::placeholder {
14
+ color: ${themeGet('colors.fg.muted')} !important;
15
+ }
16
+`
17
+export default TextInput
src/mdx/code.js
+2
-11
@@ -22,24 +22,15 @@ function Code({className: language = '', children}) {
22
tabIndex={0}
23
as="pre"
24
className={className}
25
- sx={{
26
- borderWidth: 1,
27
- borderStyle: 'solid',
28
- borderColor: 'border.default',
29
- borderRadius: 2,
30
- mt: 0,
31
- mb: 3,
32
- p: 3,
33
- border: 0,
34
- }}
25
style={{...style, overflow: 'auto'}}
26
+ sx={{borderRadius: 2, mt: 0, mb: 3, p: 3, border: 0}}
27
>
28
{/* This is the scroll handle, it is supposed to be focused with keyboard and scroll a wide codebox horizontally */}
29
<div aria-hidden="true" style={{visibility: 'hidden', position: 'absolute', ...size}} ref={scrollRef} />
30
{tokens.map((line, i) => (
31
<div key={i} {...getLineProps({line, key: i})}>
32
{line.map((token, key) => (
42
- <Text key={key} sx={{fontFamily: 'mono', fontSize: 1}} {...getTokenProps({token, key})} />
33
+ <Text key={key} {...getTokenProps({token, key})} sx={{fontFamily: 'mono', fontSize: 1}} />
34
))}
35
</div>
36
))}
src/mdx/index.js
+121
-61
@@ -1,6 +1,7 @@
1
import React from 'react'
2
-import {Box, Heading, themeGet, Text, Link as PrimerLink} from '@primer/react'
2
+import {Box, Heading, themeGet, Text, Link, Octicon} from '@primer/react'
3
import styled from 'styled-components'
4
+import {variant} from 'styled-system'
5
import {withPrefix} from 'gatsby'
6
import {LinkIcon} from '@primer/octicons-react'
7
import textContent from 'react-addons-text-content'
@@ -16,18 +17,23 @@ const required = (prop, name) => {
17
return prop
18
}
19
19
-export const Link = props => {
20
- return <PrimerLink {...props} underline={true} />
21
-}
22
-
23
-export {Code, NavHierarchy as Index}
20
+export {Link, Code, NavHierarchy as Index}
21
22
export const Pre = ({children}) => children
23
24
const SkipLinkBase = props => (
28
- <PrimerLink {...props} href={`#${SKIP_NAV}`} sx={{backgroundColor: 'blue.6', color: 'white', p: 3, fontSize: 1}}>
25
+ <Link
26
+ {...props}
27
+ href={`#${SKIP_NAV}`}
28
+ sx={{
29
+ p: 3,
30
+ color: 'fg.onEmphasis',
31
+ backgroundColor: 'accent.emphasis',
32
+ fontSize: 1,
33
+ }}
34
+ >
35
Skip to content
30
- </PrimerLink>
36
+ </Link>
37
)
38
39
export const SkipLink = styled(SkipLinkBase)`
@@ -57,14 +63,17 @@ const StyledHeading = styled(Heading)`
63
margin-top: ${themeGet('space.4')};
64
margin-bottom: ${themeGet('space.3')};
65
scroll-margin-top: ${HEADER_HEIGHT + 24}px;
66
+ line-height: ${themeGet('lineHeights.condensed')};
67
61
- & .octicon-link {
62
- visibility: hidden;
63
- }
68
+ @media (hover: hover) {
69
+ & .octicon-link {
70
+ visibility: hidden;
71
+ }
72
65
- &:hover .octicon-link,
66
- &:focus-within .octicon-link {
67
- visibility: visible;
73
+ &:hover .octicon-link,
74
+ &:focus-within .octicon-link {
75
+ visibility: visible;
76
+ }
77
}
78
`
79
@@ -76,35 +85,56 @@ const Headings = {
85
86
return (
87
<StyledHeading id={id} {...props}>
79
- <PrimerLink href={`#${id}`} sx={{p: 2, ml: -32, color: 'gray.8'}} aria-label={`${text} permalink`}>
80
- <LinkIcon className="octicon-link" verticalAlign="middle" />
81
- </PrimerLink>
82
- {children}
88
+ <Link
89
+ href={`#${id}`}
90
+ sx={{
91
+ color: 'inherit',
92
+ '&:hover, &:focus': {
93
+ textDecoration: 'none',
94
+ },
95
+ }}
96
+ aria-label={`${text} permalink`}
97
+ >
98
+ {children}
99
+ <Octicon
100
+ icon={LinkIcon}
101
+ className="octicon-link"
102
+ sx={{
103
+ ml: 2,
104
+ color: 'fg.muted',
105
+ // !important is needed here to override default icon styles
106
+ verticalAlign: 'middle !important',
107
+ }}
108
+ />
109
+ </Link>
110
</StyledHeading>
111
)
112
},
113
h1: styled(StyledHeading).attrs({as: 'h1'})`
87
- padding-bottom: ${themeGet('space.1')};
88
- font-size: ${themeGet('fontSizes.5')};
89
- border-bottom: 1px solid ${themeGet('colors.gray.2')};
114
+ padding-bottom: ${themeGet('space.2')};
115
+ font-size: ${themeGet('fontSizes.7')};
116
+ border-bottom: 1px solid ${themeGet('colors.border.default')};
117
`,
118
h2: styled(StyledHeading).attrs({as: 'h2'})`
92
- padding-bottom: ${themeGet('space.1')};
119
+ padding-bottom: ${themeGet('space.2')};
120
font-size: ${themeGet('fontSizes.4')};
94
- border-bottom: 1px solid ${themeGet('colors.gray.2')};
121
+ border-bottom: 1px solid ${themeGet('colors.border.default')};
122
+ font-weight: ${themeGet('fontWeights.semibold')};
123
`,
124
h3: styled(StyledHeading).attrs({as: 'h3'})`
125
font-size: ${themeGet('fontSizes.3')};
126
+ font-weight: ${themeGet('fontWeights.semibold')};
127
`,
128
h4: styled(StyledHeading).attrs({as: 'h4'})`
129
font-size: ${themeGet('fontSizes.2')};
130
+ font-weight: ${themeGet('fontWeights.semibold')};
131
`,
132
h5: styled(StyledHeading).attrs({as: 'h5'})`
133
font-size: ${themeGet('fontSizes.1')};
134
`,
135
h6: styled(StyledHeading).attrs({as: 'h6'})`
136
font-size: ${themeGet('fontSizes.1')};
107
- color: ${themeGet('colors.gray.5')};
137
+ color: ${themeGet('colors.fg.muted')};
138
`,
139
wrap(as) {
140
return props => <Headings.Markdown as={Headings[as]} {...props} />
@@ -121,8 +151,8 @@ export const H6 = Headings.wrap('h6')
151
export const Blockquote = styled.blockquote`
152
margin: 0 0 ${themeGet('space.3')};
153
padding: 0 ${themeGet('space.3')};
124
- color: ${themeGet('colors.gray.5')};
125
- border-left: 0.25em solid ${themeGet('colors.gray.2')};
154
+ color: ${themeGet('colors.fg.muted')};
155
+ border-left: 0.25em solid ${themeGet('colors.border.default')};
156
157
> :first-child {
158
margin-top: 0;
@@ -151,25 +181,25 @@ export const DescriptionList = styled.dl`
181
`
182
183
export const HorizontalRule = styled.hr`
154
- height: ${themeGet('space.1')};
184
+ height: ${themeGet('borderWidths.1')};
185
padding: 0;
186
margin: ${themeGet('space.4')} 0;
157
- background-color: ${themeGet('colors.gray.2')};
187
+ background-color: ${themeGet('colors.border.default')};
188
border: 0;
189
`
190
191
export const Image = styled.img`
192
max-width: 100%;
193
box-sizing: content-box;
164
- background-color: ${themeGet('colors.white')};
194
+ background-color: ${themeGet('colors.white')}; // TODO: this is wrong
195
`
196
197
export const InlineCode = styled.code`
198
padding: 0.2em 0.4em;
199
font-family: ${themeGet('fonts.mono')};
200
font-size: 85%;
171
- background-color: ${themeGet('colors.gray.1')};
172
- border-radius: ${themeGet('radii.1')};
201
+ background-color: ${themeGet('colors.neutral.muted')};
202
+ border-radius: ${themeGet('radii.2')};
203
`
204
205
export const UnorderedList = styled.ul`
@@ -201,55 +231,87 @@ export const Paragraph = styled.p`
231
`
232
233
export const Table = styled.table`
204
- display: block;
234
width: 100%;
235
margin: 0 0 ${themeGet('space.3')};
236
overflow: auto;
237
+ border-collapse: separate;
238
+ border-spacing: 0px;
239
240
th {
241
font-weight: ${themeGet('fontWeights.bold')};
242
+ background-color: ${themeGet('colors.neutral.subtle')};
243
}
244
245
th,
246
td {
247
padding: ${themeGet('space.2')} ${themeGet('space.3')};
216
- border: 1px solid ${themeGet('colors.gray.2')};
248
+ border-color: ${themeGet('colors.border.muted')};
249
+ border-style: solid;
250
+ border-width: 0;
251
+ border-left-width: ${themeGet('borderWidths.1')};
252
+ border-top-width: ${themeGet('borderWidths.1')};
253
}
254
219
- tr {
220
- background-color: ${themeGet('colors.white')};
221
- border-top: 1px solid ${themeGet('colors.gray.2')};
255
+ tr:last-child td {
256
+ border-bottom-width: ${themeGet('borderWidths.1')};
257
+ }
258
223
- &:nth-child(2n) {
224
- background-color: ${themeGet('colors.gray.1')};
225
- }
259
+ tr td:last-child,
260
+ tr th:last-child {
261
+ border-right-width: ${themeGet('borderWidths.1')};
262
+ }
263
+
264
+ thead th:first-child {
265
+ border-top-left-radius: ${themeGet('radii.2')};
266
+ }
267
+
268
+ thead th:last-child {
269
+ border-top-right-radius: ${themeGet('radii.2')};
270
+ }
271
+
272
+ tbody tr:last-child td:last-child {
273
+ border-bottom-right-radius: ${themeGet('radii.2')};
274
+ }
275
+
276
+ tbody tr:last-child td:first-child {
277
+ border-bottom-left-radius: ${themeGet('radii.2')};
278
}
279
280
img {
281
background-color: transparent;
282
+ vertical-align: middle;
283
}
284
`
285
233
-export const Note = ({children}) => (
234
- <Box
235
- sx={{
236
- borderWidth: 1,
237
- borderStyle: 'solid',
238
- borderRadius: 0,
239
- borderColor: 'blue.1',
240
- backgroundColor: 'blue.0',
241
- px: 3,
242
- py: 2,
243
- my: 4,
244
- }}
245
- >
246
- {React.Children.toArray(children).map((child, index, list) =>
247
- React.cloneElement(child, {
248
- style: index === list.length - 1 ? {marginBottom: '0'} : null,
249
- }),
250
- )}
251
- </Box>
252
-)
286
+const StyledNote = styled.div`
287
+ padding: ${themeGet('space.3')};
288
+ margin-bottom: ${themeGet('space.3')};
289
+ border-radius: ${themeGet('radii.2')};
290
+ border-left: ${themeGet('radii.2')} solid;
291
+
292
+ & *:last-child {
293
+ margin-bottom: 0;
294
+ }
295
+
296
+ ${variant({
297
+ variants: {
298
+ info: {
299
+ borderColor: 'accent.muted',
300
+ bg: 'accent.subtle',
301
+ },
302
+ warning: {
303
+ borderColor: 'attention.muted',
304
+ bg: 'attention.subtle',
305
+ },
306
+ danger: {
307
+ borderColor: 'danger.muted',
308
+ bg: 'danger.subtle',
309
+ },
310
+ },
311
+ })}
312
+`
313
+
314
+export const Note = ({variant = 'info', ...props}) => <StyledNote variant={variant} {...props} />
315
316
export const Prompt = ({children}) => (
317
<Box
@@ -259,8 +321,6 @@ export const Prompt = ({children}) => (
321
mb: 3,
322
p: 3,
323
border: 0,
262
- color: 'rgb(57, 58, 52)',
263
- backgroundColor: 'rgb(246, 248, 250)',
324
overflow: 'auto',
325
}}
326
>