diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 8bb3625a5d9..00000000000 --- a/.babelrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "presets": [ - ["@babel/preset-react", {"modules": false}], - ["@babel/preset-env", {"modules": false}] - ], - "plugins": [ - "macros", - "add-react-displayname", - "babel-plugin-styled-components", - "@babel/plugin-proposal-object-rest-spread" - ], - "env": { - "test": { - "presets": [ - ["@babel/preset-react", {"modules": "commonjs"}], - ["@babel/preset-env", {"modules": "commonjs"}] - ] - } - } -} diff --git a/.eslintrc.json b/.eslintrc.json index b0be5232a9f..14bf0a82e7c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,6 +5,9 @@ "plugin:jsx-a11y/recommended", "plugin:react-hooks/recommended" ], + "globals": { + "__DEV__": "readonly" + }, "rules": { "import/no-namespace": 0, "no-shadow": 0, diff --git a/.gitignore b/.gitignore index 25b249621de..c5e5291b99b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ node_modules .DS_Store coverage/ dist/ +lib/ public/ +stats.html diff --git a/babel-defines.js b/babel-defines.js new file mode 100644 index 00000000000..63361e78474 --- /dev/null +++ b/babel-defines.js @@ -0,0 +1,13 @@ +const shared = { + __DEV__: "process.env.NODE_ENV !== 'production'" +} + +module.exports = { + development: shared, + test: shared, + production: { + ...shared, + __DEV__: 'false', + 'process.env.NODE_ENV': "'production'" + } +} diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000000..8085b12f677 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,39 @@ +const defines = require('./babel-defines') + +function replacementPlugin(env) { + return ['babel-plugin-transform-replace-expressions', {replace: defines[env]}] +} + +const sharedPlugins = [ + 'macros', + 'preval', + 'add-react-displayname', + 'babel-plugin-styled-components', + '@babel/plugin-proposal-object-rest-spread' +] + +const devPlugins = [['@babel/plugin-transform-runtime', {version: '7.9.2', helpers: true}]] + +function makePresets(moduleValue) { + return [ + ['@babel/preset-react', {modules: moduleValue}], + ['@babel/preset-env', {modules: moduleValue}] + ] +} + +module.exports = { + env: { + development: { + presets: makePresets('commonjs'), + plugins: [...sharedPlugins, ...devPlugins, replacementPlugin('development')] + }, + production: { + presets: makePresets(false), + plugins: [...sharedPlugins, replacementPlugin('production')] + }, + test: { + presets: makePresets('commonjs'), + plugins: [...sharedPlugins, replacementPlugin('test')] + } + } +} diff --git a/css.js b/css.js deleted file mode 100644 index f6ad7185983..00000000000 --- a/css.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/css') diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 3a5b6492360..704cdf01a9e 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -4,30 +4,40 @@ title: Getting Started ## Installation -To get started using Primer Components, install the package and its two peer dependencies with your package manager of choice: +To get started using Primer Components, install the package and its peer dependencies with your package manager of choice: ```bash # with npm -npm install @primer/components react styled-components +npm install @primer/components react react-dom styled-components # with yarn -yarn add @primer/components react styled-components +yarn add @primer/components react react-dom styled-components ``` -You can now start importing Primer Components! +You can now import Primer Components from the main package module: ```javascript import {Box, Flex} from '@primer/components' ``` +Alternatively, you can import individual components from the `lib` subfolder: + +```javascript +import Box from '@primer/components/lib/Box' +import Flex from '@primer/components/lib/Flex' +``` + +Importing components individually can reduce bundle sizes if you don't have tree-shaking set up in your app. + ### Peer dependencies Primer Components ships with a few libraries labeled as peer dependencies. These libraries are separated because they are commonly already installed in the host project and having multiple versions can introduce errors. -Before getting started using Primer Components, make sure that the following libraries are installed in your host project: +Primer Components requires the following libraries to be installed along with it: - `styled-components` at version 4.0.0 or higher - `react` at versions 16.8.0 or higher +- `react-dom` at versions 16.8.0 or higher ## BaseStyles @@ -128,3 +138,7 @@ In your `tsconfig.json`, set the `types` array under the `compilerOptions` like ``` Of course, customize the array based on the `@types/` packages you have installed for your project. + +## Silencing warnings + +Like React, Primer Components emits warnings to the JavaScript console under certain conditions, like using deprecated components or props. Similar to React, you can silence these warnings by setting the `NODE_ENV` environment variable to `production` during bundling. diff --git a/docs/gatsby-node.js b/docs/gatsby-node.js new file mode 100644 index 00000000000..1cb066c3883 --- /dev/null +++ b/docs/gatsby-node.js @@ -0,0 +1,23 @@ +const defines = require('../babel-defines') + +exports.onCreateWebpackConfig = ({actions, plugins, loaders, getConfig}) => { + const config = getConfig() + // Add our `__DEV__` and `process.env.NODE_ENV` defines + config.plugins.push(plugins.define(defines[process.env.NODE_ENV || 'development'])) + + config.module.rules = [ + // Remove the original rule that compiles `.js`. and `.jsx` files... + ...config.module.rules.filter(rule => String(rule.test) !== String(/\.jsx?$/)), + // ...and replace it with a custom configuration. + { + // The new configuration is based off the original... + ...loaders.js(), + test: /\.jsx?$/, + exclude: modulePath => /node_modules/.test(modulePath), + // ...except that we want to run Primer Components through webpack as well. + // By default, Gatsby won't use the define plugin we added above on Primer Components. + include: modulePath => /@primer\/components/.test(modulePath) + } + ] + actions.replaceWebpackConfig(config) +} diff --git a/docs/package.json b/docs/package.json index 86ae05a85e0..fb214875db8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,7 @@ "scripts": { "clean": "gatsby clean", "develop": "gatsby develop", - "build": "cd .. && yarn && cd docs && gatsby build --prefix-paths" + "build": "cd .. && yarn && cd docs && cross-env NODE_ENV=production gatsby build --prefix-paths" }, "engines": { "node": ">= 10.x" @@ -23,6 +23,7 @@ "styled-system": "^5.1.0" }, "devDependencies": { + "cross-env": "7.0.2", "minipass": "^2.9.0" } -} \ No newline at end of file +} diff --git a/docs/yarn.lock b/docs/yarn.lock index b512000106d..01a355bbb35 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3906,6 +3906,13 @@ create-react-context@^0.2.1: fbjs "^0.8.0" gud "^1.0.0" +cross-env@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" + integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== + dependencies: + cross-spawn "^7.0.1" + cross-fetch@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.2.tgz#a47ff4f7fc712daba8f6a695a11c948440d45723" @@ -3943,6 +3950,15 @@ cross-spawn@^7.0.0: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" + integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypt@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" diff --git a/jest.config.js b/jest.config.js index 9a1b0e31b34..63e6363fac3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,5 +2,5 @@ module.exports = { cacheDirectory: '.test', collectCoverage: true, collectCoverageFrom: ['src/*.js'], - setupFilesAfterEnv: ['/src/utils/test-matchers.js'] + setupFilesAfterEnv: ['/src/utils/test-matchers.js', '/src/utils/test-deprecations.js'] } diff --git a/now.json b/now.json index 31791d274ec..92c75b244bc 100644 --- a/now.json +++ b/now.json @@ -2,7 +2,7 @@ "name": "primer-components", "version": 2, "alias": "primer-components.now.sh", - "files": [".babelrc", "yarn.lock", "docs", "rollup.config.js", "src", "static"], + "files": ["babel.config.js", "yarn.lock", "docs", "rollup.config.js", "src", "static"], "routes": [ {"src": "/playroom(/.*)?", "dest": "$1"}, {"src": "/components(/.*)?", "dest": "/docs$1"}, diff --git a/package.json b/package.json index c233216e7ab..98df90facd9 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,15 @@ "name": "@primer/components", "version": "19.0.0", "description": "Primer react components", - "main": "dist/index.umd.js", - "module": "dist/index.esm.js", + "main": "lib/index.js", + "module": "lib/index.js", "typings": "index.d.ts", "scripts": { "start": "cd docs && yarn run develop", "predist": "rm -rf dist", - "dist": "NODE_ENV=production rollup -c", + "dist": "yarn dist:rollup && yarn dist:transpile", + "dist:rollup": "cross-env NODE_ENV=production rollup -c", + "dist:transpile": "rm -rf lib && babel src --out-dir lib", "prepublishOnly": "yarn run dist", "lint": "eslint src docs/components", "test": "jest -- src", @@ -28,14 +30,15 @@ "files": [ "codemods", "dist", - "src", + "lib", "index.d.ts", - "!src/__tests__", - "!src/utils" + "!lib/__tests__" ], "author": "GitHub, Inc.", "license": "MIT", "dependencies": { + "@babel/helpers": "7.9.2", + "@babel/runtime": "7.9.2", "@primer/octicons-react": "^9.6.0", "@primer/primitives": "3.0.0", "@reach/dialog": "0.3.0", @@ -46,24 +49,31 @@ "@testing-library/react": "9.4.0", "@types/styled-components": "^4.4.0", "@types/styled-system": "5.1.2", - "babel-plugin-macros": "2.6.1", + "babel-plugin-macros": "2.8.0", "babel-polyfill": "6.26.0", "classnames": "^2.2.5", "details-element-polyfill": "2.4.0", "jest-axe": "3.2.0", - "nanoid": "2.1.4", "polished": "3.5.2", "react": "^16.10.2", "react-is": "16.10.2", "styled-system": "5.1.2" }, "devDependencies": { - "@babel/core": "7.7.7", - "@babel/plugin-proposal-object-rest-spread": "7.6.2", - "@babel/preset-env": "7.7.7", - "@babel/preset-react": "7.6.3", + "@babel/cli": "7.8.4", + "@babel/core": "7.9.0", + "@babel/plugin-proposal-object-rest-spread": "7.9.5", + "@babel/plugin-transform-runtime": "7.9.0", + "@babel/preset-env": "7.9.5", + "@babel/preset-react": "7.9.4", + "@rollup/plugin-commonjs": "11.1.0", + "@rollup/plugin-node-resolve": "7.1.3", + "babel-core": "7.0.0-bridge.0", "babel-plugin-add-react-displayname": "0.0.5", - "babel-plugin-styled-components": "1.10.6", + "babel-plugin-preval": "5.0.0", + "babel-plugin-styled-components": "1.10.7", + "babel-plugin-transform-replace-expressions": "0.2.0", + "cross-env": "7.0.2", "enzyme": "3.10.0", "enzyme-adapter-react-16": "1.15.1", "eslint": "6.5.1", @@ -76,26 +86,30 @@ "jscodeshift": "0.6.4", "playroom": "0.15.1", "raw.macro": "0.3.0", - "react-dom": "16.11.0", + "react-dom": "^16.10.2", "react-test-renderer": "16.10.2", - "rollup": "1.25.1", - "rollup-plugin-babel": "4.3.3", + "rollup": "2.7.3", + "rollup-plugin-babel": "4.4.0", "rollup-plugin-commonjs": "10.1.0", + "rollup-plugin-terser": "5.3.0", + "rollup-plugin-visualizer": "4.0.4", + "semver": "7.3.2", "styled-components": "4.4.0" }, "peerDependencies": { "react": "^16.8.0", + "react-dom": "^16.8.0", "styled-components": "4.x || 5.x" }, "actionBundlesize": { - "build": "yarn && yarn dist", + "build": "yarn && yarn dist:rollup", "files": [ { - "path": "dist/index.esm.js", + "path": "dist/browser.esm.js", "name": "ESM Build" }, { - "path": "dist/index.umd.js", + "path": "dist/browser.umd.js", "name": "UMD Build" } ] diff --git a/rollup.config.js b/rollup.config.js index 4403f6e2f66..e262bd16fd9 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,18 +1,40 @@ import babel from 'rollup-plugin-babel' import commonjs from 'rollup-plugin-commonjs' +import resolve from '@rollup/plugin-node-resolve' +import {terser} from 'rollup-plugin-terser' +import visualizer from 'rollup-plugin-visualizer' + +// NOTE: this can be removed once the next version of rollup-plugin-commonjs is released +const namedExports = { + 'prop-types': ['object', 'func', 'oneOfType', 'node', 'bool', 'string', 'any', 'arrayOf'], + 'react-dom': ['createPortal'], + 'react-is': ['isValidElementType'] +} const formats = ['esm', 'umd'] // 'cjs' ? -const plugins = [babel({exclude: 'node_modules/**'}), commonjs()] +const plugins = [ + babel({exclude: 'node_modules/**'}), + resolve(), + commonjs({namedExports}), + terser(), + visualizer({sourcemap: true}) +] export default [ { input: 'src/index.js', plugins, - external: ['styled-components', 'react'], + external: ['styled-components', 'react', 'react-dom'], output: formats.map(format => ({ - file: `dist/index.${format}.js`, + file: `dist/browser.${format}.js`, format, - name: 'primer' + sourcemap: true, + name: 'primer', + globals: { + react: 'React', + 'react-dom': 'ReactDOM', + 'styled-components': 'styled' + } })) } ] diff --git a/src/Breadcrumbs.js b/src/Breadcrumb.js similarity index 100% rename from src/Breadcrumbs.js rename to src/Breadcrumb.js diff --git a/src/Button.js b/src/Button/Button.js similarity index 93% rename from src/Button.js rename to src/Button/Button.js index 93dd2420b73..fb193e1e906 100644 --- a/src/Button.js +++ b/src/Button/Button.js @@ -1,7 +1,7 @@ import styled from 'styled-components' -import sx from './sx' -import {get} from './constants' -import theme from './theme' +import sx from '../sx' +import {get} from '../constants' +import theme from '../theme' import ButtonBase from './ButtonBase' const Button = styled(ButtonBase)` diff --git a/src/ButtonBase.js b/src/Button/ButtonBase.js similarity index 93% rename from src/ButtonBase.js rename to src/Button/ButtonBase.js index 980d7658e97..ab5cb63b964 100644 --- a/src/ButtonBase.js +++ b/src/Button/ButtonBase.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types' import styled from 'styled-components' -import {COMMON, LAYOUT} from './constants' -import theme from './theme' +import {COMMON, LAYOUT} from '../constants' +import theme from '../theme' import buttonBaseStyles from './ButtonStyles' import {compose, variant, fontSize} from 'styled-system' import systemPropTypes from '@styled-system/prop-types' diff --git a/src/ButtonDanger.js b/src/Button/ButtonDanger.js similarity index 94% rename from src/ButtonDanger.js rename to src/Button/ButtonDanger.js index fdb72968ccb..03f63371820 100644 --- a/src/ButtonDanger.js +++ b/src/Button/ButtonDanger.js @@ -1,8 +1,8 @@ import styled from 'styled-components' import ButtonBase from './ButtonBase' -import {get} from './constants' -import theme from './theme' -import sx from './sx' +import {get} from '../constants' +import theme from '../theme' +import sx from '../sx' const ButtonDanger = styled(ButtonBase)` color: ${get('buttons.danger.color.default')}; diff --git a/src/ButtonGroup.js b/src/Button/ButtonGroup.js similarity index 89% rename from src/ButtonGroup.js rename to src/Button/ButtonGroup.js index 6cb77d99512..e189c92b541 100644 --- a/src/ButtonGroup.js +++ b/src/Button/ButtonGroup.js @@ -1,8 +1,8 @@ import styled from 'styled-components' -import {get} from './constants' -import Box from './Box' -import theme from './theme' -import sx from './sx' +import {get} from '../constants' +import Box from '../Box' +import theme from '../theme' +import sx from '../sx' const ButtonGroup = styled(Box)` vertical-align: middle; diff --git a/src/ButtonOutline.js b/src/Button/ButtonOutline.js similarity index 94% rename from src/ButtonOutline.js rename to src/Button/ButtonOutline.js index 526bdb01ec6..869e78e81f0 100644 --- a/src/ButtonOutline.js +++ b/src/Button/ButtonOutline.js @@ -1,8 +1,8 @@ import styled from 'styled-components' import ButtonBase from './ButtonBase' -import {get} from './constants' -import theme from './theme' -import sx from './sx' +import {get} from '../constants' +import theme from '../theme' +import sx from '../sx' const ButtonOutline = styled(ButtonBase)` color: ${get('buttons.outline.color.default')}; diff --git a/src/ButtonPrimary.js b/src/Button/ButtonPrimary.js similarity index 93% rename from src/ButtonPrimary.js rename to src/Button/ButtonPrimary.js index ab27444b7d7..a73b0e40c5b 100644 --- a/src/ButtonPrimary.js +++ b/src/Button/ButtonPrimary.js @@ -1,8 +1,8 @@ import styled from 'styled-components' import ButtonBase from './ButtonBase' -import {get} from './constants' -import theme from './theme' -import sx from './sx' +import {get} from '../constants' +import theme from '../theme' +import sx from '../sx' const ButtonPrimary = styled(ButtonBase)` color: ${get('buttons.primary.color.default')}; diff --git a/src/ButtonStyles.js b/src/Button/ButtonStyles.js similarity index 94% rename from src/ButtonStyles.js rename to src/Button/ButtonStyles.js index 31272585bdc..f48e32a92b1 100644 --- a/src/ButtonStyles.js +++ b/src/Button/ButtonStyles.js @@ -1,5 +1,5 @@ import {css} from 'styled-components' -import {get} from './constants' +import {get} from '../constants' export default css` position: relative; diff --git a/src/ButtonTableList.js b/src/Button/ButtonTableList.js similarity index 90% rename from src/ButtonTableList.js rename to src/Button/ButtonTableList.js index 4bdbdc2bf85..dc06c6041ce 100644 --- a/src/ButtonTableList.js +++ b/src/Button/ButtonTableList.js @@ -1,8 +1,8 @@ import styled from 'styled-components' import PropTypes from 'prop-types' -import {COMMON, LAYOUT, TYPOGRAPHY, get} from './constants' -import theme from './theme' -import sx from './sx' +import {COMMON, LAYOUT, TYPOGRAPHY, get} from '../constants' +import theme from '../theme' +import sx from '../sx' const ButtonTableList = styled.summary` display: inline-block; diff --git a/src/Button/index.js b/src/Button/index.js new file mode 100644 index 00000000000..58149b8657f --- /dev/null +++ b/src/Button/index.js @@ -0,0 +1,7 @@ +import Button from './Button' +export default Button +export {default as ButtonDanger} from './ButtonDanger' +export {default as ButtonGroup} from './ButtonGroup' +export {default as ButtonOutline} from './ButtonOutline' +export {default as ButtonPrimary} from './ButtonPrimary' +export {default as ButtonTableList} from './ButtonTableList' diff --git a/src/Dialog.js b/src/Dialog.js index 5f02271305d..1f266ec8770 100644 --- a/src/Dialog.js +++ b/src/Dialog.js @@ -21,7 +21,7 @@ const ReachGlobalStyle = createGlobalStyle` } ` -export const StyledDialog = styled(ReachDialog)` +const StyledDialog = styled(ReachDialog)` box-shadow: 0px 4px 32px rgba(0, 0, 0, 0.35); border-radius: 4px; padding: 0 !important; diff --git a/src/FilterList.js b/src/FilterList.js index 96a07dfc8ff..1dfb2a0a90c 100644 --- a/src/FilterList.js +++ b/src/FilterList.js @@ -1,5 +1,4 @@ import React from 'react' -import nanoid from 'nanoid' import PropTypes from 'prop-types' import styled from 'styled-components' import {COMMON, get} from './constants' @@ -8,7 +7,7 @@ import sx from './sx' function ItemBase({children, count, theme, ...rest}) { return ( - + {count && ( {count} diff --git a/src/Flash.js b/src/Flash.js index c557e9549ee..94fb1b941c2 100644 --- a/src/Flash.js +++ b/src/Flash.js @@ -5,7 +5,7 @@ import {variant} from 'styled-system' import {COMMON, get} from './constants' import theme from './theme' import sx from './sx' -import deprecate from './utils/deprecate' +import {useDeprecation} from './utils/deprecate' const schemeMap = { red: 'danger', @@ -44,14 +44,17 @@ const StyledFlash = styled.div` ` const Flash = ({variant, scheme, ...props}) => { + const deprecate = useDeprecation({ + name: 'Flash "scheme" prop', + version: '20.0.0', + message: 'Use the variant prop instead. See https://primer.style/components/Flash for more details.' + }) + if (scheme) { - deprecate({ - name: 'The scheme prop', - version: '20.0.0', - message: 'Use the variant prop instead. See https://primer.style/components/Flash for more details.' - }) + deprecate() variant = schemeMap[scheme] - } // deprecate 20.0.0 + } + return } diff --git a/src/LabelGroup.js b/src/LabelGroup.js index d443ba7b10b..db4d8de10c9 100644 --- a/src/LabelGroup.js +++ b/src/LabelGroup.js @@ -4,24 +4,18 @@ import theme from './theme' import {COMMON, get} from './constants' import sx from './sx' -const transformChildren = children => { - return React.Children.map(children, child => { - return React.cloneElement(child, {className: 'LabelItem'}) - }) -} - const StyledLabelGroup = styled.span` ${COMMON} - & .LabelItem { + & * { margin-right: ${get('space.1')}; } - & .LabelItem:last-child { + & *:last-child { margin-right: 0; } ${sx}; ` -const LabelGroup = ({children, ...rest}) => {transformChildren(children)} +const LabelGroup = ({children, ...rest}) => {children} LabelGroup.defaultProps = { theme diff --git a/src/Link.js b/src/Link.js index 0466251a5ea..d2b89bbc6b6 100644 --- a/src/Link.js +++ b/src/Link.js @@ -3,7 +3,6 @@ import styled from 'styled-components' import {system} from 'styled-system' import {COMMON, TYPOGRAPHY, get} from './constants' import theme from './theme' -import elementType from './utils/elementType' import sx from './sx' const buttonStyles = { @@ -43,7 +42,7 @@ Link.defaultProps = { } Link.propTypes = { - as: elementType, + as: PropTypes.elementType, href: PropTypes.string, muted: PropTypes.bool, theme: PropTypes.object, diff --git a/src/Popover.js b/src/Popover.js index 2fb7e6d741c..4a6f8005d3f 100644 --- a/src/Popover.js +++ b/src/Popover.js @@ -3,7 +3,6 @@ import styled from 'styled-components' import classnames from 'classnames' import {COMMON, LAYOUT, POSITION, get} from './constants' import theme from './theme' -import elementType from './utils/elementType' import BorderBox from './BorderBox' import sx from './sx' @@ -202,7 +201,7 @@ Popover.Content = styled(BorderBox)` ${sx}; ` -export const CARET_POSITIONS = [ +Popover.CARET_POSITIONS = [ 'top', 'bottom', 'left', @@ -223,8 +222,8 @@ Popover.defaultProps = { } Popover.propTypes = { - as: elementType, - caret: PropTypes.oneOf(CARET_POSITIONS), + as: PropTypes.elementType, + caret: PropTypes.oneOf(Popover.CARET_POSITIONS), open: PropTypes.bool, relative: PropTypes.bool, theme: PropTypes.object, @@ -239,7 +238,7 @@ Popover.Content.defaultProps = { } Popover.Content.propTypes = { - as: elementType, + as: PropTypes.elementType, theme: PropTypes.object, ...BorderBox.propTypes, ...sx.propTypes diff --git a/src/Position.js b/src/Position.js index 2a26c5d1714..3a6ce440b21 100644 --- a/src/Position.js +++ b/src/Position.js @@ -5,7 +5,7 @@ import {COMMON, LAYOUT, POSITION} from './constants' import theme from './theme' import sx from './sx' -export const Position = styled.div` +const Position = styled.div` ${LAYOUT} ${COMMON} ${POSITION} @@ -32,6 +32,7 @@ function withPosition(position) { return WithPosition } +export default Position export const Absolute = withPosition('Absolute') export const Fixed = withPosition('Fixed') export const Relative = withPosition('Relative') diff --git a/src/SideNav.js b/src/SideNav.js index 2715e9ca537..2959c367619 100644 --- a/src/SideNav.js +++ b/src/SideNav.js @@ -4,7 +4,6 @@ import styled, {css} from 'styled-components' import classnames from 'classnames' import {COMMON, get} from './constants' import theme from './theme' -import elementType from './utils/elementType' import Link from './Link' import BorderBox from './BorderBox' import sx from './sx' @@ -148,7 +147,7 @@ SideNav.defaultProps = { } SideNav.propTypes = { - as: elementType, + as: PropTypes.elementType, bordered: PropTypes.bool, children: PropTypes.node, theme: PropTypes.object, diff --git a/src/__tests__/Avatar.js b/src/__tests__/Avatar.js index aff7a6a1a79..f132eb0026f 100644 --- a/src/__tests__/Avatar.js +++ b/src/__tests__/Avatar.js @@ -1,7 +1,7 @@ import React from 'react' -import Avatar from '../Avatar' +import {Avatar} from '..' import theme from '../theme' -import {px, render, behavesAsComponent} from '../utils/testing' +import {px, render, behavesAsComponent, checkExports} from '../utils/testing' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' import 'babel-polyfill' @@ -11,6 +11,10 @@ expect.extend(toHaveNoViolations) describe('Avatar', () => { behavesAsComponent(Avatar, [{propTypes: systemPropTypes.space}]) + checkExports('Avatar', { + default: Avatar + }) + it('should have no axe violations', async () => { const {container} = HTMLRender() const results = await axe(container) diff --git a/src/__tests__/AvatarStack.js b/src/__tests__/AvatarStack.js index 2d5ada9ac34..da895eaacbe 100644 --- a/src/__tests__/AvatarStack.js +++ b/src/__tests__/AvatarStack.js @@ -1,6 +1,6 @@ import React from 'react' -import AvatarStack from '../AvatarStack' -import {render, behavesAsComponent} from '../utils/testing' +import {AvatarStack} from '..' +import {render, behavesAsComponent, checkExports} from '../utils/testing' import {COMMON} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' @@ -28,6 +28,10 @@ const rightAvatarComp = ( describe('Avatar', () => { behavesAsComponent(AvatarStack, [COMMON], () => avatarComp) + checkExports('AvatarStack', { + default: AvatarStack + }) + it('should have no axe violations', async () => { const {container} = HTMLRender(avatarComp) const results = await axe(container) diff --git a/src/__tests__/BorderBox.js b/src/__tests__/BorderBox.js index 0ec0a016d96..4fe8682d2ea 100644 --- a/src/__tests__/BorderBox.js +++ b/src/__tests__/BorderBox.js @@ -1,7 +1,7 @@ import React from 'react' import theme, {colors} from '../theme' -import BorderBox from '../BorderBox' -import {render, behavesAsComponent} from '../utils/testing' +import {BorderBox} from '..' +import {render, behavesAsComponent, checkExports} from '../utils/testing' import {LAYOUT, COMMON, BORDER, FLEX} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' @@ -11,6 +11,10 @@ expect.extend(toHaveNoViolations) describe('BorderBox', () => { behavesAsComponent(BorderBox, [LAYOUT, COMMON, BORDER, FLEX]) + checkExports('BorderBox', { + default: BorderBox + }) + it('should have no axe violations', async () => { const {container} = HTMLRender() const results = await axe(container) diff --git a/src/__tests__/Box.js b/src/__tests__/Box.js index 69c700b0d26..d4932450bbe 100644 --- a/src/__tests__/Box.js +++ b/src/__tests__/Box.js @@ -1,7 +1,7 @@ import React from 'react' -import Box from '../Box' +import {Box} from '..' import theme from '../theme' -import {render, behavesAsComponent} from '../utils/testing' +import {render, behavesAsComponent, checkExports} from '../utils/testing' import {LAYOUT, COMMON, FLEX} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' @@ -11,6 +11,10 @@ expect.extend(toHaveNoViolations) describe('Box', () => { behavesAsComponent(Box, [COMMON, LAYOUT, FLEX]) + checkExports('Box', { + default: Box + }) + it('should have no axe violations', async () => { const {container} = HTMLRender() const results = await axe(container) diff --git a/src/__tests__/BranchName.js b/src/__tests__/BranchName.js index 7d848227d8c..441d579d88c 100644 --- a/src/__tests__/BranchName.js +++ b/src/__tests__/BranchName.js @@ -1,6 +1,6 @@ import React from 'react' -import BranchName from '../BranchName' -import {render, behavesAsComponent} from '../utils/testing' +import {BranchName} from '..' +import {render, behavesAsComponent, checkExports} from '../utils/testing' import {COMMON} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' @@ -10,6 +10,10 @@ expect.extend(toHaveNoViolations) describe('BranchName', () => { behavesAsComponent(BranchName, [COMMON]) + checkExports('BranchName', { + default: BranchName + }) + it('should have no axe violations', async () => { const {container} = HTMLRender() const results = await axe(container) diff --git a/src/__tests__/Breadcrumbs.js b/src/__tests__/Breadcrumb.js similarity index 84% rename from src/__tests__/Breadcrumbs.js rename to src/__tests__/Breadcrumb.js index 848fe1871b7..13f2ea8e9db 100644 --- a/src/__tests__/Breadcrumbs.js +++ b/src/__tests__/Breadcrumb.js @@ -1,6 +1,6 @@ import React from 'react' -import Breadcrumb from '../Breadcrumbs' -import {mount, render, rendersClass, behavesAsComponent} from '../utils/testing' +import {Breadcrumb} from '..' +import {mount, render, rendersClass, behavesAsComponent, checkExports} from '../utils/testing' import {COMMON} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' @@ -10,6 +10,10 @@ expect.extend(toHaveNoViolations) describe('Breadcrumb', () => { behavesAsComponent(Breadcrumb, [COMMON]) + checkExports('Breadcrumb', { + default: Breadcrumb + }) + it('should have no axe violations', async () => { const {container} = HTMLRender() const results = await axe(container) diff --git a/src/__tests__/BreadcrumbItem.js b/src/__tests__/BreadcrumbItem.js index 19f58d575c4..76bbfa62221 100644 --- a/src/__tests__/BreadcrumbItem.js +++ b/src/__tests__/BreadcrumbItem.js @@ -1,5 +1,5 @@ import React from 'react' -import Breadcrumb from '../Breadcrumbs' +import {Breadcrumb} from '..' import {render, behavesAsComponent} from '../utils/testing' import {COMMON} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' diff --git a/src/__tests__/Button.js b/src/__tests__/Button.js index d517ba65351..1ab0bffdcf9 100644 --- a/src/__tests__/Button.js +++ b/src/__tests__/Button.js @@ -1,6 +1,6 @@ import React from 'react' import {Button, ButtonPrimary, ButtonDanger, ButtonOutline, ButtonGroup, ButtonTableList} from '..' -import {render, behavesAsComponent} from '../utils/testing' +import {render, behavesAsComponent, checkExports} from '../utils/testing' import {COMMON, FLEX, LAYOUT, TYPOGRAPHY} from '../constants' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' @@ -12,6 +12,15 @@ function noop() {} describe('Button', () => { behavesAsComponent(Button, [COMMON, LAYOUT]) + checkExports('Button', { + default: Button, + ButtonPrimary, + ButtonDanger, + ButtonOutline, + ButtonGroup, + ButtonTableList + }) + it('renders a