Механизм цветовых режимов — одна из ключевых возможностей библиотеки Chakra UI. Он позволяет реализовать переключение между светлой и тёмной темой интерфейса, автоматически применять соответствующие цвета компонентов и сохранять выбор пользователя.
Основой системы является хук useColorMode. Он
предоставляет доступ к текущему режиму и функциям управления им.
Хук импортируется из пакета Chakra UI:
import { useColorMode } from "@chakra-ui/react"
При вызове хука возвращается объект с несколькими свойствами:
const { colorMode, toggleColorMode, setColorMode } = useColorMode()
Основные элементы:
| Свойство | Назначение |
|---|---|
colorMode |
текущий режим (light или dark) |
toggleColorMode |
переключение между режимами |
setColorMode |
установка конкретного режима |
Пример простого переключателя темы:
import { Button, useColorMode } from "@chakra-ui/react"
function ThemeToggle() {
const { colorMode, toggleColorMode } = useColorMode()
return (
<Button onCl ick={toggleColorMode}>
Текущий режим: {colorMode}
</Button>
)
}
При нажатии кнопки происходит переключение между светлой и тёмной темой.
Система цветовых режимов Chakra UI построена вокруг нескольких механизмов:
1. Контекст React
Информация о режиме хранится в контексте, который создаётся внутри
ChakraProvider.
2. CSS-переменные
Большинство цветов библиотеки представлены через CSS-переменные, которые автоматически изменяются при смене режима.
3. Хранение состояния
Выбранная тема сохраняется:
localStorageprefers-color-scheme)Для корректной работы цветовых режимов используется компонент
ColorModeScript. Он вставляет небольшой скрипт, который
устанавливает тему до загрузки React, предотвращая
визуальное “мигание” интерфейса.
Пример использования в корневом файле приложения:
import { ChakraProvider, ColorModeScript } from "@chakra-ui/react"
import theme from "./theme"
function App() {
return (
<ChakraProvider theme={theme}>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<MainApp />
</ChakraProvider>
)
}
colorModecolorMode возвращает строку, отражающую текущий
режим:
const { colorMode } = useColorMode()
Возможные значения:
"light""dark"Использование в логике интерфейса:
const { colorMode } = useColorMode()
const text = colorMode === "light"
? "Светлая тема"
: "Тёмная тема"
toggleColorModeФункция toggleColorMode переключает режим на
противоположный.
const { toggleColorMode } = useColorMode()
Типичный пример — кнопка смены темы:
<Button onCl ick={toggleColorMode}>
Переключить тему
</Button>
Алгоритм работы:
light → устанавливается darkdark → устанавливается lightlocalStoragesetColorModeИногда требуется явно установить определённый режим, а не переключать его.
Для этого используется setColorMode.
const { setColorMode } = useColorMode()
setColorMode("dark")
Пример интерфейса с явным выбором темы:
function ThemeButtons() {
const { setColorMode } = useColorMode()
return (
<>
<Button onCl ick={() => setColorMode("light")}>
Светлая тема
</Button>
<Button onCl ick={() => setColorMode("dark")}>
Тёмная тема
</Button>
</>
)
}
useColorModeValueХук useColorModeValue предназначен для выбора значения в
зависимости от текущего режима темы.
Он избавляет от ручных условий if.
const value = useColorModeValue(lightValue, darkValue)
Параметры:
| Параметр | Назначение |
|---|---|
lightValue |
значение для светлой темы |
darkValue |
значение для тёмной темы |
import { Text, useColorModeValue } from "@chakra-ui/react"
function Title() {
const color = useColorModeValue("gray.800", "gray.100")
return <Text color={color}>Заголовок</Text>
}
Поведение:
gray.800gray.100import { Box, useColorModeValue } from "@chakra-ui/react"
function Card() {
const bg = useColorModeValue("white", "gray.700")
return (
<Box p="6" bg={bg} borderRadius="md">
Контент
</Box>
)
}
Хук часто применяется вместе со свойствами компонентов:
const bg = useColorModeValue("gray.50", "gray.800")
const border = useColorModeValue("gray.200", "gray.600")
<Box bg={bg} border="1px solid" borderColor={border}>
Контент
</Box>
Тени интерфейса могут отличаться для разных режимов.
const shadow = useColorModeValue(
"0 2px 8px rgba(0,0,0,0.1)",
"0 2px 8px rgba(0,0,0,0.6)"
)
Частый паттерн — отображение разных иконок для разных режимов.
import { SunIcon, MoonIcon } from "@chakra-ui/icons"
function ThemeIcon() {
const { colorMode } = useColorMode()
return colorMode === "light"
? <MoonIcon />
: <SunIcon />
}
useColorMode и useColorModeValueОба хука часто используются совместно.
function ThemeButton() {
const { toggleColorMode } = useColorMode()
const bg = useColorModeValue("gray.200", "gray.700")
return (
<Button bg={bg} onCl ick={toggleColorMode}>
Переключить тему
</Button>
)
}
Цветовые режимы можно инкапсулировать в собственные хуки.
function useCardStyles() {
return {
bg: useColorModeValue("white", "gray.700"),
border: useColorModeValue("gray.200", "gray.600")
}
}
Использование:
const styles = useCardStyles()
<Box bg={styles.bg} borderColor={styles.border}>
Карточка
</Box>
Поведение системы цветовых режимов можно настроить в конфигурации темы.
const config = {
initialColorMode: "light",
useSystemColorMode: false
}
Параметры:
| Свойство | Назначение |
|---|---|
initialColorMode |
начальный режим |
useSystemColorMode |
использовать настройки системы |
Создание темы:
import { extendTheme } from "@chakra-ui/react"
const theme = extendTheme({ config })
Если включить useSystemColorMode, Chakra UI будет
использовать настройки операционной системы пользователя.
const config = {
initialColorMode: "light",
useSystemColorMode: true
}
При этом применяется медиазапрос:
prefers-color-scheme
Chakra UI автоматически сохраняет выбранный режим в
localStorage.
Ключ хранения:
chakra-ui-color-mode
При повторной загрузке страницы тема восстанавливается.
Цвета компонентов можно задавать с учётом режимов внутри темы.
const styles = {
global: (props) => ({
body: {
bg: props.colorMode === "dark"
? "gray.900"
: "gray.50"
}
})
}
const bg = useColorModeValue("white", "gray.800")
const color = useColorModeValue("gray.700", "gray.200")
const border = useColorModeValue("gray.200", "gray.600")
const hover = useColorModeValue("gray.100", "gray.700")
useColorModeValue реализован максимально эффективно:
При переключении темы Chakra UI обновляет только те компоненты, которые используют цветовые значения.
ChakraProviderХуки цветовых режимов работают только внутри
ChakraProvider.
Неправильно:
useColorMode()
вне дерева провайдера.
useColorModeValueНеправильно:
const { colorMode } = useColorMode()
const color =
colorMode === "light"
? "gray.800"
: "gray.100"
Правильнее:
const color = useColorModeValue("gray.800", "gray.100")
ColorModeScriptЕсли не использовать ColorModeScript, при загрузке
страницы может возникать кратковременная смена темы (flash of incorrect
theme).
Обычно система цветовых режимов строится следующим образом:
1. Конфигурация темы
theme.config
2. Провайдер
ChakraProvider
3. Скрипт инициализации
ColorModeScript
4. Управление режимом
useColorMode
5. Динамические значения
useColorModeValue
Такая архитектура позволяет реализовать полноценную поддержку светлой и тёмной темы с минимальным количеством кода и без необходимости вручную управлять CSS.