Adding Variants
You can add variants using the variants
key. There is no limit to the amount of variants you can add.
const Button = classed("button", {
variants: {
color: {
primary: "text-white bg-blue-500",
secondary: "text-white bg-gray-700",
},
},
});
() => <Button color="primary">Button</Button>;
A variant accepts a single string of tailwind class names.
Multiple variants
const Button = classed("button", {
variants: {
color: {
primary: "text-white bg-blue-500",
secondary: "text-white bg-gray-700",
},
size: {
small: "py-2 px-4",
medium: "py-3 px-6",
large: "py-4 px-8",
},
},
});
() => (
<Button color="primary" size="medium">
Button
</Button>
);
Boolean variants
Variants can be booleans by using true as the key.
const Button = classed("button", {
variants: {
// ... base variants
outlined: {
true: "border border-gray-600",
},
},
});
() => (
<Button color="primary" size="medium" outlined>
Button
</Button>
);
Default variants
You can use the defaultVariants
key to set a variant by default:
const Button = classed("button", {
variants: {
color: {
primary: "text-white bg-blue-500",
secondary: "text-white bg-gray-700",
},
},
defaultVariants: {
color: "primary",
},
});
() => <Button>Button</Button>;
Compound variants
Compound variants are variants that depend on other variants. They are defined using an array of variants and a class/className
You can use the compoundVariants
key to create compound variants:
const Button = classed("button", {
variants: {
color: {
primary: "text-white bg-blue-500",
secondary: "text-white bg-gray-700",
},
size: {
small: "py-2 px-4",
medium: "py-3 px-6",
large: "py-4 px-8",
},
},
compoundVariants: [
{
size: "small",
color: "primary",
class: "rounded", // Classes when both size and color are small and primary will be applied
className: "", // This is also supported if you prefer to use className
},
],
});
() => (
<Button color="primary" size="medium">
Button
</Button>
);
Extracting variants
You can extract variants from a component using the getVariantConfig()
function. This is useful if you want to manually compose comonents or show variants in docs/Storybook.
import { classed, getVariantConfig } from "@tw-classed/react";
const Button = classed.button({
variants: {
color: {
primary: "text-white bg-blue-500",
secondary: "text-white bg-gray-700",
},
size: {
small: "py-2 px-4",
medium: "py-3 px-6",
large: "py-4 px-8",
},
},
});
const buttonConfig = getVariantConfig(Button);
assert.equals(buttonConfig.variants, {
color: {
primary: "text-white bg-blue-500",
secondary: "text-white bg-gray-700",
},
size: {
small: "py-2 px-4",
medium: "py-3 px-6",
large: "py-4 px-8",
},
});
Usage in Storybook
Here we are assuming that you have a utility function to convert the variant config into a Storybook argTypes object.
const meta = {
argTypes: {
...variantArgTypes(getVariantConfig(Button)),
},
component: Button,
} satisfies Meta<typeof Button>;
export default meta;