React, Material Ui, Emoji slider

enter image description hereenter image description here I’m new to react I have been struggling to come up with that functionality shown in the attached pic, I have managed to implement the emoji slider with different facial expressions, Still cannot implement these different and synchronized moods with the change of every picked up emoji

**the new modification is that I need to use customized SVG Emoji instead of the pre-created standard ones . how can I approach that design ??

import React, { useState } from "react";
import { Router } from "react-router-dom";


export default function Emoji() {
  const [mood, setMood] = useState(null);

  function handleChange(e)
  {
    const val = e.target.value;
    {if (val < 25) {
      setMood("๐Ÿ˜ฃ");
      Router
    } else if (val >= 25 && val < 50) {
      setMood("๐Ÿ˜ž");
    } else if (val  >= 50 && val < 70) {
      setMood("๐Ÿ˜‘");
    } else if (val >= 75 && val < 90 ) {
      setMood("๐Ÿ™‚");
    } else if (val > 90) {
      setMood("๐Ÿ˜ƒ");
    }
  }}


  return (
    <div className="emoji">
        <div style={{position: "relative", bottom: "-90px", fontSize: "100px",transition: "ease-in-out",  }}>
        <input style={{  width: "-webkit-fill-available",}}  type="range" list="tickmarks" onChange={handleChange}  />

        </div>
      <datalist id="tickmarks">
        <option value="preserving face" label="๐Ÿ˜ฃ"></option>
        <option value="pensive face" label="๐Ÿ˜ž"></option>
        <option value="expressionless face" label="๐Ÿ˜‘"></option>
        <option value="slightly smiling face" label="๐Ÿ™‚"></option>
        <option value="grinning face with big eyes" label="๐Ÿ˜ƒ"></option>
      </datalist>

      <p style={{position: "relative", bottom: "108px", fontSize: "70px" }}>{mood}</p>
    </div>
  );
}

.

please any help and support will be much appreciated !!

Answer

The best way to handle this is to keep all the details necessary for the selected mood inside the state (In addition to the mood that you’re displaying). Therefore, storing complete object having mood display and mood features (e.g. – sad, anxious etc.) inside the state is the best possible way to tackle this issue.

Use the following example as a supportive resource to solve your issue.

import React, { useState } from "react";

const moodDetails = {
  mood0: {
    display: "๐Ÿ˜ฃ",
    details: ["Sad", "Stressed", "Anxious"],
  },
  mood1: {
    display: "๐Ÿ˜ž",
    details: ["Sad", "Stressed", "Anxious"],
  },
  mood2: {
    display: "๐Ÿ˜‘",
    details: ["Indifferent", "Board", "Numb"],
  },
  mood3: {
    display: "๐Ÿ™‚",
    details: ["Happy", "Relaxed", "Satisfied"],
  },
  mood4: {
    display: "๐Ÿ˜ƒ",
    details: ["Happy", "Relaxed", "Satisfied"],
  },
};

const gridContainerStyles = {
  display: "grid",
  gridTemplateColumns: "auto auto auto",
  backgroundColor: "#2196F3",
  padding: "10px",
};
const gridItemStyles = {
  backgroundColor: "rgba(255, 255, 255, 0.8)",
  border: "1px solid rgba(0, 0, 0, 0.8)",
  padding: "20px",
  fontSize: "30px",
  textAlign: "center",
};

export default function Emoji() {
  const [mood, setMood] = useState({});

  function handleChange(e) {
    const val = e.target.value;
    if (val < 25) {
      setMood(moodDetails.mood0);
    } else if (val >= 25 && val < 50) {
      setMood(moodDetails.mood1);
    } else if (val >= 50 && val < 70) {
      setMood(moodDetails.mood2);
    } else if (val >= 75 && val < 90) {
      setMood(moodDetails.mood3);
    } else if (val > 90) {
      setMood(moodDetails.mood4);
    }
  }

  return (
    <>
      <div className="emoji">
        <div
          style={{
            position: "relative",
            bottom: "-90px",
            fontSize: "100px",
            transition: "ease-in-out",
          }}
        >
          <input
            style={{ width: "-webkit-fill-available" }}
            type="range"
            list="tickmarks"
            onChange={handleChange}
          />
        </div>
        <datalist id="tickmarks">
          <option value="preserving face" label="๐Ÿ˜ฃ"></option>
          <option value="pensive face" label="๐Ÿ˜ž"></option>
          <option value="expressionless face" label="๐Ÿ˜‘"></option>
          <option value="slightly smiling face" label="๐Ÿ™‚"></option>
          <option value="grinning face with big eyes" label="๐Ÿ˜ƒ"></option>
        </datalist>

        <p style={{ position: "relative", bottom: "108px", fontSize: "70px" }}>
          {mood.display}
        </p>
      </div>
      <h2>How would you describe your mood ?</h2>
      <div style={gridContainerStyles}>
        {mood.details?.map((detail) => (
          <div style={gridItemStyles}>{detail}</div>
        ))}
      </div>
    </>
  );
}

Component view

enter image description here

In-line styling used to decorate the component when showing features. (Better to use antd, material-ui libraries for styling in order to achieve a better view)

mood.details?.map is used to map jsx elements dynamically.

Hope this would solve your issue.