We use the React configuration from GitHub's eslint plugin to lint our JavaScript. To check your work before pushing, run:
npm run lint
Or, you can use npx to run eslint on one or more specific files:
# lint the component and the tests in src/__tests__
npx eslint src/**/MyComponent.js
Protip: The eslint --fix
flag can automatically fix most linting errors, such as those involving whitespace or incorrect ordering of object keys and imports. You can fix those issues across the entire project with:
npm run lint -- --fix
Protip: npm run lint -- --quiet
(or npx eslint --quiet ...
) will suppress warnings so that you can focus on fixing errors.
We test our components with Jest and react-test-renderer. You can run the tests locally with npm test
(or npm t
). To run the tests as you work, run Jest in watch mode with:
npm t -- --watch
See src/__tests__/example.js
for examples of ways that we test our components.
A code coverage report is included in the npm test
output, and test coverage data is generated in the coverage/
directory.
- We use styled-components to style our components.
- We use style functions from styled-system whenever possible, and styled-systems'
style()
function to create new ones.
With a couple of exceptions, all components should be created with the styled
function from [styled-components] and should have the appropriate groups of system props attached.
Default values for system props can be set in Component.defaultProps
.
Prop Types from system props such as COMMON
or TYPOGRAPHY
as well as styled-system functions can be spread in the component's prop types declaration (see example below).
theme
prop to our theme! This allows consumers of our components to access our theme values without a ThemeProvider.
import {TYPOGRAPHY, COMMON} from './constants'
import theme from './theme'
const Component = styled.div`
${TYPOGRAPHY}
${COMMON};
`
Component.defaultProps = {
theme, // make sure to always set the default theme!
m: 0,
fontSize: 5,
}
Component.propTypes = {
...COMMON.propTypes,
...TYPOGRAPHY.propTypes
}
export default Component
Categories of system props are exported from src/constants.js
:
COMMON
includes color and spacing (margin and padding) propsTYPOGRAPHY
includes font family, font weight, and line-height propsPOSITION
includes positioning propsFLEX_CONTAINER
includes flexbox props for containersFLEX_ITEM
includes flexbox props for items in a flex container
We use Doctocat to power our documentation site at https://primer.style/components.
To add a new component to our documentation site, create a new file with the .md
extension for your component in docs/content/components
.
We deploy the Primer Components site using Now. Install the Now CLI and log in with:
npm i -g now
now login
Once you're logged in, sync your local git repo with the master
branch and run:
script/deploy
This will create a new deployment and alias it to its production URL, primer-components.now.sh.
This site is served as a subdirectory of primer.style using a path alias configured in that repo's rules.json
. If you change the production deployment URL for this app, you will also need to change it there and re-deploy that app; otherwise, Now will automatically route requests from primer.style/components to the new deployment whenever you alias this one to primer-components.now.sh
.
npm start
fails with an error like gatsby: command not found
Make sure to run npm install
from inside the docs/
subfolder as well as the root folder.
npm start
fails with a different error
Ensure you are using the latest minor of Node.js for the major version specified in the .nvmrc
file. For example, if .nvmrc
contains 8
, make sure you're using the latest version of Node.js with the major version of 8.
System props are style functions that provide one or more props, and can be passed directly the return value of [styled-components]'s styled()
function:
import {styled} from 'styled-components'
import {space} from 'styled-system'
const SpaceDiv = styled.div`
${space}
`
System props come with propTypes
that can be mixed into your own with ES6 spread syntax:
SpaceDiv.propTypes = {
stellar: PropTypes.bool,
...space.propTypes
}