I'm trying to style this component with Styled Components, but my solution seems hackish. What is the best practice for styling this component with Styled Components?
Using Plain HTML and CSS, and I can create 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;
}
Using a React component and Styled Components, I can also create it, but I don't like using two different Styled Components and the ternary to accomplish what I could 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 is possible to clean this up a little but still use Styled Components?