是否可以根据复选框的状态为复选框的子项设置样式,而无需在样式化组件中使用三元?
Is it possible to style a checkbox's child based on the checkbox's state without using ternary in Styled Components?
我正在尝试使用 Styled Components 来设置此组件的样式,但我的解决方案似乎很老套。使用 Styled Components 设置此组件样式的最佳做法是什么?
使用普通 HTML 和 CSS,我可以创建这个:
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;
}
使用 React 组件和 Styled Components,我也可以创建它,但我不喜欢使用两个不同的 Styled Components 和三元组来完成我在 CSS 中使用 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;
是否可以稍微清理一下但仍然使用样式化组件?
您可以将复选框的状态保存在一个变量中,并将其传递给样式化的组件,例如:
<StyledComponent isChecked={isChecked} />
然后在样式组件中:
const StyledComponent = styled.input`
color: ${props => props.isChecked ? '#fff' : '#000'};
`
.. 背景颜色和边框依此类推。
您可以在 styled-component
中访问道具,也可以像嵌套一样使用 sass 来定位 children。
const Checkbox = styled.label`
postion: relative;
input[type="checkbox"] {
// style here
}
.inner-checkbox {
color: ${props => props.checked ? "red" : "blue"};
// style here
}
`
const List = props => {
return props.list.map(item => (
<Checkbox key={item.id} checked={item.checked}>
<input checked={item.checked} type="checkbox" onChange={this.updateState} />
<div className="inner-checkbox" />
</Checkbox>
))
}
我极力避免的另一件事是在另一个组件中创建样式组件。
我正在尝试使用 Styled Components 来设置此组件的样式,但我的解决方案似乎很老套。使用 Styled Components 设置此组件样式的最佳做法是什么?
使用普通 HTML 和 CSS,我可以创建这个:
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;
}
使用 React 组件和 Styled Components,我也可以创建它,但我不喜欢使用两个不同的 Styled Components 和三元组来完成我在 CSS 中使用 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;
是否可以稍微清理一下但仍然使用样式化组件?
您可以将复选框的状态保存在一个变量中,并将其传递给样式化的组件,例如:
<StyledComponent isChecked={isChecked} />
然后在样式组件中:
const StyledComponent = styled.input`
color: ${props => props.isChecked ? '#fff' : '#000'};
`
.. 背景颜色和边框依此类推。
您可以在 styled-component
中访问道具,也可以像嵌套一样使用 sass 来定位 children。
const Checkbox = styled.label`
postion: relative;
input[type="checkbox"] {
// style here
}
.inner-checkbox {
color: ${props => props.checked ? "red" : "blue"};
// style here
}
`
const List = props => {
return props.list.map(item => (
<Checkbox key={item.id} checked={item.checked}>
<input checked={item.checked} type="checkbox" onChange={this.updateState} />
<div className="inner-checkbox" />
</Checkbox>
))
}
我极力避免的另一件事是在另一个组件中创建样式组件。