Skip to content
This repository has been archived by the owner on Apr 7, 2020. It is now read-only.

Commit

Permalink
refactor(Checkbox)
Browse files Browse the repository at this point in the history
-add checkMark and indeterminateMark props so users can pass in their own icons
- refactor to eliminate unnecessary wrapper di
- remove default export
  • Loading branch information
petegivens authored and brad-decker committed Mar 15, 2018
1 parent 898b709 commit 2bd044d
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 73 deletions.
58 changes: 53 additions & 5 deletions pages/checkboxes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { PureComponent } from 'react';
import styled from 'styled-components';
import { ThemeProvider, Checkbox, Box, CheckMark, List, ListItem, defaultTheme } from '../src';

const StyledCheckbox = Checkbox.extend`
Expand All @@ -11,14 +12,44 @@ const StyledCheckbox = Checkbox.extend`
stroke-width: 5px;
}
`;

const Square = styled.div`
background-color: ${props => props.theme.primary};
height: 8px;
width: 8px;
`;

const StyledCheckbox2 = Checkbox.extend`
:hover::before {
opacity: 0;
}
${Box} {
${props =>
props.checked &&
`
border: solid 3px ${props.theme.primary};
background-color: transparent;
`};
}
`;

class CheckboxesPage extends PureComponent {
state = {
checked: true,
checked: {
1: true,
2: false,
},
};

handleChange = () => {
const checked = !this.state.checked;
this.setState({ checked });
handleChange = (n) => {
const checked = !this.state.checked[n];
this.setState({
checked: {
...this.state.checked,
[n]: checked,
},
});
};

render() {
Expand Down Expand Up @@ -48,7 +79,13 @@ class CheckboxesPage extends PureComponent {
<label htmlFor="checkbox5">Checked and Disabled</label>
</ListItem>
<ListItem>
<Checkbox checked={checked} onChange={this.handleChange} id="checkbox6" />
<Checkbox
checked={checked[1]}
onChange={() => {
this.handleChange(1);
}}
id="checkbox6"
/>
<label htmlFor="checkbox6">Controlled Checkbox</label>
</ListItem>
<ListItem>
Expand All @@ -59,6 +96,17 @@ class CheckboxesPage extends PureComponent {
<StyledCheckbox id="checkbox8" />
<label htmlFor="checkbox8">Custom Checkbox</label>
</ListItem>
<ListItem>
<StyledCheckbox2
checked={checked[2]}
onChange={() => {
this.handleChange(2);
}}
id="checkbox9"
checkMark={Square}
/>
<label htmlFor="checkbox9">Custom Checkbox</label>
</ListItem>
</List>
</ThemeProvider>
);
Expand Down
138 changes: 71 additions & 67 deletions src/components/Checkbox.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,65 @@
import React, { PureComponent } from 'react';
import styled from 'styled-components';

class Checkbox extends PureComponent {
const Box = styled.div`
transition: 0.3s;
display: inline-flex;
position: absolute;
left: 11px;
top: 11px;
bottom: 11px;
right: 11px;
border: solid 2px
${(props) => {
if (props.checked || props.indeterminate) return 'transparent';
else if (props.disabled) return props.theme.disabledCheckbox;
return props.theme.textColors.secondary;
}};
border-radius: 2px;
background-color: ${(props) => {
if (props.checked || props.indeterminate) {
if (props.disabled) return props.theme.disabledCheckbox;
else if (props.primary) return props.theme.primary;
return props.theme.accent;
}
}};
align-items: center;
justify-content: center;
`;

const Input = styled.input.attrs({
type: 'checkbox',
disabled: props => props.disabled,
})`
position: absolute;
opacity: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
cursor: inherit;
margin: 0;
`;

const CheckMark = styled.svg.attrs({
viewBox: '0 0 24 24',
children: <path d="M1.73,12.91 8.1,19.28 22.79,4.59" />,
})`
fill: none;
stroke: ${props => props.theme.white};
width: 100%;
height: 100%;
stroke-width: 3.12px;
`;

const IndeterminateMark = styled.div`
transition: 0.3s;
height: 2px;
width: 14px;
background-color: ${props => props.theme.white};
`;

class CheckboxComponent extends PureComponent {
state = {
checked: this.props.checked || this.props.default === 'checked' || false,
indeterminate: this.props.default === 'indeterminate' || false,
Expand All @@ -21,21 +79,26 @@ class Checkbox extends PureComponent {
primary,
disabled,
checked: checkedProp,
checkMark: checkMarkProp,
className,
indeterminate: indeterminateProp,
indeterminateMark: indeterminateMarkProp,
value,
id,
className,
} = this.props;
// determine if checkbox is controlled or uncontrolled
const checked = checkedProp !== undefined ? checkedProp : this.state.checked;
const indeterminate =
indeterminateProp !== undefined ? indeterminateProp : this.state.indeterminate;
// check for CheckMark or IndeterminateMark icons passed as props
const CheckMarkComponent = checkMarkProp || CheckMark;
const IndeterminateMarkComponent = indeterminateMarkProp || IndeterminateMark;

return (
<Wrapper className={className} primary={primary} disabled={disabled} checked={checked}>
<div className={className}>
<Box primary={primary} checked={checked} disabled={disabled} indeterminate={indeterminate}>
{indeterminate && <IndeterminateMark />}
{checked && !indeterminate && <CheckMark />}
{indeterminate && <IndeterminateMarkComponent />}
{checked && !indeterminate && <CheckMarkComponent />}
</Box>
<Input
onChange={this.handleInputChange}
Expand All @@ -44,12 +107,12 @@ class Checkbox extends PureComponent {
value={value}
id={id}
/>
</Wrapper>
</div>
);
}
}

const Wrapper = styled.div`
const Checkbox = styled(CheckboxComponent)`
display: inline-block;
position: relative;
padding: 11px;
Expand Down Expand Up @@ -79,63 +142,4 @@ const Wrapper = styled.div`
}
`;

const Box = styled.div`
transition: 0.3s;
display: inline-flex;
position: absolute;
left: 11px;
top: 11px;
bottom: 11px;
right: 11px;
border: solid 2px
${(props) => {
if (props.checked || props.indeterminate) return 'transparent';
else if (props.disabled) return props.theme.disabledCheckbox;
return props.theme.textColors.secondary;
}};
border-radius: 2px;
background-color: ${(props) => {
if (props.checked || props.indeterminate) {
if (props.disabled) return props.theme.disabledCheckbox;
else if (props.primary) return props.theme.primary;
return props.theme.accent;
}
}};
align-items: center;
justify-content: center;
`;

const Input = styled.input.attrs({
type: 'checkbox',
disabled: props => props.disabled,
}) `
position: absolute;
opacity: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
cursor: inherit;
margin: 0;
`;

const CheckMark = styled.svg.attrs({
viewBox: '0 0 24 24',
children: <path d="M1.73,12.91 8.1,19.28 22.79,4.59" />,
}) `
fill: none;
stroke: ${props => props.theme.white};
width: 100%;
height: 100%;
stroke-width: 3.12px;
`;

const IndeterminateMark = styled.div`
transition: 0.3s;
height: 2px;
width: 14px;
background-color: ${props => props.theme.white};
`;

export default styled(Checkbox) ``;
export { Wrapper, Box, CheckMark, IndeterminateMark };
export { Checkbox, Box, CheckMark, IndeterminateMark };
1 change: 0 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export * from './components/Tabs';
export { Avatar } from './components/Avatar';
export { default as BottomSheet } from './components/BottomSheet';
export { default as Button } from './components/Button';
export { default as Checkbox } from './components/Checkbox';
export * from './components/Checkbox';
export * from './components/Chip';
export * from './components/Circular';
Expand Down

0 comments on commit 2bd044d

Please sign in to comment.