nextui-org / tailwind-variants

🦄 Tailwindcss first-class variant API
https://tailwind-variants.org
MIT License
2.42k stars 68 forks source link

Variants do not work properly when using a tailwind prefix #225

Closed nvioli closed 1 day ago

nvioli commented 2 days ago

Describe the bug Without a prefix, with a configuration like this:

const button = tv({
  base: "bg-blue-500 text-black rounded-md p-2",
  variants: {
    color: {
      primary: "bg-purple-500 text-white",
      secondary: "bg-green-500 text-white",
    },
  },
});

if I then create a button with

<button className={button({ color: "primary" })}>click me</button>

this will result in the following element created in the DOM:

<button class="rounded-md p-2 bg-purple-500 text-white">click me</button>

Note that the class contains bg-purple-500 text-white but does not contain bg-blue-500 text-black since tv has correctly determined that these classes for the primary variant override the background and text color from the base class list.

If I then add prefix: "tw-" to the tailwind config and modify my component:

const button = tv({
  base: "tw-bg-blue-500 tw-text-black tw-rounded-md tw-p-2",
  variants: {
    color: {
      primary: "tw-bg-purple-500 tw-text-white",
      secondary: "tw-bg-green-500 tw-text-white",
    },
  },
});

<button className={button({ color: "primary" })}>click me</button>

it will now produce this DOM element:

<button class="tw-bg-blue-500 tw-text-black tw-rounded-md tw-p-2 tw-bg-purple-500 tw-text-white">click me</button>

Note that there are now two bg and two text classes. The one that renders will depend on the arbitrary order in the css file.

To Reproduce Here is a minimal reproduction in codesandbox: https://codesandbox.io/p/devbox/mddmrt?file=%2Fsrc%2FApp.tsx

Note the incorrect text color on two of the buttons.

Expected behavior tv correctly identifies class overrides when using a tailwind prefix and does not include the base class if it is overridden by a variant.

Desktop (please complete the following information): (shouldn't matter but...)

prakash03yes commented 1 day ago

Describe the bug Without a prefix, with a configuration like this:

const button = tv({
  base: "bg-blue-500 text-black rounded-md p-2",
  variants: {
    color: {
      primary: "bg-purple-500 text-white",
      secondary: "bg-green-500 text-white",
    },
  },
});

if I then create a button with

<button className={button({ color: "primary" })}>click me</button>

this will result in the following element created in the DOM:

<button class="rounded-md p-2 bg-purple-500 text-white">click me</button>

Note that the class contains bg-purple-500 text-white but does not contain bg-blue-500 text-black since tv has correctly determined that these classes for the primary variant override the background and text color from the base class list.

If I then add prefix: "tw-" to the tailwind config and modify my component:

const button = tv({
  base: "tw-bg-blue-500 tw-text-black tw-rounded-md tw-p-2",
  variants: {
    color: {
      primary: "tw-bg-purple-500 tw-text-white",
      secondary: "tw-bg-green-500 tw-text-white",
    },
  },
});

<button className={button({ color: "primary" })}>click me</button>

it will now produce this DOM element:

<button class="tw-bg-blue-500 tw-text-black tw-rounded-md tw-p-2 tw-bg-purple-500 tw-text-white">click me</button>

Note that there are now two bg and two text classes. The one that renders will depend on the arbitrary order in the css file.

To Reproduce Here is a minimal reproduction in codesandbox: https://codesandbox.io/p/devbox/mddmrt?file=%2Fsrc%2FApp.tsx

Note the incorrect text color on two of the buttons.

Expected behavior tv correctly identifies class overrides when using a tailwind prefix and does not include the base class if it is overridden by a variant.

Desktop (please complete the following information): (shouldn't matter but...)

  • OS: MacOS
  • Browser Firefox
  • Version 132.0.2

hi, you need to config your tv. you can config in two ways 1. globally, 2. locally

import { tv } from "tailwind-variants";

function App() {
  const button = tv({
    base: "tw-bg-blue-500 tw-text-white tw-text-black tw-rounded-md tw-p-2",
    variants: {
      color: {
        primary: "tw-bg-purple-500 tw-text-white",
        secondary: "tw-bg-green-500 tw-text-white",
      },
    },
  },{
    twMergeConfig: {
      prefix: 'tw-',
    }
  });

  return (
    <>
      <div className="tw-m-2">
        this is right:
        <br />
        <button className={button()}>blue with black text (default)</button>
      </div>
      <div className="tw-m-2">
        text color is wrong:
        <br />
        <button className={button({ color: "primary" })}>
          purple with white text (primary)
        </button>
      </div>
      <div className="tw-m-2">
        text color is wrong:
        <br />
        <button className={button({ color: "secondary" })}>
          green with white text (secondary)
        </button>
      </div>
    </>
  );
}

export default App;

the above one locally configured. Check these links

nvioli commented 1 day ago

Thanks!