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

View File

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