Setting up accessibility linting (#433)
* Adding required packages and configurations * Fixes done by npm run lintfix * Linti errors fixed by disabling some rules * Fixing lint errors manually * Addressing comment
20shivangi committed
Feb 8, 2023 at 10:11 UTC
43ece07c151fd25e78c956d8650897e5d59b2c17
64 files changed
+532
-686
package-lock.json
+17
-8
@@ -2631,6 +2631,12 @@
2631
"resolved": "https://registry.npmjs.org/@github/paste-markdown/-/paste-markdown-1.4.2.tgz",
2632
"integrity": "sha512-ZwSgPyo9nA6TRngXV0QnFT4e5ujeOGxRDWN2aa6qfimz2o2VOsJ9bFGuGvB723nvzq5z9zKr6JWGtvK7MSJj3w=="
2633
},
2634
+ "node_modules/@github/prettier-config": {
2635
+ "version": "0.0.6",
2636
+ "resolved": "https://registry.npmjs.org/@github/prettier-config/-/prettier-config-0.0.6.tgz",
2637
+ "integrity": "sha512-Sdb089z+QbGnFF2NivbDeaJ62ooPlD31wE6Fkb/ESjAOXSjNJo+gjqzYYhlM7G3ERJmKFZRUJYMlsqB7Tym8lQ==",
2638
+ "dev": true
2639
+ },
2640
"node_modules/@github/relative-time-element": {
2641
"version": "4.1.2",
2642
"resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.1.2.tgz",
@@ -12133,9 +12139,9 @@
12139
}
12140
},
12141
"node_modules/eslint": {
12136
- "version": "8.31.0",
12137
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz",
12138
- "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==",
12142
+ "version": "8.33.0",
12143
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.33.0.tgz",
12144
+ "integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==",
12145
"dependencies": {
12146
"@eslint/eslintrc": "^1.4.1",
12147
"@humanwhocodes/config-array": "^0.11.8",
@@ -24343,9 +24349,9 @@
24349
}
24350
},
24351
"node_modules/prettier": {
24346
- "version": "2.8.1",
24347
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
24348
- "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
24352
+ "version": "2.8.3",
24353
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
24354
+ "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
24355
"dev": true,
24356
"bin": {
24357
"prettier": "bin-prettier.js"
@@ -32532,15 +32538,18 @@
32538
"styled-system": "^5.1.5"
32539
},
32540
"devDependencies": {
32541
+ "@github/prettier-config": "^0.0.6",
32542
"@npmcli/template-oss": "4.11.0",
32543
"@testing-library/jest-dom": "^5.16.5",
32544
"babel-jest": "^29.3.1",
32538
- "eslint": "^8.29.0",
32545
+ "eslint": "^8.33.0",
32546
+ "eslint-plugin-github": "^4.6.0",
32547
"eslint-plugin-jsx-a11y": "^6.6.1",
32548
"eslint-plugin-primer-react": "1.0.1",
32549
"eslint-plugin-react": "^7.31.11",
32550
"jest": "^29.3.1",
32543
- "jest-environment-jsdom": "^29.3.1"
32551
+ "jest-environment-jsdom": "^29.3.1",
32552
+ "prettier": "^2.8.3"
32553
},
32554
"engines": {
32555
"node": ">=18.0.0"
theme/.eslintrc.js
+7
-4
@@ -14,8 +14,9 @@ module.exports = {
14
'@npmcli',
15
'eslint:recommended',
16
'plugin:react/recommended',
17
- 'plugin:jsx-a11y/recommended',
17
+ 'plugin:github/react',
18
'plugin:primer-react/recommended',
19
+ 'prettier',
20
],
21
settings: {
22
react: {
@@ -28,16 +29,18 @@ module.exports = {
29
'react/display-name': 'off',
30
'eslint-comments/no-use': 'off',
31
'no-shadow': 'off',
31
- 'primer-react/no-system-props': ['warn', { includeUtilityComponents: true }],
32
+ 'primer-react/no-system-props': ['warn', {includeUtilityComponents: true}],
33
+ 'import/no-commonjs': 'off',
34
+ 'no-console': 'off',
35
},
36
overrides: [
37
{
38
files: ['gatsby-node.js', 'gatsby-config.js'],
36
- env: { node: true, browser: false },
39
+ env: {node: true, browser: false},
40
},
41
{
42
files: ['test/*', './src/**/__tests__/*'],
40
- env: { jest: true },
43
+ env: {jest: true},
44
},
45
],
46
}
theme/gatsby-browser.js
+2
-2
@@ -1,2 +1,2 @@
1
-export { default as wrapPageElement } from './src/components/wrap-page-element'
2
-export { default as wrapRootElement } from './src/components/wrap-root-element'
1
+export {default as wrapPageElement} from './src/components/wrap-page-element'
2
+export {default as wrapRootElement} from './src/components/wrap-root-element'
theme/gatsby-config.js
+2
-4
@@ -1,6 +1,6 @@
1
const path = require('path')
2
3
-module.exports = (themeOptions) => {
3
+module.exports = themeOptions => {
4
return {
5
plugins: [
6
'gatsby-plugin-styled-components',
@@ -26,9 +26,7 @@ module.exports = (themeOptions) => {
26
{
27
resolve: 'gatsby-plugin-manifest',
28
options: {
29
- icon: themeOptions.icon
30
- ? path.resolve(themeOptions.icon)
31
- : require.resolve('./src/images/favicon.png'),
29
+ icon: themeOptions.icon ? path.resolve(themeOptions.icon) : require.resolve('./src/images/favicon.png'),
30
},
31
},
32
],
theme/gatsby-node.js
+21
-31
@@ -6,7 +6,7 @@ const uniqBy = require('lodash.uniqby')
6
7
const CONTRIBUTOR_CACHE = new Map()
8
9
-exports.createSchemaCustomization = ({ actions: { createTypes } }) => {
9
+exports.createSchemaCustomization = ({actions: {createTypes}}) => {
10
createTypes(`
11
type Mdx implements Node {
12
frontmatter: MdxFrontmatter
@@ -26,10 +26,10 @@ exports.createSchemaCustomization = ({ actions: { createTypes } }) => {
26
`)
27
}
28
29
-exports.createPages = async ({ graphql, actions }, themeOptions) => {
30
- const repo = themeOptions.repo ? themeOptions.repo : { url: getPkgRepo(readPkgUp.sync().package).browse() }
29
+exports.createPages = async ({graphql, actions}, themeOptions) => {
30
+ const repo = themeOptions.repo ? themeOptions.repo : {url: getPkgRepo(readPkgUp.sync().package).browse()}
31
32
- const { data } = await graphql(`
32
+ const {data} = await graphql(`
33
{
34
allMdx {
35
nodes {
@@ -68,15 +68,9 @@ exports.createPages = async ({ graphql, actions }, themeOptions) => {
68
data.allMdx.nodes.map(async node => {
69
const pagePath = getPath(node)
70
71
- const rootAbsolutePath = path.resolve(
72
- process.cwd(),
73
- themeOptions.repoRootPath || '.'
74
- )
71
+ const rootAbsolutePath = path.resolve(process.cwd(), themeOptions.repoRootPath || '.')
72
76
- const fileRelativePath = path.relative(
77
- rootAbsolutePath,
78
- node.fileAbsolutePath
79
- )
73
+ const fileRelativePath = path.relative(rootAbsolutePath, node.fileAbsolutePath)
74
75
const editUrl = getEditUrl(themeOptions, repo, fileRelativePath, node.frontmatter)
76
@@ -98,10 +92,10 @@ exports.createPages = async ({ graphql, actions }, themeOptions) => {
92
})
93
94
if (node.frontmatter.redirect_from) {
101
- node.frontmatter.redirect_from.forEach((from) => {
95
+ for (const from of node.frontmatter.redirect_from) {
96
actions.createRedirect({
97
fromPath: from,
104
- toPath: '/' + pagePath,
98
+ toPath: `/${pagePath}`,
99
isPermanent: true,
100
redirectInBrowser: true,
101
})
@@ -109,18 +103,18 @@ exports.createPages = async ({ graphql, actions }, themeOptions) => {
103
if (pagePath.startsWith('cli/') && !from.endsWith('index')) {
104
actions.createRedirect({
105
fromPath: `${from}.html`,
112
- toPath: '/' + pagePath,
106
+ toPath: `/${pagePath}`,
107
isPermanent: true,
108
redirectInBrowser: true,
109
})
110
}
117
- })
111
+ }
112
}
119
- })
113
+ }),
114
)
115
}
116
123
-function getPath (node) {
117
+function getPath(node) {
118
// sites can programmatically override slug, that takes priority
119
if (node.fields && node.fields.slug) {
120
return node.fields.slug
@@ -132,14 +126,12 @@ function getPath (node) {
126
}
127
128
// finally, we'll just use the path on disk
135
- return path.join(
136
- node.parent.relativeDirectory,
137
- node.parent.name === 'index' ? '/' : node.parent.name
138
- )
129
+ return path
130
+ .join(node.parent.relativeDirectory, node.parent.name === 'index' ? '/' : node.parent.name)
131
.replace(/\\/g, '/') // Windows paths to forward slashes
132
}
133
142
-function getNameWithOwner (url) {
134
+function getNameWithOwner(url) {
135
const nwo = url.match(/^http(?:s)?:\/\/(?:www\.)?github\.com\/([^/]+\/[^/]+)(?:\/)?$/i)
136
137
if (nwo) {
@@ -149,7 +141,7 @@ function getNameWithOwner (url) {
141
return null
142
}
143
152
-function getGitHubData (repo, overrideData, filePath) {
144
+function getGitHubData(repo, overrideData, filePath) {
145
const gh = {
146
nwo: getNameWithOwner(repo.url),
147
branch: 'master',
@@ -168,7 +160,7 @@ function getGitHubData (repo, overrideData, filePath) {
160
if (overrideData.github_path) {
161
gh.path = overrideData.github_path
162
} else if (repo.path) {
171
- gh.path = repo.path + '/' + filePath
163
+ gh.path = `${repo.path}/${filePath}`
164
} else {
165
gh.path = filePath
166
}
@@ -176,7 +168,7 @@ function getGitHubData (repo, overrideData, filePath) {
168
return gh
169
}
170
179
-function getEditUrl (themeOptions, repo, filePath, overrideData = { }) {
171
+function getEditUrl(themeOptions, repo, filePath, overrideData = {}) {
172
if (themeOptions.editOnGitHub === false || overrideData.edit_on_github === false) {
173
return null
174
}
@@ -185,7 +177,7 @@ function getEditUrl (themeOptions, repo, filePath, overrideData = { }) {
177
return `https://github.com/${gh.nwo}/edit/${gh.branch}/${gh.path}`
178
}
179
188
-async function fetchContributors (repo, filePath, overrideData = { }, accessToken = '') {
180
+async function fetchContributors(repo, filePath, overrideData = {}, accessToken = '') {
181
const gh = getGitHubData(repo, overrideData, filePath)
182
183
const cached = CONTRIBUTOR_CACHE.get(gh)
@@ -206,7 +198,7 @@ async function fetchContributors (repo, filePath, overrideData = { }, accessToke
198
}
199
}
200
209
- const { data } = await axios.request(req)
201
+ const {data} = await axios.request(req)
202
203
const commits = data
204
.map(commit => ({
@@ -222,9 +214,7 @@ async function fetchContributors (repo, filePath, overrideData = { }, accessToke
214
CONTRIBUTOR_CACHE.set(gh, result)
215
return result
216
} catch (error) {
225
- console.error(
226
- `[ERROR] Unable to fetch contributors for ${filePath}. ${error.message}`
227
- )
217
+ console.error(`[ERROR] Unable to fetch contributors for ${filePath}. ${error.message}`)
218
return []
219
}
220
}
theme/gatsby-ssr.js
+2
-2
@@ -1,2 +1,2 @@
1
-export { default as wrapPageElement } from './src/components/wrap-page-element'
2
-export { default as wrapRootElement } from './src/components/wrap-root-element'
1
+export {default as wrapPageElement} from './src/components/wrap-page-element'
2
+export {default as wrapRootElement} from './src/components/wrap-root-element'
theme/index.js
+15
-15
@@ -1,15 +1,15 @@
1
-export { default as Caption } from './src/components/caption'
2
-export { default as Container } from './src/components/container'
3
-export { default as Contributors } from './src/components/contributors'
4
-export { Do, DoDontContainer, Dont } from './src/components/do-dont'
5
-export { default as Frame } from './src/components/frame'
6
-export { default as Head } from './src/components/head'
7
-export { default as Header } from './src/components/header'
8
-export { default as Hero } from './src/components/hero'
9
-export { default as HeroLayout } from './src/components/hero-layout'
10
-export { default as Index } from './src/components/index'
11
-export { default as Note } from './src/components/note'
12
-export { default as Screenshot } from './src/components/screenshot'
13
-export { default as Sidebar } from './src/components/sidebar'
14
-export { default as SourceLink } from './src/components/source-link'
15
-export { default as StatusLabel } from './src/components/status-label'
1
+export {default as Caption} from './src/components/caption'
2
+export {default as Container} from './src/components/container'
3
+export {default as Contributors} from './src/components/contributors'
4
+export {Do, DoDontContainer, Dont} from './src/components/do-dont'
5
+export {default as Frame} from './src/components/frame'
6
+export {default as Head} from './src/components/head'
7
+export {default as Header} from './src/components/header'
8
+export {default as Hero} from './src/components/hero'
9
+export {default as HeroLayout} from './src/components/hero-layout'
10
+export {default as Index} from './src/components/index'
11
+export {default as Note} from './src/components/note'
12
+export {default as Screenshot} from './src/components/screenshot'
13
+export {default as Sidebar} from './src/components/sidebar'
14
+export {default as SourceLink} from './src/components/source-link'
15
+export {default as StatusLabel} from './src/components/status-label'
theme/package.json
+6
-2
@@ -9,6 +9,7 @@
9
"private": true,
10
"main": "index.js",
11
"license": "MIT",
12
+ "prettier": "@github/prettier-config",
13
"scripts": {
14
"test": "jest",
15
"lint": "eslint \"**/*.js\"",
@@ -70,15 +71,18 @@
71
"styled-system": "^5.1.5"
72
},
73
"devDependencies": {
74
+ "@github/prettier-config": "^0.0.6",
75
"@npmcli/template-oss": "4.11.0",
76
"@testing-library/jest-dom": "^5.16.5",
77
"babel-jest": "^29.3.1",
76
- "eslint": "^8.29.0",
78
+ "eslint": "^8.33.0",
79
+ "eslint-plugin-github": "^4.6.0",
80
"eslint-plugin-jsx-a11y": "^6.6.1",
81
"eslint-plugin-primer-react": "1.0.1",
82
"eslint-plugin-react": "^7.31.11",
83
"jest": "^29.3.1",
81
- "jest-environment-jsdom": "^29.3.1"
84
+ "jest-environment-jsdom": "^29.3.1",
85
+ "prettier": "^2.8.3"
86
},
87
"author": "GitHub Inc.",
88
"engines": {
theme/scripts/template-oss/index.js
+2
-9
@@ -6,16 +6,9 @@ module.exports = {
6
'.eslintrc.js': false,
7
},
8
},
9
- allowPaths: [
10
- '/src',
11
- '/gatsby-*.js',
12
- '/jest*.js',
13
- '/index.js',
14
- ],
9
+ allowPaths: ['/src', '/gatsby-*.js', '/jest*.js', '/index.js'],
10
requiredPackages: {
11
devDependencies: [],
12
},
18
- allowedPackages: [
19
- 'eslint',
20
- ],
13
+ allowedPackages: ['eslint'],
14
}
theme/src/aria-live.js
+3
-3
@@ -15,7 +15,7 @@ if (typeof window !== 'undefined') {
15
}
16
17
// Announce message update to screen reader.
18
-function announce (message) {
18
+function announce(message) {
19
if (!container || !container.isConnected) {
20
/* This condition is for when the aria-live container no longer exists due to nav methods like turbo drive
21
which replace the body getting rid of the region. We add the container if it's missing. We then add a delay
@@ -33,7 +33,7 @@ function announce (message) {
33
}
34
35
// Set aria-live container to message.
36
-function setContainerContent (message) {
36
+function setContainerContent(message) {
37
if (!container) {
38
return
39
}
@@ -50,7 +50,7 @@ function setContainerContent (message) {
50
}
51
52
// Get the global screen reader notice container.
53
-function createNoticeContainer () {
53
+function createNoticeContainer() {
54
container = document.createElement('div')
55
container.setAttribute('aria-live', 'polite')
56
container.style.position = 'absolute'
theme/src/components/__tests__/contributors.test.js
+7
-9
@@ -1,9 +1,9 @@
1
-import { render } from '@testing-library/react'
1
+import {render} from '@testing-library/react'
2
import React from 'react'
3
import Contributors from '../contributors'
4
5
test('renders contributors', () => {
6
- const { queryByText } = render(
6
+ const {queryByText} = render(
7
<Contributors
8
contributors={[
9
{
@@ -21,7 +21,7 @@ test('renders contributors', () => {
21
},
22
},
23
]}
24
- />
24
+ />,
25
)
26
27
expect(queryByText(/2 contributors/)).toBeInTheDocument()
@@ -31,9 +31,7 @@ test('renders contributors', () => {
31
})
32
33
test('does not render "last edited by" if latest contributor does not have a latest commit', () => {
34
- const { queryByText } = render(
35
- <Contributors contributors={[{ login: 'ashygee' }]} />
36
- )
34
+ const {queryByText} = render(<Contributors contributors={[{login: 'ashygee'}]} />)
35
36
expect(queryByText(/1 contributor/)).toBeInTheDocument()
37
expect(queryByText(/Last edited by/)).toBeNull()
@@ -42,13 +40,13 @@ test('does not render "last edited by" if latest contributor does not have a lat
40
// The `Contributors` component is unlikely to be passed an empty array
41
// but it should be able to handle an empty array gracefully just in case.
42
test('handles no contributors', () => {
45
- const { queryByText } = render(<Contributors contributors={[]} />)
43
+ const {queryByText} = render(<Contributors contributors={[]} />)
44
45
expect(queryByText(/0 contributors/)).toBeInTheDocument()
46
})
47
48
test('does not render duplicate contributors', () => {
51
- const { queryByText } = render(
49
+ const {queryByText} = render(
50
<Contributors
51
contributors={[
52
{
@@ -66,7 +64,7 @@ test('does not render duplicate contributors', () => {
64
},
65
},
66
]}
69
- />
67
+ />,
68
)
69
70
expect(queryByText(/1 contributor/)).toBeInTheDocument()
theme/src/components/__tests__/page-footer.test.js
+6
-10
@@ -1,41 +1,37 @@
1
-import { render } from '@testing-library/react'
1
+import {render} from '@testing-library/react'
2
import React from 'react'
3
import PageFooter from '../page-footer'
4
5
test('renders correctly when editUrl and contributors are defined', () => {
6
- const { queryByText } = render(
7
- <PageFooter editUrl="#" contributors={[{ login: 'broccolini' }]} />
8
- )
6
+ const {queryByText} = render(<PageFooter editUrl="#" contributors={[{login: 'broccolini'}]} />)
7
8
expect(queryByText(/Edit this page on GitHub/)).toBeInTheDocument()
9
expect(queryByText(/contributor/)).toBeInTheDocument()
10
})
11
12
test('renders correctly when editUrl and contributors are undefined', () => {
15
- const { queryByText } = render(<PageFooter />)
13
+ const {queryByText} = render(<PageFooter />)
14
15
expect(queryByText(/Edit this page on GitHub/)).toBeNull()
16
expect(queryByText(/contributor/)).toBeNull()
17
})
18
19
test('renders correctly when editUrl is defined but contributors is undefined', () => {
22
- const { queryByText } = render(<PageFooter editUrl="#" />)
20
+ const {queryByText} = render(<PageFooter editUrl="#" />)
21
22
expect(queryByText(/Edit this page on GitHub/)).toBeInTheDocument()
23
expect(queryByText(/contributor/)).toBeNull()
24
})
25
26
test('renders correctly when contributors is defined but editUrl is undefined', () => {
29
- const { queryByText } = render(
30
- <PageFooter contributors={[{ login: 'broccolini' }]} />
31
- )
27
+ const {queryByText} = render(<PageFooter contributors={[{login: 'broccolini'}]} />)
28
29
expect(queryByText(/Edit this page on GitHub/)).toBeNull()
30
expect(queryByText(/contributor/)).toBeInTheDocument()
31
})
32
33
test('does not render contributors if contributors is an empty array', () => {
38
- const { queryByText } = render(<PageFooter contributors={[]} />)
34
+ const {queryByText} = render(<PageFooter contributors={[]} />)
35
36
expect(queryByText(/contributor/)).toBeNull()
37
})
theme/src/components/blockquote.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const Blockquote = styled.blockquote`
5
margin: 0 0 ${themeGet('space.3')};
theme/src/components/caption.js
+2
-2
@@ -1,7 +1,7 @@
1
-import { Text } from '@primer/components'
1
+import {Text} from '@primer/components'
2
import React from 'react'
3
4
-function Caption (props) {
4
+function Caption(props) {
5
return <Text as="p" mt={2} mb={3} fontSize={1} color="gray.5" {...props} />
6
}
7
theme/src/components/clipboard-copy.js
+4
-4
@@ -1,9 +1,9 @@
1
-import { Button, StyledOcticon, themeGet } from '@primer/components'
2
-import { CheckIcon, CopyIcon } from '@primer/octicons-react'
1
+import {Button, StyledOcticon, themeGet} from '@primer/components'
2
+import {CheckIcon, CopyIcon} from '@primer/octicons-react'
3
import styled from 'styled-components'
4
import copy from 'copy-to-clipboard'
5
import React from 'react'
6
-import { announce } from '../aria-live'
6
+import {announce} from '../aria-live'
7
8
const CopyToClipboard = styled(Button)`
9
&:focus {
@@ -11,7 +11,7 @@ const CopyToClipboard = styled(Button)`
11
}
12
`
13
14
-function ClipboardCopy ({ value }) {
14
+function ClipboardCopy({value}) {
15
const [copied, setCopied] = React.useState(false)
16
17
React.useEffect(() => {
theme/src/components/code.js
+23
-33
@@ -1,12 +1,12 @@
1
-import { Absolute, BorderBox, Relative, Text } from '@primer/components'
2
-import Highlight, { defaultProps } from 'prism-react-renderer'
1
+import {Absolute, BorderBox, Relative, Text} from '@primer/components'
2
+import Highlight, {defaultProps} from 'prism-react-renderer'
3
import githubTheme from 'prism-react-renderer/themes/github'
4
-import React, { useState, useEffect } from 'react'
4
+import React, {useState, useEffect} from 'react'
5
import ClipboardCopy from './clipboard-copy'
6
import LiveCode from './live-code'
7
8
-function Code ({ className, children, live, noinline }) {
9
- const [scrollHandleStyle, setScrollHandleStyle] = useState({ position: 'absolute' })
8
+function Code({className, children, live, noinline}) {
9
+ const [scrollHandleStyle, setScrollHandleStyle] = useState({position: 'absolute'})
10
const language = className ? className.replace(/language-/, '') : ''
11
const code = children.trim()
12
const scrollHandleRef = React.createRef()
@@ -24,34 +24,18 @@ function Code ({ className, children, live, noinline }) {
24
<Absolute top={0} right={0} p={2} zIndex={1}>
25
<ClipboardCopy value={code} />
26
</Absolute>
27
- <Highlight
28
- {...defaultProps}
29
- code={code}
30
- language={language}
31
- theme={githubTheme}
32
- >
33
- {({ className, style, tokens, getLineProps, getTokenProps }) => (
34
- <BorderBox
35
- as="pre"
36
- className={className}
37
- mt={0}
38
- mb={3}
39
- p={3}
40
- border={0}
41
- style={{ ...style, overflow: 'auto' }}
42
- >
27
+ <Highlight {...defaultProps} code={code} language={language} theme={githubTheme}>
28
+ {({className, style, tokens, getLineProps, getTokenProps}) => (
29
+ <BorderBox as="pre" className={className} mt={0} mb={3} p={3} border={0} style={{...style, overflow: 'auto'}}>
30
{/* This is the scroll handle, it is supposed to be focused with keyboard and scroll a wide codebox horizontally */}
31
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */}
45
- <div aria-hidden="true" tabIndex={0} style={scrollHandleStyle} ref={scrollHandleRef} aria-label={code}> </div>
32
+ <div aria-hidden="true" tabIndex={0} style={scrollHandleStyle} ref={scrollHandleRef} aria-label={code}>
33
+
34
+ </div>
35
{tokens.map((line, i) => (
47
- <div key={i} {...getLineProps({ line, key: i })}>
36
+ <div key={i} {...getLineProps({line, key: i})}>
37
{line.map((token, key) => (
49
- <Text
50
- key={key}
51
- fontFamily="mono"
52
- fontSize={1}
53
- {...getTokenProps({ token, key })}
54
- />
38
+ <Text key={key} fontFamily="mono" fontSize={1} {...getTokenProps({token, key})} />
39
))}
40
</div>
41
))}
@@ -64,7 +48,7 @@ function Code ({ className, children, live, noinline }) {
48
/**
49
* Resize the scroll handle to the size of the code contents, since the former has to be positioned absolutely.
50
*/
67
- function resizeScrollHandle () {
51
+ function resizeScrollHandle() {
52
// Skip if already resized.
53
if (typeof scrollHandleStyle.width !== 'undefined') {
54
return
@@ -73,9 +57,15 @@ function Code ({ className, children, live, noinline }) {
57
const node = scrollHandleRef.current
58
node.parentElement.style.position = 'relative'
59
const computedStyle = getComputedStyle(node.parentElement)
76
- const height = node.parentElement.clientHeight - parseInt(computedStyle.paddingTop, 10) - parseInt(computedStyle.paddingBottom, 10)
77
- const width = node.parentElement.scrollWidth - parseInt(computedStyle.paddingLeft, 10) - parseInt(computedStyle.paddingRight, 10)
78
- setScrollHandleStyle({ ...scrollHandleStyle, height, width })
60
+ const height =
61
+ node.parentElement.clientHeight -
62
+ parseInt(computedStyle.paddingTop, 10) -
63
+ parseInt(computedStyle.paddingBottom, 10)
64
+ const width =
65
+ node.parentElement.scrollWidth -
66
+ parseInt(computedStyle.paddingLeft, 10) -
67
+ parseInt(computedStyle.paddingRight, 10)
68
+ setScrollHandleStyle({...scrollHandleStyle, height, width})
69
}
70
}
71
theme/src/components/container.js
+2
-2
@@ -1,7 +1,7 @@
1
-import { Box } from '@primer/components'
1
+import {Box} from '@primer/components'
2
import React from 'react'
3
4
-function Container ({ children }) {
4
+function Container({children}) {
5
return (
6
<Box id="skip-nav" width="100%" maxWidth={960} p={5} mx="auto">
7
{children}
theme/src/components/contributors.js
+6
-13
@@ -1,12 +1,12 @@
1
-import { Avatar, Flex, Link, Text, Tooltip } from '@primer/components'
2
-import { format } from 'date-fns'
1
+import {Avatar, Flex, Link, Text, Tooltip} from '@primer/components'
2
+import {format} from 'date-fns'
3
import uniqBy from 'lodash.uniqby'
4
import pluralize from 'pluralize'
5
import React from 'react'
6
7
// The `contributors` array is fetched in gatsby-node.js at build-time.
8
9
-function Contributors ({ contributors }) {
9
+function Contributors({contributors}) {
10
const uniqueContributors = uniqBy(contributors, 'login')
11
const latestContributor = uniqueContributors[0] || {}
12
@@ -14,8 +14,7 @@ function Contributors ({ contributors }) {
14
<div>
15
<Flex alignItems="center">
16
<Text mr={2}>
17
- {uniqueContributors.length}{' '}
18
- {pluralize('contributor', uniqueContributors.length)}
17
+ {uniqueContributors.length} {pluralize('contributor', uniqueContributors.length)}
18
</Text>
19
{uniqueContributors.map(contributor => (
20
<Link
@@ -25,10 +24,7 @@ function Contributors ({ contributors }) {
24
mr={2}
25
>
26
<Tooltip key={contributor.login} aria-label={contributor.login}>
28
- <Avatar
29
- src={`https://github.com/${contributor.login}.png?size=40`}
30
- alt={contributor.login}
31
- />
27
+ <Avatar src={`https://github.com/${contributor.login}.png?size=40`} alt={contributor.login} />
28
</Tooltip>
29
</Link>
30
))}
@@ -36,10 +32,7 @@ function Contributors ({ contributors }) {
32
33
{latestContributor.latestCommit ? (
34
<Text fontSize={1} color="gray.7" mt={1}>
39
- Last edited by{' '}
40
- <Link href={`https://github.com/${latestContributor.login}`}>
41
- {latestContributor.login}
42
- </Link>{' '}
35
+ Last edited by <Link href={`https://github.com/${latestContributor.login}`}>{latestContributor.login}</Link>{' '}
36
on{' '}
37
<Link href={latestContributor.latestCommit.url}>
38
{format(new Date(latestContributor.latestCommit.date), 'MMMM d, y')}
theme/src/components/dark-button.js
+1
-1
@@ -1,4 +1,4 @@
1
-import { ButtonOutline, themeGet } from '@primer/components'
1
+import {ButtonOutline, themeGet} from '@primer/components'
2
import styled from 'styled-components'
3
4
const DarkButton = styled(ButtonOutline)`
theme/src/components/dark-text-input.js
+1
-1
@@ -1,4 +1,4 @@
1
-import { TextInput, themeGet } from '@primer/components'
1
+import {TextInput, themeGet} from '@primer/components'
2
import styled from 'styled-components'
3
4
const DarkTextInput = styled(TextInput)`
theme/src/components/description-list.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const DescriptionList = styled.dl`
5
padding: 0;
theme/src/components/details.js
+6
-6
@@ -25,14 +25,14 @@ const DetailsReset = styled.details`
25
}
26
`
27
28
-function getRenderer (children) {
28
+function getRenderer(children) {
29
return typeof children === 'function' ? children : () => children
30
}
31
32
-function Details ({ children, overlay, render = getRenderer(children), ...rest }) {
32
+function Details({children, overlay, render = getRenderer(children), ...rest}) {
33
const [open, setOpen] = React.useState(Boolean(rest.open))
34
35
- function toggle (event) {
35
+ function toggle(event) {
36
if (event) {
37
event.preventDefault()
38
}
@@ -43,21 +43,21 @@ function Details ({ children, overlay, render = getRenderer(children), ...rest }
43
}
44
}
45
46
- function openMenu () {
46
+ function openMenu() {
47
if (!open) {
48
setOpen(true)
49
document.addEventListener('click', closeMenu)
50
}
51
}
52
53
- function closeMenu () {
53
+ function closeMenu() {
54
setOpen(false)
55
document.removeEventListener('click', closeMenu)
56
}
57
58
return (
59
<DetailsReset {...rest} open={open}>
60
- {render({ open, toggle })}
60
+ {render({open, toggle})}
61
</DetailsReset>
62
)
63
}
theme/src/components/do-dont.js
+8
-12
@@ -1,15 +1,11 @@
1
-import { Flex, Grid, Text, StyledOcticon } from '@primer/components'
2
-import { CheckIcon, XIcon } from '@primer/octicons-react'
1
+import {Flex, Grid, Text, StyledOcticon} from '@primer/components'
2
+import {CheckIcon, XIcon} from '@primer/octicons-react'
3
import React from 'react'
4
import Caption from './caption'
5
6
-export function DoDontContainer ({ stacked, children }) {
6
+export function DoDontContainer({stacked, children}) {
7
return (
8
- <Grid
9
- gridTemplateColumns={['1fr', null, stacked ? '1fr' : '1fr 1fr']}
10
- gridGap={3}
11
- mb={3}
12
- >
8
+ <Grid gridTemplateColumns={['1fr', null, stacked ? '1fr' : '1fr 1fr']} gridGap={3} mb={3}>
9
{children}
10
</Grid>
11
)
@@ -19,19 +15,19 @@ DoDontContainer.defaultProps = {
15
stacked: false,
16
}
17
22
-export function Do (props) {
18
+export function Do(props) {
19
return <DoDontBase {...props} text="Do" icon={CheckIcon} iconBg="green.5" />
20
}
21
26
-export function Dont (props) {
22
+export function Dont(props) {
23
return <DoDontBase {...props} text="Don't" icon={XIcon} iconBg="red.5" />
24
}
25
30
-function DoDontBase ({ src, alt, children, text, icon: Icon, iconBg }) {
26
+function DoDontBase({src, alt, children, text, icon: Icon, iconBg}) {
27
return (
28
<Flex flexDirection="column">
29
<Flex alignSelf="start" flexDirection="row" alignItems="center" mb="2">
34
- <Flex bg={iconBg} color="white" p={1} style={{ borderRadius: '50%' }}>
30
+ <Flex bg={iconBg} color="white" p={1} style={{borderRadius: '50%'}}>
31
<StyledOcticon icon={Icon} verticalAlign="middle" size={12} />
32
</Flex>
33
<Text fontWeight="bold" color="gray.9" ml={2}>
theme/src/components/drawer.js
+13
-13
@@ -1,9 +1,9 @@
1
-import { Fixed } from '@primer/components'
2
-import { AnimatePresence, motion } from 'framer-motion'
1
+import {Fixed} from '@primer/components'
2
+import {AnimatePresence, motion} from 'framer-motion'
3
import React from 'react'
4
-import { FocusOn } from 'react-focus-on'
4
+import {FocusOn} from 'react-focus-on'
5
6
-function Drawer ({ isOpen, onDismiss, children }) {
6
+function Drawer({isOpen, onDismiss, children}) {
7
return (
8
<AnimatePresence>
9
{isOpen ? (
@@ -19,10 +19,10 @@ function Drawer ({ isOpen, onDismiss, children }) {
19
<Fixed
20
key="overlay"
21
as={motion.div}
22
- initial={{ opacity: 0 }}
23
- animate={{ opacity: 1 }}
24
- exit={{ opacity: 0 }}
25
- transition={{ type: 'tween' }}
22
+ initial={{opacity: 0}}
23
+ animate={{opacity: 1}}
24
+ exit={{opacity: 0}}
25
+ transition={{type: 'tween'}}
26
top={0}
27
right={0}
28
bottom={0}
@@ -34,16 +34,16 @@ function Drawer ({ isOpen, onDismiss, children }) {
34
<Fixed
35
key="drawer"
36
as={motion.div}
37
- initial={{ x: '100%' }}
38
- animate={{ x: 0 }}
39
- exit={{ x: '100%' }}
40
- transition={{ type: 'tween', duration: 0.2 }}
37
+ initial={{x: '100%'}}
38
+ animate={{x: 0}}
39
+ exit={{x: '100%'}}
40
+ transition={{type: 'tween', duration: 0.2}}
41
width={300}
42
top={0}
43
right={0}
44
bottom={0}
45
bg="gray.0"
46
- style={{ zIndex: 1 }}
46
+ style={{zIndex: 1}}
47
>
48
{children}
49
</Fixed>
theme/src/components/frame.js
+6
-6
@@ -1,14 +1,14 @@
1
import React from 'react'
2
-import FrameComponent, { FrameContextConsumer } from 'react-frame-component'
3
-import { StyleSheetManager } from 'styled-components'
2
+import FrameComponent, {FrameContextConsumer} from 'react-frame-component'
3
+import {StyleSheetManager} from 'styled-components'
4
import Measure from 'react-measure'
5
6
-function Frame ({ children }) {
6
+function Frame({children}) {
7
const [height, setHeight] = React.useState('auto')
8
return (
9
- <FrameComponent style={{ width: '100%', border: 0, height }}>
9
+ <FrameComponent style={{width: '100%', border: 0, height}}>
10
<FrameContextConsumer>
11
- {({ document }) => {
11
+ {({document}) => {
12
// By default, styled-components injects styles in the head of the page.
13
// However, styles from the page's head don't apply inside iframes.
14
// We're using StyleSheetManager to make styled-components inject styles
@@ -22,7 +22,7 @@ function Frame ({ children }) {
22
bounds={true}
23
onResize={rect => setHeight(rect.bounds.height)}
24
>
25
- {({ measureRef }) => <div ref={measureRef}>{children}</div>}
25
+ {({measureRef}) => <div ref={measureRef}>{children}</div>}
26
</Measure>
27
</StyleSheetManager>
28
)
theme/src/components/head.js
+3
-5
@@ -1,12 +1,10 @@
1
import React from 'react'
2
-import Helmet from 'react-helmet'
2
+import {Helmet} from 'react-helmet'
3
import useSiteMetdata from '../use-site-metadata'
4
5
-function Head (props) {
5
+function Head(props) {
6
const siteMetadata = useSiteMetdata()
7
- const title = props.title
8
- ? `${props.title} | ${siteMetadata.title}`
9
- : siteMetadata.title
7
+ const title = props.title ? `${props.title} | ${siteMetadata.title}` : siteMetadata.title
8
const description = props.description || siteMetadata.description
9
const lang = props.lang || siteMetadata.lang
10
theme/src/components/header.js
+15
-33
@@ -1,17 +1,14 @@
1
-import { Box, Flex, Link, Sticky } from '@primer/components'
2
-import {
3
- SearchIcon,
4
- ThreeBarsIcon,
5
-} from '@primer/octicons-react'
6
-import { Link as GatsbyLink } from 'gatsby'
1
+import {Box, Flex, Link, Sticky} from '@primer/components'
2
+import {SearchIcon, ThreeBarsIcon} from '@primer/octicons-react'
3
+import {Link as GatsbyLink} from 'gatsby'
4
import React from 'react'
8
-import styled, { ThemeContext } from 'styled-components'
5
+import styled, {ThemeContext} from 'styled-components'
6
import headerNavItems from '../header-nav.yml'
7
import useSiteMetadata from '../use-site-metadata'
8
import DarkButton from './dark-button'
9
import MobileSearch from './mobile-search'
13
-import NavDrawer, { useNavDrawerState } from './nav-drawer'
14
-import NavDropdown, { NavDropdownItem } from './nav-dropdown'
10
+import NavDrawer, {useNavDrawerState} from './nav-drawer'
11
+import NavDropdown, {NavDropdownItem} from './nav-dropdown'
12
import Search from './search'
13
import NpmLogo from './npm-logo'
14
@@ -22,16 +19,14 @@ const NpmHeaderBar = styled(Box)`
19
background-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff);
20
`
21
25
-function Header ({ location, isSearchEnabled = true }) {
22
+function Header({location, isSearchEnabled = true}) {
23
const theme = React.useContext(ThemeContext)
27
- const [isNavDrawerOpen, setIsNavDrawerOpen] = useNavDrawerState(
28
- theme.breakpoints[2]
29
- )
24
+ const [isNavDrawerOpen, setIsNavDrawerOpen] = useNavDrawerState(theme.breakpoints[2])
25
const [isMobileSearchOpen, setIsMobileSearchOpen] = React.useState(false)
26
const siteMetadata = useSiteMetadata()
27
33
- const logoStyle = { color: '#cb0000', marginRight: '16px' }
34
- const titleStyle = { color: '#dddddd', fontWeight: '600', display: 'flex', alignItems: 'center' }
28
+ const logoStyle = {color: '#cb0000', marginRight: '16px'}
29
+ const titleStyle = {color: '#dddddd', fontWeight: '600', display: 'flex', alignItems: 'center'}
30
31
return (
32
<Sticky role="banner">
@@ -69,10 +64,7 @@ function Header ({ location, isSearchEnabled = true }) {
64
>
65
<SearchIcon />
66
</DarkButton>
72
- <MobileSearch
73
- isOpen={isMobileSearchOpen}
74
- onDismiss={() => setIsMobileSearchOpen(false)}
75
- />
67
+ <MobileSearch isOpen={isMobileSearchOpen} onDismiss={() => setIsMobileSearchOpen(false)} />
68
</>
69
) : null}
70
<DarkButton
@@ -83,11 +75,7 @@ function Header ({ location, isSearchEnabled = true }) {
75
>
76
<ThreeBarsIcon />
77
</DarkButton>
86
- <NavDrawer
87
- location={location}
88
- isOpen={isNavDrawerOpen}
89
- onDismiss={() => setIsNavDrawerOpen(false)}
90
- />
78
+ <NavDrawer location={location} isOpen={isNavDrawerOpen} onDismiss={() => setIsNavDrawerOpen(false)} />
79
</Flex>
80
</Flex>
81
</Flex>
@@ -95,7 +83,7 @@ function Header ({ location, isSearchEnabled = true }) {
83
)
84
}
85
98
-function HeaderNavItems ({ items }) {
86
+function HeaderNavItems({items}) {
87
return (
88
<Flex alignItems="center" color="gray.2">
89
{items.map((item, index) => {
@@ -103,7 +91,7 @@ function HeaderNavItems ({ items }) {
91
return (
92
<Box ml={4} key={index}>
93
<NavDropdown title={item.title}>
106
- {item.children.map((child) => (
94
+ {item.children.map(child => (
95
<NavDropdownItem key={child.title} href={child.url}>
96
{child.title}
97
</NavDropdownItem>
@@ -114,13 +102,7 @@ function HeaderNavItems ({ items }) {
102
}
103
104
return (
117
- <Link
118
- key={index}
119
- href={item.url}
120
- display="block"
121
- color="inherit"
122
- ml={4}
123
- >
105
+ <Link key={index} href={item.url} display="block" color="inherit" ml={4}>
106
{item.title}
107
</Link>
108
)
theme/src/components/heading.js
+18
-24
@@ -1,11 +1,11 @@
1
-import { Heading, Link } from '@primer/components'
2
-import { LinkIcon } from '@primer/octicons-react'
3
-import themeGet from '@styled-system/theme-get'
1
+import {Heading, Link} from '@primer/components'
2
+import {LinkIcon} from '@primer/octicons-react'
3
+import {themeGet} from '@styled-system/theme-get'
4
import GithubSlugger from 'github-slugger'
5
import React from 'react'
6
import textContent from 'react-addons-text-content'
7
import styled from 'styled-components'
8
-import { HEADER_HEIGHT } from './header'
8
+import {HEADER_HEIGHT} from './header'
9
10
const StyledHeading = styled(Heading)`
11
margin-top: ${themeGet('space.4')};
@@ -22,20 +22,14 @@ const StyledHeading = styled(Heading)`
22
}
23
`
24
25
-function MarkdownHeading ({ children, ...props }) {
25
+function MarkdownHeading({children, ...props}) {
26
const slugger = new GithubSlugger()
27
const text = children ? textContent(children) : ''
28
const id = text ? slugger.slug(text) : ''
29
30
return (
31
<StyledHeading id={id} {...props}>
32
- <Link
33
- href={`#${id}`}
34
- p={2}
35
- ml={-32}
36
- color="gray.8"
37
- aria-label={`${text} permalink`}
38
- >
32
+ <Link href={`#${id}`} p={2} ml={-32} color="gray.8" aria-label={`${text} permalink`}>
33
<LinkIcon className="octicon-link" verticalAlign="middle" />
34
</Link>
35
{children}
@@ -43,38 +37,38 @@ function MarkdownHeading ({ children, ...props }) {
37
)
38
}
39
46
-const StyledH1 = styled(StyledHeading).attrs({ as: 'h1' })`
40
+const StyledH1 = styled(StyledHeading).attrs({as: 'h1'})`
41
padding-bottom: ${themeGet('space.1')};
42
font-size: ${themeGet('fontSizes.5')};
43
border-bottom: 1px solid ${themeGet('colors.gray.2')};
44
`
45
52
-const StyledH2 = styled(StyledHeading).attrs({ as: 'h2' })`
46
+const StyledH2 = styled(StyledHeading).attrs({as: 'h2'})`
47
padding-bottom: ${themeGet('space.1')};
48
font-size: ${themeGet('fontSizes.4')};
49
border-bottom: 1px solid ${themeGet('colors.gray.2')};
50
`
51
58
-const StyledH3 = styled(StyledHeading).attrs({ as: 'h3' })`
52
+const StyledH3 = styled(StyledHeading).attrs({as: 'h3'})`
53
font-size: ${themeGet('fontSizes.3')};
54
`
55
62
-const StyledH4 = styled(StyledHeading).attrs({ as: 'h4' })`
56
+const StyledH4 = styled(StyledHeading).attrs({as: 'h4'})`
57
font-size: ${themeGet('fontSizes.2')};
58
`
59
66
-const StyledH5 = styled(StyledHeading).attrs({ as: 'h5' })`
60
+const StyledH5 = styled(StyledHeading).attrs({as: 'h5'})`
61
font-size: ${themeGet('fontSizes.1')};
62
`
63
70
-const StyledH6 = styled(StyledHeading).attrs({ as: 'h6' })`
64
+const StyledH6 = styled(StyledHeading).attrs({as: 'h6'})`
65
font-size: ${themeGet('fontSizes.1')};
66
color: ${themeGet('colors.gray.5')};
67
`
68
75
-export const H1 = (props) => <MarkdownHeading as={StyledH1} {...props} />
76
-export const H2 = (props) => <MarkdownHeading as={StyledH2} {...props} />
77
-export const H3 = (props) => <MarkdownHeading as={StyledH3} {...props} />
78
-export const H4 = (props) => <MarkdownHeading as={StyledH4} {...props} />
79
-export const H5 = (props) => <MarkdownHeading as={StyledH5} {...props} />
80
-export const H6 = (props) => <MarkdownHeading as={StyledH6} {...props} />
69
+export const H1 = props => <MarkdownHeading as={StyledH1} {...props} />
70
+export const H2 = props => <MarkdownHeading as={StyledH2} {...props} />
71
+export const H3 = props => <MarkdownHeading as={StyledH3} {...props} />
72
+export const H4 = props => <MarkdownHeading as={StyledH4} {...props} />
73
+export const H5 = props => <MarkdownHeading as={StyledH5} {...props} />
74
+export const H6 = props => <MarkdownHeading as={StyledH6} {...props} />
theme/src/components/hero-layout.js
+5
-10
@@ -1,4 +1,4 @@
1
-import { Box, Flex } from '@primer/components'
1
+import {Box, Flex} from '@primer/components'
2
import React from 'react'
3
import Container from './container'
4
import PageFooter from './page-footer'
@@ -7,8 +7,8 @@ import Header from './header'
7
import Hero from './hero'
8
import Sidebar from './sidebar'
9
10
-function HeroLayout ({ children, pageContext, location }) {
11
- const { additionalContributors = [] } = pageContext.frontmatter
10
+function HeroLayout({children, pageContext, location}) {
11
+ const {additionalContributors = []} = pageContext.frontmatter
12
13
return (
14
<Flex flexDirection="column" minHeight="100vh">
@@ -17,10 +17,7 @@ function HeroLayout ({ children, pageContext, location }) {
17
<Flex flex="1 1 auto" flexDirection="row" role="main">
18
<Box display={['none', null, null, 'block']}>
19
<Sidebar
20
- editOnGitHub={
21
- pageContext.themeOptions.showSidebarEditLink &&
22
- pageContext.themeOptions.editOnGitHub
23
- }
20
+ editOnGitHub={pageContext.themeOptions.showSidebarEditLink && pageContext.themeOptions.editOnGitHub}
21
location={location}
22
/>
23
</Box>
@@ -31,9 +28,7 @@ function HeroLayout ({ children, pageContext, location }) {
28
<PageFooter
29
editOnGitHub={pageContext.themeOptions.editOnGitHub}
30
editUrl={pageContext.themeOptions.editUrl}
34
- contributors={pageContext.contributors.concat(
35
- additionalContributors.map(login => ({ login }))
36
- )}
31
+ contributors={pageContext.contributors.concat(additionalContributors.map(login => ({login})))}
32
/>
33
</Container>
34
</Box>
theme/src/components/hero.js
+3
-3
@@ -1,10 +1,10 @@
1
-import { Box, Heading, Text } from '@primer/components'
1
+import {Box, Heading, Text} from '@primer/components'
2
import React from 'react'
3
import useSiteMetadata from '../use-site-metadata'
4
import Container from './container'
5
6
-function Hero () {
7
- const { title, description } = useSiteMetadata()
6
+function Hero() {
7
+ const {title, description} = useSiteMetadata()
8
9
return (
10
<Box bg="black" py={6}>
theme/src/components/horizontal-rule.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const HorizontalRule = styled.hr`
5
height: ${themeGet('space.1')};
theme/src/components/image.js
+1
-1
@@ -1,4 +1,4 @@
1
-import themeGet from '@styled-system/theme-get'
1
+import {themeGet} from '@styled-system/theme-get'
2
import styled from 'styled-components'
3
4
const Image = styled.img`
theme/src/components/index.js
+13
-11
@@ -1,11 +1,11 @@
1
import React from 'react'
2
// eslint-disable-next-line import/no-unresolved
3
-import { Location } from '@reach/router'
4
-import { Box, Link } from '@primer/components'
5
-import { Link as GatsbyLink } from 'gatsby'
3
+import {Location} from '@reach/router'
4
+import {Box, Link} from '@primer/components'
5
+import {Link as GatsbyLink} from 'gatsby'
6
import NavHierarchy from '../nav-hierarchy'
7
8
-function showHierarchy (items, props, depth = 1) {
8
+function showHierarchy(items, props, depth = 1) {
9
let hierarchy
10
11
if (props.depth && depth > props.depth) {
@@ -16,25 +16,27 @@ function showHierarchy (items, props, depth = 1) {
16
<Box as="ul">
17
{items.map(item => (
18
<Box as="li" key={item.url}>
19
- <Link as={GatsbyLink} key={item.title} to={item.url}>{item.title}</Link>
19
+ <Link as={GatsbyLink} key={item.title} to={item.url}>
20
+ {item.title}
21
+ </Link>
22
{item.description != null ? (
23
<>
22
- <Box style={{ fontSize: '0.85em', marginBottom: '0.5em' }}>
23
- {item.description}
24
- </Box>
24
+ <Box style={{fontSize: '0.85em', marginBottom: '0.5em'}}>{item.description}</Box>
25
</>
26
) : null}
27
- {(hierarchy = NavHierarchy.getHierarchy(item, props)) != null ? showHierarchy(hierarchy, props, depth + 1) : null}
27
+ {(hierarchy = NavHierarchy.getHierarchy(item, props)) != null
28
+ ? showHierarchy(hierarchy, props, depth + 1)
29
+ : null}
30
</Box>
31
))}
32
</Box>
33
)
34
}
35
34
-function Index (props) {
36
+function Index(props) {
37
return (
38
<Location>
37
- {({ location }) => {
39
+ {({location}) => {
40
const path = NavHierarchy.getLocation(location.pathname)
41
let root = props.root ? props.root : path
42
root = root.replace(/\/+$/g, '')
theme/src/components/inline-code.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const InlineCode = styled.code`
5
padding: 0.2em 0.4em;
theme/src/components/layout.js
+36
-61
@@ -1,19 +1,9 @@
1
-import {
2
- BorderBox,
3
- Box,
4
- Details,
5
- Flex,
6
- Grid,
7
- Heading,
8
- Position,
9
- StyledOcticon,
10
- Text,
11
-} from '@primer/components'
12
-import { ChevronDownIcon, ChevronRightIcon } from '@primer/octicons-react'
1
+import {BorderBox, Box, Details, Flex, Grid, Heading, Position, StyledOcticon, Text} from '@primer/components'
2
+import {ChevronDownIcon, ChevronRightIcon} from '@primer/octicons-react'
3
import React from 'react'
14
-import { MDXProvider } from '@mdx-js/react'
4
+import {MDXProvider} from '@mdx-js/react'
5
import Head from './head'
16
-import Header, { HEADER_HEIGHT } from './header'
6
+import Header, {HEADER_HEIGHT} from './header'
7
import Index from './index'
8
import Note from './note'
9
import PageFooter from './page-footer'
@@ -27,36 +17,28 @@ import TableOfContents from './table-of-contents'
17
import VariantSelect from './variant-select'
18
import NavHierarchy from '../nav-hierarchy'
19
30
-function Layout ({ children, pageContext, location }) {
31
- const {
32
- title,
33
- description,
34
- status,
35
- source,
36
- additionalContributors = [],
37
- } = pageContext.frontmatter
20
+function Layout({children, pageContext, location}) {
21
+ const {title, description, status, source, additionalContributors = []} = pageContext.frontmatter
22
23
const variantRoot = NavHierarchy.getVariantRoot(location.pathname)
24
25
return (
42
- <MDXProvider components={{
43
- Index,
44
- Note,
45
- Prompt,
46
- PromptReply,
47
- Screenshot,
48
- }}>
49
-
26
+ <MDXProvider
27
+ components={{
28
+ Index,
29
+ Note,
30
+ Prompt,
31
+ PromptReply,
32
+ Screenshot,
33
+ }}
34
+ >
35
<Flex flexDirection="column" minHeight="100vh">
36
<Head title={title} description={description} />
37
<Header location={location} isSearchEnabled={pageContext.isSearchEnabled} />
53
- <Flex flex="1 1 auto" flexDirection="row" css={{ zIndex: 0 }} role="main">
38
+ <Flex flex="1 1 auto" flexDirection="row" css={{zIndex: 0}} role="main">
39
<Box display={['none', null, null, 'block']}>
40
<Sidebar
56
- editOnGitHub={
57
- pageContext.themeOptions.showSidebarEditLink &&
58
- pageContext.themeOptions.editOnGitHub
59
- }
41
+ editOnGitHub={pageContext.themeOptions.showSidebarEditLink && pageContext.themeOptions.editOnGitHub}
42
location={location}
43
/>
44
</Box>
@@ -64,25 +46,16 @@ function Layout ({ children, pageContext, location }) {
46
id="skip-nav"
47
maxWidth="100%"
48
gridTemplateColumns={['100%', null, 'minmax(0, 65ch) 220px']}
67
- gridTemplateAreas={[
68
- '"heading" "content"',
69
- null,
70
- '"heading table-of-contents" "content table-of-contents"',
71
- ]}
49
+ gridTemplateAreas={['"heading" "content"', null, '"heading table-of-contents" "content table-of-contents"']}
50
gridColumnGap={[null, null, 6, 7]}
51
gridRowGap={3}
52
mx="auto"
53
p={[5, 6, null, 7]}
76
- css={{ alignItems: 'start', alignSelf: 'start' }}
54
+ css={{alignItems: 'start', alignSelf: 'start'}}
55
role="region"
56
>
79
- <Box css={{ gridArea: 'heading' }}>
80
- <BorderBox
81
- borderWidth={0}
82
- borderBottomWidth={1}
83
- borderRadius={0}
84
- pb={2}
85
- >
57
+ <Box css={{gridArea: 'heading'}}>
58
+ <BorderBox borderWidth={0} borderBottomWidth={1} borderRadius={0} pb={2}>
59
<Box>
60
<Box>
61
<Heading as="h1">{title}</Heading>
@@ -91,15 +64,21 @@ function Layout ({ children, pageContext, location }) {
64
</Box>
65
</BorderBox>
66
{variantRoot != null ? (
94
- <Box css={{ 'margin-top': '25px' }}>
95
- <VariantSelect overlay={true} direction="se" menuWidth="min(30ch, 500px)" root={variantRoot} location={location} />
67
+ <Box css={{'margin-top': '25px'}}>
68
+ <VariantSelect
69
+ overlay={true}
70
+ direction="se"
71
+ menuWidth="min(30ch, 500px)"
72
+ root={variantRoot}
73
+ location={location}
74
+ />
75
</Box>
76
) : null}
77
</Box>
78
{pageContext.tableOfContents.items ? (
79
<Position
80
display={['none', null, 'block']}
102
- css={{ gridArea: 'table-of-contents', overflow: 'auto' }}
81
+ css={{gridArea: 'table-of-contents', overflow: 'auto'}}
82
position="sticky"
83
top={HEADER_HEIGHT + 24}
84
mt="6px"
@@ -108,13 +87,13 @@ function Layout ({ children, pageContext, location }) {
87
pl={1}
88
pb={1}
89
>
111
- <Text display="inline-block" fontWeight="bold" mb={1} id='table-of-content-label'>
90
+ <Text display="inline-block" fontWeight="bold" mb={1} id="table-of-content-label">
91
Table of contents
92
</Text>
114
- <TableOfContents items={pageContext.tableOfContents.items} labelId='table-of-content-label'/>
93
+ <TableOfContents items={pageContext.tableOfContents.items} labelId="table-of-content-label" />
94
</Position>
95
) : null}
117
- <Box css={{ gridArea: 'content' }}>
96
+ <Box css={{gridArea: 'content'}}>
97
{status || source ? (
98
<Flex mb={3} alignItems="center">
99
{status ? <StatusLabel status={status} /> : null}
@@ -125,7 +104,7 @@ function Layout ({ children, pageContext, location }) {
104
{pageContext.tableOfContents.items ? (
105
<Box display={['block', null, 'none']} mb={3}>
106
<Details>
128
- {({ open }) => (
107
+ {({open}) => (
108
<>
109
<Text as="summary" fontWeight="bold">
110
{open ? (
@@ -136,9 +115,7 @@ function Layout ({ children, pageContext, location }) {
115
Table of contents
116
</Text>
117
<Box pt={1}>
139
- <TableOfContents
140
- items={pageContext.tableOfContents.items}
141
- />
118
+ <TableOfContents items={pageContext.tableOfContents.items} />
119
</Box>
120
</>
121
)}
@@ -149,9 +126,7 @@ function Layout ({ children, pageContext, location }) {
126
<PageFooter
127
editOnGitHub={pageContext.themeOptions.editOnGitHub}
128
editUrl={pageContext.editUrl}
152
- contributors={pageContext.contributors.concat(
153
- additionalContributors.map((login) => ({ login }))
154
- )}
129
+ contributors={pageContext.contributors.concat(additionalContributors.map(login => ({login})))}
130
/>
131
</Box>
132
</Grid>
theme/src/components/list.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const List = styled.ul`
5
padding-left: 2em;
theme/src/components/live-code.js
+12
-28
@@ -1,10 +1,10 @@
1
-import { Absolute, BorderBox, Relative, Text } from '@primer/components'
1
+import {Absolute, BorderBox, Relative, Text} from '@primer/components'
2
import htmlReactParser from 'html-react-parser'
3
import githubTheme from 'prism-react-renderer/themes/github'
4
-import React, { useState } from 'react'
4
+import React, {useState} from 'react'
5
import reactElementToJsxString from 'react-element-to-jsx-string'
6
-import { LiveEditor, LiveError, LivePreview, LiveProvider } from 'react-live'
7
-import { ThemeContext } from 'styled-components'
6
+import {LiveEditor, LiveError, LivePreview, LiveProvider} from 'react-live'
7
+import {ThemeContext} from 'styled-components'
8
import scope from '../live-code-scope'
9
import ClipboardCopy from './clipboard-copy'
10
import LivePreviewWrapper from './live-preview-wrapper'
@@ -14,7 +14,7 @@ const languageTransformers = {
14
jsx: jsx => wrapWithFragment(jsx),
15
}
16
17
-function htmlToJsx (html) {
17
+function htmlToJsx(html) {
18
try {
19
const reactElement = htmlReactParser(removeNewlines(html))
20
// The output of htmlReactParser could be a single React element
@@ -26,30 +26,22 @@ function htmlToJsx (html) {
26
}
27
}
28
29
-function removeNewlines (string) {
29
+function removeNewlines(string) {
30
return string.replace(/(\r\n|\n|\r)/gm, '')
31
}
32
33
-function wrapWithFragment (jsx) {
33
+function wrapWithFragment(jsx) {
34
return `<React.Fragment>${jsx}</React.Fragment>`
35
}
36
37
-function LiveCode ({ code, language, noinline }) {
37
+function LiveCode({code, language, noinline}) {
38
const theme = React.useContext(ThemeContext)
39
const [liveCode, setLiveCode] = useState(code)
40
- const handleChange = (updatedLiveCode) => setLiveCode(updatedLiveCode)
40
+ const handleChange = updatedLiveCode => setLiveCode(updatedLiveCode)
41
42
return (
43
- <BorderBox
44
- flexDirection="column"
45
- mb={3}
46
- >
47
- <LiveProvider
48
- scope={scope}
49
- code={liveCode}
50
- transformCode={languageTransformers[language]}
51
- noInline={noinline}
52
- >
43
+ <BorderBox flexDirection="column" mb={3}>
44
+ <LiveProvider scope={scope} code={liveCode} transformCode={languageTransformers[language]} noInline={noinline}>
45
<LivePreviewWrapper>
46
<LivePreview />
47
</LivePreviewWrapper>
@@ -70,15 +62,7 @@ function LiveCode ({ code, language, noinline }) {
62
<ClipboardCopy value={liveCode} />
63
</Absolute>
64
</Relative>
73
- <Text
74
- as={LiveError}
75
- m={0}
76
- p={3}
77
- fontFamily="mono"
78
- fontSize={1}
79
- color="white"
80
- bg="red.5"
81
- />
65
+ <Text as={LiveError} m={0} p={3} fontFamily="mono" fontSize={1} color="white" bg="red.5" />
66
</LiveProvider>
67
</BorderBox>
68
)
theme/src/components/live-preview-wrapper.js
+2
-2
@@ -1,10 +1,10 @@
1
-import { BaseStyles, Box } from '@primer/components'
1
+import {BaseStyles, Box} from '@primer/components'
2
import Frame from './frame'
3
import React from 'react'
4
5
// Users can shadow this file to wrap live previews.
6
// This is useful for applying global styles.
7
-function LivePreviewWrapper ({ children }) {
7
+function LivePreviewWrapper({children}) {
8
return (
9
<Frame>
10
<BaseStyles>
theme/src/components/mobile-search.js
+23
-34
@@ -1,38 +1,38 @@
1
-import { Absolute, Fixed, Flex } from '@primer/components'
2
-import { XIcon } from '@primer/octicons-react'
1
+import {Absolute, Fixed, Flex} from '@primer/components'
2
+import {XIcon} from '@primer/octicons-react'
3
import Downshift from 'downshift'
4
-import { AnimatePresence, motion } from 'framer-motion'
5
-import { navigate } from 'gatsby'
4
+import {AnimatePresence, motion} from 'framer-motion'
5
+import {navigate} from 'gatsby'
6
import React from 'react'
7
-import { FocusOn } from 'react-focus-on'
7
+import {FocusOn} from 'react-focus-on'
8
import useSearch from '../use-search'
9
import DarkButton from './dark-button'
10
import DarkTextInput from './dark-text-input'
11
import SearchResults from './search-results'
12
import useSiteMetadata from '../use-site-metadata'
13
14
-function stateReducer (state, changes) {
14
+function stateReducer(state, changes) {
15
switch (changes.type) {
16
case Downshift.stateChangeTypes.changeInput:
17
if (!changes.inputValue) {
18
// Close the menu if the input is empty.
19
- return { ...changes, isOpen: false }
19
+ return {...changes, isOpen: false}
20
}
21
return changes
22
case Downshift.stateChangeTypes.blurInput:
23
// Don't let a blur event change the state of `inputValue` or `isOpen`.
24
- return { ...changes, inputValue: state.inputValue, isOpen: state.isOpen }
24
+ return {...changes, inputValue: state.inputValue, isOpen: state.isOpen}
25
default:
26
return changes
27
}
28
}
29
30
-function MobileSearch ({ isOpen, onDismiss }) {
30
+function MobileSearch({isOpen, onDismiss}) {
31
const [query, setQuery] = React.useState('')
32
const results = useSearch(query)
33
const siteMetadata = useSiteMetadata()
34
35
- function handleDismiss () {
35
+ function handleDismiss() {
36
setQuery('')
37
onDismiss()
38
}
@@ -44,9 +44,9 @@ function MobileSearch ({ isOpen, onDismiss }) {
44
<Fixed top={0} left={0} right={0} bottom={0} zIndex={1}>
45
<Absolute
46
as={motion.div}
47
- initial={{ opacity: 0 }}
48
- animate={{ opacity: 1 }}
49
- exit={{ opacity: 0 }}
47
+ initial={{opacity: 0}}
48
+ animate={{opacity: 1}}
49
+ exit={{opacity: 0}}
50
top={0}
51
left={0}
52
right={0}
@@ -57,25 +57,18 @@ function MobileSearch ({ isOpen, onDismiss }) {
57
/>
58
<Downshift
59
inputValue={query}
60
- onInputValueChange={(inputValue) => setQuery(inputValue)}
60
+ onInputValueChange={inputValue => setQuery(inputValue)}
61
selectedItem={null}
62
- onSelect={(item) => {
62
+ onSelect={item => {
63
if (item) {
64
navigate(item.path)
65
handleDismiss()
66
}
67
}}
68
- itemToString={(item) => (item ? item.title : '')}
68
+ itemToString={item => (item ? item.title : '')}
69
stateReducer={stateReducer}
70
>
71
- {({
72
- getInputProps,
73
- getItemProps,
74
- getMenuProps,
75
- getRootProps,
76
- isOpen: isMenuOpen,
77
- highlightedIndex,
78
- }) => (
71
+ {({getInputProps, getItemProps, getMenuProps, getRootProps, isOpen: isMenuOpen, highlightedIndex}) => (
72
<Flex
73
{...getRootProps({
74
flexDirection: 'column',
@@ -84,11 +77,11 @@ function MobileSearch ({ isOpen, onDismiss }) {
77
>
78
<Flex bg="gray.9" color="white" p={3} flex="0 0 auto">
79
<motion.div
87
- initial={{ scaleX: 0.1 }}
88
- animate={{ scaleX: 1 }}
89
- exit={{ scaleX: 0.1, transition: { duration: 0.1 } }}
90
- transition={{ type: 'tween', duration: 0.2 }}
91
- style={{ width: '100%', originX: '100%' }}
80
+ initial={{scaleX: 0.1}}
81
+ animate={{scaleX: 1}}
82
+ exit={{scaleX: 0.1, transition: {duration: 0.1}}}
83
+ transition={{type: 'tween', duration: 0.2}}
84
+ style={{width: '100%', originX: '100%'}}
85
>
86
<DarkTextInput
87
{...getInputProps({
@@ -97,11 +90,7 @@ function MobileSearch ({ isOpen, onDismiss }) {
90
})}
91
/>
92
</motion.div>
100
- <DarkButton
101
- ml={3}
102
- aria-label="Cancel"
103
- onClick={handleDismiss}
104
- >
93
+ <DarkButton ml={3} aria-label="Cancel" onClick={handleDismiss}>
94
<XIcon />
95
</DarkButton>
96
</Flex>
theme/src/components/nav-drawer.js
+16
-48
@@ -1,6 +1,6 @@
1
-import { BorderBox, Flex, Link, Text } from '@primer/components'
2
-import { ChevronDownIcon, ChevronUpIcon, XIcon } from '@primer/octicons-react'
3
-import { Link as GatsbyLink } from 'gatsby'
1
+import {BorderBox, Flex, Link, Text} from '@primer/components'
2
+import {ChevronDownIcon, ChevronUpIcon, XIcon} from '@primer/octicons-react'
3
+import {Link as GatsbyLink} from 'gatsby'
4
import debounce from 'lodash.debounce'
5
import React from 'react'
6
import navItems from '../nav.yml'
@@ -11,7 +11,7 @@ import Details from './details'
11
import Drawer from './drawer'
12
import NavItems from './nav-items'
13
14
-export function useNavDrawerState (breakpoint) {
14
+export function useNavDrawerState(breakpoint) {
15
// Handle string values from themes with units at the end
16
if (typeof breakpoint === 'string') {
17
breakpoint = parseInt(breakpoint, 10)
@@ -24,9 +24,7 @@ export function useNavDrawerState (breakpoint) {
24
}
25
}, [setOpen])
26
27
- const debouncedOnResize = React.useCallback(debounce(onResize, 250), [
28
- onResize,
29
- ])
27
+ const debouncedOnResize = React.useCallback(debounce(onResize, 250), [onResize])
28
29
React.useEffect(() => {
30
if (isOpen) {
@@ -42,7 +40,7 @@ export function useNavDrawerState (breakpoint) {
40
return [isOpen, setOpen]
41
}
42
45
-function NavDrawer ({ location, isOpen, onDismiss }) {
43
+function NavDrawer({location, isOpen, onDismiss}) {
44
const siteMetadata = useSiteMetadata()
45
return (
46
<Drawer isOpen={isOpen} onDismiss={onDismiss}>
@@ -50,30 +48,12 @@ function NavDrawer ({ location, isOpen, onDismiss }) {
48
flexDirection="column"
49
height="100%"
50
bg="gray.0"
53
- style={{ overflow: 'auto', WebkitOverflowScrolling: 'touch' }}
51
+ style={{overflow: 'auto', WebkitOverflowScrolling: 'touch'}}
52
>
53
<Flex flexDirection="column" flex="1 0 auto" color="gray.7" bg="gray.0">
56
- <BorderBox
57
- borderWidth={0}
58
- borderRadius={0}
59
- borderBottomWidth={1}
60
- borderColor="gray.7"
61
- >
62
- <Flex
63
- py={3}
64
- pl={4}
65
- pr={3}
66
- alignItems="center"
67
- justifyContent="space-between"
68
- color="gray.1"
69
- bg="gray.9"
70
- >
71
- <Link
72
- as={GatsbyLink}
73
- to="/"
74
- display="inline-block"
75
- color="inherit"
76
- >
54
+ <BorderBox borderWidth={0} borderRadius={0} borderBottomWidth={1} borderColor="gray.7">
55
+ <Flex py={3} pl={4} pr={3} alignItems="center" justifyContent="space-between" color="gray.1" bg="gray.9">
56
+ <Link as={GatsbyLink} to="/" display="inline-block" color="inherit">
57
{siteMetadata.title}
58
</Link>
59
<DarkButton aria-label="Close" onClick={onDismiss}>
@@ -88,12 +68,7 @@ function NavDrawer ({ location, isOpen, onDismiss }) {
68
) : null}
69
</Flex>
70
{headerNavItems.length > 0 ? (
91
- <Flex
92
- flexDirection="column"
93
- flex="1 0 auto"
94
- color="gray.1"
95
- bg="gray.9"
96
- >
71
+ <Flex flexDirection="column" flex="1 0 auto" color="gray.1" bg="gray.9">
72
<HeaderNavItems items={headerNavItems} />
73
</Flex>
74
) : null}
@@ -102,7 +77,7 @@ function NavDrawer ({ location, isOpen, onDismiss }) {
77
)
78
}
79
105
-function HeaderNavItems ({ items }) {
80
+function HeaderNavItems({items}) {
81
return items.map((item, index) => {
82
return (
83
<BorderBox
@@ -115,24 +90,17 @@ function HeaderNavItems ({ items }) {
90
>
91
{item.children ? (
92
<Details key={index}>
118
- {({ open, toggle }) => (
93
+ {({open, toggle}) => (
94
<>
120
- <summary onClick={toggle} style={{ cursor: 'pointer' }}>
95
+ <summary onClick={toggle} style={{cursor: 'pointer'}}>
96
<Flex alignItems="center" justifyContent="space-between">
97
<Text>{item.title}</Text>
98
{open ? <ChevronUpIcon /> : <ChevronDownIcon />}
99
</Flex>
100
</summary>
101
<Flex flexDirection="column" mt={2}>
127
- {item.children.map((child) => (
128
- <Link
129
- key={child.title}
130
- href={child.url}
131
- py={1}
132
- mt={2}
133
- fontSize={1}
134
- color="inherit"
135
- >
102
+ {item.children.map(child => (
103
+ <Link key={child.title} href={child.url} py={1} mt={2} fontSize={1} color="inherit">
104
{child.title}
105
</Link>
106
))}
theme/src/components/nav-dropdown.js
+6
-12
@@ -1,26 +1,20 @@
1
-import { Absolute, BorderBox, StyledOcticon, Text, themeGet } from '@primer/components'
2
-import { ChevronDownIcon } from '@primer/octicons-react'
1
+import {Absolute, BorderBox, StyledOcticon, Text, themeGet} from '@primer/components'
2
+import {ChevronDownIcon} from '@primer/octicons-react'
3
import React from 'react'
4
import styled from 'styled-components'
5
import Details from './details'
6
7
-function NavDropdown ({ title, children }) {
7
+function NavDropdown({title, children}) {
8
return (
9
<Details overlay={true}>
10
- {({ toggle }) => (
10
+ {({toggle}) => (
11
<>
12
- <summary style={{ cursor: 'pointer' }} onClick={toggle}>
12
+ <summary style={{cursor: 'pointer'}} onClick={toggle}>
13
<Text>{title}</Text>
14
<StyledOcticon icon={ChevronDownIcon} ml={1} />
15
</summary>
16
<Absolute>
17
- <BorderBox
18
- bg="white"
19
- py={1}
20
- mt={2}
21
- boxShadow="medium"
22
- color="gray.8"
23
- >
17
+ <BorderBox bg="white" py={1} mt={2} boxShadow="medium" color="gray.8">
18
{children}
19
</BorderBox>
20
</Absolute>
theme/src/components/nav-items.js
+27
-29
@@ -1,6 +1,6 @@
1
-import { BorderBox, Box, Flex, StyledOcticon, Link, themeGet } from '@primer/components'
2
-import { LinkExternalIcon } from '@primer/octicons-react'
3
-import { Link as GatsbyLink } from 'gatsby'
1
+import {BorderBox, Box, Flex, StyledOcticon, Link, themeGet} from '@primer/components'
2
+import {LinkExternalIcon} from '@primer/octicons-react'
3
+import {Link as GatsbyLink} from 'gatsby'
4
import preval from 'preval.macro'
5
import React from 'react'
6
import styled from 'styled-components'
@@ -18,18 +18,18 @@ const repositoryUrl = preval`
18
}
19
`
20
21
-const getActiveProps = (className) => (props) => {
21
+const getActiveProps = className => props => {
22
const location = NavHierarchy.getLocation(props.location.pathname)
23
const href = NavHierarchy.getLocation(props.href)
24
25
if (NavHierarchy.isActiveUrl(location, href)) {
26
- return { className: `${className} active` }
26
+ return {className: `${className} active`}
27
}
28
29
- return { className: `${className}` }
29
+ return {className: `${className}`}
30
}
31
32
-const ActiveLink = ({ className, children, ...props }) => (
32
+const ActiveLink = ({className, children, ...props}) => (
33
<Link as={GatsbyLink} getProps={getActiveProps(className)} {...props}>
34
{children}
35
</Link>
@@ -87,28 +87,24 @@ const Description = styled(Box)`
87
}
88
`
89
90
-function topLevelItems (items, path) {
90
+function topLevelItems(items, path) {
91
if (items == null) {
92
return null
93
}
94
95
return (
96
<>
97
- {items.map((item) => {
98
- const children = NavHierarchy.isActiveUrl(path, item.url) ? NavHierarchy.getHierarchy(item, { path: path, hideVariants: true }) : null
97
+ {items.map(item => {
98
+ const children = NavHierarchy.isActiveUrl(path, item.url)
99
+ ? NavHierarchy.getHierarchy(item, {path, hideVariants: true})
100
+ : null
101
102
return (
101
- <BorderBox
102
- key={item.title}
103
- borderWidth={0}
104
- borderRadius={0}
105
- borderTopWidth={1}
106
- py={3}
107
- px={4}
108
- role="listitem"
109
- >
103
+ <BorderBox key={item.title} borderWidth={0} borderRadius={0} borderTopWidth={1} py={3} px={4} role="listitem">
104
<Flex flexDirection="column">
111
- <TopLevelLink to={item.url} key={item.title}>{item.title}</TopLevelLink>
105
+ <TopLevelLink to={item.url} key={item.title}>
106
+ {item.title}
107
+ </TopLevelLink>
108
{secondLevelItems(children, path)}
109
</Flex>
110
</BorderBox>
@@ -118,15 +114,17 @@ function topLevelItems (items, path) {
114
)
115
}
116
121
-function secondLevelItems (items, path) {
117
+function secondLevelItems(items, path) {
118
if (items == null) {
119
return null
120
}
121
122
return (
123
<Flex flexDirection="column" mt={2} role="list">
128
- {items.map((item) => {
129
- const children = NavHierarchy.isActiveUrl(path, item.url) ? NavHierarchy.getHierarchy(item, { path: path, hideVariants: true }) : null
124
+ {items.map(item => {
125
+ const children = NavHierarchy.isActiveUrl(path, item.url)
126
+ ? NavHierarchy.getHierarchy(item, {path, hideVariants: true})
127
+ : null
128
return (
129
<Box key={item.title} role="listitem">
130
<SecondLevelLink key={item.url} to={item.url}>
@@ -145,14 +143,14 @@ function secondLevelItems (items, path) {
143
)
144
}
145
148
-function thirdLevelItems (items) {
146
+function thirdLevelItems(items) {
147
if (items == null) {
148
return null
149
}
150
151
return (
152
<Flex flexDirection="column" mt={2} role="list">
155
- {items.map((item) => (
153
+ {items.map(item => (
154
<Box key={item.title} role="listitem">
155
<ThirdLevelLink key={item.url} to={item.url}>
156
{item.title}
@@ -163,7 +161,7 @@ function thirdLevelItems (items) {
161
)
162
}
163
166
-function githubLink () {
164
+function githubLink() {
165
if (!repositoryUrl) {
166
return null
167
}
@@ -172,7 +170,7 @@ function githubLink () {
170
<BorderBox borderWidth={0} borderTopWidth={1} borderRadius={0} py={5} px={4}>
171
<Link href={repositoryUrl} color="inherit">
172
<Flex justifyContent="space-between" alignItems="center" color="gray.5">
175
- Edit on GitHub
173
+ Edit on GitHub
174
<StyledOcticon icon={LinkExternalIcon} color="gray.5" />
175
</Flex>
176
</Link>
@@ -180,9 +178,9 @@ function githubLink () {
178
)
179
}
180
183
-function NavItems (props) {
181
+function NavItems(props) {
182
const path = NavHierarchy.getLocation(props.location.pathname)
185
- const items = NavHierarchy.getHierarchy(null, { path: path, hideVariants: true })
183
+ const items = NavHierarchy.getHierarchy(null, {path, hideVariants: true})
184
185
return (
186
<>
theme/src/components/note.js
+7
-15
@@ -1,22 +1,14 @@
1
import React from 'react'
2
-import { BorderBox } from '@primer/components'
2
+import {BorderBox} from '@primer/components'
3
4
-function Note ({ children }) {
4
+function Note({children}) {
5
return (
6
- <BorderBox
7
- borderWidth={1}
8
- borderRadius={0}
9
- borderColor='blue.1'
10
- backgroundColor='blue.0'
11
- px={3}
12
- py={2}
13
- my={4}
14
- >
15
- {React.Children.toArray(children).map((child, index, list) => (
6
+ <BorderBox borderWidth={1} borderRadius={0} borderColor="blue.1" backgroundColor="blue.0" px={3} py={2} my={4}>
7
+ {React.Children.toArray(children).map((child, index, list) =>
8
React.cloneElement(child, {
17
- style: index === list.length - 1 ? { marginBottom: '0' } : null,
18
- })
19
- ))}
9
+ style: index === list.length - 1 ? {marginBottom: '0'} : null,
10
+ }),
11
+ )}
12
</BorderBox>
13
)
14
}
theme/src/components/npm-logo.js
+10
-3
@@ -1,14 +1,21 @@
1
import React from 'react'
2
3
export default class NpmLogo extends React.Component {
4
- render () {
4
+ render() {
5
const bgcolor = this.props.bg || '#cb0000'
6
const fgcolor = this.props.fg || '#ffffff'
7
8
return (
9
- <svg height={this.props.size} width={this.props.size} viewBox="0 0 700 700" fill="currentColor" style={this.props.style} aria-hidden="true">
9
+ <svg
10
+ height={this.props.size}
11
+ width={this.props.size}
12
+ viewBox="0 0 700 700"
13
+ fill="currentColor"
14
+ style={this.props.style}
15
+ aria-hidden="true"
16
+ >
17
<polygon fill={bgcolor} points="0,700 700,700 700,0 0,0" />
11
- <polygon fill={fgcolor} points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150 "/>
18
+ <polygon fill={fgcolor} points="150,550 350,550 350,250 450,250 450,550 550,550 550,150 150,150 " />
19
</svg>
20
)
21
}
theme/src/components/page-footer.js
+4
-6
@@ -1,9 +1,9 @@
1
-import { BorderBox, Grid, StyledOcticon, Link } from '@primer/components'
2
-import { PencilIcon } from '@primer/octicons-react'
1
+import {BorderBox, Grid, StyledOcticon, Link} from '@primer/components'
2
+import {PencilIcon} from '@primer/octicons-react'
3
import React from 'react'
4
import Contributors from './contributors'
5
6
-function PageFooter ({ editOnGitHub, editUrl, contributors }) {
6
+function PageFooter({editOnGitHub, editUrl, contributors}) {
7
return editUrl || contributors.length > 0 ? (
8
<BorderBox borderWidth={0} borderTopWidth={1} mt={8} py={5}>
9
<Grid gridGap={4}>
@@ -14,9 +14,7 @@ function PageFooter ({ editOnGitHub, editUrl, contributors }) {
14
</Link>
15
) : null}
16
17
- {contributors.length > 0 ? (
18
- <Contributors contributors={contributors} />
19
- ) : null}
17
+ {contributors.length > 0 ? <Contributors contributors={contributors} /> : null}
18
</Grid>
19
</BorderBox>
20
) : null
theme/src/components/paragraph.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const Paragraph = styled.p`
5
margin: 0 0 ${themeGet('space.3')};
theme/src/components/prompt-reply.js
+2
-2
@@ -1,7 +1,7 @@
1
import React from 'react'
2
3
-function PromptReply ({ children }) {
4
- return (<strong>{children}</strong>)
3
+function PromptReply({children}) {
4
+ return <strong>{children}</strong>
5
}
6
7
export default PromptReply
theme/src/components/prompt.js
+6
-4
@@ -1,7 +1,7 @@
1
import React from 'react'
2
-import { BorderBox, Text } from '@primer/components'
2
+import {BorderBox, Text} from '@primer/components'
3
4
-function Prompt ({ children }) {
4
+function Prompt({children}) {
5
return (
6
<BorderBox
7
as="pre"
@@ -9,9 +9,11 @@ function Prompt ({ children }) {
9
mb={3}
10
p={3}
11
border={0}
12
- style={{ color: 'rgb(57, 58, 52)', backgroundColor: 'rgb(246, 248, 250)', overflow: 'auto' }}
12
+ style={{color: 'rgb(57, 58, 52)', backgroundColor: 'rgb(246, 248, 250)', overflow: 'auto'}}
13
>
14
- <Text fontFamily="mono" fontSize={1}>{children}</Text>
14
+ <Text fontFamily="mono" fontSize={1}>
15
+ {children}
16
+ </Text>
17
</BorderBox>
18
)
19
}
theme/src/components/screenshot.js
+9
-3
@@ -1,7 +1,7 @@
1
import React from 'react'
2
-import { withPrefix } from 'gatsby'
2
+import {withPrefix} from 'gatsby'
3
4
-function Screenshot (props) {
4
+function Screenshot(props) {
5
if (!props.src) {
6
throw new Error('src is required')
7
}
@@ -11,7 +11,13 @@ function Screenshot (props) {
11
}
12
13
return (
14
- <div><img src={withPrefix(props.src)} alt={props.alt} style={{ border: 'solid 1px #999999', marginTop: '15px', maxWidth: 'min(100%, 525px)', maxHeight: '300px' }} /></div>
14
+ <div>
15
+ <img
16
+ src={withPrefix(props.src)}
17
+ alt={props.alt}
18
+ style={{border: 'solid 1px #999999', marginTop: '15px', maxWidth: 'min(100%, 525px)', maxHeight: '300px'}}
19
+ />
20
+ </div>
21
)
22
}
23
theme/src/components/search-results.js
+6
-9
@@ -1,9 +1,9 @@
1
-import { Flex, Text } from '@primer/components'
1
+import {Flex, Text} from '@primer/components'
2
import React from 'react'
3
import useSiteMetadata from '../use-site-metadata'
4
import NavHierarchy from '../nav-hierarchy'
5
6
-function SearchResults ({ results, getItemProps, highlightedIndex }) {
6
+function SearchResults({results, getItemProps, highlightedIndex}) {
7
const siteMetadata = useSiteMetadata()
8
9
if (results.length === 0) {
@@ -25,13 +25,10 @@ function SearchResults ({ results, getItemProps, highlightedIndex }) {
25
py: 2,
26
color: highlightedIndex === index ? 'white' : 'gray.8',
27
bg: highlightedIndex === index ? 'blue.5' : 'transparent',
28
- style: { cursor: 'pointer' },
28
+ style: {cursor: 'pointer'},
29
})}
30
>
31
- <Text
32
- fontSize={0}
33
- color={highlightedIndex === index ? 'blue.2' : 'gray.7'}
34
- >
31
+ <Text fontSize={0} color={highlightedIndex === index ? 'blue.2' : 'gray.7'}>
32
{getBreadcrumbs(siteMetadata.shortName, item.path).join(' / ')}
33
</Text>
34
{item.title}
@@ -39,12 +36,12 @@ function SearchResults ({ results, getItemProps, highlightedIndex }) {
36
))
37
}
38
42
-function getBreadcrumbs (siteTitle, path) {
39
+function getBreadcrumbs(siteTitle, path) {
40
const hierarchy = NavHierarchy.getItemHierarchy(path)
41
42
if (hierarchy) {
43
hierarchy.pop()
47
- return hierarchy.map(item => item.shortName ? item.shortName : item.title)
44
+ return hierarchy.map(item => (item.shortName ? item.shortName : item.title))
45
} else {
46
return [siteTitle]
47
}
theme/src/components/search.js
+9
-20
@@ -1,18 +1,18 @@
1
-import { BorderBox, Position } from '@primer/components'
1
+import {BorderBox, Position} from '@primer/components'
2
import Downshift from 'downshift'
3
-import { navigate } from 'gatsby'
3
+import {navigate} from 'gatsby'
4
import React from 'react'
5
import useSearch from '../use-search'
6
import useSiteMetadata from '../use-site-metadata'
7
import DarkTextInput from './dark-text-input'
8
import SearchResults from './search-results'
9
10
-function stateReducer (state, changes) {
10
+function stateReducer(state, changes) {
11
switch (changes.type) {
12
case Downshift.stateChangeTypes.changeInput:
13
if (!changes.inputValue) {
14
// Close the menu if the input is empty.
15
- return { ...changes, isOpen: false }
15
+ return {...changes, isOpen: false}
16
}
17
return changes
18
default:
@@ -20,7 +20,7 @@ function stateReducer (state, changes) {
20
}
21
}
22
23
-function Search () {
23
+function Search() {
24
const [query, setQuery] = React.useState('')
25
const results = useSearch(query)
26
const siteMetadata = useSiteMetadata()
@@ -43,15 +43,8 @@ function Search () {
43
itemToString={item => (item ? item.title : '')}
44
stateReducer={stateReducer}
45
>
46
- {({
47
- getInputProps,
48
- getItemProps,
49
- getMenuProps,
50
- getRootProps,
51
- isOpen,
52
- highlightedIndex,
53
- }) => (
54
- <Position {...getRootProps({ position: 'relative' })}>
46
+ {({getInputProps, getItemProps, getMenuProps, getRootProps, isOpen, highlightedIndex}) => (
47
+ <Position {...getRootProps({position: 'relative'})}>
48
<DarkTextInput
49
{...getInputProps({
50
placeholder: `Search ${siteMetadata.title}`,
@@ -73,13 +66,9 @@ function Search () {
66
py={1}
67
boxShadow="medium"
68
bg="white"
76
- style={{ overflow: 'auto' }}
69
+ style={{overflow: 'auto'}}
70
>
78
- <SearchResults
79
- results={results}
80
- getItemProps={getItemProps}
81
- highlightedIndex={highlightedIndex}
82
- />
71
+ <SearchResults results={results} getItemProps={getItemProps} highlightedIndex={highlightedIndex} />
72
</BorderBox>
73
</Position>
74
) : null}
theme/src/components/sidebar.js
+4
-10
@@ -1,10 +1,10 @@
1
-import { BorderBox, Flex, Position } from '@primer/components'
1
+import {BorderBox, Flex, Position} from '@primer/components'
2
import React from 'react'
3
import navItems from '../nav.yml'
4
-import { HEADER_HEIGHT } from './header'
4
+import {HEADER_HEIGHT} from './header'
5
import NavItems from './nav-items'
6
7
-function Sidebar ({ location, editOnGitHub }) {
7
+function Sidebar({location, editOnGitHub}) {
8
return (
9
<Position
10
position="sticky"
@@ -15,13 +15,7 @@ function Sidebar ({ location, editOnGitHub }) {
15
bg="gray.0"
16
role="navigation"
17
>
18
- <BorderBox
19
- borderWidth={0}
20
- borderRightWidth={1}
21
- borderRadius={0}
22
- height="100%"
23
- style={{ overflow: 'auto' }}
24
- >
18
+ <BorderBox borderWidth={0} borderRightWidth={1} borderRadius={0} height="100%" style={{overflow: 'auto'}}>
19
<Flex flexDirection="column" role="list">
20
<NavItems location={location} items={navItems} editOnGitHub={editOnGitHub} />
21
</Flex>
theme/src/components/skip-link.js
+3
-10
@@ -1,17 +1,10 @@
1
-import { Link } from '@primer/components'
1
+import {Link} from '@primer/components'
2
import styled from 'styled-components'
3
import React from 'react'
4
5
-function SkipLinkBase (props) {
5
+function SkipLinkBase(props) {
6
return (
7
- <Link
8
- {...props}
9
- backgroundColor="blue.6"
10
- color="white"
11
- p={3}
12
- href="#skip-nav"
13
- fontSize={1}
14
- >
7
+ <Link {...props} backgroundColor="blue.6" color="white" p={3} href="#skip-nav" fontSize={1}>
8
Skip to content
9
</Link>
10
)
theme/src/components/source-link.js
+3
-3
@@ -1,8 +1,8 @@
1
-import { Link, StyledOcticon } from '@primer/components'
2
-import { CodeIcon } from '@primer/octicons-react'
1
+import {Link, StyledOcticon} from '@primer/components'
2
+import {CodeIcon} from '@primer/octicons-react'
3
import React from 'react'
4
5
-function SourceLink ({ href }) {
5
+function SourceLink({href}) {
6
return (
7
<Link href={href} lineHeight="condensedUltra" fontSize={1}>
8
<StyledOcticon icon={CodeIcon} mr={2} />
theme/src/components/status-label.js
+4
-4
@@ -1,5 +1,5 @@
1
-import { BorderBox, StyledOcticon, Flex, Text } from '@primer/components'
2
-import { DotFillIcon } from '@primer/octicons-react'
1
+import {BorderBox, StyledOcticon, Flex, Text} from '@primer/components'
2
+import {DotFillIcon} from '@primer/octicons-react'
3
import React from 'react'
4
5
const STATUS_COLORS = {
@@ -10,11 +10,11 @@ const STATUS_COLORS = {
10
deprecated: 'red.6',
11
}
12
13
-function getStatusColor (status) {
13
+function getStatusColor(status) {
14
return STATUS_COLORS[status.toLowerCase()] || 'gray.5'
15
}
16
17
-function StatusLabel ({ status }) {
17
+function StatusLabel({status}) {
18
return (
19
<BorderBox display="inline-block" px={2} py={1}>
20
<Flex alignItems="center">
theme/src/components/table-of-contents.js
+13
-7
@@ -1,17 +1,23 @@
1
-import { Box, Link } from '@primer/components'
1
+import {Box, Link} from '@primer/components'
2
import React from 'react'
3
4
-function TableOfContents ({ items, depth, labelId }) {
4
+function TableOfContents({items, depth, labelId}) {
5
return (
6
- <Box key={items} as="ul" role='list' m={0} p={0} css={{ listStyle: 'none', lineHeight: '1.4em' }} aria-labelledby={labelId}>
6
+ <Box
7
+ key={items}
8
+ as="ul"
9
+ role="list"
10
+ m={0}
11
+ p={0}
12
+ css={{listStyle: 'none', lineHeight: '1.4em'}}
13
+ aria-labelledby={labelId}
14
+ >
15
{items.map(item => (
8
- <Box as="li" role='listitem' key={item.url} pl={depth > 0 ? 3 : 0}>
16
+ <Box as="li" role="listitem" key={item.url} pl={depth > 0 ? 3 : 0}>
17
<Link key={item.title} display="inline-block" py={1} href={item.url} color="gray.6">
18
{item.title}
19
</Link>
12
- {item.items ? (
13
- <TableOfContents items={item.items} depth={depth + 1} />
14
- ) : null}
20
+ {item.items ? <TableOfContents items={item.items} depth={depth + 1} /> : null}
21
</Box>
22
))}
23
</Box>
theme/src/components/table.js
+1
-1
@@ -1,5 +1,5 @@
1
import styled from 'styled-components'
2
-import themeGet from '@styled-system/theme-get'
2
+import {themeGet} from '@styled-system/theme-get'
3
4
const Table = styled.table`
5
display: block;
theme/src/components/variant-select.js
+25
-18
@@ -5,10 +5,10 @@
5
// then you'll get a selection for the different variants (v1.0, v2.0).
6
7
import React from 'react'
8
-import { ActionList, ActionMenu, ThemeProvider } from '@primer/react'
8
+import {ActionList, ActionMenu, ThemeProvider} from '@primer/react'
9
import NavHierarchy from '../nav-hierarchy'
10
11
-function VariantSelect (props) {
11
+function VariantSelect(props) {
12
const [open, setOpen] = React.useState(false)
13
const path = NavHierarchy.getPath(props.location.pathname)
14
const vp = NavHierarchy.getVariantAndPage(props.root, path)
@@ -25,40 +25,47 @@ function VariantSelect (props) {
25
return null
26
}
27
28
- function anchorClickHandler (event, url) {
28
+ function anchorClickHandler(event, url) {
29
event.preventDefault()
30
- window.location.href = url + '?v=true'
30
+ window.location.href = `${url}?v=true`
31
}
32
33
- function onItemEnterKey (event, url) {
33
+ function onItemEnterKey(event, url) {
34
if (event.key === 'Enter') {
35
- window.location.href = url + '?v=true'
35
+ window.location.href = `${url}?v=true`
36
}
37
}
38
39
- variantPages.forEach((match, index) => {
39
+ for (const [index, match] of variantPages.entries()) {
40
let active = false
41
if (match.page.url === path) {
42
selectedItem = match
43
active = true
44
}
45
- items.push(<ActionList.Item
46
- onKeyDown={e => onItemEnterKey(e, match.page.url)}
47
- onClick={e => anchorClickHandler(e, match.page.url)}
48
- id={match.variant.shortName}
49
- key={index}
50
- active={active}>
51
- {match.variant.title}
52
- </ActionList.Item>)
53
- })
45
+ items.push(
46
+ <ActionList.Item
47
+ onKeyDown={e => onItemEnterKey(e, match.page.url)}
48
+ onClick={e => anchorClickHandler(e, match.page.url)}
49
+ id={match.variant.shortName}
50
+ key={index}
51
+ active={active}
52
+ >
53
+ {match.variant.title}
54
+ </ActionList.Item>,
55
+ )
56
+ }
57
58
const ariaLabelMenuButton = open ? 'Version release' : selectedItem.variant.title
59
60
return (
61
<ThemeProvider>
59
- <label id="label-versions-list-item" htmlFor='versions-list-item'>Select CLI Version:</label>
62
+ <label id="label-versions-list-item" htmlFor="versions-list-item">
63
+ Select CLI Version:
64
+ </label>
65
<ActionMenu open={open} onOpenChange={setOpen}>
61
- <ActionMenu.Button autofocus="true" aria-label={ariaLabelMenuButton}>{selectedItem.variant.title}</ActionMenu.Button>
66
+ <ActionMenu.Button autofocus="true" aria-label={ariaLabelMenuButton}>
67
+ {selectedItem.variant.title}
68
+ </ActionMenu.Button>
69
<ActionMenu.Overlay width="medium" onEscape={() => setOpen(false)}>
70
<ActionList id="versions-list-item" aria-labelledby="label-versions-list-item">
71
{items}
theme/src/components/wrap-page-element.js
+2
-2
@@ -1,8 +1,8 @@
1
-import { BaseStyles } from '@primer/components'
1
+import {BaseStyles} from '@primer/components'
2
import React from 'react'
3
import SkipLink from './skip-link'
4
5
-function wrapPageElement ({ element }) {
5
+function wrapPageElement({element}) {
6
return (
7
<BaseStyles>
8
<SkipLink />
theme/src/components/wrap-root-element.js
+5
-5
@@ -1,11 +1,11 @@
1
-import { MDXProvider } from '@mdx-js/react'
2
-import { Link, theme } from '@primer/components'
1
+import {MDXProvider} from '@mdx-js/react'
2
+import {Link, theme} from '@primer/components'
3
import React from 'react'
4
-import { ThemeProvider } from 'styled-components'
4
+import {ThemeProvider} from 'styled-components'
5
import Blockquote from './blockquote'
6
import Code from './code'
7
import DescriptionList from './description-list'
8
-import { H1, H2, H3, H4, H5, H6 } from './heading'
8
+import {H1, H2, H3, H4, H5, H6} from './heading'
9
import HorizontalRule from './horizontal-rule'
10
import Image from './image'
11
import InlineCode from './inline-code'
@@ -34,7 +34,7 @@ const components = {
34
dl: DescriptionList,
35
}
36
37
-function wrapRootElement ({ element }) {
37
+function wrapRootElement({element}) {
38
return (
39
<MDXProvider components={components}>
40
<ThemeProvider theme={theme}>{element}</ThemeProvider>
theme/src/nav-hierarchy.js
+39
-37
@@ -1,8 +1,8 @@
1
import navItems from './nav.yml'
2
-import { withPrefix } from 'gatsby'
2
+import {withPrefix} from 'gatsby'
3
4
export default {
5
- getLocation (path) {
5
+ getLocation(path) {
6
const pathPrefix = withPrefix('/')
7
8
if (!pathPrefix || pathPrefix === '/') {
@@ -13,7 +13,7 @@ export default {
13
return path.replace(match, '/')
14
},
15
16
- getPath (path) {
16
+ getPath(path) {
17
while (path && path.endsWith('/')) {
18
path = path.substring(0, path.length - 1)
19
}
@@ -21,11 +21,11 @@ export default {
21
return path
22
},
23
24
- getVariantRoot (path) {
24
+ getVariantRoot(path) {
25
path = this.getPath(path)
26
27
- return this.findItem((item) => {
28
- if (item.variants && path.startsWith(item.url + '/')) {
27
+ return this.findItem(item => {
28
+ if (item.variants && path.startsWith(`${item.url}/`)) {
29
return item.url
30
}
31
@@ -33,7 +33,7 @@ export default {
33
})
34
},
35
36
- findItem (fn, items = navItems) {
36
+ findItem(fn, items = navItems) {
37
for (let i = 0; i < items.length; i++) {
38
const item = items[i]
39
let result = fn(item)
@@ -50,7 +50,7 @@ export default {
50
return null
51
},
52
53
- getItemHierarchy (path, items = navItems) {
53
+ getItemHierarchy(path, items = navItems) {
54
if (!path) {
55
return null
56
}
@@ -76,9 +76,9 @@ export default {
76
return null
77
},
78
79
- getItem (path, items = navItems) {
79
+ getItem(path, items = navItems) {
80
if (!path) {
81
- return { url: '/', children: items }
81
+ return {url: '/', children: items}
82
}
83
84
for (let i = 0; i < items.length; i++) {
@@ -102,19 +102,19 @@ export default {
102
return null
103
},
104
105
- isPathForItem (path, item) {
106
- return (this.getPath(item.url) === this.getPath(path))
105
+ isPathForItem(path, item) {
106
+ return this.getPath(item.url) === this.getPath(path)
107
},
108
109
- isChildItem (path, items = navItems) {
109
+ isChildItem(path, items = navItems) {
110
if (!path) {
111
return false
112
}
113
114
- return (this.findItem((item) => this.isPathForItem(path, item) ? item : null, items) != null)
114
+ return this.findItem(item => (this.isPathForItem(path, item) ? item : null), items) != null
115
},
116
117
- getHierarchy (root, props = { }) {
117
+ getHierarchy(root, props = {}) {
118
let children
119
120
if (!root) {
@@ -135,7 +135,7 @@ export default {
135
return children
136
},
137
138
- hideVariantsForItems (items, props) {
138
+ hideVariantsForItems(items, props) {
139
if (!items) {
140
return null
141
}
@@ -144,7 +144,7 @@ export default {
144
145
for (const item of items) {
146
if (item.variants) {
147
- const cloned = { }
147
+ const cloned = {}
148
Object.assign(cloned, item)
149
150
const variant = this.getCurrentOrDefaultVariant(item, props.path)
@@ -160,7 +160,7 @@ export default {
160
return updated
161
},
162
163
- getCurrentOrDefaultVariant (root, path) {
163
+ getCurrentOrDefaultVariant(root, path) {
164
let variant = path ? this.getCurrentVariant(root, path) : null
165
166
if (!variant) {
@@ -170,7 +170,7 @@ export default {
170
return variant
171
},
172
173
- getCurrentVariant (root, path) {
173
+ getCurrentVariant(root, path) {
174
for (const v of root.variants) {
175
if (this.isActiveItem(path, v)) {
176
return v
@@ -180,7 +180,7 @@ export default {
180
return null
181
},
182
183
- getDefaultVariant (root) {
183
+ getDefaultVariant(root) {
184
for (const v of root.variants) {
185
if (v.default) {
186
return v
@@ -190,8 +190,8 @@ export default {
190
return root.variants[0]
191
},
192
193
- getVariantAndPage (root, path) {
194
- if (!path.startsWith(root + '/')) {
193
+ getVariantAndPage(root, path) {
194
+ if (!path.startsWith(`${root}/`)) {
195
return null
196
}
197
@@ -203,17 +203,17 @@ export default {
203
return null
204
}
205
206
- return { variant: match[1], page: match[2] }
206
+ return {variant: match[1], page: match[2]}
207
},
208
209
- getVariantsForPage (root, page) {
209
+ getVariantsForPage(root, page) {
210
const pages = []
211
- const rootItem = this.findItem((item) => this.getPath(item.url) === this.getPath(root) ? item : null)
211
+ const rootItem = this.findItem(item => (this.getPath(item.url) === this.getPath(root) ? item : null))
212
213
if (rootItem && rootItem.variants) {
214
- rootItem.variants.forEach((variant) => {
214
+ for (const variant of rootItem.variants) {
215
if (!variant.children) {
216
- return
216
+ continue
217
}
218
219
const vp = this.getVariantAndPage(root, variant.url)
@@ -222,30 +222,32 @@ export default {
222
if (vp.page === page) {
223
variantPage = variant
224
} else {
225
- variantPage = this.findItem((item) => {
225
+ variantPage = this.findItem(item => {
226
const vp = this.getVariantAndPage(root, item.url)
227
- return (vp && vp.page === page) ? item : null
227
+ return vp && vp.page === page ? item : null
228
}, variant.children)
229
}
230
231
if (!variantPage) {
232
- return
232
+ continue
233
}
234
235
- pages.push({ variant: variant, page: variantPage })
236
- })
235
+ pages.push({variant, page: variantPage})
236
+ }
237
}
238
239
return pages
240
},
241
242
- isActiveItem (currentPath, linkItem) {
243
- return (this.isPathForItem(currentPath, linkItem) ||
244
- (linkItem.children && this.isChildItem(currentPath, linkItem.children)) ||
245
- (linkItem.variants && this.isChildItem(currentPath, linkItem.variants)))
242
+ isActiveItem(currentPath, linkItem) {
243
+ return (
244
+ this.isPathForItem(currentPath, linkItem) ||
245
+ (linkItem.children && this.isChildItem(currentPath, linkItem.children)) ||
246
+ (linkItem.variants && this.isChildItem(currentPath, linkItem.variants))
247
+ )
248
},
249
248
- isActiveUrl (currentPath, linkPath) {
250
+ isActiveUrl(currentPath, linkPath) {
251
const linkItem = this.getItem(linkPath)
252
return linkItem ? this.isActiveItem(currentPath, linkItem) : false
253
},
theme/src/search.worker.js
+10
-7
@@ -1,7 +1,6 @@
1
import Fuse from 'fuse.js'
2
import debounce from 'lodash.debounce'
3
-
4
-(function searchWorker () {
3
+;(function searchWorker() {
4
let fuse = null
5
6
// [MKT]: I landed on the debouce wait value of 50 based mostly on
@@ -13,12 +12,16 @@ import debounce from 'lodash.debounce'
12
// > Note: If `leading` and `trailing` options are `true`, `func` is invoked
13
// > on the trailing edge of the timeout only if the debounced function is
14
// > invoked more than once during the wait timeout.
16
- const performSearch = debounce(function performSearch (query) {
17
- const results = fuse.search(query).slice(0, 20)
18
- postMessage({ results: results, query: query })
19
- }, 50, { leading: true, trailing: true })
15
+ const performSearch = debounce(
16
+ function performSearch(query) {
17
+ const results = fuse.search(query).slice(0, 20)
18
+ postMessage({results, query})
19
+ },
20
+ 50,
21
+ {leading: true, trailing: true},
22
+ )
23
21
- onmessage = function ({ data }) {
24
+ onmessage = function ({data}) {
25
if (data.list) {
26
fuse = new Fuse(data.list, {
27
threshold: 0.2,
theme/src/use-search.js
+20
-19
@@ -1,7 +1,7 @@
1
-import { graphql, useStaticQuery } from 'gatsby'
1
+import {graphql, useStaticQuery} from 'gatsby'
2
import React from 'react'
3
4
-function useSearch (query) {
4
+function useSearch(query) {
5
const latestQuery = React.useRef(query)
6
const workerRef = React.useRef()
7
@@ -28,29 +28,30 @@ function useSearch (query) {
28
const mdxNodes = data.allMdx.nodes.reduce((map, obj) => {
29
map[obj.id] = obj
30
return map
31
- }, { })
31
+ }, {})
32
33
const list = React.useMemo(
34
() =>
35
- data.allSitePage.nodes.filter(node => {
36
- return (node.pageContext && node.pageContext.mdxId && mdxNodes[node.pageContext.mdxId] != null)
37
- }).map(node => {
38
- const mdxNode = mdxNodes[node.pageContext.mdxId]
35
+ data.allSitePage.nodes
36
+ .filter(node => {
37
+ return node.pageContext && node.pageContext.mdxId && mdxNodes[node.pageContext.mdxId] != null
38
+ })
39
+ .map(node => {
40
+ const mdxNode = mdxNodes[node.pageContext.mdxId]
41
40
- const obj =
41
- {
42
- path: node.path,
43
- title: mdxNode.frontmatter.title,
44
- rawBody: mdxNode.rawBody,
45
- }
46
- return obj
47
- }),
48
- [data]
42
+ const obj = {
43
+ path: node.path,
44
+ title: mdxNode.frontmatter.title,
45
+ rawBody: mdxNode.rawBody,
46
+ }
47
+ return obj
48
+ }),
49
+ [data],
50
)
51
52
const [results, setResults] = React.useState(list)
53
53
- const handleSearchResults = React.useCallback(({ data }) => {
54
+ const handleSearchResults = React.useCallback(({data}) => {
55
if (data.query && data.results && data.query === latestQuery.current) {
56
setResults(data.results)
57
}
@@ -59,7 +60,7 @@ function useSearch (query) {
60
React.useEffect(() => {
61
const worker = new Worker(new URL('./search.worker.js', import.meta.url))
62
worker.addEventListener('message', handleSearchResults)
62
- worker.postMessage({ list })
63
+ worker.postMessage({list})
64
workerRef.current = worker
65
66
return () => {
@@ -70,7 +71,7 @@ function useSearch (query) {
71
React.useEffect(() => {
72
latestQuery.current = query
73
if (query && workerRef.current) {
73
- workerRef.current.postMessage({ query: query })
74
+ workerRef.current.postMessage({query})
75
} else {
76
setResults(list)
77
}
theme/src/use-site-metadata.js
+2
-2
@@ -1,6 +1,6 @@
1
-import { useStaticQuery, graphql } from 'gatsby'
1
+import {useStaticQuery, graphql} from 'gatsby'
2
3
-function useSiteMetadata () {
3
+function useSiteMetadata() {
4
const data = useStaticQuery(graphql`
5
{
6
site {