@mytbin

Нормальная ToogleButton на React. Как?

Здравствуйте. Подскажите пожалуйста как решить следующую проблему.
Если пишем stateless кнопку со свойством pressed, то её невозможно использовать независимо ибо кто-то должен передать ей это свойство.
Если пишем statefull кнопку с состоянием pressed, то это состояние невозможно изменить извне.
Как не крути, а получается какое-то УГ с крайне сомнительными перспективами повторного использования.
  • Вопрос задан
  • 146 просмотров
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Можно использовать нативный скрытый checkbox. Использовать его можно будет как контролируемый, так и как самостоятельный элемент. Слушать onChange или использовать ref. Стилизовать его можно под что угодно. Чтобы работало, надо обязательно использовать элемент label.
Думаю, это самый универсальный и оптимальный вариант для этой задачи.
Пример с использованием StyledComponents:
spoiler
import * as React from 'react';
import styled from 'styled-components';


const Wrapper = styled.label`
  position: relative;
  display: inline-block;
  width: 40px;
  height: 24px;
`;

const Input: any = styled.input`
  display: none;
`;

const Slider = styled.div`
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .2s;
  border-radius: 34px;
  
  &:before {
    position: absolute;
    content: "";
    height: 22px;
    width: 22px;
    left: 1px;
    bottom: 1px;
    background-color: white;
    transition: .2s;
    border-radius: 50%;
  }
  
  ${Input}:checked + & {
    background-color: ${props => props.theme.someColor1};
  }
  
  ${Input}:focus + & {
    box-shadow: 0 0 1px ${props => props.theme.someColor2};
  }
  
  ${Input}:checked + &:before {
    transform: translateX(16px);
  }
`;

interface Props = {
  name?: string
  checked?: boolean
  onChange?: Function
  innerRef?: Function
  className?: string
}

const ToggleSwitch = ({ innerRef, checked, onChange, className, name }: Props) => {
  return (
    <Wrapper className={className}>
      <Input 
        innerRef={innerRef}
        checked={checked}
        onChange={onChange}
        name={name}
        type="checkbox"
      />
      <Slider />
    </Wrapper>
  );
}

Ни одно свойство не является обязательным.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы