I'm looking to create a Slider component using @material-ui/core that has a track divided into two sections with distinct colors for the left and right sides. How

When the slider ranges from -10 to 0, I want it to display in red. For values between 0 and +10, I would like it to be shown in green.

Is there a way to implement this color change using the <Slider /> component from @material-ui/core?

Answer №1

Uncertain about whether you were referring to the rail or track element of the Slider, I've included styles for both below. It's simply a matter of targeting the appropriate classes made available by the Material-UI API. For a comprehensive list of the Slider element's classes, refer to the documentation here.

The background of the rail can be customized with a linear-gradient image created using CSS, and the track itself can be conditionally styled by providing a prop to the makeStyles function:

import React from "react";

import Slider from "@material-ui/core/Slider";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles({
  rail: {
    background: "linear-gradient(90deg, red 50%, green 50%)"
  },
  track: {
    background: ({ value }) => (value >= 0 ? "green" : "red")
  }
});

const marks = Array.from({ length: 21 }, (_, i) => ({
  value: i - 10,
  label: i - 10
}));

const App = () => {
  const [value, setValue] = React.useState(0);

  const classes = useStyles({ value });

  return (
    <Slider
      onChange={(e, newValue) => setValue(newValue)}
      max={10}
      min={-10}
      value={value}
      classes={classes}
      marks={marks}
      step={1}
    />
  );
};

export default App;

In line with your suggestion, you can also pass the value prop to the rail and style it based on conditions. The need to style the left side of the rail gray is eliminated as it will continuously be obscured by the track in that scenario:

rail: {
    background: ({ value }) =>
      `linear-gradient(90deg, red 50%, ${value < 0 ? "gray" : "green"} 50%)`
},

If not required, consider excluding the track element entirely and increase the opacity of the rail while addressing the two distinct sides through conditional statements:

rail: {
  opacity: 0.7,
  background: ({ value }) => {
    const left = value < 0 ? "red" : "gray";
    const right = value < 0 ? "gray" : "green";
    return `linear-gradient(90deg, ${left} 50%, ${right} 50%)`;
  }
},
track: {
  display: "none",
}

Answer №2

Visit this link to view the code sample

import React, { useState } from "react";
import { Box, Typography, Slider } from "@mui/material";

function CustomizeSlider(props) {
  const {
    title,
    reverse,
    values,
    min,
    max,
    thresholdMarks,
    thresholdTitles,
    style,
    ...rest
  } = props;

  const [value, setValue] = useState(
    reverse ? values.map((val) => -val) : values
  );
  const [marks, setMarks] = useState(
    reverse ? thresholdMarks.map((val) => -val) : thresholdMarks
  );
  const [perc, setPerc] = useState(
    reverse
      ? values.map((val) => parseInt((1 - Math.abs(val / max)) * 100))
      : values.map((val) => (val / max) * 100)
  );

  const onChange = (e, tValues) => {
    const [minVal, maxVal] = tValues;
    if (maxVal > minVal && maxVal !== minVal) {
      setValue(tValues);
      if (!reverse) {
        setMarks([
          parseInt((min + minVal) / 2, 10),
          parseInt((minVal + maxVal) / 2, 10),
          parseInt((maxVal + max) / 2, 10),
        ]);
        setPerc(tValues.map((val) => (val / max) * 100));
      } else {
        setMarks([
          parseInt((-max + minVal) / 2, 10),
          parseInt((minVal + maxVal) / 2, 10),
          parseInt((maxVal + -min) / 2, 10),
        ]);
        setPerc(
          tValues.map((val) => parseInt((1 - Math.abs(val / max)) * 100))
        );
      }
    }
  };

  console.log(value, perc, marks);
  return (
    <Box
      sx={{
        width: "80%",
        margin: "16px",
      }}
    >
      <Typography
        id="custom-slider"
        gutterBottom
        sx={{
          marginBottom: "40px",
        }}
      >
        {title}
      </Typography>
      <Slider
        sx={{
          "& .MuiSlider-track": {
            background: "#47D7AC",
            borderColor: "#47D7AC",
          },
          // Other styles...
          
        }}
        valueLabelDisplay="on"
        valueLabelFormat={(x) => `< ${x}`}
        {/* Additional slider properties */}
        {...rest}
      />
    </Box>
  );
}

export default function CustomSliderComponent() {
  return (
    <Box>
      <CustomizeSlider
        title="Reverse custom range"
        reverse={true}
        step={1}
        values={[10.0, 4.0]}
        min={0}
        max={24}
        thresholdMarks={[17, 7, 2]}
        thresholdTitles={["R", "Y", "G"]}
      />
      <CustomizeSlider
        title="Normal range"
        reverse={false}
        step={1}
        values={[4, 5, 7]}
        min={0}
        max={10}
        thresholdMarks={[3, 5, 8]}
        thresholdTitles={["R", "Y", "G"]}
      />
    </Box>
  );
}

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

How to Implement a ForwardedRef in Material-UI using Typescript

Currently, I have implemented a customized checkbox that is being forwarded as a component to a DataGrid. const CustomCheckbox = ({ checkboxRef, ...props }: { checkboxRef: React.ForwardedRef<unknown>; }) => ( <Checkbox {...props} ...

Cross-browser compatibility issue: Chrome displays image class in HTML CSS, while Firefox does not

I am building a webpage and have encountered an issue with displaying images in different browsers. Specifically, the image appears correctly in Chrome and Safari but doesn't show up in Firefox. By "doesn't show," I mean that the image is not vi ...

Determine the sphere's color using the coordinate system in three.js

Is there a way to customize the color of this sphere rendered in three.js based on its coordinates? For instance, can I make the top half of the sphere red and the bottom half black? var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamer ...

Dealing with cascading jQuery deferred callsHere are some guidelines on

When I have a function that needs to retrieve data and return a promise, I often find myself making multiple requests one after another. This results in nested deffered calls where the last call resolves on the deferred object that the function ultimatel ...

Filling a Textbox with pre-selected options from a Dropdown menu

I have a dropdown list that has been populated from my database, along with three textboxes. Now, I need help retrieving data into the textboxes from the database based on the selected item in the dropdown using JavaScript. If anyone could assist me with ...

Ways to examine a JavaScript Bound Function

Can a JavaScript bound function be inspected somehow? I need to be able to return a bound function from a function, and when unit testing, I'd like to verify the bound function's target, boundThis, and boundArgs. These properties seem to be inte ...

Hiding my valuable content with a sneaky CSS nav bar

My current issue involves the nav bar overlaying my content Here is a link to the problem for reference I am seeking advice on how to resolve this issue, as I'm unsure of what steps to take The nav bar functions properly in responsive/mobile mode, ...

What could be the reason for the empty value of driver_execute?

I'm attempting to input text into a textfield using code. binary = FirefoxBinary("C:\Program Files\Mozilla Firefox\Firefox.exe") driver = webdriver.Firefox(firefox_binary=binary) text = 'sending something to the text area' ...

I designed three interactive buttons that allow users to change the language of the website with a simple click. While my JavaScript code functions perfectly on local host, it seems to encounter issues when deployed

For those interested, the live server can be accessed at . After creating 3 buttons that change the language of the website when clicked, the issue arose where the JavaScript code worked perfectly on localhost but failed to function properly on the online ...

The video.play() function encountered an unhandled rejection with a (notallowederror) on IOS

Using peer.js to stream video on a React app addVideoStream(videoElement: HTMLVideoElement, stream: MediaStream) { videoElement.srcObject = stream videoElement?.addEventListener('loadedmetadata', () => { videoElement.play() ...

Utilize AngularJS to import a unique custom css stylesheet for every individual webpage

Is there a way to apply different stylesheets to each page without mixing classes? For example, how can I link style.css to index.html and about.css to about.html? This is my AngularJS code: // Define module var myApp = angular.module('myApp', ...

Unusual behavior observed in Angular.js using ng-pattern

I've been working on creating a form that can accept Twitter parameters like # and @ to display a Twitter feed. Initially, I intended to use the ng-pattern directive in Angular.js to validate the input before saving. However, the validation process i ...

Struggling to implement a vertical scroll bar in HTML code?

<body ng-app="myApp" ng-controller="myCtrl"> <div ng-show = "dataFromRest" ng-repeat = "x in dataFromRest.posts" > <div class="tittle" style="width: 25%;"> <a href="" ng-click="showDi ...

An easy way to place text along the border of an input field in a React JS application using CSS

I am struggling to figure out how to create an input box with text on the border like the one shown in the image below using CSS. I have searched extensively but have not been able to find any solutions to achieve this effect. I attempted using <input&g ...

Adjust the size of items using a background image that covers the element

I'm struggling with a seemingly simple task here. I've been experimenting with different methods, but I just can't seem to grasp it. On the front page of my website, there is a cover section that contains a logo and a button: <section i ...

Error: The React Native code is unable to access the property 'CameraType' because it is undefined

I'm experiencing issues with my app crashing on an Android device when trying to utilize the expo-camera for camera features. Here is a snippet of my JavaScript code: import React, { useState, useEffect, useRef } from 'react'; import { Text, ...

I'm looking to showcase a snippet of my dynamic text in this section, limited to just two lines and ending with three dots, with a "read more" link positioned alongside

I've attempted using the CSS ellipsis property, but it's cutting off the first line. I want to display two lines (or set a max character length if possible). I looked into the 'limit' property in Angular to trim text, but it's not ...

ClickAwayListener in MUI has the potential to impact all the elements within a popper when attempting

As a new react developer, I have encountered a small problem with my ClickAwayListener. It should close the Popper component when clicking 'x' or outside of it, which it does successfully. However, I have another component inside my Paper, and wi ...

What is the significance of the term "Object object"?

I am new to javascript and encountering an issue. When I use alert in my script, the output data is shown as [Object object]. The function below is called when the button (onClick) is clicked. There are [Object object] elements in the array. The last line ...

Modifying Margin and Spacing for Selections in Radio Buttons

I have successfully implemented the code for a radio button, and everything is working as expected div > label { margin-right: 80px !important; box-shadow: .3rem .3rem .6rem #c8d0e7, -.2rem -.2rem .5rem #FFFFFF; position: relative; ...