Search code examples
cssreactjsmaterial-uiflexboxstyled-components

How to change the line connectors in the MUI Stepper component to not have a space between steps' icons


I am trying to create a Stepper component with MUI V5, but I am having a problem where there is a space between the icons and the line connectors. Here is what I currently have:

enter image description here

This is what I am trying to achieve:

enter image description here

Here is my code:

import * as React from "react";
import Box from "@mui/material/Box";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import { StepLabel, StepConnector } from "@mui/material";
import StepContent from "@mui/material/StepContent";
import Button from "@mui/material/Button";
import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import RadioButtonCheckedIcon from "@mui/icons-material/RadioButtonChecked";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import CircleOutlinedIcon from "@mui/icons-material/CircleOutlined";

const steps = [
  {
    label: "Trade-in started",
    description: `04/01/2023`
  },
  {
    label: "Device inspected"
  },
  {
    label: "Trade-in complete (credit pending)"
  }
];

const ActiveStepIcon = styled(RadioButtonCheckedIcon)(({ theme }) => ({
  color: "black"
}));

const NonActiveStepIcon = styled(CircleOutlinedIcon)(({ theme }) => ({
  color: "grey"
}));

const CompletedStepIcon = styled(CheckCircleIcon)(({ theme }) => ({
  color: "black"
}));

const CustomStepConnector = styled(StepConnector)(({ theme }) => ({
  "& .MuiStepConnector-line": {
    minHeight: "131px",
    borderLeft: "2.5px solid black" // Add a border to simulate the line
  },
  "& .MuiStepConnector-icon": {
    marginLeft: "-12px" // Adjust this value as needed to control the spacing
  }
}));

export default function VerticalLinearStepper() {
  const [activeStep, setActiveStep] = React.useState(0);

  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };

  const handleBack = () => {
    setActiveStep((prevActiveStep) => prevActiveStep - 1);
  };

  const handleReset = () => {
    setActiveStep(0);
  };

  return (
    <Box sx={{ maxWidth: 400 }}>
      <Stepper
        activeStep={activeStep}
        orientation="vertical"
        connector={<CustomStepConnector />}
      >
        {steps.map((step, index) => {
          const stepProps = {};
          const labelProps = {
            StepIconComponent:
              activeStep === index
                ? ActiveStepIcon
                : steps[index].completed
                ? CompletedStepIcon
                : NonActiveStepIcon
          };
          if (index === 0) {
            labelProps.optional = (
              <Typography variant="caption">{step.description}</Typography>
            );

            // setActiveStep(1)
          }
          // if (isStepSkipped(index)) {
          //   stepProps.completed = false
          // }
          return (
            <Step key={step.label} {...stepProps}>
              <StepLabel {...labelProps}>{step.label}</StepLabel>
            </Step>
          );
        })}
      </Stepper>
    </Box>
  );
}

I tried removing padding and margins on both MuiStep-root and MuiStepLabel-root classes and adding a minHeight on MuiStepConnector-root, but those didn't remove the spacing in between

Can someone shed some light into the matter?


Solution

  • <Stepper
       {...otherProps}
       sx={{
         "& .MuiStep-root": {
            "& .MuiStepLabel-root": {
              padding: 0,
              height: '20px'
            }
          },
          "& .MuiStepConnector-root": {
            marginLeft: "11px"
          }
       }}
    
       {children}
    </Stepper>
    

    demo (forked)