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", }, }, }, }, })compoundVariantsCompound 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.