Chakra Factory
使用 Chakra factory 创建超级组件
概述
Chakra factory 是一种从任何 HTML 元素创建超级 JSX 组件的方法,使它们能够接收 JSX 样式属性。
import { chakra } from "@chakra-ui/react"
Chakra factory 可以通过两种方式使用:作为 JSX 元素或作为工厂函数。
JSX 元素
样式属性是可以作为 props 传递给组件的 CSS 属性。通过 JSX factory,你可以使用 chakra.<element>
语法创建支持样式属性的 JSX 元素。
import { chakra } from "@chakra-ui/react"
const Button = ({ children }) => (
<chakra.button bg="blue.500" color="white" py="2" px="4" rounded="md">
{children}
</chakra.button>
)
工厂函数
使用 chakra
函数来转换原生元素或自定义组件。主要要求是该组件必须接受 className
作为 props。
const Link = chakra("a")
function Example() {
return <Link bg="red.200" href="https://chakra-ui.com.cn" />
}
另一个使用自定义组件的示例。
import * as RadixScrollArea from "@radix-ui/react-scroll-area"
const ScrollArea = chakra(RadixScrollArea.Root)
function Example() {
return (
<ScrollArea>
<RadixScrollArea.Viewport>
<div>Hello</div>
</RadixScrollArea.Viewport>
</ScrollArea>
)
}
附加样式
使用 chakra
函数来为组件附加样式或样式配方。
const Link = chakra("a", {
base: {
bg: "papayawhip",
color: "red.500",
},
})
// usage: <Link href="https://chakra-ui.com.cn" />
附加样式配方
以下是为组件附加样式配方的示例。
const Card = chakra("div", {
base: {
shadow: "lg",
rounded: "lg",
bg: "white",
},
variants: {
variant: {
outline: {
border: "1px solid",
borderColor: "red.500",
},
solid: {
bg: "red.500",
color: "white",
},
},
},
})
// usage: <Card variant="outline" />
转发 Props
默认情况下,chakra
factory 只过滤与 Chakra 相关的样式属性,防止它们传递到 DOM。要更精细地控制 props 的转发方式,请传递 shouldForwardProp
选项。
以下是一个示例,它会转发所有不以 $
开头的 props
function shouldForwardProp(prop: string) {
return !prop.startsWith("$")
}
const Component = chakra("div", {}, { shouldForwardProp })
要创建自定义的 props 转发逻辑,请结合使用 @emotion/is-prop-valid 包和 Chakra UI 中的 isValidProperty
。
import { chakra, defaultSystem } from "@chakra-ui/react"
import shouldForwardProp from "@emotion/is-prop-valid"
const { isValidProperty } = defaultSystem
function shouldForwardProp(prop: string, variantKeys: string[]) {
const chakraSfp = !variantKeys?.includes(prop) && !isValidProperty(prop)
return shouldForwardProp(prop) || chakraSfp
}
const Component = chakra("div", {}, { shouldForwardProp })
默认 Props
使用 defaultProps
选项将默认 props 传递给组件。
const Button = chakra(
"button",
{
base: {
bg: "blue.500",
color: "white",
},
},
{ defaultProps: { type: "button" } },
)
多态性
使用 Chakra factory 创建的每个组件都可以接受 as
和 asChild
属性来改变底层 DOM 元素。
<Button as="a" href="https://chakra-ui.com.cn">
Chakra UI
</Button>
或
<Button asChild>
<a href="https://chakra-ui.com.cn">Chakra UI</a>
</Button>