diff --git a/spec/pivotal-ui-react/alerts/alerts_spec.js b/spec/pivotal-ui-react/alerts/alerts_spec.js
index 1547762b9..23ebff748 100644
--- a/spec/pivotal-ui-react/alerts/alerts_spec.js
+++ b/spec/pivotal-ui-react/alerts/alerts_spec.js
@@ -38,8 +38,8 @@ describe('Alert Component', () => {
it('has a close button', () => {
expect('.pui-alert button').toHaveLength(1);
- expect('.pui-btn-default-flat.pui-btn-icon').toHaveClass('pui-alert-close-btn');
- expect('.pui-btn-default-flat.pui-btn-icon .icon-close').toExist();
+ expect('.pui-btn--default.pui-btn--flat.pui-btn--icon').toHaveClass('pui-alert-close-btn');
+ expect('.pui-btn--default.pui-btn--flat.pui-btn--icon .icon-close').toExist();
});
it('has an sr-only close button', () => {
diff --git a/spec/pivotal-ui-react/buttons/buttons_spec.js b/spec/pivotal-ui-react/buttons/buttons_spec.js
index aef201888..d20c58fb9 100644
--- a/spec/pivotal-ui-react/buttons/buttons_spec.js
+++ b/spec/pivotal-ui-react/buttons/buttons_spec.js
@@ -11,8 +11,8 @@ describe('UIButton', () => {
it('creates a button', () => {
expect('button').toHaveClass('pui-btn');
- expect('button').toHaveClass('pui-btn-default');
- expect('button').toHaveText('Click here');
+ expect('button').toHaveClass('pui-btn--default');
+ expect('button .pui-btn__inner-content').toHaveText('Click here');
});
describe('when href attribute is set', () => {
@@ -135,7 +135,7 @@ describe('UIButton', () => {
});
it('adds the kind class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-default');
+ expect('button.pui-btn').toHaveClass('pui-btn--default');
});
});
@@ -145,7 +145,7 @@ describe('UIButton', () => {
});
it('adds the kind class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-danger');
+ expect('button.pui-btn').toHaveClass('pui-btn--danger');
});
});
@@ -155,7 +155,7 @@ describe('UIButton', () => {
});
it('adds the kind class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-brand');
+ expect('button.pui-btn').toHaveClass('pui-btn--brand');
});
});
@@ -165,7 +165,7 @@ describe('UIButton', () => {
});
it('adds the kind class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-primary');
+ expect('button.pui-btn').toHaveClass('pui-btn--primary');
});
});
@@ -175,7 +175,7 @@ describe('UIButton', () => {
});
it('adds the large button class', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-lg');
+ expect('button.pui-btn').toHaveClass('pui-btn--lg');
});
});
@@ -185,7 +185,7 @@ describe('UIButton', () => {
});
it('adds the large button class', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-full');
+ expect('button.pui-btn').toHaveClass('pui-btn--full');
});
});
@@ -195,7 +195,7 @@ describe('UIButton', () => {
});
it('adds the large button class', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-sm');
+ expect('button.pui-btn').toHaveClass('pui-btn--sm');
});
});
@@ -205,7 +205,7 @@ describe('UIButton', () => {
});
it('adds the large button class', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-icon');
+ expect('button.pui-btn').toHaveClass('pui-btn--icon');
});
});
@@ -214,44 +214,8 @@ describe('UIButton', () => {
subject::setProps({alt: true});
});
- describe('when kind is default', () => {
- beforeEach(() => {
- subject::setProps({kind: 'default'});
- });
-
- it('adds appropriate alt class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-default-alt');
- });
- });
-
- describe('when kind is danger', () => {
- beforeEach(() => {
- subject::setProps({kind: 'danger'});
- });
-
- it('adds appropriate alt class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-danger-alt');
- });
- });
-
- describe('when kind is brand', () => {
- beforeEach(() => {
- subject::setProps({kind: 'brand'});
- });
-
- it('adds appropriate alt class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-brand-alt');
- });
- });
-
- describe('when kind is primary', () => {
- beforeEach(() => {
- subject::setProps({kind: 'primary'});
- });
-
- it('adds appropriate alt class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-primary-alt');
- });
+ it('adds appropriate alt class to the button', () => {
+ expect('button.pui-btn').toHaveClass('pui-btn--alt');
});
});
@@ -260,44 +224,8 @@ describe('UIButton', () => {
subject::setProps({flat: true});
});
- describe('when kind is default', () => {
- beforeEach(() => {
- subject::setProps({kind: 'default'});
- });
-
- it('adds appropriate flat class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-default-flat');
- });
- });
-
- describe('when kind is danger', () => {
- beforeEach(() => {
- subject::setProps({kind: 'danger'});
- });
-
- it('adds appropriate flat class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-danger-flat');
- });
- });
-
- describe('when kind is brand', () => {
- beforeEach(() => {
- subject::setProps({kind: 'brand'});
- });
-
- it('adds appropriate flat class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-brand-flat');
- });
- });
-
- describe('when kind is primary', () => {
- beforeEach(() => {
- subject::setProps({kind: 'primary'});
- });
-
- it('adds appropriate flat class to the button', () => {
- expect('button.pui-btn').toHaveClass('pui-btn-primary-flat');
- });
+ it('adds appropriate flat class to the button', () => {
+ expect('button.pui-btn').toHaveClass('pui-btn--flat');
});
});
diff --git a/spec/pivotal-ui-react/flyout/flyout_spec.js b/spec/pivotal-ui-react/flyout/flyout_spec.js
index e918bb27f..7df606360 100644
--- a/spec/pivotal-ui-react/flyout/flyout_spec.js
+++ b/spec/pivotal-ui-react/flyout/flyout_spec.js
@@ -45,8 +45,9 @@ describe('Flyout', () => {
});
it('renders an icon button', () => {
- expect('.pui-dialog .pui-flyout-icon-btn').toHaveClass('pui-btn-default-flat');
- expect('.pui-dialog .pui-flyout-icon-btn').toHaveClass('pui-btn-icon');
+ expect('.pui-dialog .pui-flyout-icon-btn').toHaveClass('pui-btn--default');
+ expect('.pui-dialog .pui-flyout-icon-btn').toHaveClass('pui-btn--flat');
+ expect('.pui-dialog .pui-flyout-icon-btn').toHaveClass('pui-btn--icon');
expect('.pui-dialog .pui-flyout-icon-btn').toHaveAttr('aria-label', 'Close');
expect(Icon).toHaveBeenRenderedWithProps({
src: 'chevron_left',
@@ -102,7 +103,7 @@ describe('Flyout', () => {
});
it('renders the specified icon', () => {
- expect('.pui-flyout-header.grid > .col.col-fixed .pui-btn.pui-btn-default-flat.pui-btn-icon .icon.icon-middle .icon-chevron_left').toHaveText('');
+ expect('.pui-flyout-header.grid > .col.col-fixed .icon.icon-middle .icon-chevron_left').toExist();
});
describe('when clicking the icon button', () => {
@@ -127,7 +128,7 @@ describe('Flyout', () => {
});
it('renders that icon instead of the close icon', () => {
- expect(`.pui-flyout-header.grid > .col.col-fixed .pui-btn.pui-btn-default-flat.pui-btn-icon .icon.icon-middle .icon-${iconSrc}`).toHaveText('');
+ expect(`.pui-flyout-header.grid > .col.col-fixed .icon.icon-middle .icon-${iconSrc}`).toExist();
});
});
});
diff --git a/spec/pivotal-ui-react/modal/modal_spec.js b/spec/pivotal-ui-react/modal/modal_spec.js
index de1eff133..a56fad33d 100644
--- a/spec/pivotal-ui-react/modal/modal_spec.js
+++ b/spec/pivotal-ui-react/modal/modal_spec.js
@@ -45,8 +45,9 @@ describe('Modal', () => {
it('renders a close button', () => {
expect('.pui-dialog.pui-modal-dialog .pui-modal-close-btn').toHaveAttr('aria-label', 'Close');
- expect('.pui-dialog.pui-modal-dialog .pui-modal-close-btn').toHaveClass('pui-btn-default-flat');
- expect('.pui-dialog.pui-modal-dialog .pui-modal-close-btn').toHaveClass('pui-btn-icon');
+ expect('.pui-dialog.pui-modal-dialog .pui-modal-close-btn').toHaveClass('pui-btn--default');
+ expect('.pui-dialog.pui-modal-dialog .pui-modal-close-btn').toHaveClass('pui-btn--flat');
+ expect('.pui-dialog.pui-modal-dialog .pui-modal-close-btn').toHaveClass('pui-btn--icon');
expect(Icon).toHaveBeenRenderedWithProps({src: 'close', size: 'inherit', style: {}, verticalAlign: 'middle'});
});
diff --git a/spec/pivotal-ui-react/pagination/pagination_spec.js b/spec/pivotal-ui-react/pagination/pagination_spec.js
index f50824ba0..2a51533df 100644
--- a/spec/pivotal-ui-react/pagination/pagination_spec.js
+++ b/spec/pivotal-ui-react/pagination/pagination_spec.js
@@ -29,9 +29,9 @@ describe('Pagination', () => {
});
it('renders all buttons with flat class', () => {
- expect('.pagination .pui-btn:eq(0)').toHaveClass('pui-btn-default-flat');
- expect('.pagination .pui-btn:eq(1)').toHaveClass('pui-btn-brand-flat');
- expect('.pagination .pui-btn:eq(2)').toHaveClass('pui-btn-default-flat');
+ expect('.pagination .pui-btn:eq(0)').toHaveClass(['pui-btn--default', 'pui-btn--flat']);
+ expect('.pagination .pui-btn:eq(1)').toHaveClass(['pui-btn--brand', 'pui-btn--flat']);
+ expect('.pagination .pui-btn:eq(2)').toHaveClass(['pui-btn--default', 'pui-btn--flat']);
});
describe('props', () => {
@@ -63,7 +63,7 @@ describe('Pagination', () => {
it('renders an active .pui-btn when activePage number is specified', () => {
renderComponent({activePage: 1});
- expect('.pagination .pui-btn:eq(1)').toHaveClass('pui-btn-brand-flat');
+ expect('.pagination .pui-btn:eq(1)').toHaveClass(['pui-btn--brand', 'pui-btn--flat']);
expect('.pagination .pui-btn:eq(1)').toHaveClass('active');
});
diff --git a/spec/pivotal-ui-react/wizard/wizard_spec.js b/spec/pivotal-ui-react/wizard/wizard_spec.js
index 69c197ccb..3a267927a 100644
--- a/spec/pivotal-ui-react/wizard/wizard_spec.js
+++ b/spec/pivotal-ui-react/wizard/wizard_spec.js
@@ -234,7 +234,7 @@ describe('Wizard', () => {
});
it('renders a cancel button', () => {
- expect('.wizard-cancel-btn.pui-btn-primary-alt').toHaveText('Cancel');
+ expect('.wizard-cancel-btn.pui-btn--primary.pui-btn--alt').toHaveText('Cancel');
});
describe('with custom cancel text', () => {
@@ -243,7 +243,7 @@ describe('Wizard', () => {
});
it('renders a cancel button with custom text', () => {
- expect('.wizard-cancel-btn.pui-btn-primary-alt').toHaveText('Close');
+ expect('.wizard-cancel-btn.pui-btn--primary.pui-btn--alt').toHaveText('Close');
});
});
});
@@ -253,7 +253,7 @@ describe('Wizard', () => {
});
it('renders a "next" PrimaryButton', () => {
- expect('.wizard-next-btn.pui-btn-primary').toHaveText('Next');
+ expect('.wizard-next-btn.pui-btn--primary').toHaveText('Next');
});
it('checks if the next button is enabled', () => {
@@ -279,7 +279,7 @@ describe('Wizard', () => {
});
it('does not render the next button', () => {
- expect('.wizard-next-btn.pui-btn-primary').not.toExist();
+ expect('.wizard-next-btn.pui-btn--primary').not.toExist();
});
});
@@ -290,7 +290,7 @@ describe('Wizard', () => {
});
it('renders the custom text', () => {
- expect('.wizard-next-btn.pui-btn-primary').toHaveText('customNext');
+ expect('.wizard-next-btn.pui-btn--primary').toHaveText('customNext');
});
});
@@ -306,7 +306,7 @@ describe('Wizard', () => {
});
it('disables the "next" button', () => {
- expect('.wizard-next-btn.pui-btn-primary').toHaveAttr('disabled');
+ expect('.wizard-next-btn.pui-btn--primary').toHaveAttr('disabled');
});
});
});
@@ -317,7 +317,7 @@ describe('Wizard', () => {
});
it('renders a "finish" PrimaryButton', () => {
- expect('.wizard-finish-btn.pui-btn-primary').toHaveText('Finish');
+ expect('.wizard-finish-btn.pui-btn--primary').toHaveText('Finish');
});
describe('when "hideFinishButton" is true', () => {
@@ -345,11 +345,11 @@ describe('Wizard', () => {
});
it('does not render a "next" PrimaryButton', () => {
- expect('.wizard-next-btn.pui-btn-primary').not.toExist();
+ expect('.wizard-next-btn.pui-btn--primary').not.toExist();
});
it('renders a "back" alt PrimaryButton', () => {
- expect('.wizard-back-btn.pui-btn-primary-alt').toHaveText('Back');
+ expect('.wizard-back-btn.pui-btn--primary.pui-btn--alt').toHaveText('Back');
});
describe('when clicking the "back" button', () => {
@@ -370,7 +370,7 @@ describe('Wizard', () => {
});
it('renders the custom text', () => {
- expect('.wizard-finish-btn.pui-btn-primary').toHaveText('customFinish');
+ expect('.wizard-finish-btn.pui-btn--primary').toHaveText('customFinish');
});
});
diff --git a/src/react/buttons/buttons.js b/src/react/buttons/buttons.js
index 46da35c0c..ab9ea45db 100644
--- a/src/react/buttons/buttons.js
+++ b/src/react/buttons/buttons.js
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {mergeProps} from '../helpers';
+import classnames from 'classnames';
export class UIButton extends React.Component {
static propTypes = {
@@ -26,28 +26,29 @@ export class UIButton extends React.Component {
}
render() {
- const {alt, flat, icon, iconPosition, iconOnly, large, small, kind, children, fullWidth, ...others} = this.props;
+ const {alt, className, flat, icon, iconPosition, iconOnly, large, small, kind, children, fullWidth, ...others} = this.props;
if (iconOnly && !others['aria-label'] && process.env.NODE_ENV === 'development') {
console.error('Icon-only buttons should have an accessible title set via the "aria-label" prop.');
}
- const buttonClasses = {
- className: [
+ let props = {
+ className: classnames(
+ className,
+ 'pui-btn',
+ `pui-btn--${kind}`,
{
- 'pui-btn': true,
- [`pui-btn-${kind}-alt`]: alt,
- [`pui-btn-${kind}-flat`]: flat,
- [`pui-btn-${kind}`]: !alt && !flat,
- 'pui-btn-lg': large,
- 'pui-btn-sm': small,
- 'pui-btn-icon': iconOnly,
- 'pui-btn-icon-right': !!icon && iconPosition === 'right',
- 'pui-btn-full': fullWidth
+ 'pui-btn--alt': alt,
+ 'pui-btn--flat': flat,
+ 'pui-btn--lg': large,
+ 'pui-btn--sm': small,
+ 'pui-btn--icon': iconOnly,
+ 'pui-btn--icon-right': !!icon && iconPosition === 'right',
+ 'pui-btn--full': fullWidth
}
- ]
+ ),
+ ...others
};
- let props = mergeProps(others, buttonClasses);
const buttonText = Array.isArray(children) ?
children.filter(child => typeof child === 'string').join(' ') :
@@ -56,32 +57,23 @@ export class UIButton extends React.Component {
let btnChildren = children;
if (buttonText && !iconOnly) {
- props = mergeProps(props, {'aria-label': buttonText});
+ props = {'aria-label': buttonText, ...props};
btnChildren = ({children});
}
- let buttonContent = (
-
- {icon}
- {btnChildren}
- );
-
- if (iconPosition === 'right') {
- buttonContent = (
-
- {btnChildren}
- {icon}
- );
- }
-
- return this.props.href ?
- {buttonContent} :
- ;
+ const buttonContent = (
+
+ {iconPosition === 'right' ? btnChildren : icon}
+ {iconPosition === 'right' ? icon : btnChildren}
+
+ );
+ return this.props.href
+ ? {buttonContent}
+ : ;
}
}
+
const defButton = propOverrides => {
return class extends React.Component {
render() {