Search code examples
javascriptreactjsmapping

How to add different colors to different letters in a word in React?


How can i add specfic color to each letter in a word , the color of each letter should be same if it is repeating. Like if b is repeating then all b letters should have the same color.

Here is my color obj as key value pair-

const colorObj = 
{
  a: "red",
  b: "green",
  c: "blue",
  d: "violet",
  e: "yellow",
  f: "orange",
  g: "brown",
  h: "indigo",
  i: "cadetblue",
  j: "chocolate",
  k: "crimson",
  l: "darkcyan",
  m: "darkgrey",
  n: "darkolivegreen",
  o: "darkorange",
  p: "darkviolet",
  q: "deeppink",
  r: "fuchsia",
  s: "gold",
  t: "greenyellow",
  u: "khaki",
  v: "springgreen",
  w: "yellowgreen",
  x: "sienna",
  y: "royalblue",
  z: "peachpuff",
},

Here curState is the string , for eg curState = "hello" i tried to create an array of objects -

  let arr = [];
  const [cards, setCards] = useState(arr);

  for (let i = 0; i < curState.length; i++) {
    arr.push({
      id: i,
      letter: curState[i],
      color: colorObj [curState[i]],
      isPressed: false,
    });
  }

i was rendering the final array in a card component like this -

<div className="flex items-center justify-center">
        <div className="my-grid">
          {cards.map((item) => (
            <Cards
              color={item.color}
              key={item.id}
              id={item.id}
              text={item.letter}
            />
          ))}
        </div>
      </div>

here is the card compoent-

import React from "react";
import { BsTrashFill } from "react-icons/bs";
function Cards(props) {
  return (
    <div
      style={{ backgroundColor: props.color }}
      onClick={props.handleClick}
      className="h-20 w-20 text-yellow-100 flex items-center justify-center cursor-pointer relative rounded-xl"
    >
      {props.text}
      <span onClick={props.delete} className=" absolute top-2 right-2">
        <BsTrashFill />
      </span>
    </div>
  );
}
Cards.defaultProps = {
  // color: "blue",
};
export default Cards;

note the color prop is set to as the style for the card component. but for some reason it dosen't seem to work.


Solution

  • I'm not sure why your code doesn't work When I tried the code in sandbox, it does render properly.

    One issue that I can think of is that in your code, where you loop through the string, once you finish the loop, you need to set the cards value to the array returned.

    But again, I cannot be sure about that since you have not included the complete code. But here's the solution that I used. Maybe you can compare the code and then fix it.

    import "./styles.css";
    import React, {useState, useEffect} from "react";
    import { BsTrashFill } from "react-icons/bs";
    
    const colorObj = 
    {
      a: "red",
      b: "green",
      c: "blue",
      d: "violet",
      e: "yellow",
      f: "orange",
      g: "brown",
      h: "indigo",
      i: "cadetblue",
      j: "chocolate",
      k: "crimson",
      l: "darkcyan",
      m: "darkgrey",
      n: "darkolivegreen",
      o: "darkorange",
      p: "darkviolet",
      q: "deeppink",
      r: "fuchsia",
      s: "gold",
      t: "greenyellow",
      u: "khaki",
      v: "springgreen",
      w: "yellowgreen",
      x: "sienna",
      y: "royalblue",
      z: "peachpuff",
    };
    
    
    function Cards(props) {
      return (
        <div
          style={{ backgroundColor: props.color }}
          onClick={props.handleClick}
          className="h-20 w-20 text-yellow-100 flex items-center justify-center cursor-pointer relative rounded-xl"
        >
          {props.text}
          <span onClick={props.delete} className=" absolute top-2 right-2">
            <BsTrashFill />
          </span>
        </div>
      );
    }
    
    
    
    export default function App() {
    
      const [cards, setCards] = useState([]);
    
      useEffect(() => {
        let arr = [];
        const curState = 'It workssz';
    
      for (let i = 0; i < curState.length; i++) {
        arr.push({
          id: i,
          letter: curState[i],
          color: colorObj [curState[i]],
          isPressed: false,
        });
      }
      setCards(arr);
      },[])
      return (
        <div className="App">
         <div className="flex items-center justify-center">
            <div className="my-grid">
              {cards.map((item) => (
                <Cards
                  color={item.color}
                  key={item.id}
                  id={item.id}
                  text={item.letter}
                />
              ))}
            </div>
          </div>
        </div>
      );
    }
    
    export { Cards };
    

    Here's the sandbox link