Skip to content

Commit

Permalink
Improve Button component to allow pass custom href when renderAs Reac…
Browse files Browse the repository at this point in the history
…t component (To use with Link from react-router)
  • Loading branch information
couds committed Oct 3, 2017
1 parent f92eada commit 1c99e96
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/components/breadcrumb/breadcrumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Breadcrumb = ({

}) => {
if (renderAs !== 'a' && !hrefAttr) {
console.warn('if renderAs is different the anchor (a), hrefAttr is required. Check Breadcrumb render method');
console.warn('if renderAs is different the anchor (a), hrefAttr is required. Check Breadcrumb props');
}
const Element = renderAs;
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ exports[`Button component Should be a default Button 1`] = `
<a
className="button"
disabled={false}
href="http://google.com"
onClick={[Function]}
style={Object {}}
/>
Expand All @@ -47,6 +48,14 @@ exports[`Button component Should be a submit form button 1`] = `
/>
`;

exports[`Button component Should render as a React element link with custom href 1`] = `
<a
href="http://google.com"
>
TEST
</a>
`;

exports[`Button component Should render as a html button 1`] = `
<button
className="is-danger button"
Expand Down
33 changes: 32 additions & 1 deletion src/components/button/__test__/button.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import Button from '..';

const Link = ({
to,
children,
}) => (
<a href={to}>{children}</a>
);

Link.propTypes = {
to: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

describe('Button component', () => {
it('Should be a default Button', () => {
const component = renderer.create(
<Button />,
<Button href="http://google.com" />,
);
expect(component.toJSON()).toMatchSnapshot();
});
Expand Down Expand Up @@ -34,6 +47,24 @@ describe('Button component', () => {
);
expect(component.toJSON()).toMatchSnapshot();
});
it('Should render as a React element link with custom href', () => {
const component = renderer.create(
<Button renderAs={Link} href="http://google.com" hrefAttr="to" color="danger" >
TEST
</Button>,
);
expect(component.toJSON()).toMatchSnapshot();
});
it('Should throw a console.error if no hrefAttr is defined when renderAs different as A and href attr is defined', () => {
console.error = jest.genMockFn();
renderer.create(
<Button renderAs={Link} href="http://google.com" color="danger" >
TEST
</Button>,
);
expect(console.error).toHaveBeenCalled();
console.error.mockRestore();
});
it('Should render be disabled', () => {
const component = renderer.create(
<Button disabled />,
Expand Down
18 changes: 17 additions & 1 deletion src/components/button/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@ const Button = ({
disabled,
remove,
link,
href,
hrefAttr,
...props
}) => {
let Element = props.static ? 'span' : renderAs;
const otherProps = {};
if (href) {
otherProps[renderAs === 'a' ? 'href' : hrefAttr] = href;
if (renderAs !== 'a' && !hrefAttr) {
console.error('warning: if renderAs is different the anchor (a), hrefAttr is required. Check Button props');
}
}
if (submit) {
Element = 'input';
otherProps.type = 'submit';
Expand All @@ -35,6 +43,7 @@ const Button = ({
Element = 'input';
otherProps.type = 'reset';
}

return (
<Element
{...otherProps}
Expand Down Expand Up @@ -62,8 +71,13 @@ const Button = ({
Button.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
href: PropTypes.string,
hrefAttr: PropTypes.string,
style: PropTypes.object,
renderAs: PropTypes.oneOf(['a', 'button']),
renderAs: PropTypes.oneOfType([
PropTypes.oneOf(['a', 'button']),
PropTypes.func,
]),
static: PropTypes.bool,
onClick: PropTypes.func,
color: PropTypes.oneOf(colors),
Expand All @@ -83,6 +97,8 @@ Button.propTypes = {
Button.defaultProps = {
children: null,
className: '',
href: '',
hrefAttr: '',
style: {},
renderAs: 'a',
onClick: () => null,
Expand Down
33 changes: 25 additions & 8 deletions src/components/button/button.story.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import React from 'react';

import PropTypes from 'prop-types';
import { storiesOf } from '@storybook/react';
import { withInfo } from '@storybook/addon-info';

import Button from '.';
import Section from '../section';
import Box from '../box';

const Link = ({
to,
children,
className,
}) => (
<a className={className} href={to}>{children}</a>
);

Link.propTypes = {
to: PropTypes.string.isRequired,
className: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

storiesOf('Button', module)
.addDecorator(story => (
<div className="button-display">
Expand Down Expand Up @@ -53,22 +67,25 @@ storiesOf('Button', module)
<Section>
<Box>
<Button fullwidth color="primary">
Full Width
Full Width
</Button>
<Button loading color="info">
Loading
Loading
</Button>
<Button outlined color="danger">
Warning Outlined
Warning Outlined
</Button>
<Button inverted color="success">
Success Inverted
Success Inverted
</Button>
<Button disabled color="info">
Disabled
Disabled
</Button>
<Button link href="http://google.com">
Link
</Button>
<Button link>
Link
<Button renderAs={Link} hrefAttr="to" color="primary" href="http://google.com">
Custom component
</Button>

<Button remove />
Expand Down

0 comments on commit 1c99e96

Please sign in to comment.