Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Add ButtonGroup component #33

Merged
merged 11 commits into from
Mar 8, 2018
4 changes: 2 additions & 2 deletions dist/toolbox.js

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions src/components/ButtonGroup/ButtonGroup.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import { arrayOf, bool, node } from 'prop-types';
import glamorous, { Div } from 'glamorous';

import Button from '../Button/Button';
import constants from '../../constants';

const { borderRadius } = constants;

const ButtonGroupItem = glamorous(Button)({
borderRadius: 0,
borderRightWidth: 0,

'&:first-of-type': {
borderTopLeftRadius: borderRadius,
borderBottomLeftRadius: borderRadius,
},
'&:last-of-type': {
borderTopRightRadius: borderRadius,
borderBottomRightRadius: borderRadius,
borderRightWidth: 1,
},
});

const ButtonGroup = ({ children, disabled, ...props }) => (
<Div display="inline-block" {...props}>
{React.Children.map(children, child => {
if (child.type !== Button) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little bit confused why this is necessary. Is there really a good reason to ever wrap something that isn't a Button in a ButtonGroup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my use case I have a hidden input inside the ButtonGroup so there's one.

return child;
}
return (
<ButtonGroupItem
{...child.props}
disabled={disabled || child.props.disabled}
/>
);
})}
</Div>
);

ButtonGroup.propTypes = {
/** Buttons to be grouped together. */
children: arrayOf(node).isRequired,
/** Indicates that the control is not available for interaction */
disabled: bool,
};

ButtonGroup.defaultProps = {
disabled: false,
};

export default ButtonGroup;
53 changes: 53 additions & 0 deletions src/components/ButtonGroup/ButtonGroup.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import renderer from 'react-test-renderer';
import ButtonGroup from './ButtonGroup';
import Button from '../Button/Button';

test('renders without crashing', () => {
const tree = renderer
.create(
<ButtonGroup>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>,
)
.toJSON();
expect(tree).toMatchSnapshot();
});

test('renders when disabled', () => {
const tree = renderer
.create(
<ButtonGroup disabled>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>,
)
.toJSON();
expect(tree).toMatchSnapshot();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add a test for when ButtonGroup wraps a component other than Button.


test('renders with disabled children', () => {
const tree = renderer
.create(
<ButtonGroup>
<Button disabled>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>,
)
.toJSON();
expect(tree).toMatchSnapshot();
});

test('renders with non-button children', () => {
const tree = renderer
.create(
<ButtonGroup>
<Button>Button 1</Button>
<Button>Button 2</Button>
<span>Span</span>
</ButtonGroup>,
)
.toJSON();
expect(tree).toMatchSnapshot();
});
10 changes: 10 additions & 0 deletions src/components/ButtonGroup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### Example

```
<ButtonGroup>
<Button>File</Button>
<Button>Edit</Button>
<Button>View</Button>
<Button>History</Button>
</ButtonGroup>
```
Loading