В наши дни каждому нужна функция темного режима в своем приложении. Почему? Ну, люди любят использовать то, что не вредит их глазам и может быть использовано незаметно (Да, я смотрю на вас, ночные совы).
Теперь возникает вопрос, почему бы не сделать его темным с самого начала?
Ответ заключается в том, что есть люди, которым неудобно пользоваться темным режимом, поэтому возникает проблема доступности.
Поэтому я работал над созданием трех разных приложений и решил, что мне следует сохранить переключатель темного режима.
Заголовок
Обычно тумблер размещается в заголовке. Поэтому мы создадим компонент React, который будет содержать кнопку для переключения тем.
Используя хуки React, useState и useEffect, мы создадим состояние и побочный эффект, который будет добавлять/удалять класс для темного режима.
function Header() {
const [ darkMode, setDarkMode ] = React.useState(false)
React.useEffect(() => {
const body = document.body
const toggle = document.querySelector('.toggle-inner')
// If dark mode is enabled - adds classes to update dark-mode styling.
// Else, removes and styling is as normal.
if( darkMode === true ) {
body.classList.add('dark-mode')
toggle.classList.add('toggle-active')
} else {
body.classList.remove('dark-mode')
toggle.classList.remove('toggle-active')
}
}, [darkMode])
return (
<header>
<div
id="toggle"
onClick={() => darkMode === false ? setDarkMode(true) : setDarkMode(false)}
>
<div className="toggle-inner"/>
</div>
</header>
)
}
Приложение
Чтобы создать немного контента для страницы, я добавил немного текста.
Мы импортируем компонент Header.
function App() {
return (
<main>
<Header />
<div id="container">
<h1>React Dark Mode</h1>
<p>Uses state to set a class on the body if dark mode is enabled.</p>
<p>Implementation is done due to a side effect</p>
</div>
</main>
)
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
CSS
После того как мы закончили с компонентами, нам нужно немного стилизовать их.
Базовая настройка — это просто удаление margin и padding, а также общей ширины и высоты элемента в качестве box-sizing.
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Затем мы продолжаем и задаем основной фон, высоту и ширину нашей страницы.
body {
color: #1a202c;
transition: color 0.2s ease-in;
}
#app {
height: 100vh;
width: 100%;
}
После этого нам нужно придать стиль основному разделу и заголовку.
Интересным дополнением является свойство transition. Оно обеспечивает плавное изменение цвета фона. И мы добавим position: absolute;
в заголовок, чтобы можно было накладывать его на другие элементы.
main {
background-color: #f7fafc;
height: 100%;
width: 100%;
padding: 20px;
transition: background-color 0.2s ease-in;
}
header {
position: absolute;
right: 2rem;
}
Затем стилизуем контейнер, содержащий небольшой текст, который мы написали. Ничего особенного, мы просто центрируем его по окну и применяем несколько цветовых вариаций к заголовкам и абзацам.
#container {
display: flex;
height: 100%;
width: 100%;
align-items: center;
justify-content: center;
flex-direction: column;
}
#container h1 {
padding: 0;
margin: 0 0 10px 0;
}
#container p {
opacity: 0.8;
}
После того, как мы закончим с этим, 60% будет готово. Осталось только реализовать стили для переключения и темного режима.
Давайте перейдем к переключению:
#toggle {
width: 50px;
display: flex;
padding: 5px;
background-color: #1a202c;
border-radius: 1000px;
cursor: pointer;
box-shadow: 0px 5px 20px -10px #000;
transition: background-color 0.2s ease-in;
}
#toggle .toggle-inner {
width: 20px;
height: 15px;
background-color: white;
border-radius: 1000px;
transition: margin-left 0.2s ease-in, background-color 0.2s ease-in;
}
#toggle .toggle-active {
margin-left: 20px;
}
Наконец, стилизация темного режима выполняется примерно так, как показано ниже. Мы просто изменим цвета фона и цвет текста. Вот и все
.dark-mode {
color: white;
}
.dark-mode main {
background-color: #1a202c;
}
.dark-mode #toggle {
background-color: white;
}
.dark-mode #toggle .toggle-inner {
background-color: #1a202c;
}
Вот и все. Это будет большим подспорьем для вашего следующего проекта, как и для меня. Теперь мне не нужно постоянно проверять разные ручки для одной и той же вещи xD.
Настраивайте его и получайте удовольствие!