React UI 组件库 Chakra UI - 03主题对象和 chakra factory

主题对象

使用

Chakra UI 默认主题对象中包含很多样式的预设值。

打印 theme 对象:

在这里插入图片描述

在使用样式属性设置样式的时候,Chakra 会先从主题对象中获取对应的预设值,如果不存在,则将值作为 CSS 的值去设置。

例如:

  • <Box bg="gray.200"></Box> 会找到 theme.colors.gray.200#E2E8F0
  • <Box bg="gray"></Box> 没有对应的预设值,最终则会设置为 gray

文档:

扩展

可以通过 extendTheme(theme) 重写或扩展主题对象,它接收一个对象,会将这个对象和默认对象进行深层次合并:

import { extendTheme } from '@chakra-ui/react'
const theme = extendTheme({
  colors: {
    gray: {
      10: 'gray', // 向 theme.colors.gray 添加一个预设
      50: '#333' // 重写 theme.colors.gray.50
    },
    blue: 'blue' // 重写 theme.colors.blue
  },
  bigSize: '1000px' // 向 theme 添加一个预设
})

响应式断点

介绍

主题对象中默认有一个 breakpoints对象,它表示响应式断点

响应式断点是 Chakra 提供的为元素添加响应式样式的方式,来替代在代码中手动添加 @media和嵌套样式。

使用

theme.breakpoints 的值是一个对象:

// 默认主题的 breakpoints
{
  2xl: "96em",
  base: "0em",
  lg: "62em",
  md: "48em",
  sm: "30em",
  xl: "80em",
}

Chakra UI 会将 breakpoints 中定义的值转换成数组,并按升序排列:

// 内部转换成这样
["0em", "30em", "48em", "62em", "80em", "96em"]

通过给样式属性传递一个对象或数组,来响应对应的值:

<Box w={{ base: '300px', md: '600px', lg: '1000px' }} h="100px" bg="pink">
  <Text fontSize={['14px', null, '20px', '40px']}>在数组中使用 null 跳过断点,避免生成不必要的CSS</Text>
</Box>

Chakra UI 使用 @media(min-width) 媒体查询来保证移动优先。

所以上面示例 Box 的宽度取值是:

  • 300px:文档宽度 base(0em) 以上
  • 600px:文档宽度 md(48em)以上
  • 1000px:文档宽度 lg(62em)以上

Text 字号的取值是:

  • 14px:文档宽度 base(0em) 以上
  • 20px:文档宽度 md(48em)以上
  • 40px:文档宽度 lg(62em)以上

自定义

可以使用 @chakra-ui/theme-tollscreateBreakpoints 定义自定义断点,并通过 extendTheme 重写主题。

createBreakpoints 接收一个对象:

  • Chakra 建议使用常见的别名,如 smmdlg
  • 确保 css 单位相同,全部使用 pxem,不要混合使用。
  • 默认会生成 base: 0em,不用手动设置,也不用担心单位混用问题,当然也可以重写它。

返回的对象会替换 theme.breakPoints(不是合并)。

npm i @chakra-ui/theme-tools
// theme.js
import { createBreakpoints } from '@chakra-ui/theme-tools'
import { extendTheme } from '@chakra-ui/react'

const breakPoints = createBreakpoints({
  sm: '768px',
  md: '1000px'
})

const theme = extendTheme({ breakPoints })

console.log(theme)

export default theme

在这里插入图片描述

function Example() {
  return <Box w={['100%', '50%', '25%']}
}

如果向createBreakpoints 传递一个数组,则会以下标为名创建对象(因为数组就是以下标为名的对象):

const breakPoints = createBreakpoints(['768px','1000px'])

在这里插入图片描述

Chakra Factory

chakra 是一个支持 Chakra 的 JSX 元素的对象,也是一个可以用来支持自定义组件接收 Chakra 样式属性的函数。

普通 HTML 元素组件

使用 chakra.<element>创建可以传递 Chakra 样式属性的普通 HTML 元素组件。

import { chakra } from '@chakra-ui/react'

function App() {
  return (
    <chakra.div p="10px" w="200px" h="100px" bg="gray.600">
      <chakra.p color="white">可以使用 Chakra 样式属性的普通 HMLT 元素组件</chakra.p>
    </chakra.div>
  )
}

export default App

自定义 Chakra 组件

使用 chakra 方法可以封装非 Chakra 组件,使其可以传递 Chakra 样式属性。

实际上内部使用了 Emotion,所以包装的组件需要能接收并设置 className 属性。

import { chakra } from '@chakra-ui/react'

function Foo({className, children}) {
  // 确保正确接收 className
  return <div className={className}>{children}</div>
}

// 封装的组件
const ChakraFoo = chakra(Foo)

function App() {
  return (
    <ChakraFoo p="10px" w="200px" h="100px" bg="gray.600">
      <chakra.p color="white">自定义 Chakra 组件</chakra.p>
    </ChakraFoo>
  )
}

export default App

定义初始样式

可以为自定义的 Chakra 组件定义初始样式:

import { chakra } from '@chakra-ui/react'

function Foo({className, children}) {
  // 确保正确接收 className
  return <div className={className}>{children}</div>
}

// 包装的组件
const ChakraFoo = chakra(Foo, {
  baseStyle: {
   p: '10px',
   w: '200px',
   h: '100px',
   bg: 'gray.600'
  }
})

function App() {
  return (
    <ChakraFoo>
      <chakra.p color="white">带有初始样式的自定义 Chakra 组件</chakra.p>
    </ChakraFoo>
  )
}

export default App

也可以创建带有初始样式的普通HTML组件:

import { chakra } from '@chakra-ui/react'

const ChakraDiv = chakra('div', {
  baseStyle: {
   p: '10px',
   w: '200px',
   h: '100px',
   bg: 'gray.600'
  }
})

function App() {
  return (
    <ChakraDiv>
      <chakra.p color="white">带有初始样式的普通 HTML 元素组件</chakra.p>
    </ChakraDiv>
  )
}

export default App

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值