Browse Source

Merge pull request #76 from meriadec/master

CheckBox & Radio refacto + Tabbable work with space
master
Loëck Vézien 7 years ago
committed by GitHub
parent
commit
43fbdfe91c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/components/base/Box/index.js
  2. 67
      src/components/base/CheckBox/index.js
  3. 14
      src/components/base/CheckBox/stories.js
  4. 106
      src/components/base/Checkbox/index.js
  5. 11
      src/components/base/Checkbox/stories.js
  6. 80
      src/components/base/Radio/index.js
  7. 5
      src/components/base/Radio/stories.js
  8. 6
      src/components/modals/AddAccount/ImportAccounts.js

2
src/components/base/Box/index.js

@ -98,7 +98,7 @@ export class Tabbable extends PureComponent<any, TabbableState> {
handleBlur = () => this.setState({ isFocused: false })
handleKeydown = (e: SyntheticKeyboardEvent<any>) => {
if (e.which === 13 && this.state.isFocused && this.props.onClick) {
if ((e.which === 13 || e.which === 32) && this.state.isFocused && this.props.onClick) {
this.props.onClick(e)
}
}

67
src/components/base/CheckBox/index.js

@ -0,0 +1,67 @@
// @flow
import React from 'react'
import noop from 'lodash/noop'
import styled, { keyframes } from 'styled-components'
import { Tabbable } from 'components/base/Box'
import Icon from 'components/base/Icon'
const bounce = keyframes`
0% {
transform: scale(1);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
`
const Base = styled(Tabbable).attrs({
align: 'center',
justify: 'center',
})`
cursor: pointer;
outline: none;
border-radius: 3px;
border: 1px solid transparent;
background-color: ${p => (p.isChecked ? p.theme.colors.blue : p.theme.colors.white)};
box-shadow: 0 0 0 ${p => (p.isChecked ? 4 : 1)}px
${p => (p.isChecked ? p.theme.colors.cream : p.theme.colors.argile)};
font-size: 7px;
height: 19px;
width: 19px;
transition: all ease-in 0.1s;
&:focus {
border-color: ${p => p.theme.colors.mouse};
}
`
const IconWrapper = styled(Icon).attrs({
color: 'white',
})`
animation: ${bounce} ease-in-out 350ms;
`
type Props = {
isChecked: boolean,
onChange?: Function,
}
function CheckBox(props: Props) {
const { isChecked, onChange, ...p } = props
return (
<Base isChecked={isChecked} onClick={() => onChange(!isChecked)} {...p}>
{isChecked && <IconWrapper name="check" />}
</Base>
)
}
CheckBox.defaultProps = {
onChange: noop,
}
export default CheckBox

14
src/components/base/CheckBox/stories.js

@ -0,0 +1,14 @@
// @flow
import React from 'react'
import { storiesOf } from '@storybook/react'
import { boolean } from '@storybook/addon-knobs'
import { action } from '@storybook/addon-actions'
import CheckBox from 'components/base/CheckBox'
const stories = storiesOf('CheckBox', module)
stories.add('basic', () => (
<CheckBox isChecked={boolean('isChecked', false)} onChange={action('onChange')} />
))

106
src/components/base/Checkbox/index.js

@ -1,106 +0,0 @@
// @flow
import React, { PureComponent } from 'react'
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',
relative: true,
})`
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)};
font-size: 7px;
height: 19px;
width: 19px;
transition: all ease-in-out 0.1s;
input[type='checkbox'] {
bottom: 0;
cursor: pointer;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
right: 0;
top: 0;
width: 100%;
z-index: 10;
}
`
const IconWrapper = styled(Icon).attrs({
color: 'white',
})`
animation: ${bounce} ease-in-out 0.5s;
`
type Props = {
checked: boolean,
onChange?: Function,
}
type State = {
checked: boolean,
}
class Checkbox extends PureComponent<Props, State> {
static defaultProps = {
checked: false,
}
state = {
checked: this.props.checked,
}
componentWillReceiveProps(nextProps: Props) {
this.setState({
checked: nextProps.checked,
})
}
handleChange = (e: SyntheticInputEvent<HTMLInputElement>) => {
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 (
<Base {...props} checked={checked}>
<input type="checkbox" checked={checked} onChange={this.handleChange} />
{checked && <IconWrapper name="check" />}
</Base>
)
}
}
export default Checkbox

11
src/components/base/Checkbox/stories.js

@ -1,11 +0,0 @@
// @flow
import React from 'react'
import { storiesOf } from '@storybook/react'
import { boolean } from '@storybook/addon-knobs'
import Checkbox from 'components/base/Checkbox'
const stories = storiesOf('Checkbox', module)
stories.add('basic', () => <Checkbox checked={boolean('checked', false)} />)

80
src/components/base/Radio/index.js

@ -1,33 +1,22 @@
// @flow
import React, { PureComponent } from 'react'
import React from 'react'
import noop from 'lodash/noop'
import styled from 'styled-components'
import Box from 'components/base/Box'
import { Tabbable } 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)};
const Base = styled(Tabbable).attrs({ relative: true })`
outline: none;
box-shadow: 0 0 0 1px ${p => (p.isChecked ? 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;
&:focus {
box-shadow: 0 0 0 ${p => (p.isChecked ? 4 : 2)}px
${p => (p.isChecked ? p.theme.colors.cream : p.theme.colors.argile)};
}
&:before,
@ -45,7 +34,7 @@ const Base = styled(Box).attrs({
&:before {
background-color: ${p => p.theme.colors.blue};
${p =>
p.checked &&
p.isChecked &&
`
bottom: 0;
left: 0;
@ -57,7 +46,7 @@ const Base = styled(Box).attrs({
&:after {
background-color: ${p => p.theme.colors.white};
${p =>
p.checked &&
p.isChecked &&
`
bottom: 7px;
left: 7px;
@ -68,52 +57,17 @@ const Base = styled(Box).attrs({
`
type Props = {
checked: boolean,
isChecked: boolean,
onChange?: Function,
}
type State = {
checked: boolean,
function Radio(props: Props) {
const { isChecked, onChange } = props
return <Base {...props} isChecked={isChecked} onClick={() => onChange(!isChecked)} />
}
class Radio extends PureComponent<Props, State> {
static defaultProps = {
checked: false,
}
state = {
checked: this.props.checked,
}
componentWillReceiveProps(nextProps: Props) {
this.setState({
checked: nextProps.checked,
})
}
handleChange = (e: SyntheticInputEvent<HTMLInputElement>) => {
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 (
<Base {...props} checked={checked}>
<input type="radio" checked={checked} onChange={this.handleChange} />
</Base>
)
}
Radio.defaultProps = {
onChange: noop,
}
export default Radio

5
src/components/base/Radio/stories.js

@ -2,10 +2,13 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import { boolean } from '@storybook/addon-knobs'
import Radio from 'components/base/Radio'
const stories = storiesOf('Radio', module)
stories.add('basic', () => <Radio checked={boolean('checked', false)} />)
stories.add('basic', () => (
<Radio isChecked={boolean('checked', false)} onChange={action('onChange')} />
))

6
src/components/modals/AddAccount/ImportAccounts.js

@ -9,7 +9,7 @@ import { formatBTC } from 'helpers/format'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import Checkbox from 'components/base/Checkbox'
import CheckBox from 'components/base/CheckBox'
import Input from 'components/base/Input'
type Props = {
@ -86,8 +86,8 @@ class ImportAccounts extends PureComponent<Props, State> {
return (
<Box key={account.id} horizontal flow={10}>
<Box>
<Checkbox
checked={selected}
<CheckBox
isChecked={selected}
onChange={this.handleSelectAccount(account.id, selected)}
/>
</Box>

Loading…
Cancel
Save