diff --git a/changelogs/react-button-refactor.txt b/changelogs/react-button-refactor.txt
new file mode 100644
index 0000000000..559c09a90a
--- /dev/null
+++ b/changelogs/react-button-refactor.txt
@@ -0,0 +1,4 @@
+___DESCRIPTION___
+change
+minor
+- (React) Refactored ButtonWithIcon to replace ButtonSearch component #81
diff --git a/react/src/components/atoms/buttons/ButtonSearch/ButtonSearch.md b/react/src/components/atoms/buttons/ButtonSearch/ButtonSearch.md
deleted file mode 100644
index 650e74ff26..0000000000
--- a/react/src/components/atoms/buttons/ButtonSearch/ButtonSearch.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### Description
-A button used for a keyword search.
-
-### Changes for React
-* `classes` array: To improve reusability of this component, classes can now be added to the button by adding them to the new `classes` array.
-* `ariaLabel` string: To improve accessablitily of this component, an aria-label can be added if the displayed text is not helpful to assistive technologies.
-
-### Variables
-~~~
-onClick:
- type: function / optional
-text:
- type: string / optional
-ariaLabel:
- type: string / optional
-classes:
- type: array (string) / optional
-~~~
diff --git a/react/src/components/atoms/buttons/ButtonSearch/ButtonSearch.stories.js b/react/src/components/atoms/buttons/ButtonSearch/ButtonSearch.stories.js
deleted file mode 100644
index 60cc725769..0000000000
--- a/react/src/components/atoms/buttons/ButtonSearch/ButtonSearch.stories.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from 'react';
-
-import { storiesOf } from '@storybook/react';
-import { withInfo } from '@storybook/addon-info';
-import { text, withKnobs } from '@storybook/addon-knobs/react';
-import { action } from '@storybook/addon-actions';
-
-import ButtonSearch from '.';
-import ButtonSearchReadme from './ButtonSearch.md';
-
-storiesOf('atoms/buttons', module)
- .addDecorator(withKnobs)
- .add(
- 'ButtonSearch',
- withInfo(`
${ButtonSearchReadme}
`)(() => {
- const props = {
- text: text('ButtonSearch.text', 'Search'),
- ariaLabel: text('ButtonSearch.ariaLabel', 'Search'),
- onClick: action('ButtonSearch.onClick')
- };
-
- return();
- })
- );
diff --git a/react/src/components/atoms/buttons/ButtonSearch/index.js b/react/src/components/atoms/buttons/ButtonSearch/index.js
deleted file mode 100644
index 899a81d2c7..0000000000
--- a/react/src/components/atoms/buttons/ButtonSearch/index.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import SvgSearch from '../../icons/SvgSearch';
-
-const ButtonSearch = (buttonSearch) => {
- const onButtonClick = Object.prototype.hasOwnProperty.call(buttonSearch, 'onClick');
- return((
-
- ));
-};
-
-ButtonSearch.propTypes = {
- /** Custom click handler function. */
- onClick: PropTypes.func,
- /** The text to display in the button */
- text: PropTypes.string,
- /** The aria-label property is used to provide the label to any assistive
- * technologies. This is useful if the text value is not descriptive of the
- * button's functionality. */
- ariaLabel: PropTypes.string.isRequired,
- /** Optional classes to apply to the button in place of the default */
- classes: PropTypes.arrayOf(PropTypes.string)
-};
-
-ButtonSearch.defaultProps = {
- text: 'Search',
- classes: ['ma__button-search']
-};
-
-export default ButtonSearch;
diff --git a/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.knob.options.js b/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.knob.options.js
index c375504caf..c6711fa337 100644
--- a/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.knob.options.js
+++ b/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.knob.options.js
@@ -6,5 +6,10 @@ export default {
color: {
'': 'grey (default)',
green: 'green'
+ },
+ type: {
+ button: 'button',
+ submit: 'submit',
+ reset: 'reset'
}
};
diff --git a/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.md b/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.md
index c06169dafe..a32983cf1d 100644
--- a/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.md
+++ b/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.md
@@ -1,2 +1,9 @@
### Description
A button that displays with an icon component.
+e.g. ButtonSearch, which is used for submitting a keyword search.
+e.g. Button with chevron, which is used for toggling between the expanded state and the collapsed state.
+
+### Changes for React
+* Button with Icon is a common button pattern that is currently not available in Patternlab. It's an extension on top of the [Button Search atom](https://mayflower.digital.mass.gov/?p=atoms-button-search).
+* `classes` array: To improve reusability of this component, classes can now be added to the button by adding them to the new `classes` array.
+* `ariaLabel` string: To improve accessibility of this component, an aria-label can be added if the displayed text is not helpful to assistive technologies.
diff --git a/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.stories.js b/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.stories.js
index 3fd00b63f3..6902eb448f 100644
--- a/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.stories.js
+++ b/react/src/components/atoms/buttons/ButtonWithIcon/ButtonWithIcon.stories.js
@@ -25,9 +25,10 @@ storiesOf('atoms/buttons', module)
const props = {
onClick: action('ButtonWithIcon clicked'),
text: text('ButtonWithIcon.text', 'Button With Icon'),
+ type: select('ButtonWithIcon.type', buttonWithIconOptions.type, 'submit'),
classes: array('ButtonWithIcon.classes', []),
icon: select('ButtonWithIcon.icon', Object.keys(icons), 'chevron'),
- iconSize: select('ButtonWithIcon.iconSize', buttonWithIconOptions.size),
+ iconSize: select('ButtonWithIcon.iconSize', buttonWithIconOptions.size, ''),
iconColor: select('ButtonWithIcon.iconColor', buttonWithIconOptions.color),
canExpand: boolean('ButtonWithIcon.canExpand', true),
expanded: boolean('ButtonWithIcon.expanded', true),
@@ -37,6 +38,21 @@ storiesOf('atoms/buttons', module)
// Set the icon prop to the actual element based on knob selection.
props.icon = icons[props.icon];
+ return(
+
+ );
+ })
+ )
+ .add(
+ 'ButtonSearch',
+ withInfo(`
${buttonWithIconReadme}
`)(() => {
+ const props = {
+ onClick: action('ButtonWithIcon clicked')
+ };
+
+ // Set the icon prop to the actual element based on knob selection.
+ props.icon = icons[props.icon];
+
return(
);
diff --git a/react/src/components/atoms/buttons/ButtonWithIcon/index.js b/react/src/components/atoms/buttons/ButtonWithIcon/index.js
index c885dea3ff..d70ff4849a 100644
--- a/react/src/components/atoms/buttons/ButtonWithIcon/index.js
+++ b/react/src/components/atoms/buttons/ButtonWithIcon/index.js
@@ -21,28 +21,36 @@ class ButtonWithIcon extends React.Component {
}
}
render() {
- let classNames = this.props.classes.join(' ');
- if (this.props.canExpand) {
+ const {
+ classes, canExpand, expanded, capitalized, iconSize, iconColor, icon, type
+ } = this.props;
+ let classNames = classes.join(' ');
+ if (canExpand) {
classNames += ' ma__button-icon--expandable';
- classNames += this.props.expanded ? ' ma__button-icon--expanded' : '';
+ if (expanded) {
+ classNames += ' ma__button-icon--expanded';
+ }
}
- if (this.props.capitalized) {
+ if (capitalized) {
classNames += ' ma__button-capitalized';
}
- if (this.props.iconSize === 'small') {
+ if (iconSize === 'small' || icon.type.name === 'SvgChevron') {
classNames += ' ma__icon-small';
}
- if (this.props.iconColor === 'green') {
+ if (iconColor === 'green') {
classNames += ' ma__icon-green';
}
+ if (icon.type.name === 'SvgSearch') {
+ classNames += ' ma__button-search';
+ }
const buttonProps = {
- type: 'submit',
+ type,
className: `ma__button-icon ${classNames}`,
onClick: this.handleClick,
tabIndex: 0
};
return(
-