React UI 组件库 Chakra UI - 02 颜色模式

Color Mode 颜色模式

Chakra UI 内置支持管理应用程序的颜色模式,默认可配置的颜色模式有浅色模式(light)、暗色模式(dark)、系统模式(system)。

大部分组件默认都支持暗色模式(dark mode)。

Chakra 将颜色模式存储在 localStorage中,通过给 附加一个类名确保颜色模式是持久的,

切换暗色模式

Chakra UI 模式使用的浅色模式(light)。

可以使用钩子函数 useColorMode获取和切换当前颜色模式。

import {
      Button, useColorMode } from '@chakra-ui/react'

function App() {
     
  // 注意这里是对象解构,不是 useState 的数组结构
  const {
     colorMode, toggleColorMode} = useColorMode()
  return (
    <div>
      <div>当前的颜色模式为:{
     colorMode}</div>
      <Button onClick={
     toggleColorMode}>切换颜色模式</Button>
    </div>
  )
}

export default App

访问页面,body元素上会有一个 chakra-ui-light 的类名。

点击按钮,Chakra 通过切换 body 上的类名实现模式切换。

刷新页面颜色模板不会还原,因为切换模式会在 localStorage 中缓存一个名为 chakra-ui-color-mode 的状态,以实现持久化。

React UI 组件库 Chakra UI - 02 颜色模式_第1张图片

React UI 组件库 Chakra UI - 02 颜色模式_第2张图片

设置初始颜色模式

Chakra UI 默认使用的浅色模式,可以通过修改主题对象的 theme.config 属性下的 initialColorModeuseSystemColorMode 设置初始的颜色模式:

  • initialColorMode:指定初始颜色模式
    • light:默认值,浅色模式
    • dark:暗色模式
    • system:系统的颜色模式
      • 运行环境(浏览器)的主题颜色配置优先级高于操作系统的配置
  • useSystemColorMode:是否根据系统的主题颜色配置自动切换应用程序的颜色模式
    • false:默认值
    • true
      • 如果设置为 true,则会在初始加载后获取系统配置,并缓存到 localStorage 中,覆盖 initialColorMode 的配置
      • 当系统配置发生变化时,应用程序会自动切换
  1. 自定义或扩展主题配置,通过主题指定颜色模式
    • 记得将主题对象传递给 ChakraProvider 组件。
  2. 添加 ColorModeScript 组件。
    • initialColorMode属性传递默认值
// theme.js
// extendTheme 方法用于在默认主题对象的基础上进行扩展
import {
      extendTheme } from '@chakra-ui/react'

const config = {
     
  initialColorMode: 'dark',
  useSystemColorMode: false
}

const theme = extendTheme({
      config })

export default theme

// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import {
      ChakraProvider } from '@chakra-ui/react'
import theme from './theme'

// 也可以这样设置
// theme.config.initialColorMode = 'dark'

ReactDOM.render(
  <React.StrictMode>
    {
     /* 一定要记得将主题对象传递给 ChakraProvider */}
    <ChakraProvider theme={
     theme}>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
  document.getElementById('root')
)

记得清除 localStorage 中缓存的 chakra-ui-light,它将覆盖你设置的默认值。

向浏览器缓存记录的时机:

  • 如果指定了自动同步系统配置,初始加载的时候会缓存。
  • 其它情况只有切换颜色模式的时候才会缓存。

尽管上面的示例已经实现了,不过Chakra UI 官方还要求添加 ColorModeScript 组件:Adding the ColorModeScript,目前没有找到相关依据:

// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import {
      ChakraProvider, ColorModeScript } from '@chakra-ui/react'
import theme from './theme'

ReactDOM.render(
  <React.StrictMode>
    <ColorModeScript initialColorMode={
     theme.config.initialColorMode} />
    <ChakraProvider theme={
     theme}>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
  document.getElementById('root')
)

useColorModeValue 钩子函数

手动判断每个模式使用的样式

Chakra UI 默认大部分组件兼容暗色模式,组件的样式会随着切换颜色模式而改变。

但手动设置的样式不会随着切换颜色模式而改变,例如:

import {
      Box, Text, Button, useColorMode } from '@chakra-ui/react'

function App() {
     
  const {
     colorMode, toggleColorMode} = useColorMode()
  return (
    // 背景色永远是 yellow.200
    <Box bg="yellow.200">
      {
     /* 文本颜色永远是 blue.200 */}
      <Text color="blue.200">当前的颜色模式为:{
     colorMode}</Text>
      <Button onClick={
     toggleColorMode}>切换颜色模式</Button>
    </Box>
  )
}

export default App

可以根据当前颜色模式设置对应的样式:

import {
      Box, Text, Button, useColorMode } from '@chakra-ui/react'

function App() {
     
  const {
     colorMode, toggleColorMode} = useColorMode()

  const bg = colorMode === 'light' ? 'yellow.200' : 'blue.700'
  const color = colorMode === 'light' ? 'gray.600' : 'blue.200'

  return (
    <Box bg={
     bg}>
      <Text color={
     color}>当前的颜色模式为:{
     colorMode}</Text>
      <Button onClick={
     toggleColorMode}>切换颜色模式</Button>
    </Box>
  )
}

export default App

当有很多地方都需要判断颜色模式的时候,就需要编写大量这样的三元表达式判断,更好的方式是使用 Chakra UI 提供的 useColorModeValue 钩子函数。

使用钩子函数指定每个模式的样式

Chakra UI 提供的 useColorModeValue(lightModeValue, darkModeValue) 钩子函数,根据颜色模式返回指定的值。

它接收两个参数:浅色模式使用的值 和 暗色模式使用的值。

它会根据当前颜色模式,返回传入的值,这个值可以当作样式和其它任何值去使用。

import {
      Box, Text, Button, useColorMode, useColorModeValue } from '@chakra-ui/react'

function App() {
     
  const {
     colorMode, toggleColorMode} = useColorMode()

  // const bg = colorMode === 'light' ? 'yellow.200' : 'blue.700'
  // const color = colorMode === 'light' ? 'gray.600' : 'blue.200'

  const bg = useColorModeValue('yellow.200', 'blue.700')
  const color = useColorModeValue('gray.600', 'blue.200')

  return (
    <Box bg={
     bg}>
      <Text color={
     color}>当前的颜色模式为:{
     colorMode}</Text>
      <Button onClick={
     toggleColorMode}>切换颜色模式</Button>
    </Box>
  )
}

export default App

强制颜色模式

在某些情况下,可能希望 Chakra 的一些组件始终使用指定颜色模式下的主题样式,且不会根据当前颜色模式的变化而改变。

可以将组件包括在 LightModeDarkMode 组件中,这样将覆盖全局的 colorMode,强制使用浅色 或 暗色模式的主题样式

强制颜色模式是指强制组件使用指定颜色模式下的一系列主题样式。

  • 实际上是通过固定组件类名的方式实现的。
  • 组件未设置的,继承自父级的样式,仍然会随着变化。
    • 例如 Button 组件的背景色会固定,而文本颜色会随着变化
    • 可以通过指定 colorScheme (配色方案)属性,使用默认的主题样式以固定
      • 有的组件并没有在默认主题中实现配色方案,需自己扩展,例如 Text
  • 如果只希望固定某个样式,可以通过手动设置样式实现。
import {
      Box, Heading, Button, useColorMode, LightMode, DarkMode } from '@chakra-ui/react'

function App() {
     
  const {
     colorMode, toggleColorMode} = useColorMode()

  return (
    <Box>
      当前的颜色模式为:{
     colorMode}
      <Button onClick={
     toggleColorMode}>切换颜色模式</Button>

      <LightMode>
        <Heading>强制浅色模式</Heading>

        <Button>未指定配色方案的 Button</Button>
        <Button colorScheme="blue">指定了蓝色配色方案的 Button</Button>
      </LightMode>

      <DarkMode>
        <Heading>强制暗色模式</Heading>

        <Button>未指定配色方案的 Button</Button>
        <Button colorScheme="blue">指定了蓝色配色方案的 Button</Button>
      </DarkMode>
    </Box>
  )
}

export default App

你可能感兴趣的:(react)