From 9896cdbedf473cef78fa548a2fb0d8ccf3e0d843 Mon Sep 17 00:00:00 2001 From: Avi Sharvit Date: Sun, 17 Dec 2017 13:49:05 +0200 Subject: [PATCH] feat(DropdownButton): DropdownButton and SplitButton components Export DropdownButton and SplitButton from react-bootstrap re #11 --- package-lock.json | 34 +- src/components/Button/Button.js | 5 +- src/components/Button/Button.stories.js | 48 +- src/components/Button/ButtonGroup.js | 3 +- src/components/Button/DropdownButton.js | 15 + src/components/Button/DropdownButton.test.js | 26 ++ src/components/Button/SplitButton.js | 15 + src/components/Button/SplitButton.test.js | 26 ++ .../__snapshots__/DropdownButton.test.js.snap | 385 ++++++++++++++++ .../__snapshots__/SplitButton.test.js.snap | 413 ++++++++++++++++++ src/components/Button/index.js | 2 + src/components/Modal/Modal.js | 5 +- 12 files changed, 952 insertions(+), 25 deletions(-) create mode 100644 src/components/Button/DropdownButton.js create mode 100644 src/components/Button/DropdownButton.test.js create mode 100644 src/components/Button/SplitButton.js create mode 100644 src/components/Button/SplitButton.test.js create mode 100644 src/components/Button/__snapshots__/DropdownButton.test.js.snap create mode 100644 src/components/Button/__snapshots__/SplitButton.test.js.snap diff --git a/package-lock.json b/package-lock.json index 353cb9e8e64..7fc6aa8e547 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5739,14 +5739,6 @@ } } }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, "string-width": { "version": "1.0.2", "bundled": true, @@ -5757,6 +5749,14 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.0.1" + } + }, "stringstream": { "version": "0.0.5", "bundled": true, @@ -13502,15 +13502,6 @@ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", "dev": true }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -13575,6 +13566,15 @@ "function-bind": "1.1.1" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", diff --git a/src/components/Button/Button.js b/src/components/Button/Button.js index c27a637af35..83b7103e6cf 100644 --- a/src/components/Button/Button.js +++ b/src/components/Button/Button.js @@ -5,9 +5,10 @@ import { BUTTON_BS_STYLES } from './constants'; const Button = props => ; -Button.propTypes = Object.assign(BsButton.propTypes, { +Button.propTypes = { + ...BsButton.propTypes, bsStyle: PropTypes.oneOf(BUTTON_BS_STYLES), -}); +}; Button.BUTTON_BS_STYLES = BUTTON_BS_STYLES; diff --git a/src/components/Button/Button.stories.js b/src/components/Button/Button.stories.js index 3efa01be63b..93930a0f098 100644 --- a/src/components/Button/Button.stories.js +++ b/src/components/Button/Button.stories.js @@ -1,8 +1,11 @@ import React from 'react'; import { storiesOf } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import { withKnobs, select } from '@storybook/addon-knobs'; import { defaultTemplate } from '../../../storybook/decorators/storyTemplates'; -import { Button, ButtonGroup } from './index'; -import { Grid, Row, Col } from '../../index'; +import { Grid, Row, Col, MenuItem } from '../../index'; +import { Button, ButtonGroup, DropdownButton, SplitButton } from './index'; +import { BUTTON_BS_STYLES } from './constants'; const stories = storiesOf('Button', module); @@ -16,6 +19,7 @@ const description = (

); +stories.addDecorator(withKnobs); stories.addDecorator( defaultTemplate({ title: 'Button', @@ -138,3 +142,43 @@ stories.addWithInfo('ButtonGroup', () => { ); }); + +stories.addWithInfo('DropdownButton', '', () => { + const bsStyle = select('Style', BUTTON_BS_STYLES, 'default'); + const bsSize = select('Size', [undefined, 'xsmall', 'small', 'large']); + + const props = { bsStyle, title: bsStyle, id: 'dropdown-example' }; + if (bsSize) props.bsSize = bsSize; + + return ( + + Action + Another action + + Active Item + + + Separated link + + ); +}); + +stories.addWithInfo('SplitButton', '', () => { + const bsStyle = select('Style', BUTTON_BS_STYLES, 'default'); + const bsSize = select('Size', [undefined, 'xsmall', 'small', 'large']); + + const props = { bsStyle, title: bsStyle, id: 'dropdown-example' }; + if (bsSize) props.bsSize = bsSize; + + return ( + + Action + Another action + + Active Item + + + Separated link + + ); +}); diff --git a/src/components/Button/ButtonGroup.js b/src/components/Button/ButtonGroup.js index 2c273a7a4ee..30fefbe96dc 100644 --- a/src/components/Button/ButtonGroup.js +++ b/src/components/Button/ButtonGroup.js @@ -1,2 +1 @@ -import { ButtonGroup } from 'react-bootstrap'; -export default ButtonGroup; +export { ButtonGroup as default } from 'react-bootstrap'; diff --git a/src/components/Button/DropdownButton.js b/src/components/Button/DropdownButton.js new file mode 100644 index 00000000000..4bda1189043 --- /dev/null +++ b/src/components/Button/DropdownButton.js @@ -0,0 +1,15 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { DropdownButton as BsDropdownButton } from 'react-bootstrap'; +import { BUTTON_BS_STYLES } from './constants'; + +const DropdownButton = props => ; + +DropdownButton.propTypes = { + ...BsDropdownButton.propTypes, + bsStyle: PropTypes.oneOf(BUTTON_BS_STYLES), +}; + +DropdownButton.BUTTON_BS_STYLES = BUTTON_BS_STYLES; + +export default DropdownButton; diff --git a/src/components/Button/DropdownButton.test.js b/src/components/Button/DropdownButton.test.js new file mode 100644 index 00000000000..5553f27a183 --- /dev/null +++ b/src/components/Button/DropdownButton.test.js @@ -0,0 +1,26 @@ +/* eslint-env jest */ + +import React from 'react'; +import renderer from 'react-test-renderer'; + +import DropdownButton from './DropdownButton'; +import { MenuItem } from '../MenuItem'; + +test('DropdownButton should renders properly', () => { + DropdownButton.BUTTON_BS_STYLES.forEach(bsStyle => { + const component = renderer.create( + + Action + Another action + + Active Item + + + Separated link + , + ); + + const tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/src/components/Button/SplitButton.js b/src/components/Button/SplitButton.js new file mode 100644 index 00000000000..dc36d38da5b --- /dev/null +++ b/src/components/Button/SplitButton.js @@ -0,0 +1,15 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { SplitButton as BsSplitButton } from 'react-bootstrap'; +import { BUTTON_BS_STYLES } from './constants'; + +const SplitButton = props => ; + +SplitButton.propTypes = { + ...BsSplitButton.propTypes, + bsStyle: PropTypes.oneOf(BUTTON_BS_STYLES), +}; + +SplitButton.BUTTON_BS_STYLES = BUTTON_BS_STYLES; + +export default SplitButton; diff --git a/src/components/Button/SplitButton.test.js b/src/components/Button/SplitButton.test.js new file mode 100644 index 00000000000..bc17889810e --- /dev/null +++ b/src/components/Button/SplitButton.test.js @@ -0,0 +1,26 @@ +/* eslint-env jest */ + +import React from 'react'; +import renderer from 'react-test-renderer'; + +import SplitButton from './SplitButton'; +import { MenuItem } from '../MenuItem'; + +test('SplitButton should renders properly', () => { + SplitButton.BUTTON_BS_STYLES.forEach(bsStyle => { + const component = renderer.create( + + Action + Another action + + Active Item + + + Separated link + , + ); + + const tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + }); +}); diff --git a/src/components/Button/__snapshots__/DropdownButton.test.js.snap b/src/components/Button/__snapshots__/DropdownButton.test.js.snap new file mode 100644 index 00000000000..d1c863add52 --- /dev/null +++ b/src/components/Button/__snapshots__/DropdownButton.test.js.snap @@ -0,0 +1,385 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DropdownButton should renders properly 1`] = ` +
+ + +
+`; + +exports[`DropdownButton should renders properly 2`] = ` +
+ + +
+`; + +exports[`DropdownButton should renders properly 3`] = ` +
+ + +
+`; + +exports[`DropdownButton should renders properly 4`] = ` +
+ + +
+`; diff --git a/src/components/Button/__snapshots__/SplitButton.test.js.snap b/src/components/Button/__snapshots__/SplitButton.test.js.snap new file mode 100644 index 00000000000..19aa6ade452 --- /dev/null +++ b/src/components/Button/__snapshots__/SplitButton.test.js.snap @@ -0,0 +1,413 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SplitButton should renders properly 1`] = ` +
+ + + +
+`; + +exports[`SplitButton should renders properly 2`] = ` +
+ + + +
+`; + +exports[`SplitButton should renders properly 3`] = ` +
+ + + +
+`; + +exports[`SplitButton should renders properly 4`] = ` +
+ + + +
+`; diff --git a/src/components/Button/index.js b/src/components/Button/index.js index bbd8448bb21..cca70d25597 100644 --- a/src/components/Button/index.js +++ b/src/components/Button/index.js @@ -1,2 +1,4 @@ export { default as Button } from './Button'; export { default as ButtonGroup } from './ButtonGroup'; +export { default as DropdownButton } from './DropdownButton'; +export { default as SplitButton } from './SplitButton'; diff --git a/src/components/Modal/Modal.js b/src/components/Modal/Modal.js index 6a560019f7c..d3d00aca97c 100644 --- a/src/components/Modal/Modal.js +++ b/src/components/Modal/Modal.js @@ -10,8 +10,9 @@ class Modal extends BsModal { } } -Modal.defaultProps = Object.assign(BsModal.defaultProps, { +Modal.defaultProps = { + ...BsModal.defaultProps, dialogComponentClass: CustomModalDialog, -}); +}; export default Modal;