Switching over to styled components from plain CSS using a ternary operator

Currently, I am in the process of converting my project from using regular CSS to styled components (https://styled-components.com/). So far, I have successfully converted all my other components except for one that I'm having trouble with. I've looked at examples on Stack Overflow, but nothing quite matches my scenario. I am dealing with conditional class names.

My main question is how to convert the InfoBox component to utilize styled components. The issue lies with the 'className' attribute which is proving to be a bit tricky to translate into a styled component. Do you have any ideas on how to approach this?

English is not my native language so there may be mistakes.

Here is a snippet of my code:

import React from 'react'
import "./InfoBox.css"
import { Card } from "@material-ui/core"

function InfoBox({ isRed, active, activetored, ...props }) {
    return (
        <Card onClick={props.onClick}
            className={`infoBox ${active && "infoBox--selected"} 
            ${activetored && "infoBox--selectedtored"}
            ${isRed && "infoBox--red"} `} >
           
        </Card>
    )
}

export default InfoBox

<div className="app__stats">
    <InfoBox
        isRed
        active={typeofCase === "cases"}
        onClick={(e) => setTypeofCase('cases')}
       
    />
    <InfoBox
        isGreen
        active={typeofCase === "recovered"}
        onClick={(e) => setTypeofCase('recovered')}
     
    />
    <InfoBox
        isRed
        activetored={typeofCase === "deaths"}
        onClick={(e) => setTypeofCase('deaths')}
       
    />
</div>

The CSS structure looks something like this (you can adjust as needed):

.infoBox--selected {
  border-top: 10px solid greenyellow;
}

.infoBox--selectedtored {
  border-top: 10px solid red;
}

.infoBox--red {
  border-color: darkblue;
}

Answer №1

If you're ready to get started, take a look here for guidance on using props with styled-components. Using these props allows for endless possibilities within a styled component, and it can be implemented in your code like this:

import React from 'react'
import "./InfoBox.css"
import { Card } from "@material-ui/core"
import styled from 'styled-components'

const StyledCard = styled(Card)`
  border-top: ${({$active, $activetored}) => $active ? '10px solid greenyellow' : $activetored && '10px solid red'};
  border-color: ${({$isRed}) => $isRed && 'darkblue'};
`

function InfoBox({ isRed, active, activetored, ...props }) {
    return (
        <StyledCard $isRed={isRed} $active={active} $activetored={activetored} onClick={props.onClick}>
           
        </StyledCard>
    )
}

export default InfoBox

It's important to note that the values of active and activetored may conflict depending on the order of ternary conditions if both are true. In your example, there isn't a scenario where both props are set to true so everything should work as expected.

Answer №2

To make conditional class names more manageable, I recommend utilizing the classnames package: https://www.npmjs.com/package/classnames

With this import, you can easily create intricate class names that are easy to understand. In your scenario, the code may look something like this:

import classNames from 'classnames';

....

className={classNames('infoBox', {
  'infoBox--selected': active,
  'infoBox--selectedtored': activetored,
  'infoBox--red': isRed
})}

Answer №3

If you're using CSS modules, here's a solution to clear up any confusion:

Start by importing the styles from your CSS file:

import * as customStyles from "./InfoBox.css"

You can then use the available classes in className like this:

className={customStyles['infoBox'] + `${isActive && customStyles['infoBox--highlighted']}`} 

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

What is the best way to transfer variables defined in PHP to JavaScript?

Can the variables previously defined in JavaScript be used in the line that starts with $sql =? var southWestLat = map.getBounds().getSouthWest().lat(); var southWestLng = map.getBounds().getSouthWest().lng(); var northEastLat = map.getBounds().getNort ...

AngularJS restructured the homepage to function as a shell page instead of the traditional index page

As a newcomer to angularJS, I am learning that it is typically designed for Single Page Applications. Most example logins I come across define the index.html as the main page, with the ng-view portion contained within. However, in my situation, the Login ...

Waiting for Promise Js to be fulfilled

I've been exploring the use of Bluebird for handling promises in Node.Js. I have encountered a situation where I need a function to return only when a promise is fulfilled. The desired behavior can be illustrated by the following code snippet: functi ...

View a specific selected newsAPI article on its own dedicated page

I have been working on a news website and successfully displayed all the articles on a single page using the news API in nodeJs. Everything is functioning well, but now I want to show the clicked article on a separate page. Although I managed to route it t ...

Change all instances of the asterisk character to a red color on every page using CSS styling

Is it possible to change the color of the asterisk that indicates required fields on all forms across my site without having to wrap it in a div or another wrapper? ...

This error message in AngularJS indicates that the argument 'fn' is not being recognized as a function

I am currently working with angularjs and typescript and I am attempting to create a directive in the following manner: Below is my controller : export const test1 = { template: require('./app.html'), controller($scope, $http) { ...

ReactJS fetching previous data through POST request

I am facing an issue while trying to replicate Google Translate. I have an API that sends and returns data as expected during the first translation attempt. However, after changing the text and attempting another translation, it sends the updated text but ...

Using Rowspan in Bootstrap 4 Beta 0 Grid System

Hey there, currently I'm working on an eCommerce template using Bootstrap 4 Beta. While I managed to get it working smoothly on mobile devices, I've run into a snag on desktop. I can't seem to figure out how to keep the Buy Box positioned un ...

Ways to retrieve a variable within the init() function

My current project involves using datatables along with ajax to display information dynamically. Below is the code snippet I am working with: // Setting up the module var DatatableAdvanced = function() { // Examples of Basic Datatables var _c ...

turn on labels for every individual cell in the bar graph

I'm working on setting labels of A, B, and C for each bar chart cell to display all my data on the chart. I attempted using data.addColumn('string', 'Alphabets'); but it's not functioning as expected. It seems like a simple ta ...

Combining an Image with a CanvasJS Graph and Generating a Downloadable Image of the Composite

I am attempting to combine an image (a background image for my graph) with my canvasJS chart. Once these elements have been merged on a canvas, I aim to obtain a DataURL of this canvas, enabling me to download an image of it (depicting the graph along wit ...

Creating a personalized pivot-table using the WebDataRock Javascript library with a unique configuration based on a

I'm having trouble getting this demo to work with the "hierarchy" parameter. Even when I specify the parameter value, it seems to apply the condition to the entire hierarchy chain. "conditions": [{ "formula": "#val ...

The video element in HTML5 is not showing up on Safari browsers, but it is functioning properly on Chrome

I have set up a video slider on my webpage. You can view the site The code is functioning perfectly on Chrome and iOS Safari, but there seems to be an issue on desktop browsers. When inspecting the page in Safari, the video elements are present in the HTM ...

What is the best way to conceal a canvas or another item?

Within my main canvas, there are three smaller canvases and a text element. <canvas id="Background" width="350" height="300" style="border:6px solid black; position: absolute; left: 10px; top: 10px;"> </canvas> <canvas id="Canvas1" width ...

How can I transfer checkbox data to another page utilizing ajax or javascript?

These are the checkboxes I am using and I want to pass the selected items' values to another page using ajax with javascript. I am looking to send the selected checkbox values through ajax to a different page... Your help would be greatly appreciate ...

What's preventing the mobx @computed value from being used?

Issue: The computed value is not updating accordingly when the observable it is referencing goes through a change. import {observable,computed,action} from 'mobx'; export default class anObject { // THESE WRITTEN CHARACTERISTICS ARE COMPUL ...

Utilize user input to fetch data from an external API

Let's say there is a field for 'part number' input that is not enclosed in a form tag. Whenever a user enters a value, the onblur event or a button positioned next to the input field should trigger a query to an external site via its API and ...

Angular 2 can efficiently generate multiple HTTP requests simultaneously from a single HTTP request

Backend API's: url: [ { "name": "ABC", "occupation": "Student", "address_url": "http://www.sample.com/address/person=hgjgjgyyfhg" }, { "name": "ABC1", "occupation": "Carpenter", "address ...

Looking for a logo placed in the center with a top fixed navigation using Bootstrap

I am in need of a Centered Logo using Bootstrap fixed top navigation. The goal is to have the brand centered within the navigation. Check out my Sample Fiddle .LandPageNavLinks { list-style-type:none; margin:0; padding:0; } .LandPageNavLin ...

The mysterious case of the vanishing close button on Curator.io's mobile

Currently, I am using curator.io aggregator to showcase my Instagram feed on the website. An issue arises when switching to mobile view as the close button (class="crt-close") disappears. You can see an example of this here: To replicate the pr ...