Tom Kirkpatrick
6 years ago
4 changed files with 208 additions and 0 deletions
@ -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 |
@ -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> |
||||
|
)) |
@ -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() |
||||
|
}) |
||||
|
}) |
@ -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…
Reference in new issue