简体   繁体   中英

Material UI Slider won't slide

I have a Material UI slider that won't slide when you click on it and drag it. I've more or less copied one of the examples from https://material-ui.com/components/slider/ and added an onChange function. The values update just fine if you click around to different spots. I've been staring at this too long and have gone code blind and can't figure out what I'm missing.

Here's a link to a Sandbox

import React, { useState } from "react";
import PropTypes from "prop-types";
import withStyles from "@material-ui/styles/withStyles";
import Card from "@material-ui/core/Card";
import { Typography, Paper, Grid, CssBaseline } from "@material-ui/core";
import Slider from "@material-ui/core/Slider";

function App(props) {
  const [state, setState] = useState({
    fields: {
      contractAmount: 10000,
      termValue: 2
    }
  });

  const handleInvestmentChange = name => (e, value) => {
    setState({
      ...state,
      fields: {
        ...state.fields,
        [name]: value
      }
    });
  };

  const AmountSlider = withStyles({
    root: {
      color: "#52af77",
      height: 8
    },
    thumb: {
      height: 24,
      width: 24,
      backgroundColor: "#fff",
      border: "2px solid currentColor",
      marginTop: -8,
      marginLeft: -12,
      "&:focus,&:hover,&$active": {
        boxShadow: "inherit"
      }
    },
    active: {},
    valueLabel: {
      left: "calc(-50% + 14px)",
      top: -22,
      "& *": {
        background: "transparent",
        color: "#000"
      }
    },
    track: {
      height: 8,
      borderRadius: 4
    },
    rail: {
      height: 8,
      borderRadius: 4
    }
  })(Slider);

  const TermSlider = withStyles({
    root: {
      color: "#52af77",
      height: 8
    },
    thumb: {
      height: 24,
      width: 24,
      backgroundColor: "#fff",
      border: "2px solid currentColor",
      marginTop: -8,
      marginLeft: -12,
      "&:focus,&:hover,&$active": {
        boxShadow: "inherit"
      }
    },
    active: {},
    valueLabel: {
      left: "calc(-50% + 4px)"
    },
    track: {
      height: 8,
      borderRadius: 4
    },
    rail: {
      height: 8,
      borderRadius: 4
    }
  })(Slider);

  return (
    <div>
      <CssBaseline />
      <Typography variant="h4" align="center" component="h1" gutterBottom>
        Select your Investment Level
      </Typography>
      <Card>
        <Paper style={{ padding: 16, minHeight: 445, maxHeight: 445 }}>
          <Grid container alignItems="flex-start" spacing={2}>
            <Grid item xs={12} lg={12} xl={12}>
              <Typography variant="h4">Investment Amount</Typography>
              <Typography variant="h6" gutterBottom>
                ${state.fields.contractAmount.toLocaleString()}
              </Typography>
              <AmountSlider
                valueLabelDisplay="auto"
                defaultValue={10000}
                value={
                  typeof state.fields.contractAmount === "number"
                    ? state.fields.contractAmount
                    : 2000
                }
                onChange={handleInvestmentChange("contractAmount")}
                step={1000}
                min={2000}
                max={100000}
              />
              <Typography variant="h4">Investment Term</Typography>
              <Typography variant="h6" gutterBottom>
                {state.fields.termValue} years
              </Typography>
              <TermSlider
                name="termValue"
                valueLabelDisplay="off"
                aria-label="term slider"
                defaultValue={10}
                value={
                  typeof state.fields.termValue === "number"
                    ? state.fields.termValue
                    : 2
                }
                onChange={handleInvestmentChange("termValue")}
                min={2}
                max={25}
              />
              <Grid
                item
                style={{
                  marginTop: 16,
                  alignContent: "right",
                  alignItems: "right"
                }}
              >
                <Typography variant="p">
                  *Your investment amount and contract length can be changed at
                  any time as described in our Terms & Conditions.
                </Typography>
              </Grid>
            </Grid>
          </Grid>
        </Paper>
      </Card>
    </div>
  );
}

export default App;

If you need to customize the theme of MUI Slider then you need to use MUI Theme Provider .

And you need to import it like,

import { ThemeProvider, createMuiTheme } from "@material-ui/styles";

Then try moving your custom css into a variable with the value of createMuiTheme method which has overrides property like,

  const AmountSlider = createMuiTheme({
    overrides: {
      MuiSlider: {
        root: {
          color: "#52af77",
          height: 8
        },
        thumb: {
          height: 24,
          width: 24,
          backgroundColor: "#fff",
          border: "2px solid currentColor",
          marginTop: -8,
          marginLeft: -12,
          "&:focus,&:hover,&$active": {
            boxShadow: "inherit"
          }
        },
        active: {},
        valueLabel: {
          left: "calc(-50% + 14px)",
          top: -22,
          "& *": {
            background: "transparent",
            color: "#000"
          }
        },
        track: {
          height: 8,
          borderRadius: 4
        },
        rail: {
          height: 8,
          borderRadius: 4
        }
      }
    }
  });

Then in template use it like,

          <ThemeProvider theme={AmountSlider}>
            <Slider
              valueLabelDisplay="off"
              defaultValue={10000}
              value={
                typeof state.fields.contractAmount === "number"
                  ? state.fields.contractAmount
                  : 2000
              }
              onChange={handleInvestmentChange("contractAmount")}
              step={1000}
              min={2000}
              max={100000}
            />
          </ThemeProvider>

Same way you can implement the custom theme for TermSlider as well..

Forked Codesandbox

Note: I think you are using the same css for both AmountSlider and TermSlider if so, create a single theme variable and use it for both..

Eg.., You could use theme={AmountSlider} for both the Amount and Term sliders if both has the same css.. Ofcourse the variable name can be unique in this case..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM