Having the following html/css code that enables html elements to behave like a radio group:
.radios .radio{
background-color:#c5e043;
display:inline-block;
width:20px;
height:20px;
cursor:pointer
}
.radios input[type=radio]{
display:none
}
.radios input[type=radio]:checked + .radio{
background-color:#241009
}
<div class="radios">
<div>
<input type="radio" name="rGroup" id="r1" />
<label class="radio" for="r1"></label>
<input type="radio" name="rGroup" id="r2" />
<label class="radio" for="r2"></label>
<input type="radio" name="rGroup" id="r3" />
<label class="radio" for="r3"></label></div>
</div>
I want to write in React some Styled components that behave in the same way but don't know how to write in styled components input[type=radio]
and .radios input[type=radio]:checked + .radio
.
Here is the code, a code sandbox here. It shows the elements but click isn't working, it doesn't change the selected element like in the above code.
What should be changed?
import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
export const XSelectionBoxContainer = styled.div`
background-color: #c5e043;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
`;
export const Xlabel = styled.label`
background-color: #c5e043;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
`;
export const Xinput = styled.input`
display: none;
:checked {
background-color: #241009;
}
`;
function App() {
const options = [
{
label: "first",
value: "first",
name: "radio-group"
},
{
label: "second",
value: "second",
name: "radio-group"
},
{
label: "third",
value: "third",
name: "radio-group"
}
];
return (
<XSelectionBoxContainer>
{options.map((option) => {
return (
<div key={option.label}>
<Xlabel htmlFor={option.value}></Xlabel>
<Xinput
type="radio"
name={option.value}
value="1"
id={option.value}
/>
</div>
);
})}
</XSelectionBoxContainer>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You need to place the label
component below the input
element so that you can use the +
operator in css to style the label element if the input
is :checked
.
Updated code below:
import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
export const XSelectionBoxContainer = styled.div`
background-color: #c5e043;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
`;
export const Xlabel = styled.label`
background-color: #c5e043;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
`;
export const Xinput = styled.input`
display: none;
&:checked {
& + label {
background-color: #241009;
}
}
`;
function App() {
const options = [
{
label: "first",
value: "first",
name: "radio-group"
},
{
label: "second",
value: "second",
name: "radio-group"
},
{
label: "third",
value: "third",
name: "radio-group"
}
];
return (
<XSelectionBoxContainer>
{options.map((option) => {
return (
<div key={option.label}>
<Xinput
type="radio"
name={option.name}
value="1"
id={option.value}
/>
<Xlabel htmlFor={option.value}></Xlabel>
</div>
);
})}
</XSelectionBoxContainer>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);