Commit a3887819 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Amend `Button` to take `iconPosition` prop; add styling options

- Make `Button` take `iconPosition` prop {`left|right`} to allow for
  right-aligned icons on buttons
- Add parameters to `button--labeled` mixin to allow for background
  color overrides
parent 0101a09d
......@@ -14,6 +14,8 @@ import propTypes from 'prop-types';
* See `buttons` SCSS mixins module for more details.
* @prop {string} [icon] -
* The name of the SVGIcon to render. This is optional if a `buttonText` is provided.
* @prop {'left'|'right'} [iconPosition] - Whether icon should render to the left or
* to the right of label text
* @prop {boolean} [isExpanded] -
* Is the expandable element controlled by this button currently expanded?
* @prop {boolean} [isPressed] -
......@@ -40,6 +42,7 @@ export default function Button({
className = '',
disabled = false,
icon = '',
iconPosition = 'left',
isExpanded,
isPressed,
onClick = () => {},
......@@ -78,8 +81,9 @@ export default function Button({
disabled={disabled}
{...extraProps}
>
{icon && <SvgIcon name={icon} />}
{icon && iconPosition === 'left' && <SvgIcon name={icon} />}
{buttonText}
{icon && iconPosition === 'right' && <SvgIcon name={icon} />}
</button>
);
}
......@@ -108,6 +112,7 @@ Button.propTypes = {
buttonText: propTypes.string,
className: propTypes.string,
icon: requiredStringIfButtonTextMissing,
iconPosition: propTypes.string,
isExpanded: propTypes.bool,
isPressed: propTypes.bool,
onClick: propTypes.func,
......
......@@ -34,6 +34,23 @@ describe('Button', () => {
assert.equal(wrapper.find('SvgIcon').prop('name'), 'fakeIcon');
});
it('positions `SvgIcon` left (first) by default', () => {
const wrapper = createComponent({ buttonText: 'My Button' });
assert.isTrue(wrapper.find('button').childAt(0).is('SvgIcon'));
assert.equal(wrapper.find('button').childAt(1).text(), 'My Button');
});
it('positions `SvgIcon` right (second) with `iconPosition` prop', () => {
const wrapper = createComponent({
buttonText: 'My Button',
iconPosition: 'right',
});
assert.equal(wrapper.find('button').childAt(0).text(), 'My Button');
assert.isTrue(wrapper.find('button').childAt(1).is('SvgIcon'));
});
[true, false].forEach(isExpanded => {
it('sets `aria-expanded` attribute if `isExpanded` is a boolean', () => {
const wrapper = createComponent({ isExpanded });
......
......@@ -87,17 +87,27 @@
}
}
/* A button with displayed text. It may or may not have an icon. */
@mixin button--labeled {
/**
* A button with displayed text. It may or may not have an icon. The default
* colors assume the button is displayed on a white background.
*
* @param {CSSColor} [$background-color] - The button's background color when
* neither hovered nor active.
* @param {CSSColor} [$active-background-color]
*/
@mixin button--labeled(
$background-color: var.$grey-1,
$active-background-color: var.$grey-2
) {
@include button;
white-space: nowrap; // Keep multi-word button labels from wrapping
color: var.$grey-mid;
font-weight: 700;
background-color: var.$grey-1;
background-color: $background-color;
&:hover:not([disabled]),
&:focus:not([disabled]) {
background-color: var.$grey-2;
background-color: $active-background-color;
}
// Icon
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment