skip to Main Content

I am trying to convert the below code to cva..

{items.map((item, index) => {
          const isActive = item.key === SOMETHING;
          return (
            <div
              key={index}
              className={clsx(
                `cursor-pointer`,
                {
                  "text-white": isActive && variant === "inverted",
                  "text-stone-950": isActive && variant === "default",
                  "text-[#9b9b9b]": !isActive,
                  "hover:text-white": variant === "inverted",
                  "hover:text-stone-950": variant === "default",
                },
              )}
            >...</div>
    });

I am trying this way –

const textContentCva = cva("", {
    variants: {
      variant: {
        inverted: "hover:text-white",
        default: "hover:text-stone-950",
      },
    },
  });

But not sure how to pass the isActive variable.

I can create activeInverted, activeDefault variant but that doesn’t seem good.

Could anyone please tell how should I convert it to use cva?

2

Answers


  1. What I have understand so far is that you are trying to do as below:

    const textContentCva = cva("", {
      variants: {
        variant: {
          inverted: "hover:text-white",
          default: "hover:text-stone-950",
        },
        state: {
          active: "",
          inactive: "text-[#9b9b9b]",
        },
      },
      compoundVariants: [
        { variant: "default", state: "active", class: "text-stone-950" },
        { variant: "inverted", state: "active", class: "text-white" },
      ],
    });
    
    {items.map((item, index) => {
      const isActive = item.key === SOMETHING;
      return (
        <div
          key={index}
          className={clsx(
            `cursor-pointer`,
            textContentCva({variant: variant, state: isActive ? 'active' : 'inactive' })
          )}
        >...</div>
    });
    
    Login or Signup to reply.
  2. You could use CSS variables in CVA class names.

    We can rationalize the conditions:

    • variant changes the "accent" color.
    • isActive changes the default inactive text color #9b9b9b to the accent color.

    In CVA, you can have a boolean true variant value but not a boolean false. For the false condition, we can use the defaultVariants to apply the appropriate classes.

    const classes = cva('cursor-pointer', {
      variants: {
        variant: {
          default: '[--color:theme(colors.stone.950)]',
          inverted: '[--color:theme(colors.white)]',
        },
        isActive: {
          'default': 'text-[#9b9b9b] hover:text-[--color]',
          true: 'text-[--color]',
        },
      },
      defaultVariants: {
        variant: 'default',
        isActive: 'default',
      },
    });
      
    
    function CVAVersion({ variant, isActive }) {
      return <div className={classes({ variant, isActive })}>...</div>;
    }
    
    function CLSXVersion({ variant, isActive }) {
      return (
        <div
          className={clsx(
            `cursor-pointer`,
            {
              "text-white": isActive && variant === "inverted",
              "text-stone-950": isActive && variant === "default",
              "text-[#9b9b9b]": !isActive,
              "hover:text-white": variant === "inverted",
              "hover:text-stone-950": variant === "default",
            }
          )}
        >...</div>
      );
    }
    
    
    ReactDOM.createRoot(document.getElementById('app')).render(
      <React.Fragment>
        <CLSXVersion variant="default"/>
        <CLSXVersion variant="default" isActive/>
        <CVAVersion variant="default"/>
        <CVAVersion variant="default" isActive/>
        <div class="bg-slate-950">
          <CLSXVersion variant="inverted" />
          <CLSXVersion variant="inverted" isActive />
          <CVAVersion variant="inverted" />
          <CVAVersion variant="inverted" isActive />
        </div>
      </React.Fragment>
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://www.unpkg.com/[email protected]/dist/clsx.min.js" integrity="sha384-dEq4EUqxSIwObxCTXRGn1G8uU8Dqce+ragCb5MYDS6s+QHC2gaYQLxHklTJLaked" crossorigin="anonymous"></script>
    <script src="https://cdn.tailwindcss.com/3.4.3"></script>
    <script>window.exports = {};window.require=()=>clsx</script>
    <script src="https://www.unpkg.com/[email protected]/dist/index.js" integrity="sha384-Ua/NUydOXqPPKWdUxsvNqN7S97GagbtZ08VsSKGzqMYr/WwqcQ6Ajsq1LYfkfOn4" crossorigin="anonymous"></script>
    <script src="https://cdn.tailwindcss.com/3.4.3"></script>
    
    <div id="app"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search