tailwind-variants icon indicating copy to clipboard operation
tailwind-variants copied to clipboard

Using compondVariants with slots and defaultVariants breaks

Open mehdibha opened this issue 10 months ago • 2 comments

Describe the bug

Using tailwind-variants with slots, compoundVariants, defaultVariants and explicitly passing the variants as undefined breaks.

To Reproduce

import { tv } from "tailwind-variants";

const variants = tv({
  slots: {
    root: "",
  },
  variants: {
    variant: {
      solid: {},
    },
    orientation: {
      horizontal: {
        root: "",
      },
    },
  },
  compoundVariants: [
    {
      orientation: "horizontal",
      variant: "solid",
      className: {
        root: "border-b",
      },
    },
  ],
  defaultVariants: {
    orientation: "horizontal",
    variant: "solid",
  },
});

const { root } = variants();

console.log(root({})) // Output: "border-b" 
console.log(root({ orientation: undefined, variant: undefined })) // Output: "" 

Expected behavior It should use the defaultVariants

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser Chrome 131
  • Version 0.31

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context Add any other context about the problem here.

mehdibha avatar Jan 23 '25 15:01 mehdibha

I have the same? experience:

const tvSpeaker = tv({
  slots: {
    slotRoot: "flex",
    slotBody: "flex flex-col",
    slotFontSize: "",
  },
  variants: {
    layout: {
      vertical: {
        slotRoot: "flex-col",
        slotBody: "text-center",
        slotFontSize: "",
      },
      horizontal: {
        slotRoot: "flex-row flex-nowrap",
        slotBody: "flex-row",
        slotFontSize: "",
      },
    },
  },
  defaultVariants: {
    layout: "horizontal",
  },
});
export const Speaker: React.FC<SpeakerProps> = ({
  layout,
  ...props
}) => {}

When I log layout it's undefined.

davidhellmann avatar Mar 07 '25 17:03 davidhellmann

Exactly the same behavior with compoundSlots :

  const avatar = tv({
    slots: {
      image: "rounded-full object-cover",
      icon: "text-foreground",
    },
    variants: {
      size: {
        small: {},
        medium: {},
        large: {},
      },
    },
    defaultVariants : {
      size : "medium",
    },
    compoundSlots: [
      {
        slots: ["image", "icon"],
        size: "small",
        class: "size-8",
      },
      {
        slots: ["image", "icon"],
        size: "medium",
        class: "size-10",
      },
      {
        slots: ["image", "icon"],
        size: "large",
        class: "size-12",
      },
    ],
  });

  const props = defineProps<Props>();

  const { image, icon } = avatar();

  console.log(image()); // rounded-full object-cover size-10

  console.log(image({ size: undefined })); // rounded-full object-cover

xerox0213 avatar May 03 '25 13:05 xerox0213