Home > other >  Add className to elements based on received number
Add className to elements based on received number

Time:10-22

I'm trying to do a 7 segment led display, and based on number that the application receive, it has to add the disable className to specific item. I've been thinking in a logic to this, but I don't know how to set it up in the code.


Logic:

  1. Do a switch to get what is the received number.
  2. According to the number, I'm doing a disabledSegments array. (e.g. disabledSegments = ['segment-a', 'segment-b', 'segment-c']).
  3. And this is the part that I'm stopped... I coudn't think in a logic to solve my problem.

App:

function App() {  
  let disabledSegments = [];

  switch(3) {
    case '1':
        disabledSegments = ['segment-a', 'segment-d', 'segment-e', 'segment-f', 'segment-g']
        break;
    case '2':
        disabledSegments = ['segment-c', 'segment-f'];
        break;
    case '3':
        disabledSegments = ['segment-e', 'segment-f'];
        break;
    default:
        break;
  }

  return(
    <div className="led-number">
      <div className="segment segment-a">
        <svg width="69" height="15" viewBox="0 0 69 15" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M14.269 14.8295H54.5517L68.4885 1.59469C67.1985 0.597612 65.5846 3.8147e-06 63.8301 3.8147e-06H4.63794C2.89411 3.8147e-06 1.29303 0.589094 0.00726318 1.57233L14.269 14.8295Z" fill="#262A34"/>
        </svg>
      </div>
      
      <div className="segment segment-b">
        <svg width="17" height="65" viewBox="0 0 17 65" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M0.624405 14.2662V55.4704L12.2954 64.2173C14.77 62.9539 16.4669 60.3866 16.4669 57.4177V5.62484C16.4669 3.80751 15.8299 2.14251 14.7721 0.832241L0.624405 14.2662Z" fill="#262A34"/>
        </svg>
      </div>

      <div className="segment segment-c">
        <svg width="17" height="65" viewBox="0 0 17 65" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M0.624405 50.7207V9.51645L12.2954 0.769611C14.77 2.03407 16.4669 4.60029 16.4669 7.56917V59.3621C16.4669 61.1783 15.8299 62.8433 14.7721 64.1557L0.624405 50.7207Z" fill="#262A34"/>
        </svg>
      </div>
  
      <div className="segment segment-d">
        <svg width="69" height="15" viewBox="0 0 69 15" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M14.269 0.169458H54.5517L68.4885 13.4053C67.1985 14.4003 65.5846 15 63.8301 15H4.63793C2.8941 15 1.29302 14.4088 0.00725555 13.4256L14.269 0.169458Z" fill="#262A34"/>
        </svg>
      </div>
      
      <div className="segment segment-e">
        <svg width="16" height="65" viewBox="0 0 16 65" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M1.71614 64.1944C0.644493 62.8799 0 61.2032 0 59.3741V7.58124C0 4.61236 1.69695 2.04614 4.17155 0.781677L15.8425 9.52852V51.064L1.71614 64.1944Z" fill="#262A34"/>
        </svg>
      </div>

      <div className="segment segment-f">
        <svg width="16" height="65" viewBox="0 0 16 65" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M1.71614 0.815502C0.644493 2.1311 0 3.80888 0 5.63687V57.4298C0 60.3986 1.69695 62.9659 4.17155 64.2293L15.8425 55.4825V13.947L1.71614 0.815502Z" fill="#262A34"/>
        </svg>
      </div>

      <div className="segment segment-g">
        <svg width="63" height="17" viewBox="0 0 63 17" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M51.4494 0.390018H11.0175L0.249847 8.32726L11.0175 16.2656H26.4329H36.034H51.4494L62.217 8.32726L51.4494 0.390018Z" fill="#262A34"/>
        </svg>
      </div>
    </div>
  )
}

CSS:

.led-number {
    position: relative;
    width: 75px;
    height: 135px;
    margin: 0px 5px; }

.segment {position: absolute}

.segment-a {    
    left: 3px;
    top: 0; }

.segment-b {    
    right: 0;
    top: 2px; }

.segment-c {
    right: 0;
    bottom: -1px; }

.segment-d {
    left: 3px;
    bottom: -3px; }

.segment-e {
    left: 0;
    bottom: -1px; }

.segment-f {
    left: 0;
    top: 2px; }

.segment-g {
    left: 6px;
    top: 58px; }

.segment-disable svg path {fill: #DDDDDD !important;}

Output without logic / Expected output:

OutputWithoutLogic ExpectedOutput


P.S: The number in the switch is hard coded just to show the problem.

CodePudding user response:

You can create an array of 14 binary values, 0/1 or T/F, and flip them depending on the received number.

Since you tagged this with React, you should be using state:

import { useState } from 'react';
// ...
const [segments, setSegments] = useState([0,0,0,0,0,0,0,0,0,0,0,0,0,0]);

As for styling, create "active" and "inactive" classes:

.active svg {
    fill: blueviolet;
}

.inactive svg {
    fill: lightgray;
}

Then just render the segments with the appropriate class depending on the state:

<div className={segments[0] === 1 ? 'active' : 'inactive'}>
    // ...
</div>

Here's a basic sandbox to get you going.

CodePudding user response:

You know about the disabled segments by adding them in the disabledSegments array.

So, you need to check for disabled elements and pass them disabled className. there are many ways to do that. as a solution, you can check every segment too if they are in the disabledSemgents and add the segment-disable class name for the disabled item:

<div className={`segment segment-a ${disabledSegments.includes("seggment-a") && "segment-disable" }`}>
  <svg width="69" height="15" viewBox="0 0 69 15" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M14.269 14.8295H54.5517L68.4885 1.59469C67.1985 0.597612 65.5846 3.8147e-06 63.8301 3.8147e-06H4.63794C2.89411 3.8147e-06 1.29303 0.589094 0.00726318 1.57233L14.269 14.8295Z" fill="#262A34"/>
  </svg>
</div>

since the logic is the same for the other segments, you can create a simple function to do that:

function disableCheker (segmenetName) {
  let className = "segment"   segmenetName
  if (disabledSegments.includes(segmentName)) {
    className  = "segment-disable"
  }
  
  return className;
}

With this simple implementation, the segment class name and the segmanet name are always passed to the className, but if the segmentName was in the disabledSegments array, the segment-disable class name also added to the other classNames and return them as a string, so easy you can use this function to determines your className in segments elements:

<div className={disbaleChecker("segment-a")}>
 // rest of the codes ...
</div>

<div className={disbaleChecker("segment-b")}>
 // rest of the codes ...
</div>

But, wait a minute, with this approach, your segments will not re-render with changes on the disabledSegments array. So, easily you can create a state variable instead of defining your disablesSegments array in the component.

import React, {useState} from 'react';

function App () {
  const [disabledSegments, setDisabledSegments] = useState([])

  // rest of the codes ...
  
  handleChange = () => {
    switch(numer) {
      case '1':
        setDisabledSegments(['segment-a', 'segment-d', 'segment-e', 'segment-f', 'segment-g'])
        break;
      case '2':
        setDisabledSegments(['segment-c', 'segment-f']);
        break;
      case '3':
        setDisabledSegments(['segment-e', 'segment-f']);
        break;
      default:
        return;
    }
  }

  // rest of the codes ...
}
  • Related