Используйте настоящий input type='checkbox' внутри label и отдельный декоративный трек. Состояние checked управляет цветом фона и сдвигом круга на 26px.
React‑компонент стилизованного переключателя‑чекбокса
Используйте настоящий input type='checkbox' внутри label и отдельный декоративный трек. Состояние checked управляет цветом фона и сдвигом круга на 26px.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Создать в React UI‑элемент чекбокса, который меняет внешний вид при переключении между состояниями «включено» и «выключено». Для оформления использовать параметры, указанные в комментариях:
// Цвета: white, #4caf50, #ccc
// border-radius: 34px
// Круг: width: 26px; height: 26px;
// Переключатель: width: 60px; height: 34px;
Ответ
Используйте настоящий input type='checkbox' внутри label и отдельный декоративный трек. Состояние checked управляет цветом фона и сдвигом круга на 26px.
function Toggle() {
const [checked, setChecked] = React.useState(false);
return <label className="switch">
<input type="checkbox" aria-label="Включить настройку" checked={checked}
onChange={e => setChecked(e.target.checked)} />
<span className="track" aria-hidden="true" />
</label>;
}
.switch { position: relative; display: inline-block; width: 60px; height: 34px; }
.switch input { position: absolute; inset: 0; margin: 0; width: 100%; height: 100%; opacity: 0; z-index: 1; cursor: pointer; }
.track { position: absolute; inset: 0; border-radius: 34px; background: #ccc; transition: background .2s; }
.track::before { content: ''; position: absolute; left: 4px; top: 4px; width: 26px; height: 26px; border-radius: 50%; background: white; transition: transform .2s; }
.switch input:checked + .track { background: #4caf50; }
.switch input:checked + .track::before { transform: translateX(26px); }
.switch input:focus-visible + .track { outline: 2px solid #222; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .track, .track::before { transition: none; } }
Сохраняются переключение клавишей Space и видимый фокус, в отличие от декоративного div без семантики.