使用高级 Chakra UI 组件更快地构建 💎
了解更多2025年1月3日
假设你需要根据按钮的按下状态来改变其内边距(padding)。
const App = () => {
const [isPressed, setPressed] = useState(false)
// How do style the button separately based on the pressed state?
return <Button>Click Me</Button>
}
你可能会尝试这样做
import { defineRecipe } from "@chakra-ui/react"
export const buttonRecipe = defineRecipe({
base: {
display: "flex",
},
variants: {
size: {
sm: ({ isPressed }) => ({
padding: isPressed ? "8" : "4",
fontSize: "12px",
}),
},
},
})
这不起作用,因为 Chakra 不支持在配方中使用函数。我们要求配方是可序列化的。
有两种方法可以处理这个问题
data-*
属性首先,使用 data-*
属性将动态值应用于组件。
const App = () => {
const [isPressed, setPressed] = useState(false)
return <Button data-pressed={isPressed || undefined}>Click Me</Button>
}
接下来,使用 data-*
属性为配方设置样式。
export const buttonRecipe = defineRecipe({
base: {
display: "flex",
},
variants: {
size: {
sm: {
padding: "4",
fontSize: "12px",
"&[data-pressed]": {
padding: "8",
},
},
},
},
})
compoundVariants
复合变体允许你根据变体组合创建样式覆盖。
isActive
变体compoundVariants
数组import { defineRecipe } from "@chakra-ui/react"
export const buttonRecipe = defineRecipe({
base: {
display: "flex",
},
variants: {
size: {
sm: {
padding: "4",
fontSize: "12px",
},
},
isPressed: {
true: {},
false: {},
},
},
compoundVariants: [
{
size: "sm",
isPressed: true,
css: {
padding: "8px",
fontSize: "12px",
},
},
],
})
然后,你可以将 isPressed
变体作为 props 传递给组件。
<Button visual="solid" isPressed={isPressed}>
Click Me
</Button>
npx @chakra-ui/cli typegen
命令来为配方生成类型。