Можно ли стилизовать дочерний элемент флажка на основе состояния флажка без использования троичного в Styled Components? - PullRequest
0 голосов
/ 01 апреля 2019

Я пытаюсь стилизовать этот компонент с помощью 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;

Можно очиститьэто немного, но все еще использовать Styled Components?

Ответы [ 2 ]

0 голосов
/ 01 апреля 2019

Вы можете получить доступ к реквизитам внутри styled-component, а также использовать sass, например, вложенность для целевых детей.

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>
  ))
}

Еще одна вещь, которой я бы настоятельно хотел избежать, - это создание стилизованных компонентов внутри другого компонента.

0 голосов
/ 01 апреля 2019

Можно установить состояние флажка в переменной и передать его в стилизованный компонент, например:

<StyledComponent isChecked={isChecked} />

Затем в стилизованном компоненте:

const StyledComponent = styled.input`

 color: ${props => props.isChecked ? '#fff' : '#000'};

`

.. ии так далее для цвета фона и границы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...