I am currently working on styling this component using Styled Components, but I feel like my current approach is a bit of a hack. What would be the best practice for incorporating Styled Components to style this component effectively?
If I were to use Plain HTML and CSS, the structure would look something like this:
HTML:
<label>
<input type="checkbox" value="s1"/>
<div class="container">s1</div>
</label>
<label>
<input type="checkbox" value="s2"/>
<div class="container">s2</div>
</label>
<label>
<input type="checkbox" value="s3"/>
<div class="container">s3</div>
</label>
<label>
<input type="checkbox" value="s4"/>
<div class="container">s4</div>
</label>
CSS:
input[type=checkbox] {
position: absolute;
width: 0;
}
.container {
width: 5em;
border: solid #aaa 1px;
background: #fff
color: #000;
}
.container:hover {
background: #999;
}
.container:active {
background: #333;
color:#fff
}
input[type=checkbox]:checked + .container {
background: #000;
color: #fff;
}
input[type=checkbox]:checked + .container:hover {
background: #ddd;
}
input[type=checkbox]:checked + .container:hover:active {
background: white;
color: black;
}
When using a React component with Styled Components, the process can be achieved, however, I find it cumbersome to use two different Styled Components along with a ternary operator compared to achieving the same result directly in CSS using
input[type=checkbox]:checked + .container
.
import React, { useState } from 'react';
import styled from 'styled-components'
function Test() {
const [selectedStations, setSelectedStations] = useState([]);
const Input = styled.input`
position: absolute;
width: 0;
`
const UncheckedContainer = styled.div`
width: 5em;
border: solid #aaa 1px;
background: #fff;
color: #000;
&:hover {
background: #999;
}
&:active {
background: #333;
color: #fff;
}
`
const CheckedContainer = styled.div`
width: 5em;
border: solid black 1px;
background: #000;
color: #fff;
&:hover {
background: #ddd;
}
&:active {
background: #fff;
color: #000;
}
`
function selectStations(e) {
let station = e.target.value;
const s = [...selectedStations]
const stationIndex = s.indexOf(station)
if (stationIndex > -1) {
s.splice(stationIndex, 1);
} else {
s.push(station);
s.sort();
}
setSelectedStations(s)
};
return (
<div>
{new Array(4).fill('').map((v, i) =>{
let checked = selectedStations.indexOf(`s${i+1}`) > -1
return(
<label key={`station${i + 1}`}>
<Input
type="checkbox"
value={`s${i+1}`}
checked={checked}
onChange={(e)=>selectStations(e)}
/>;
{checked ?
<CheckedContainer>
{`s${i+1}`}
</CheckedContainer>;
:
<UncheckedContainer>
{`Station ${i+1}`}
</UncheckedContainer>;
}
</label>;
)}
)}
</div>;
)
}
export default Test;
Is there a way to simplify this code while still utilizing Styled Components?