Skip to main content

variants

Macro variants 

Source
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 the variant: block
  • pub enum {Name}Size { ... } with one variant per key in the size: block
  • pub struct {Name}Variants { pub variant: {Name}Variant, pub size: {Name}Size }
  • impl Default for {Name}Variants — uses the keys named in defaults: { variant: X, size: Y }
  • pub struct {Name}; — a namespace type; never instantiated
  • impl {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 },
}