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 >
src/page.js renamed
src/root.js renamed