How to create Variants in Version 3 and ensure type safety #9453
-
Hello, I currently try to create a variant in Version 3 and encounter some issues. const theme = extendTheme({
components: {
Button: {
variants: {
myCustomButtonVariant: {
color: "red.50"
}
}
}
}
}) And the usage would be something like: <Button variant="myCustomButtonVariant">Hello</Button> In V3 I have found something called recipes that can be used to create variants. export const buttonRecipe = defineRecipe({
variants: {
myCustomButtonVariant: {
base: {
fontSize: "lg",
px: 6,
py: 3,
},
},
},
});
const config = defineConfig({
theme: {
recipes: {
Button: buttonRecipe,
},
},
});
export default createSystem(defaultBaseConfig, config); Now I execute the CLI to generate Types npx @chakra-ui/cli typegen ./theme.ts Next I want to create a Button with the newly defined variant <Button variant="myCustomButtonVariant"></Button> But the style is not applied and TypeScript throws this error: Type '"myCustomButtonVariant"' is not assignable to type 'ConditionalValue<"outline" | "solid" | "subtle" | "surface" | "ghost" | "plain" | undefined>' In addition I tried something like myCustomButtonVariant.base or {myCustomButtonVariant: "base"} the behavior is analogous to the previous one. How can I create variants in v3 and ensure that TypeScript adds them to the union type of variant? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
Here's the migration for the recipe. const buttonRecipe = defineRecipe({
variants: {
variant: {
myCustomButtonVariant: {
fontSize: "lg",
px: 6,
py: 3,
},
},
},
}) Notice the use of |
Beta Was this translation helpful? Give feedback.
-
Hey, thank you for your help. // theme.ts
import {
createSystem,
defaultBaseConfig,
defineConfig,
defineRecipe,
} from "@chakra-ui/react";
const buttonRecipe = defineRecipe({
variants: {
variant: {
myCustomButtonVariant: {
fontSize: "lg",
px: 6,
py: 3,
color: "red.500",
},
},
},
});
const config = defineConfig({
theme: {
recipes: {
button: buttonRecipe,
},
},
});
export default createSystem(defaultBaseConfig, config); // CustomChakraProvider.tsx
import chakraTheme from "$lib/theme";
import { ChakraProvider } from "@chakra-ui/react";
import { ColorModeProvider, type ColorModeProviderProps } from "./color-mode";
export function CustomChakraProvider(props: ColorModeProviderProps) {
return (
<ChakraProvider value={chakraTheme}>
<ColorModeProvider {...props} />
</ChakraProvider>
);
} // main.tsx
import { CustomChakraProvider } from "$components/chakra/CustomChakraProvider";
import { Button } from "@chakra-ui/react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<CustomChakraProvider>
<Button variant="myCustomButtonVariant">Click Me</Button>
</CustomChakraProvider>
</StrictMode>,
); |
Beta Was this translation helpful? Give feedback.
-
Hey, I could resolve the issue. Thanks for the input/ideas :) |
Beta Was this translation helpful? Give feedback.
-
Just to add something that I ran into today, for anyone else finding their way to this discussion through searching, which I don't think the docs do a very good job of calling it out. If you're writing custom variant recipes for a slotted component like But what you might glaze over at the bottom of the page on Slot Recipes is that you also need to pass these recipes separately into the theme
If you include a slot recipe in the regular When you actually go to use |
Beta Was this translation helpful? Give feedback.
Here's the migration for the recipe.
Notice the use of
variants.variant
to define the custom variant