refactoring toggle component

This commit is contained in:
Alex Windett 2017-01-09 18:04:56 +00:00
parent 0b8b1ee379
commit 98933873c1
3 changed files with 79 additions and 200 deletions

View File

@ -1,136 +0,0 @@
const constants = require('../../shared/constants');
const composers = require('../../shared/composers');
const fns = require('../../shared/functions');
const React = require('react');
const Styled = require('styled-components');
const {
boxes,
colors,
typography
} = constants;
const {
pseudoEl
} = composers;
const {
remcalc,
rndId
} = fns;
const {
default: styled
} = Styled;
const classNames = {
label: rndId()
};
const StyledLabel = styled.label`
border-radius: ${boxes.borderRadius};
color: #464646;
height: 2.5rem;
width: ${remcalc(110)};
`;
const StyledToggleLabel = styled.div`
background-color: #E6E6E6;
border: solid 1px #D8D8D8;
border-radius: ${boxes.borderRadius};
color: #000000;
height: ${remcalc(54)};
margin: 0.125rem;
padding-left: ${remcalc(12)};
position: relative;
text-align: right;
width: ${remcalc(106)};
&::before {
content: "${props => props.labelRight}";
font-family: ${typography.fontPrimary};
font-size: inherit;
font-weight: bold;
position: absolute;
right: 24px;
top: 19px;
}
&::after {
content: "${props => props.labelLeft}";
background-color: #FFFFFF;
border-radius: ${boxes.borderRadius};
height: ${remcalc(46)};
width: ${remcalc(46)};
${pseudoEl({
top: '3px',
left: '3px',
})}
}
`;
const StyledInput = styled.input`
display: none;
&:checked {
& + .${classNames.label} {
background: ${colors.confirmation};
border: ${boxes.border.confirmed};
color: #FFFFFF;
padding-left: 0;
padding-right: ${remcalc(12)};
text-align: left;
&::before {
content: "${props => props.labelLeft}";
left: 20px;
right: auto;
}
&::after {
left: auto;
right: 3px;
}
}
}
`;
const Toggle = ({
checked,
className,
defaultChecked,
labelLeft = "On",
labelRight = "Off",
id = rndId(),
style
}) => {
return (
<StyledLabel
className={className}
htmlFor={id}
style={style}
>
<StyledInput
id={id}
labelLeft={labelLeft}
type='checkbox'
/>
<StyledToggleLabel
className={classNames.label}
labelRight={labelRight}
/>
</StyledLabel>
);
};
Toggle.propTypes = {
checked: React.PropTypes.bool,
className: React.PropTypes.string,
defaultChecked: React.PropTypes.bool,
id: React.PropTypes.string,
style: React.PropTypes.object
};
module.exports = Toggle;

View File

@ -5,13 +5,10 @@ const React = require('react');
const Styled = require('styled-components');
const {
boxes,
colors,
typography
colors
} = constants;
const {
pseudoEl,
baseBox
} = composers;
@ -22,36 +19,22 @@ const {
const {
default: styled,
keyframes
css
} = Styled;
const classNames = {
label: rndId()
};
const slide = (
direction = 'left'
) => {
keyframes`
from {
left: 0;
}
to {
left: 100%;
}
`;
}
/*
const backgroundGradient = (index) => {
const colorDefault = index === 1 ? 'red' : 'blue';
const colorAlt = index === 1 ? 'blue' : 'red';
debugger
// debugger
return css`
background: linear-gradient(to right, ${colorDefault} 50%, ${colorAlt} 50%);
// background: linear-gradient(to right,
${colorDefault} 50%,
${colorAlt} 50%);
background: linear-gradient(to right, red 50%, blue 50%);
`;
}
};
*/
const StyledText = styled.span`
padding: 1rem;
@ -61,77 +44,104 @@ const StyledText = styled.span`
const StyledDiv = styled.div`
display: inline-block;
background-color: ${colors.brandInactive};
animation: ${slide} 0.5s forwards;
${baseBox()}
`;
const inputStyled = css`
background-size: 200% 100%;
transition:all .5s ease;
min-width: ${remcalc(120)};
text-align: center;
`;
const StyledInput_1 = styled.input`
const StyledInput0 = styled.input`
display: none;
& + span {
background: #ff3232;
background: linear-gradient(to right, red 50%, blue 50%);
background-size: 200% 100%;
background-position:left bottom;
transition:all .5s ease;
background: linear-gradient(to right,
transparent 50%,
${colors.brandSecondary} 50%);
background-position: left bottom;
${inputStyled}
}
&:checked {
& + span {
background-position: right bottom;
}
}
`;
const StyledInput_2 = styled.input`
const StyledInput1 = styled.input`
display: none;
& + span {
background: #ff3232;
background: linear-gradient(to right, blue 50%, red 50%);
background-size: 200% 100%;
background-position:right bottom;
transition:all .5s ease;
& + span {
background: linear-gradient(to right,
${colors.brandSecondary} 50%,
transparent 50%);
background-position: right bottom;
${inputStyled}
}
&:checked {
& + span {
background-position: left bottom;
}
}
`;
const StyledLabel = styled.label`
`;
const Toggle = ({
checked,
className,
defaultChecked,
options = [
"On",
"Off"
{
label: 'On',
checked: true
},
{
label: 'Off',
checked: false
}
],
id = rndId(),
style
}) => {
return (
<StyledDiv>
<StyledLabel>
<StyledInput_1 defaultChecked name="toggler" type="radio" value={options[0]} index={1} />
<StyledText>{options[0]}</StyledText>
</StyledLabel>
<StyledLabel>
<StyledInput_2 name="toggler" type="radio" value={options[1]} index={2} />
<StyledText>{options[1]}</StyledText>
</StyledLabel>
{options.map( (option, index) => {
if ( index > 2 ) return;
const customProps = {
defaultChecked: option.checked,
name: 'toggler',
type: 'radio',
value: option.label,
id: rndId()
};
const InputVarients = {
input_0: (<StyledInput0 {...customProps} />),
input_1: (<StyledInput1 {...customProps} />)
};
return (
<label
htmlFor={customProps.id}
key={index}
>
{InputVarients[`input_${index}`]}
<StyledText>{option.label}</StyledText>
</label>
);
})}
</StyledDiv>
);
};
@ -141,6 +151,7 @@ Toggle.propTypes = {
className: React.PropTypes.string,
defaultChecked: React.PropTypes.bool,
id: React.PropTypes.string,
options: React.PropTypes.array,
style: React.PropTypes.object
};

View File

@ -339,16 +339,20 @@ storiesOf('Toggle', module)
.add('checked', () => (
<Toggle
defaultChecked
labelLeft='Topology'
labelRight='List'
options={[
{
label: 'Topology',
checked: true
},
{
label: 'List',
checked: false
}
]}
/>
))
.add('no props', () => (
<Toggle
checked
labelLeft='Topology'
labelRight='List'
/>
<Toggle />
));
storiesOf('Tooltip', module)