What is the process for transforming conditional classes from clxs to cva format?

Looking for a way to convert the code snippet below into cva format...

{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 have attempted the following approach -

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

However, I am unsure how to include the isActive variable.

Creating separate activeInverted and activeDefault variants doesn't seem optimal.

Can someone provide guidance on how to properly convert this code using cva?

Answer №1

Utilizing CSS variables in CVA class names is a great way to customize your styling.

The conditions can be rationalized as follows:

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

In CVA, you are able to set a boolean value of true for the variant but not for false. In cases where the condition is false, the defaultVariants can be used to add 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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="482b243b30087a66796679">[email protected]</a>/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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d9bab5b8aaaaf4afb8abb0b8b7babcf4b8acadb1b6abb0ada099e9f7eef7e9">[email protected]</a>/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>

Answer №2

From what I have gathered, it seems like you are attempting to achieve the following:

const dynamicTextContent = createDynamicTextContent("", {
  variations: {
    variation: {
      inverted: "hover:text-white",
      default: "hover:text-stone-950",
    },
    status: {
      active: "",
      inactive: "text-[#9b9b9b]",
    },
  },
  compoundVariations: [
    { variation: "default", state: "active", className: "text-stone-950" },
    { variation: "inverted", state: "active", className: "text-white" },
  ],
});
{items.map((item, index) => {
  const isActive = item.key === SOMETHING;
  return (
    <div
      key={index}
      className={clsx(
        `cursor-pointer`,
        dynamicTextContent({variation: variant, state: isActive ? 'active' : 'inactive' })
      )}
    >...</div>;
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Choose according to reactjs using react-select

Currently working on a ReactJS app that includes a page with two select elements, where one is dependent on the other. I am integrating react-select and @material-ui. Within the context of dates: [ { "id": 1, "name": "20 ...

When utilizing Angular, the mat-datepicker is displayed underneath the modal, even after attempting to modify the z-index

I am encountering a problem with a mat-datepicker displaying below a modal in my Angular application. Here are the key details: Html: <div class="col-12"> <mat-form-field appearance="fill"> <mat-label>Start Date ...

Issue with exporting Typescript React component

Despite searching for answers, none of the related questions have been helpful... My goal is to export React components from a TypeScript library that I plan to publish on npm. For testing purposes before publishing, I am utilizing npm link. The structu ...

Is there a way to remove backdrop-filter: blur effect from elements within a div?

Having an issue with a CSS property. I have designed a modal that includes inputs and labels, and I want to blur the background content. However, the problem I am facing is that the blur effect is also being applied to all elements inside the container, in ...

During the rendering process, the array mysteriously disappears

Currently, I have a working MYProfile.js file from which I removed the imports and styles section for simplicity. class MyProfile extends Component { constructor({match}) { console.log("constructor"); super() this.state = { user: &apos ...

Error: The current element cannot be clicked. Please try again

I have been attempting to trigger a click event on another button within an onClick event function. An error occurred: Uncaught TypeError: this.clickBack.current.click is not a function The React version being used is 16.8.6 constructor(props) { s ...

Issue with fortawesome icon: relative and absolute positioning not functioning as expected

I have utilized a diamond symbol from the Fort Awesome icon collection and noticed that when I target the i tag in my CSS, the icon becomes highlighted (see screenshot attached). However, I am encountering issues with relative and absolute positioning not ...

Combining React components with SCSS styles from separate files may cause overlap

Currently, I am in the process of developing a project that involves integrating SCSS with React. The Issue Despite using 3 global style files and 1 individual SCSS file for each component, it appears that styles are being applied without even importing ...

Issue: I am encountering a "Not Found" error when attempting to render the chart

"I keep encountering the Element not found error when using chart.render(). Removing the question mark fixes it temporarily, but upon page refresh, the same error reappears. Interestingly, adding back the question mark resolves the issue. However, occ ...

Ensure that the header stays centered on the page as you scroll horizontally

Below is a given code snippet: header { text-align: center; } /* This section is just for simulation purposes */ p.text { width: 20rem; height: 50rem; } <html> <body> <header> <h1>Page Title</h1> <detail ...

Fade In/Out Scroll Effect

As the user scrolls down the page, I have a slider that smoothly slides from right to left. What I'm trying to achieve is for the slider to fade out when the last slide is no longer in view during downward scrolling, and fade back in as the last slid ...

What is the best way to position a div at the bottom of the main div?

How can I position a div with the class "boxLinks" at the bottom of the main box with the class "main-box"? Here's my idea: The main class has a width of 1200px; within this main class, there are 5 divs with each div having a width of 25%. .main- ...

Inadequate text alignment

Trying to create a header mockup for a website featuring branding elements like a logo and brand name. Utilizing Angular.js for the webpage development process, incorporating a URL for the logo image from an online source. Encountering alignment issues th ...

Omitting an element from the CSS styling

How can I create a CSS selector that targets the text content within this snippet, excluding the <label> component? Essentially, I want to style the text in the div while leaving the label unchanged. <div id="edit-cc" class="form-item form-type ...

site with scrolling options in various directions

Someone recently asked me if I could create a multi-directional scrolling website similar to the one found at COS, but using WordPress. At first, I assumed it might be done with Flash, but the source code suggests it could actually be more simple, possibly ...

Exploring the benefits of using getServerSideProps with NextJS and Typescript for

Dear community, I am facing a challenge with integrating NextJS Layout and Typescript. Although everything seems to be working fine, I can't seem to get rid of the squiggly line under the props when passing them from getServerSideProps. The prop {som ...

Display a remote page on hover using Javascript, CSS, and HTML without providing any clickable link

How can I display a preview of another page within a div container without actually making the text clickable? I want the preview to show when the mouse hovers over specific text, but I need the original text to stay on the main page. I've experiment ...

CSS guidelines for handling single line breaks with the white-space property set to pre-wrap

Is it considered acceptable to include solitary carriage return characters in an HTML block styled with white-space: pre-wrap? I am working with an application that receives SOAP messages and logs them to a file. The logging process involves removing new- ...

The strange behavior of !important, display:none, and .height()

While working with a piece of JS code yesterday, I stumbled upon something peculiar. There was a div element that was initially hidden using display:none, and I was utilizing its height in some JavaScript calculations. Everything was functioning properly u ...

Tips for refreshing the appearance of a window in angular when it is resized

I have a chat feature integrated into my application. I am looking to dynamically resize an image within the chat window when the width of the window falls below a certain threshold. Is there a method available to modify the CSS style or class based on the ...