Build faster with Premium Chakra UI Components 💎
Learn moreJanuary 3, 2025
Suppose that you need to change the padding of a button based on some pressed state.
const App = () => {
const [isPressed, setPressed] = useState(false)
// How do style the button separately based on the pressed state?
return <Button>Click Me</Button>
}
You might be tempted to do something like this:
import { defineRecipe } from "@chakra-ui/react"
export const buttonRecipe = defineRecipe({
base: {
display: "flex",
},
variants: {
size: {
sm: ({ isPressed }) => ({
padding: isPressed ? "8" : "4",
fontSize: "12px",
}),
},
},
})
This doesn't work because Chakra doesn't support functions in recipes. We require recipes to be serializable.
There are two ways to handle this:
data-*
attributesFirst, apply the dynamic values to the component using the data-*
attribute.
const App = () => {
const [isPressed, setPressed] = useState(false)
return <Button data-pressed={isPressed || undefined}>Click Me</Button>
}
Next, style the recipe using the data-*
attribute.
export const buttonRecipe = defineRecipe({
base: {
display: "flex",
},
variants: {
size: {
sm: {
padding: "4",
fontSize: "12px",
"&[data-pressed]": {
padding: "8",
},
},
},
},
})
compoundVariants
Compound variants allow you to create style overrides based on variant combinations.
isActive
variantcompoundVariants
array that contains the style overridesimport { 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",
},
},
],
})
Then, you can pass the isPressed
variant to the component as props.
<Button visual="solid" isPressed={isPressed}>
Click Me
</Button>
npx @chakra-ui/cli typegen
command to generate the types for the recipe.