6

I'm trying to implement a horizontal timeline using Material UI in React. In their documentation I could find only vertical timeline demos and I couldn't find any prop that can directly change the alignment. Is there a way to solve this?

I would want to implement something like the below image, but horizontal.

enter image description here

2 Answers2

10

You can override the timeline styles and do something like this:

const useStyles = makeStyles({
  timeline: {
    transform: "rotate(90deg)"
  },
  timelineContentContainer: {
    textAlign: "left"
  },
  timelineContent: {
    display: "inline-block",
    transform: "rotate(-90deg)",
    textAlign: "center",
    minWidth: 50
  },
  timelineIcon: {
    transform: "rotate(-90deg)"
  }
});

function App() {
  const classes = useStyles();

  return (
    <Timeline className={classes.timeline} align="alternate">
      <TimelineItem>
        <TimelineSeparator>
          <CheckCircleOutlineIcon
            color="primary"
            className={classes.timelineIcon}
          />
          <TimelineConnector />
        </TimelineSeparator>
        <TimelineContent className={classes.timelineContentContainer}>
          <Paper className={classes.timelineContent}>
            <Typography>Eat</Typography>
          </Paper>
        </TimelineContent>
      </TimelineItem>
      <TimelineItem>
        <TimelineSeparator>
          <PauseCircleFilledIcon
            color="primary"
            className={classes.timelineIcon}
          />
          <TimelineConnector />
        </TimelineSeparator>
        <TimelineContent className={classes.timelineContentContainer}>
          <Paper className={classes.timelineContent}>
            <Typography>Code</Typography>
          </Paper>
        </TimelineContent>
      </TimelineItem>
      <TimelineItem>
        <TimelineSeparator>
          <CachedIcon color="primary" className={classes.timelineIcon} />
          <TimelineConnector />
        </TimelineSeparator>
        <TimelineContent className={classes.timelineContentContainer}>
          <Paper className={classes.timelineContent}>
            <Typography>Sleep</Typography>
          </Paper>
        </TimelineContent>
      </TimelineItem>
      <TimelineItem>
        <TimelineSeparator>
          <CachedIcon color="primary" className={classes.timelineIcon} />
          <TimelineConnector />
        </TimelineSeparator>
        <TimelineContent className={classes.timelineContentContainer}>
          <Paper className={classes.timelineContent}>
            <Typography>Repeat</Typography>
          </Paper>
        </TimelineContent>
      </TimelineItem>
      <TimelineItem>
        <TimelineSeparator>
          <ErrorIcon color="primary" className={classes.timelineIcon} />
        </TimelineSeparator>
        <TimelineContent className={classes.timelineContentContainer}>
          <Paper className={classes.timelineContent}>
            <Typography>Sleep</Typography>
          </Paper>
        </TimelineContent>
      </TimelineItem>
    </Timeline>
  );
}

If the labels aren't on the same elevation, adjust minWidth.


The result looks like this:

timeline

One thing that will feel weird using this approach is that the visually left most element is the last element in the timeline, because of the rotation.

Bas van der Linden
  • 11,895
  • 4
  • 22
  • 47
6

If you like, you can use stepper as an alternative solution

Material UI stepper

user3184687
  • 79
  • 1
  • 2