From bbd73d0675c594c1a181a3eab39b588e80971031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Wed, 31 Jan 2018 17:58:40 +0100 Subject: [PATCH 1/2] Add Radio component, change Checkbox component --- src/components/base/Checkbox/index.js | 49 +++++++---- src/components/base/Modal/index.js | 11 ++- src/components/base/Radio/index.js | 119 ++++++++++++++++++++++++++ src/components/base/Radio/stories.js | 9 ++ 4 files changed, 167 insertions(+), 21 deletions(-) create mode 100644 src/components/base/Radio/index.js create mode 100644 src/components/base/Radio/stories.js diff --git a/src/components/base/Checkbox/index.js b/src/components/base/Checkbox/index.js index a0ec9526..33f7c1ef 100644 --- a/src/components/base/Checkbox/index.js +++ b/src/components/base/Checkbox/index.js @@ -1,11 +1,25 @@ // @flow import React, { PureComponent } from 'react' -import styled from 'styled-components' +import styled, { keyframes } from 'styled-components' import Box from 'components/base/Box' import Icon from 'components/base/Icon' +const bounce = keyframes` + 0% { + transform: scale(1, 1); + } + + 50% { + transform: scale(1.7, 1.7); + } + + 100% { + transform: scale(1, 1); + } +` + const Base = styled(Box).attrs({ align: 'center', justify: 'center', @@ -14,9 +28,7 @@ const Base = styled(Box).attrs({ background-color: ${p => (p.checked ? p.theme.colors.blue : p.theme.colors.white)}; box-shadow: 0 0 0 ${p => (p.checked ? 4 : 1)}px ${p => (p.checked ? p.theme.colors.cream : p.theme.colors.argile)}; - border-radius: 50%; font-size: 7px; - height: 19px; width: 19px; transition: all ease-in-out 0.1s; @@ -33,17 +45,16 @@ const Base = styled(Box).attrs({ width: 100%; z-index: 10; } +` - > span { - position: relative; - top: 1px; - opacity: ${p => (p.checked ? 1 : 0)}; - transition: all ease-in-out 0.1s; - } +const IconWrapper = styled(Icon).attrs({ + color: 'white', +})` + animation: ${bounce} ease-in-out 0.5s; ` type Props = { - checked?: boolean, + checked: boolean, onChange?: Function, } @@ -52,16 +63,18 @@ type State = { } class Checkbox extends PureComponent { + static defaultProps = { + checked: false, + } + state = { - checked: this.props.checked || false, + checked: this.props.checked, } componentWillReceiveProps(nextProps: Props) { - if (nextProps.checked) { - this.setState({ - checked: nextProps.checked, - }) - } + this.setState({ + checked: nextProps.checked, + }) } handleChange = (e: SyntheticInputEvent) => { @@ -82,9 +95,9 @@ class Checkbox extends PureComponent { const { onChange, ...props } = this.props return ( - + - + {checked && } ) } diff --git a/src/components/base/Modal/index.js b/src/components/base/Modal/index.js index cd5f8f1b..61b4a9b0 100644 --- a/src/components/base/Modal/index.js +++ b/src/components/base/Modal/index.js @@ -126,9 +126,14 @@ export class Modal extends PureComponent { > {(m, isVisible) => ( - - - + + + e.stopPropagation()} + > {render({ data, onClose })} diff --git a/src/components/base/Radio/index.js b/src/components/base/Radio/index.js new file mode 100644 index 00000000..04b18404 --- /dev/null +++ b/src/components/base/Radio/index.js @@ -0,0 +1,119 @@ +// @flow + +import React, { PureComponent } from 'react' +import styled from 'styled-components' + +import Box from 'components/base/Box' + +const Base = styled(Box).attrs({ + align: 'center', + justify: 'center', + relative: true, +})` + box-shadow: 0 0 0 ${p => (p.checked ? 4 : 1)}px + ${p => (p.checked ? p.theme.colors.cream : p.theme.colors.argile)}; + border-radius: 50%; + height: 19px; + width: 19px; + transition: all ease-in-out 0.1s; + + input[type='radio'] { + bottom: 0; + cursor: pointer; + height: 100%; + left: 0; + opacity: 0; + position: absolute; + right: 0; + top: 0; + width: 100%; + z-index: 10; + } + + &:before, + &:after { + border-radius: 50%; + bottom: 100%; + content: ' '; + left: 100%; + position: absolute; + right: 100%; + top: 100%; + transition: all ease-in-out 0.2s; + } + + &:before { + background-color: ${p => p.theme.colors.blue}; + ${p => + p.checked && + ` + bottom: 0; + left: 0; + right: 0; + top: 0; + `}; + } + + &:after { + background-color: ${p => p.theme.colors.white}; + ${p => + p.checked && + ` + bottom: 7px; + left: 7px; + right: 7px; + top: 7px; + `}; + } +` + +type Props = { + checked: boolean, + onChange?: Function, +} + +type State = { + checked: boolean, +} + +class Radio extends PureComponent { + static defaultProps = { + checked: false, + } + + state = { + checked: this.props.checked, + } + + componentWillReceiveProps(nextProps: Props) { + this.setState({ + checked: nextProps.checked, + }) + } + + handleChange = (e: SyntheticInputEvent) => { + const { onChange } = this.props + const { checked } = e.target + + this.setState({ + checked, + }) + + if (onChange) { + onChange(checked) + } + } + + render() { + const { checked } = this.state + const { onChange, ...props } = this.props + + return ( + + + + ) + } +} + +export default Radio diff --git a/src/components/base/Radio/stories.js b/src/components/base/Radio/stories.js new file mode 100644 index 00000000..978a6e18 --- /dev/null +++ b/src/components/base/Radio/stories.js @@ -0,0 +1,9 @@ +import React from 'react' +import { storiesOf } from '@storybook/react' +import { boolean } from '@storybook/addon-knobs' + +import Radio from 'components/base/Radio' + +const stories = storiesOf('Radio', module) + +stories.add('basic', () => ) From a6688fdd3d981fbddf9528e29eda7ce0b4c28f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Wed, 31 Jan 2018 18:08:33 +0100 Subject: [PATCH 2/2] Add @flow on all stories --- src/components/base/Box/stories.js | 2 ++ src/components/base/Button/stories.js | 2 ++ src/components/base/Checkbox/stories.js | 2 ++ src/components/base/GrowScroll/stories.js | 2 ++ src/components/base/Input/stories.js | 2 ++ src/components/base/Modal/stories.js | 2 ++ src/components/base/Radio/stories.js | 2 ++ src/components/base/Search/stories.js | 2 ++ src/components/base/Tabs/stories.js | 2 ++ 9 files changed, 18 insertions(+) diff --git a/src/components/base/Box/stories.js b/src/components/base/Box/stories.js index 861283d7..3c6610bf 100644 --- a/src/components/base/Box/stories.js +++ b/src/components/base/Box/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { select, boolean, number } from '@storybook/addon-knobs' diff --git a/src/components/base/Button/stories.js b/src/components/base/Button/stories.js index afad1735..926c753d 100644 --- a/src/components/base/Button/stories.js +++ b/src/components/base/Button/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { storiesOf } from '@storybook/react' diff --git a/src/components/base/Checkbox/stories.js b/src/components/base/Checkbox/stories.js index 34222a4b..0841d3e9 100644 --- a/src/components/base/Checkbox/stories.js +++ b/src/components/base/Checkbox/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { storiesOf } from '@storybook/react' import { boolean } from '@storybook/addon-knobs' diff --git a/src/components/base/GrowScroll/stories.js b/src/components/base/GrowScroll/stories.js index e8e9c9aa..ba442cf0 100644 --- a/src/components/base/GrowScroll/stories.js +++ b/src/components/base/GrowScroll/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { storiesOf } from '@storybook/react' import { boolean } from '@storybook/addon-knobs' diff --git a/src/components/base/Input/stories.js b/src/components/base/Input/stories.js index 091ffa7f..2fd65956 100644 --- a/src/components/base/Input/stories.js +++ b/src/components/base/Input/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { storiesOf } from '@storybook/react' diff --git a/src/components/base/Modal/stories.js b/src/components/base/Modal/stories.js index 6abd2d47..4529c878 100644 --- a/src/components/base/Modal/stories.js +++ b/src/components/base/Modal/stories.js @@ -1,3 +1,5 @@ +// @flow + import React, { Fragment } from 'react' import { storiesOf } from '@storybook/react' import { boolean } from '@storybook/addon-knobs' diff --git a/src/components/base/Radio/stories.js b/src/components/base/Radio/stories.js index 978a6e18..e21dff6e 100644 --- a/src/components/base/Radio/stories.js +++ b/src/components/base/Radio/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { storiesOf } from '@storybook/react' import { boolean } from '@storybook/addon-knobs' diff --git a/src/components/base/Search/stories.js b/src/components/base/Search/stories.js index 8c3bf388..c5165058 100644 --- a/src/components/base/Search/stories.js +++ b/src/components/base/Search/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import PropTypes from 'prop-types' import { storiesOf } from '@storybook/react' diff --git a/src/components/base/Tabs/stories.js b/src/components/base/Tabs/stories.js index 5cbb22b7..9479da94 100644 --- a/src/components/base/Tabs/stories.js +++ b/src/components/base/Tabs/stories.js @@ -1,3 +1,5 @@ +// @flow + import React from 'react' import { number } from '@storybook/addon-knobs'