I'm such a fool.
I'd like to change the design of the check box with React.
The new design is Checkbox.js
.I designed it in js.
I want to turn this on/off, but it never works.
I want to use clip-path, but when I use it, the checkbox doesn't work at all.
I really want to know the answer. Because of this, I spent 8 hours.
Please teach me the way. Please.
ListPage.js
import React, { useState } from 'react';
import styled from 'styled-components';
import Checkbox from '../Checkbox/Checkbox';
import { MdKeyboardArrowDown } from 'react-icons/md';
function KeywordButton() {
const [isChecked, setIsChecked] = useState(false);
const changeOption = e => {
setIsChecked(e.target.isChecked);
};
return (
<React.Fragment>
<CheckBoxWrap>
<WrapBox>
<BoxAndTextWrap>
<CheckboxShell>
<Checkbox onChange={changeOption} isChecked={isChecked} />
</CheckboxShell>
<TextBoxWrap> exercise </TextBoxWrap>
</BoxAndTextWrap>
</WrapBox>
</CheckBoxWrap>
</LeftModalWrap>
</React.Fragment>
);
}
Checkbox.js
import React, { useState } from 'react';
import styled from 'styled-components';
function Checkbox({ isChecked, ...props }) {
return (
<LabelLabal>
<A>
<B type="checkbox" isChecked={isChecked} {...props} />
<C>
<D>
<Icon viewBox="0 0 24 24">
<polyline points="20 6 9 17 4 12" />
</Icon>
</D>
</C>
</A>
</LabelLabal>
);
}
const LabelLabal = styled.label`
cursor: pointer;
`;
const Icon = styled.svg`
fill: none;
stroke: white;
stroke-width: 2px;
display: block;
height: 16px;
width: 16px;
stroke-width: 4;
overflow: visible;
cursor: pointer;
`;
const A = styled.span`
position: relative;
display: inline-block;
cursor: pointer;
padding: 0px;
`;
const B = styled.input`
position: absolute;
opacity: 0;
cursor: pointer;
`;
const C = styled.span`
display: inline-block;
border-width: 1px;
border-style: solid;
height: 24px;
width: 24px;
text-align: center;
overflow: hidden;
vertical-align: top;
border-radius: 4px;
border: ${props => (props.checked ? 'none' : 'solid 0.1rem #dddddd')};
background: ${props => (props.checked ? 'black' : 'black')};
color: rgb(255, 255, 255);
cursor: pointer;
${Icon} {
visibility: ${props => (props.checked ? 'hidden' : 'visible')};
}
`;
const D = styled.span`
-webkit-box-pack: center;
-webkit-box-align: center;
display: block;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
margin-top: 2px;
margin-left: 3px;
color: rgb(255, 255, 255);
cursor: pointer;
`;
export default Checkbox;
You don't have to pay attention to the tag name. I was so tired that I couldn't care about name.
I really want to fix this!!
CodePudding user response:
The code is using an input checkbox and a svg on top of that. So even though your checkbox is getting toggled, the svg is not changing based on the toggle state.
Also since <B type="checkbox" isChecked={isChecked} {...props} />
is an input checkbox component, and you're controlling the component value, you need to use a checked
property. I think isChecked
is mistyped.
So if you update isChecked
to checked
and pass the checked
value to the svg to dynamically update the CSS, it will work properly.
Here's a working code sandbox.
Updated CheckBox.js
import React, { useState } from 'react';
import styled from 'styled-components';
function Checkbox({ isChecked, ...props }) {
return (
<LabelLabal>
<A>
<B type="checkbox" checked={isChecked} {...props} />
<C>
<D>
<Icon checked={isChecked} viewBox="0 0 24 24">
<polyline points="20 6 9 17 4 12" />
</Icon>
</D>
</C>
</A>
</LabelLabal>
);
}
const Icon = styled.svg`
fill: none;
stroke: ${(props) => (props.checked ? "white" : "none")};
stroke-width: 2px;
display: block;
height: 16px;
width: 16px;
stroke-width: 4;
overflow: visible;
cursor: pointer;
`;
// rest of the styling