diff --git a/package.json b/package.json index 623787c746..11a533dffd 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ }, "resolutions": { "**/**/handlebars": "^4.5.3", - "**/**/mem": "^4.0.0" + "**/**/mem": "^4.0.0", + "**/**/terser-webpack-plugin": "^1.4.2" }, "prettier": { "bracketSpacing": true, diff --git a/packages/docs-site/package.json b/packages/docs-site/package.json index 086f9b890a..ac5ab6f4a2 100644 --- a/packages/docs-site/package.json +++ b/packages/docs-site/package.json @@ -43,20 +43,21 @@ "@royalnavy/icon-library": "^1.8.0", "@royalnavy/react-component-library": "^1.8.0", "change-case": "^3.1.0", - "formik": "^2.0.6", - "gatsby": "^2.18.5", + "eslint-plugin-import": "2.18.2", + "formik": "^2.0.7", + "gatsby": "^2.18.8", "gatsby-image": "^2.2.34", "gatsby-plugin-catch-links": "^2.1.19", - "gatsby-plugin-manifest": "^2.2.30", - "gatsby-plugin-mdx": "^1.0.58", - "gatsby-plugin-offline": "^3.0.25", + "gatsby-plugin-manifest": "^2.2.31", + "gatsby-plugin-mdx": "^1.0.59", + "gatsby-plugin-offline": "^3.0.27", "gatsby-plugin-react-helmet": "^3.1.16", "gatsby-plugin-sass": "^2.1.24", "gatsby-plugin-sass-resources": "^2.0.0", - "gatsby-plugin-sharp": "^2.3.4", + "gatsby-plugin-sharp": "^2.3.5", "gatsby-plugin-styled-components": "^3.1.14", - "gatsby-source-filesystem": "^2.1.39", - "gatsby-transformer-sharp": "^2.3.6", + "gatsby-source-filesystem": "^2.1.40", + "gatsby-transformer-sharp": "^2.3.7", "lodash": "^4.17.15", "mixin-deep": "^2.0.1", "normalize-scss": "^7.0.1", @@ -70,7 +71,7 @@ "uuid": "^3.3.3" }, "devDependencies": { - "@babel/core": "^7.7.4", + "@babel/core": "^7.7.5", "@royalnavy/eslint-config-react": "^1.8.0", "@svgr/cli": "^4.3.3", "@testing-library/jest-dom": "^4.2.4", @@ -79,16 +80,16 @@ "babel-jest": "^24.9.0", "babel-plugin-styled-components": "^1.10.6", "babel-preset-gatsby": "^0.2.23", - "eslint": "^6.7.1", + "eslint": "^6.7.2", "eslint-config-airbnb": "^18.0.1", "eslint-config-prettier": "^6.7.0", "eslint-junit": "^1.0.1", "eslint-plugin-import": "^2.18.2", - "eslint-plugin-jest": "^23.0.5", + "eslint-plugin-jest": "^23.1.1", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-react": "^7.17.0", - "firebase-tools": "^7.8.1", + "firebase-tools": "^7.9.0", "formik": "^2.0.3", "identity-obj-proxy": "^3.0.0", "jest": "^24.9.0", diff --git a/packages/docs-site/src/library/pages/components/button.md b/packages/docs-site/src/library/pages/components/button.md index bce79d540a..97f02a7697 100644 --- a/packages/docs-site/src/library/pages/components/button.md +++ b/packages/docs-site/src/library/pages/components/button.md @@ -208,7 +208,7 @@ source={` { Name: 'onClick', Type: '(event: React.SyntheticEvent):void', - Required: 'True', + Required: 'False', Default: '', Description: 'Function to call when a user clicks on a button', }, diff --git a/packages/eslint-config-react/package.json b/packages/eslint-config-react/package.json index e28490ad38..d44ef0bbce 100644 --- a/packages/eslint-config-react/package.json +++ b/packages/eslint-config-react/package.json @@ -8,7 +8,7 @@ "node": ">=10.13.0 <13" }, "devDependencies": { - "eslint": "^6.7.1", + "eslint": "^6.7.2", "eslint-config-airbnb": "^18.0.1", "eslint-config-prettier": "^6.7.0", "eslint-plugin-import": "^2.18.2", diff --git a/packages/icon-library/package.json b/packages/icon-library/package.json index 052ad15aa4..5e09ee9998 100644 --- a/packages/icon-library/package.json +++ b/packages/icon-library/package.json @@ -26,9 +26,9 @@ "react": "^16.12.0" }, "devDependencies": { - "@babel/cli": "^7.7.4", - "@babel/core": "^7.7.4", - "@babel/preset-env": "^7.7.4", + "@babel/cli": "^7.7.5", + "@babel/core": "^7.7.5", + "@babel/preset-env": "^7.7.6", "@babel/preset-react": "^7.7.4", "@babel/preset-typescript": "^7.7.4", "@svgr/cli": "^4.3.3", @@ -36,7 +36,7 @@ "clean-webpack-plugin": "^3.0.0", "npm-run-all": "^4.1.5", "source-map-loader": "^0.2.4", - "typescript": "^3.7.2", + "typescript": "^3.7.3", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-merge": "^4.2.2" diff --git a/packages/react-component-library/package.json b/packages/react-component-library/package.json index 11a9fb89b1..89528573fa 100755 --- a/packages/react-component-library/package.json +++ b/packages/react-component-library/package.json @@ -40,55 +40,55 @@ "*.@(js|jsx|ts|tsx)": "eslint" }, "devDependencies": { - "@babel/cli": "^7.7.4", - "@babel/core": "^7.7.4", + "@babel/cli": "^7.7.5", + "@babel/core": "^7.7.5", "@babel/plugin-proposal-class-properties": "^7.7.4", "@babel/plugin-proposal-object-rest-spread": "^7.7.4", - "@babel/plugin-transform-modules-commonjs": "^7.7.4", - "@babel/preset-env": "^7.7.4", + "@babel/plugin-transform-modules-commonjs": "^7.7.5", + "@babel/preset-env": "^7.7.6", "@babel/preset-react": "^7.7.4", "@babel/preset-typescript": "^7.7.4", "@royalnavy/storybook-react-input-state": "^1.8.0", - "@storybook/addon-actions": "^5.2.6", - "@storybook/addon-knobs": "^5.2.6", - "@storybook/addon-links": "^5.2.6", - "@storybook/addons": "^5.2.6", - "@storybook/react": "^5.2.6", + "@storybook/addon-actions": "^5.2.8", + "@storybook/addon-knobs": "^5.2.8", + "@storybook/addon-links": "^5.2.8", + "@storybook/addons": "^5.2.8", + "@storybook/react": "^5.2.8", "@svgr/webpack": "^4.3.3", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@types/classnames": "^2.2.9", - "@types/enzyme": "^3.10.3", + "@types/enzyme": "^3.10.4", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/jest": "^24.0.23", "@types/jsdom": "^12.2.4", "@types/lodash": "^4.14.149", - "@types/node": "^12.12.14", - "@types/react": "^16.9.13", + "@types/node": "^12.12.16", + "@types/react": "^16.9.16", "@types/react-addons-css-transition-group": "^15.0.5", "@types/react-dom": "^16.9.4", "@types/react-select": "^3.0.8", "@types/storybook__react": "^4.0.2", "@types/uuid": "^3.4.6", "@types/yup": "^0.26.26", - "@typescript-eslint/eslint-plugin": "^2.9.0", + "@typescript-eslint/eslint-plugin": "^2.11.0", "babel-loader": "^8.0.6", "babel-polyfill": "^6.26.0", "clean-webpack-plugin": "^3.0.0", - "concurrently": "^5.0.0", - "css-loader": "^3.2.0", - "eslint": "^6.7.1", + "concurrently": "^5.0.1", + "css-loader": "^3.3.0", + "eslint": "^6.7.2", "eslint-config-airbnb": "^18.0.1", "eslint-config-prettier": "^6.7.0", "eslint-junit": "^1.0.1", "eslint-plugin-import": "^2.18.2", - "eslint-plugin-jest": "^23.0.5", + "eslint-plugin-jest": "^23.1.1", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-react": "^7.17.0", "express": "^4.17.1", "file-loader": "^4.3.0", - "formik": "^2.0.6", + "formik": "^2.0.7", "html-webpack-plugin": "^3.2.0", "image-webpack-loader": "^6.0.0", "jest": "^24.9.0", @@ -104,7 +104,7 @@ "sass-loader": "^8.0.0", "source-map-loader": "^0.2.4", "style-loader": "^1.0.1", - "typescript": "^3.7.2", + "typescript": "^3.7.3", "webpack": "^4.41.2", "webpack-bundle-analyzer": "^3.6.0", "webpack-cli": "^3.3.10", @@ -128,12 +128,13 @@ "@types/react-responsive": "^8.0.2", "classnames": "^2.2.6", "date-fns": "^2.8.1", + "eslint-plugin-import": "2.18.2", "react-addons-css-transition-group": "^15.6.2", "react-children-utilities": "^1.3.3", "react-compound-slider": "^2.4.0", "react-indiana-drag-scroll": "^1.5.2", "react-responsive": "^8.0.1", "react-select": "^3.0.8", - "react-tether": "^2.0.5" + "react-tether": "^2.0.6" } } diff --git a/packages/react-component-library/src/components/Button/Button.test.tsx b/packages/react-component-library/src/components/Button/Button.test.tsx index f6bea53fe2..1e9fd93c7c 100644 --- a/packages/react-component-library/src/components/Button/Button.test.tsx +++ b/packages/react-component-library/src/components/Button/Button.test.tsx @@ -49,6 +49,27 @@ describe('Button', () => { }) }) + describe('when the onClick callback has not been specified', () => { + beforeEach(() => { + wrapper = render() + button = wrapper.getByText('Click me').parentElement + }) + + describe('when the button is clicked', () => { + beforeEach(() => { + fireEvent.click(button, { + target: { + blur: blurSpy, + }, + }) + }) + + it('should blur the button so it does not remain active', () => { + expect(blurSpy).toHaveBeenCalledTimes(1) + }) + }) + }) + describe('when the size is specified', () => { it.each` size | expected diff --git a/packages/react-component-library/src/components/Button/Button.tsx b/packages/react-component-library/src/components/Button/Button.tsx index 5237209471..899d3e7758 100644 --- a/packages/react-component-library/src/components/Button/Button.tsx +++ b/packages/react-component-library/src/components/Button/Button.tsx @@ -18,7 +18,7 @@ export const Button: React.FC = ({ color, disabled, icon, - onClick = () => {}, + onClick, size = 'regular', type = 'button', variant, @@ -39,7 +39,10 @@ export const Button: React.FC = ({ type={type} onClick={e => { e.currentTarget.blur() - onClick(e) + + if (onClick) { + onClick(e) + } }} {...rest} > diff --git a/packages/react-component-library/src/components/NumberInput/NumberInput.test.tsx b/packages/react-component-library/src/components/NumberInput/NumberInput.test.tsx index ceec2e5bcc..4e812662a7 100644 --- a/packages/react-component-library/src/components/NumberInput/NumberInput.test.tsx +++ b/packages/react-component-library/src/components/NumberInput/NumberInput.test.tsx @@ -12,7 +12,6 @@ describe('NumberInput', () => { props = { name: 'balloons', onChange: jest.fn(), - onBlur: jest.fn(), } wrapper = undefined @@ -485,4 +484,26 @@ describe('NumberInput', () => { }) }) }) + + describe('when the onBlur callback has been specified', () => { + let onBlurSpy: jest.SpyInstance + + beforeEach(() => { + props.onBlur = () => { return true } + onBlurSpy = jest.spyOn(props, 'onBlur') + + wrapper = render() + }) + + describe('when the number input loses focus', () => { + beforeEach(() => { + wrapper.getByTestId('number-input-input').focus() + wrapper.getByTestId('number-input-increase').focus() + }) + + it('should call the onBlur callback once', () => { + expect(onBlurSpy).toHaveBeenCalledTimes(1) + }) + }) + }) }) diff --git a/packages/react-component-library/src/components/NumberInput/NumberInput.tsx b/packages/react-component-library/src/components/NumberInput/NumberInput.tsx index 4d00bf68c7..71e4dfb680 100644 --- a/packages/react-component-library/src/components/NumberInput/NumberInput.tsx +++ b/packages/react-component-library/src/components/NumberInput/NumberInput.tsx @@ -54,7 +54,7 @@ export const NumberInput: React.FC = ({ max, min, name, - onBlur = () => {}, + onBlur, onChange, placeholder = '', step = 1, @@ -116,7 +116,10 @@ export const NumberInput: React.FC = ({ const onLocalBlur = (event: React.FormEvent) => { setFocus(false) - onBlur(event) + + if (onBlur) { + onBlur(event) + } } const EndAdornment = ( diff --git a/packages/react-component-library/src/components/TabSet/TabSet.test.tsx b/packages/react-component-library/src/components/TabSet/TabSet.test.tsx index d4c6e0f275..d57ebc03c7 100644 --- a/packages/react-component-library/src/components/TabSet/TabSet.test.tsx +++ b/packages/react-component-library/src/components/TabSet/TabSet.test.tsx @@ -18,7 +18,9 @@ describe('TabSet', () => { beforeEach(() => { const props = { className: 'rn-tab-set--modifier', - onChangeCallback: () => {}, + onChangeCallback: () => { + return true + }, } onChangeSpy = jest.spyOn(props, 'onChangeCallback') @@ -130,7 +132,9 @@ describe('TabSet', () => { ) const tabs = wrapper.getByTestId('tabs') - tabs.scrollTo = () => {} + tabs.scrollTo = () => { + return true + } scrollToSpy = jest .spyOn(tabs, 'scrollTo') diff --git a/packages/react-component-library/src/components/TextArea/TextArea.test.tsx b/packages/react-component-library/src/components/TextArea/TextArea.test.tsx index 91daf13e49..b14d3dc038 100644 --- a/packages/react-component-library/src/components/TextArea/TextArea.test.tsx +++ b/packages/react-component-library/src/components/TextArea/TextArea.test.tsx @@ -17,8 +17,8 @@ describe('TextArea', () => { field = { name: 'colour', value: '', - onChange: jest.fn(), - onBlur: jest.fn(), + onBlur: null, + onChange: jest.fn() } form = { @@ -187,4 +187,33 @@ describe('TextArea', () => { ) }) }) + + describe('when the onBlur callback is provided', () => { + let onBlurSpy: jest.SpyInstance + + beforeEach(() => { + field.onBlur = () => { + return true + } + onBlurSpy = jest.spyOn(field, 'onBlur') + + textInput = render( +
+