Реализация темного / светлого режима в приложениях с помощью React
Как следует из названия, этот блог посвящен реализации темного / светлого режима в приложениях, использующих React. Я считаю, что вы уже знаете о светлых и темных темах в приложениях.
Светлый режим: относится к темному шрифту на светлом фоне (положительная контрастная полярность).
Темный режим: обозначает сочетание светлого (например, белого) текста на темном (например, черном) фоне (отрицательная контрастная полярность).
Эти две темы имеют некоторые преимущества и могут быть настроены как на мобильном устройстве, так и на компьютере. Мы можем изменить этот темный / светлый режим с Setting-> Display-> THEME
на большинстве устройств. Или мы также можем добавить функцию переключения на веб-сайтах, чтобы явно переключаться между светлой и темной темами.
Почему это важно? Что ж, есть несколько моментов, которые делают веб-сайт лучше, когда у него есть тема темного режима:
- Он улучшает видимость для пользователей с плохим зрением и тех, кто чувствителен к яркому свету.
- Облегчает использование устройства в условиях низкой освещенности.
Если говорить о части реализации, я использовал window.matchMedia
для проверки темы prefers-color-scheme
.
// EventListener when mode/theme is changed window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { if (event.matches) { // set mode state to Dark here } else { // set mode state to Light here } });
Этот код выше является слушателем, который проверяет, есть ли изменение в событии (prefers-color-scheme: dark)
. Итак, если системная тема темная, тогда if
условие истинно, и мы можем переключить состояние режима на Dark
здесь, иначе в операторе else, где мы можем переключить состояние в режим Light
.
Я использовал это же событие window.matchMedia('(prefers-color-scheme: dark)')
, чтобы установить состояние темы по умолчанию в моем приложении следующим образом:
// To set default value when page is refreshed let defaultMode = 'light'; if (window.matchMedia('(prefers-color-scheme: dark)').matches) { defaultMode = 'dark'; }
Таким образом, если системный параметр уже установлен как Dark, тогда условие if (window.matchMedia('(prefers-color-scheme: dark)').matches)
оценивается как истинное, а для приложения defaultMode устанавливается значение dark.
Давайте реализуем пример, показанный ниже, в котором, если настройка изменяется с системы со светлого на темный, цвет фона должен измениться на черный с белого, а цвет текста изменится с черного на белый в случае изменения темы от светлой к темной.
Светлая тема (изображение слева): Цвет фона: белый, Цвет текста: черный.
Темная тема (изображение справа): Цвет фона: Черный, Цвет текста: Белый.
Начните с добавления контекста в приложение.
Здесь у контекста есть две клавиши mode (значение темы: темный / светлый) и toggle ( функция для переключения режима ).
Затем мы можем создать хук useDarkmode
, который поддерживает состояние mode, а также устанавливает стиль тела. Затем мы будем использовать эту функцию в нашем провайдере, как указано ниже.
В этом файле мы добавляем поставщика, который использует useDarkmode
и darkModeContext
Теперь у нас есть код, поддерживающий темный / светлый режим, нам просто нужно использовать этот приведенный выше код в нашем приложении, чтобы он работал в нашем приложении.
Чтобы реализовать эту функциональность, оберните свое приложение внутри провайдера, как этот (Файл приложения):
import React from 'react'; import { object } from 'prop-types'; import DarkProvider from './darkModeProvider'; import MainComponent from './mainComponent'; function App({ history, client }) { return ( <DarkProvider> <MainComponent /> </DarkProvider> ); } App.propTypes = { client: object.isRequired, history: object.isRequired, }; export default App;
Если ваш MainComponent
выглядит примерно так (файл mainComponent.js)
import React from 'react'; import { useDarkmodeContext } from './darkModeProvider'; import { setThemeMode } from './styles'; const MainComponent = () => { const { mode } = useDarkmodeContext(); const themeMode = mode || 'light'; const css = setThemeMode(themeMode); return ( <div className={css.container}> <div> <div className={css.emptySearchHeading}> {themeMode?.toUpperCase()} THEME </div> <div className={css.emptySearchText}> Demo... </div> </div> </div> ); }; export default MainComponent;
В приведенном выше файле useDarkmodeContext
получает состояние режима независимо от того, светлый он или темный. Из этого состояния мы можем затем установить нашу тему в файле styles.js. Как указано ниже (файл styles.js):
import { css } from 'react-emotion'; import { Theme } from './colors'; // set colors dynamically based on the mode from Theme // color: ${Theme[mode].blackNewRgba}; export const setThemeMode = mode => { return { container: css` display: flex; padding: 16px; justify-content: center; background: ${Theme[mode].containerColor}; `, emptySearchHeading: css` font-size: 16px; color: ${Theme[mode].headingColor}; text-align: center; font-weight: bold; `, emptySearchText: css` font-size: 12px; color: ${Theme[mode].textColor}; text-align: center; `, }; };
Объект Theme содержит все варианты цвета для светлого и темного режимов. Мы можем проверить этот объектный код ниже (./colors.js).
// Base color export const headingColor = 'rgba(49, 53, 59, 0.96)'; export const textColor = `rgba(49, 53, 59, 0.68)`; export const containerColor = '#ffffff'; const lightTheme = { headingColor, textColor, containerColor, }; const darkTheme = { headingColor: '#ffffff', textColor : '#ffffff', containerColor: '#000', }; export const Theme = { light: lightTheme, dark: darkTheme, };
Итак, из этого файла мы экспортируем объект Тема, например:
export const Theme = { light: lightTheme, dark: darkTheme, };
Вывод
Я надеюсь, что это поможет. Возможно, мы сможем устанавливать темы, используя другой подход, например, используя библиотеки управления состоянием или используя только css. Пожалуйста, поделитесь со мной своей реализацией :).