macro_rules! variants {
(
$name:ident,
base: $base:literal,
variant: { $( $variant_key:ident : $variant_class:literal ),+ $(,)? },
size: { $( $size_key:ident : $size_class:literal ),+ $(,)? },
defaults: { variant: $default_variant:ident, size: $default_size:ident } $(,)?
) => { ... };
(@paste
$name:ident,
$base:literal,
[ $( $variant_key:ident : $variant_class:literal ),+ ],
[ $( $size_key:ident : $size_class:literal ),+ ],
$default_variant:ident,
$default_size:ident
) => { ... };
}Expand description
Declarative macro that reproduces the TypeScript cva (class-variance-authority) API in Rust.
Expands to:
pub enum {Name}Variant { ... }with one variant per key in thevariant:blockpub enum {Name}Size { ... }with one variant per key in thesize:blockpub struct {Name}Variants { pub variant: {Name}Variant, pub size: {Name}Size }impl Default for {Name}Variants— uses the keys named indefaults: { variant: X, size: Y }pub struct {Name};— a namespace type; never instantiatedimpl {Name} { pub fn class(v: {Name}Variants) -> String { ... } }
Usage:
ⓘ
variants! {
Button,
base: "inline-flex items-center ...",
variant: {
default: "bg-primary text-primary-foreground",
destructive: "bg-destructive ...",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
},
defaults: { variant: default, size: default },
}