官方文档:Component Style
大多数组件的样式由基础样式和修改器样式组成,修改器样式根据某些特性或状态更改其大小或视觉样式。
props
切换的样式
props.size
切换props.variant
切换props.colorSchmeme
切换一个样式配置对象可以配置以下属性:
baseStyle
:基础样式对象sizes
:为每个尺寸设置样式对象variants
:为每个风格设置样式对象defaultProps
:默认样式配置,可配置的属性:
size
:尺寸variant
:风格colorScheme
:配色方案colorMode
:强制的颜色模式parts
:用于配置复合组件的样式设置样式的方式有两种:
props
作为参数,最终返回一个样式对象props
包含:
defaultProps
配置的属性theme
colorMode
一个组件的样式配置对象示例:
const Button = {
// 基础样式
baseStyle: {
// 可以使用样式属性配置
fontWeight: 'bold',
borderRadius: 'base'
},
// 尺寸样式(注意是带`s`的复数名称)
sizes: {
// 修改已有的尺寸样式
xs: {
h: '20px'
fontSize: "12px",
},
// 新增一个尺寸样式
sl: {
h: "56px",
fontSize: "lg",
px: "32px",
}
},
// 风格样式(注意是带`s`的复数名称)
variants: {
// 使用函数定义样式对象
solid: props => ({
// 根据 colorScheme 生成边线颜色
borderColor: props.colorScheme === 'teal' ? 'blue' : 'black',
// 根据 colorMode 生成背景色
bgColor: props.colorMode === 'dark' ? 'white' : 'black'
}),
},
// 默认 props
defaultProps: {
// 默认尺寸(注意不带`s`)
size: 'sl',
// 默认风格(注意不带`s`)
variant: 'solid',
// 默认配色风格
colorScheme: 'teal',
// 强制颜色模式(配置后 `props.colorMode` 将不会改变)
colorMode: 'dark'
}
}
通过主题对象的 components
属性修改或扩展 Chakra 组件的全局样式配置。
通常创建一个 theme
目录管理主题配置:
theme
index.js # 主题主入口
components # 组件样式配置
button.js # Button 按钮的样式配置
// theme/components/button.js
const Button = {
baseStyle: {
px: '20px',
py: '10px'
},
sizes: {
small: {
fontSize: '14px',
},
big: {
fontSize: '30px'
}
}
}
export default Button
// theme/index.js
import {
extendTheme } from '@chakra-ui/react'
import Button from './components/button'
const theme = extendTheme({
components: {
Button
}
})
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'
ReactDOM.render(
<React.StrictMode>
<ChakraProvider theme={
theme}>
<App />
</ChakraProvider>
</React.StrictMode>,
document.getElementById('root')
)
import {
Button } from '@chakra-ui/react'
function App() {
return (
<div>
<Button size="xs">默认配置的 xs 尺寸</Button>
<Button size="small">自定义的 small 尺寸</Button>
<Button size="big">自定义的 big 尺寸</Button>
</div>
)
}
export default App
在主题中扩展自定义组件的样式配置需要做几件事情:
key
设置为组件名__css
属性
useStyleConfig(themeKey, props)
钩子函数用于获取主题对象中组件的样式配置
__css
属性__css
属性设置的样式优先级低于手动通过组件的样式属性设置的样式themeKey
:theme.components
对象中的对应组件的 key
props
:配置默认方案// theme/components/content.js
// 文章内容样式配置
const content = {
baseStyle: {
bgColor: 'gray.200',
mt: '40px',
mx: 'auto'
},
sizes: {
small: {
fontSize: '12px',
lineHeight: '18px',
w: '30%',
p: '10px'
},
large: {
fontSize: '20px',
lineHeight: '36px',
w: '80%',
p: '20px'
}
},
variants: {
solid: {
border: '1px solid',
borderColor: 'gray.800'
},
card: {
boxShadow: 'md'
}
},
defaultProps: {
size: 'large',
variant: 'solid'
}
}
export default content
// theme/index.js
import {
extendTheme } from '@chakra-ui/react'
import Content from './components/content'
const theme = extendTheme({
components: {
Content
}
})
export default theme
// components/Content.js
// 文章内容组件
import {
Box, useStyleConfig } from '@chakra-ui/react'
function Content(props) {
const {
children, size, variant } = props
const styles = useStyleConfig('Content', {
size: size,
variant: variant
})
return <Box __css={
styles }>{
children }</Box>
}
export default Content
// App.js
import Content from './components/Content'
function App() {
return (
<>
<Content size="small" variant="card">这是用于展示文章内容的 Content 组件</Content>
</>
)
}
export default App
上面是设置 single part components(单部分组件) 的样式配置,如果一个组件由多个组件组成,就称为 multipart components(多部份组件或复合组件)。
复合组件设置样式配置与单个组件类似,主要区别是:
parts
属性中定义每个部分的 part
key。
key
part
提供 baseStyle
、sizes
和 variants
。useMultiStyleConfig
钩子函数,获取复合组件的样式配置对象,
useMultiStyleConfig
接收的参数与 useStyleConfig
一样part
的样式配置的对象__css
StylesProvider
组件向上下文共享样式配置对象
useStyles
钩子函数获取上下文中的样式配置对象// components/Article.js
// 文章复合组件
import {
Box, Heading } from '@chakra-ui/react'
// 复合组件
function Article(props) {
const {
title, content } = props
return (
<Box>
<Heading>{
title}</Heading>
<Box>{
content}</Box>
</Box>
)
}
export default Article
// App.js
import Article from './components/Article'
function App() {
return <Article title="文章标题" content="文章内容" />
}
export default App
// theme/components/article.js
// 文章样式配置
const article = {
parts: ['article', 'title', 'content'],
baseStyle: {
article: {
mt: '40px',
mx: 'auto'
},
title: {
textAlign: 'center',
fontFamily: 'Microsoft YaHei'
},
content: {
fontFamily: 'sans-serif'
}
},
sizes: {
small: {
article: {
w: '50%',
p: '5px'
},
title: {
my: '10px'
},
content: {
lineHeight: '1.2em'
}
},
large: {
article: {
w: '80%',
p: '20px'
},
title: {
my: '20px'
},
content: {
lineHeight: '1.8em'
}
}
},
variants: {
solid: {
article: {
border: '1px solid',
borderColor: 'gray.800'
}
},
card: {
article: {
boxShadow: 'md',
}
}
},
defaultProps: {
size: 'large',
variant: 'solid'
}
}
export default article
// components/Article.js
// 文章复合组件
import {
Box, Heading, useMultiStyleConfig } from '@chakra-ui/react'
// 复合组件
function Article(props) {
const {
title, content } = props
const styles = useMultiStyleConfig('Article', {
variant: 'card'
})
return (
<Box __css={
styles.article}>
<Heading __css={
styles.title}>{
title}</Heading>
<Box __css={
styles.content}>{
content}</Box>
</Box>
)
}
export default Article
// App.js
import {
StylesProvider, useMultiStyleConfig } from '@chakra-ui/react'
import Article from './components/Article'
function App() {
const styles = useMultiStyleConfig('Article', {
variant: 'card'
})
return (
<StylesProvider value={
styles}>
<Article title="文章标题" content="文章内容"></Article>
</StylesProvider>
)
}
export default App
// components/Article.js
// 文章复合组件
import {
Box, Heading, useStyles } from '@chakra-ui/react'
// 复合组件
function Article(props) {
const {
title, content } = props
const styles = useStyles()
return (
<Box __css={
styles.article}>
<Heading __css={
styles.title}>{
title}</Heading>
<Box __css={
styles.content}>{
content}</Box>
</Box>
)
}
export default Article