Browse Source

feat(ui): add Button component

renovate/lint-staged-8.x
Tom Kirkpatrick 6 years ago
parent
commit
4e4ef61947
No known key found for this signature in database GPG Key ID: 72203A8EC5967EA8
  1. 83
      app/components/UI/Button.js
  2. 56
      stories/components/button.stories.js
  3. 10
      test/unit/components/UI/Button.spec.js
  4. 59
      test/unit/components/UI/__snapshots__/Button.spec.js.snap

83
app/components/UI/Button.js

@ -0,0 +1,83 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { Button as BaseButton, Flex, Text } from 'rebass'
import Spinner from './Spinner'
const Wrapper = styled(BaseButton)`
transition: all 0.25s;
outline: none;
border-radius: 5;
font-weight: normal;
line-height: '18px';
&:focus {
box-shadow: 0 0 3px ${props => props.theme.lightningOrange};
}
&:disabled {
opacity: 0.5;
}
&:hover:enabled {
cursor: pointer;
}
`
Wrapper.displayName = 'Button'
/**
* @render react
* @name Button
* @example
* <Button><Basic button</Button>
*/
class Button extends React.PureComponent {
static displayName = 'Button'
static defaultProps = {
processing: false,
size: 'medium',
variant: 'normal'
}
static propTypes = {
processing: PropTypes.bool,
size: PropTypes.oneOf(['small', 'medium', 'large']),
variant: PropTypes.string
}
render() {
const { children, processing, size, ...rest } = this.props
const sizes = {
small: {
x: 3,
y: 2,
fontSize: 's'
},
medium: {
x: 3,
y: 2,
fontSize: 'm'
},
large: {
x: 5,
y: 3,
fontSize: 'l'
}
}
return (
<Wrapper
px={sizes[size]['x']}
py={sizes[size]['y']}
fontSize={sizes[size]['fontSize']}
{...rest}
>
{processing ? (
<Flex>
{processing && <Spinner size="2em" mr="0.5em" />}
<Text fontFamily="sans">{children}</Text>
</Flex>
) : (
<Text fontFamily="sans">{children}</Text>
)}
</Wrapper>
)
}
}
export default Button

56
stories/components/button.stories.js

@ -0,0 +1,56 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import Button from 'components/UI/Button'
import SystemNavPrevious from 'components/Icon/SystemNavPrevious'
import SystemNavNext from 'components/Icon/SystemNavNext'
storiesOf('Components.Button', module)
.add('Basic', () => <Button onClick={action('clicked')}>Basic button</Button>)
.add('With Icon', () => (
<section>
<Button onClick={action('clicked')}>
<SystemNavPrevious />
Previous
</Button>{' '}
<Button onClick={action('clicked')}>
Next
<SystemNavNext />
</Button>
</section>
))
.add('Processing', () => (
<Button processing onClick={action('clicked')}>
Processing
</Button>
))
.add('Disabled', () => (
<Button disabled onClick={action('clicked')}>
Disabled button
</Button>
))
.add('Primary', () => (
<Button onClick={action('clicked')} variant="primary">
Primary button
</Button>
))
.add('Secondary', () => (
<Button onClick={action('clicked')} variant="secondary">
Secondary button
</Button>
))
.add('Small', () => (
<Button onClick={action('clicked')} size="small">
Small button
</Button>
))
.add('Medium', () => (
<Button onClick={action('clicked')} size="medium">
Medium button
</Button>
))
.add('Large', () => (
<Button onClick={action('clicked')} size="large">
Large button
</Button>
))

10
test/unit/components/UI/Button.spec.js

@ -0,0 +1,10 @@
import React from 'react'
import Button from 'components/UI/Button'
import renderer from 'react-test-renderer'
describe('component.UI.Button', () => {
it('should render correctly', () => {
const tree = renderer.create(<Button />).toJSON()
expect(tree).toMatchSnapshot()
})
})

59
test/unit/components/UI/__snapshots__/Button.spec.js.snap

@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`component.UI.Button should render correctly 1`] = `
.c1 {
font-family: sans;
}
.c0 {
margin: 0px;
padding-left: 16px;
padding-right: 16px;
padding-top: 8px;
padding-bottom: 8px;
font-size: m;
color: white;
background-color: blue;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
display: inline-block;
text-align: center;
line-height: inherit;
-webkit-text-decoration: none;
text-decoration: none;
font-weight: bold;
border: 0;
border-radius: 4px;
-webkit-transition: all 0.25s;
transition: all 0.25s;
outline: none;
border-radius: 5;
font-weight: normal;
line-height: '18px';
}
.c0:focus {
box-shadow: 0 0 3px;
}
.c0:disabled {
opacity: 0.5;
}
.c0:hover:enabled {
cursor: pointer;
}
<button
className="c0"
color="white"
fontSize="m"
fontWeight="bold"
>
<div
className="c1"
fontFamily="sans"
/>
</button>
`;
Loading…
Cancel
Save