Skip to content

Commit

Permalink
feat: add button component
Browse files Browse the repository at this point in the history
  • Loading branch information
icelam committed Jun 20, 2020
1 parent 268d4e2 commit d29efce
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 1 deletion.
61 changes: 61 additions & 0 deletions src/components/Buttons/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const ActionButton = styled.button`
display: inline-block;
border: none;
border-radius: 0;
box-shadow: none;
background-color: ${({ theme: { color } }) => color.buttonBackgroundColor};
color: ${({ theme: { color } }) => color.buttonTextColor};
padding: 0.625rem 3.75rem;
margin: 0 0 1.875rem 0;
font-size: 1rem;
font-family: inherit;
text-decoration: none;
text-align: center;
white-space: nowrap;
cursor: pointer;
outline: none;
&:hover {
background-color: ${({ theme: { color } }) => color.buttonHoverBackgroundColor};
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
`;

const Button = ({
id, children, onClick, disabled
}) => (
<ActionButton
id={id}
className="action-button"
type="button"
onClick={onClick}
disabled={disabled}
>
{children}
</ActionButton>
);

Button.propTypes = {
id: PropTypes.string,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]).isRequired,
onClick: PropTypes.func.isRequired,
disabled: PropTypes.bool
};

Button.defaultProps = {
id: undefined,
disabled: false
};

export default Button;
51 changes: 51 additions & 0 deletions src/components/Buttons/__test__/Button.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import { mountWithProvider } from '../../../../jest.utils';
import Button from '../Button';

const buttonText = 'Button Text';
const disabledButtonText = 'Disabled Button Text';
const clickFunction = jest.fn();

afterEach(() => {
clickFunction.mockClear();
});

describe('Button', () => {
it('should render', () => {
const wrapper = mountWithProvider(<Button onClick={clickFunction}>{buttonText}</Button>);
expect(wrapper.find('button.action-button')).toHaveLength(1);
expect(wrapper).toMatchSnapshot();
});

it('should display button with button text', () => {
const wrapper = mountWithProvider(<Button onClick={clickFunction}>{buttonText}</Button>);
expect(wrapper.find('button.action-button').text()).toEqual(buttonText);
expect(wrapper.find('button.action-button')).not.toHaveStyleRule('opacity', '0,5');
expect(wrapper.find('button.action-button')).toHaveStyleRule('cursor', 'pointer');
});

it('should display disabled button with button text', () => {
const wrapper = mountWithProvider(
<Button onClick={clickFunction} disabled>{disabledButtonText}</Button>
);
expect(wrapper.find('button.action-button').text()).toEqual(disabledButtonText);
expect(wrapper.find('button.action-button')).toHaveStyleRule('opacity', '0.5', { modifier: ':disabled' });
expect(wrapper.find('button.action-button')).toHaveStyleRule('cursor', 'not-allowed', { modifier: ':disabled' });
});

it('should trigger function when clicking on button', () => {
const wrapper = mountWithProvider(
<Button onClick={clickFunction}>{buttonText}</Button>
);
wrapper.find('button.action-button').simulate('click');
expect(clickFunction).toHaveBeenCalledTimes(1);
});

it('should not trigger function when clicking on disabled button', () => {
const wrapper = mountWithProvider(
<Button onClick={clickFunction} disabled>{disabledButtonText}</Button>
);
wrapper.find('button.action-button').simulate('click');
expect(clickFunction).toHaveBeenCalledTimes(0);
});
});
52 changes: 52 additions & 0 deletions src/components/Buttons/__test__/__snapshots__/Button.test.jsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Button should render 1`] = `
.c0 {
display: inline-block;
border: none;
border-radius: 0;
box-shadow: none;
background-color: #828b8e;
color: #ffffff;
padding: 0.625rem 3.75rem;
margin: 0 0 1.875rem 0;
font-size: 1rem;
font-family: inherit;
-webkit-text-decoration: none;
text-decoration: none;
text-align: center;
white-space: nowrap;
cursor: pointer;
outline: none;
}
.c0:hover {
background-color: #98a2a5;
}
.c0:disabled {
opacity: 0.5;
cursor: not-allowed;
}
<Button
disabled={false}
onClick={[MockFunction]}
>
<styled.button
className="action-button"
disabled={false}
onClick={[MockFunction]}
type="button"
>
<button
className="c0 action-button"
disabled={false}
onClick={[MockFunction]}
type="button"
>
Button Text
</button>
</styled.button>
</Button>
`;
1 change: 1 addition & 0 deletions src/components/Buttons/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Button } from './Button'; // eslint-disable-line import/prefer-default-export
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Buttons';
export * from './Inputs';
export * from './Loading';
export * from './Pages';
Expand Down
18 changes: 18 additions & 0 deletions src/stories/Button.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { action } from '@storybook/addon-actions';
import { Button } from '@components';

export default {
title: 'Buttons'
};

export const ButtonStory = () => (
<>
<Button onClick={action('Clicked')}>Normal Button</Button><br />
<Button onClick={action('Clicked')} disabled> Disabled Button</Button>
</>
);

ButtonStory.story = {
name: 'Button'
};
5 changes: 4 additions & 1 deletion src/styles/themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ const themes = {
borderColor: colors.midTurquoise,
messageBackgroundColor: colors.greyTurquoise,
messageTextColor: colors.white,
shadowColor: `rgba(${convertHexToRgb(colors.black)}, 0.7)`
shadowColor: `rgba(${convertHexToRgb(colors.black)}, 0.7)`,
buttonBackgroundColor: colors.greyTurquoise,
buttonHoverBackgroundColor: colors.lightGreyTurquoise,
buttonTextColor: colors.white
},
mediaQueries: {
...mediaQueries
Expand Down

0 comments on commit d29efce

Please sign in to comment.