Когда дело доходит до Gatsby, есть несколько уникальных приемов, о которых вам следует знать, чтобы успешно создать темный режим для вашего приложения.
В этом посте мы пройдем всю реализацию от начала до конца.
Предпосылки
- Установлен Gatsby CLI
Начиная
Добавьте простую команду ниже, чтобы создать новый сайт.
npm init gatsby
💡 Примечание. Продолжайте следовать инструкциям, чтобы выбрать нужный язык (JavaScript или TypeScript), CMS, инструменты для оформления и другие функции.
Когда все будет загружено, вы получите уведомление с инструкциями о том, как перейти на ваш сайт и выполнить его локально.
// Start by going to the directory with
cd my-gatsby-site
// Start the local development server with
npm run develop
💡 Примечание. Перейдите на localhost: 8000, и вы должны увидеть, что ваше приложение работает. Отредактируйте домашнюю страницу в src/pages/index.js, сохраните ее и перезагрузите страницу, чтобы увидеть изменения в браузере.
Часть 1: Добавление переменных CSS
Цель состоит в том, чтобы использовать переменные CSS и хук UseState в React. Любой альтернативный менеджер состояния также будет работать, но для простоты мы просто воспользуемся стандартным хуком UseState.
Мы начнем создавать CSS для темного режима.
/* 1 */
:root {
--color-primary: #CD104D;
--color-text: #2e353f;
--color-text-light: #4f5969;
--color-heading: #1a202c;
--color-heading-black: #000000;
--color-accent: #d1dce5;
--color-background: #FFFFFF;
--dark-mode: #000;
--dark-mode-hf: #CD104D;
}
/* 2 */
body {
color: var(--color-text);
background-color: var(--color-background);
}
💡 Примечание. Добавляя эти переменные к элементу
body
, они становятся доступными для всех наших компонентов и классов по всему миру.
Далее мы добавим значения к переменным темного и светлого режима. Мы достигнем этого, определив класс.
/* 3 */
body.dark {
--color-background: #171717;
--color-primary: #CD104D;
--color-text: #ffffff;
--color-text-light: #4f5969;
--color-heading: #DFDFDE;
--color-heading-black: #EDEDED;
--color-accent: #d1dce5;
--image: url("./images/sun.svg");
}
/* 4 */
body.light {
--color-primary: #CD104D;
--color-text: #2e353f;
--color-text-light: #4f5969;
--color-heading: #1a202c;
--color-heading-black: black;
--color-accent: #d1dce5;
--color-background: #FFFFFF;
--image: url("./images/moon.svg");
}
💡 Примечание. Теперь мы определили темы для светлого и темного режимов.
Часть 2. Добавление кнопки переключения между темной и светлой темами
У нас будет компонент переключатель, который появляется на всех наших страницах, поэтому кажется разумным иметь там кнопку переключения.
Вот как выглядит компонент toggle:
import React from "react"
import "../style.scss"
import Sun from "../images/sun.svg"
import Moon from "../images/moon.svg"
export default function DarkMode() {
const [isDark, setIsDark] = React.useState(false)
React.useEffect(() => {
if (isDark) {
document.body.classList.add('dark');
} else {
document.body.classList.remove('dark');
}
}, [isDark])
return (
<div className="global-toggle-switch">
<span>
{isDark ? (<img onClick={() => setIsDark(!isDark)} src={Sun} alt="sun img" />) : (<img onClick={() => setIsDark(!isDark)} src={Moon} alt="moon img" />)}
</span>
</div>
)
}
💡 Примечание. Эти значки функционируют как кнопки, и при выборе они либо добавляют, либо удаляют класс
.dark
из тела, изменяя тему приложения.
Часть 3. Сохранение темы по умолчанию в локальном хранилище
Теперь нам также нужно сохранить предпочтительный режим в локальном хранилище, чтобы он оставался даже при сбросе страницы или приложения. Для этого я создаю глобальную служебную функцию с именем getDefaultTheme:
/* 5 */
function getDefaultTheme() {
const savedTheme = window.localStorage.getItem('theme');
return savedTheme ? savedTheme : 'light';
}
💡 Примечание. Теперь этот метод должен вызываться в хуке useState, созданном в моем компоненте DarkMode.
/* 6 */
const [isDark, setIsDark] = React.useState(getDefaultTheme())
Для этого я возвращаюсь к хуку useEffect и вставляю следующий код:
/* 7 */
React.useEffect(() => {
if (isDark === 'dark') {
document.body.classList.add('dark');
} else {
document.body.classList.remove('dark');
}
window.localStorage.setItem('theme', isDark);
}, [isDark])
Если вы следовали инструкциям, ваш готовый код должен выглядеть так:
import React from "react"
import "../style.scss"
import Sun from "../images/sun.svg"
import Moon from "../images/moon.svg"
function getDefaultTheme() {
const savedTheme = window.localStorage.getItem("theme")
return savedTheme ? savedTheme : "light"
}
export default function DarkMode() {
const [isDark, setIsDark] = React.useState(getDefaultTheme())
React.useEffect(() => {
if (isDark === "dark") {
document.body.classList.add("dark")
} else {
document.body.classList.remove("dark")
}
window.localStorage.setItem("theme", isDark)
}, [isDark])
return (
<div className="global-toggle-switch">
<span onClick={() => setIsDark(isDark === "dark" ? "light" : "dark")}>
{isDark === "dark" ? (
<img src={Sun} alt="sun img" />
) : (
<img src={Moon} alt="moon img" />
)}
</span>
</div>
)
}