12

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

Athira Sreekumar
  • 192
  • 1
  • 1
  • 8
  • Has Google not given you any good ideas? When I searched I got some good results by searching `horizontal timelines ui` – user115014 Jul 30 '20 at 14:43
  • 1
    Could you tell a bit more about your use case, because using a Stepper is might be the better (easier) approach. – 5eb Jul 30 '20 at 14:55
  • 1
    @MikeW This question is about implementing it with this library (https://material-ui.com/) specifically. – 5eb Jul 30 '20 at 14:58
  • @BasvanderLinden apologies - I missed that – user115014 Jul 30 '20 at 15:00
  • @BasvanderLinden I've edited my post with more details. I too thought about stepper, but then I feel it would be complicated, since i can't use properties like align="alternate". – Athira Sreekumar Jul 31 '20 at 06:51

3 Answers3

14

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.

5eb
  • 14,798
  • 5
  • 21
  • 65
12

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

Material UI stepper

user3184687
  • 147
  • 1
  • 4
0

In terms of UX, a timeline is most likely vertical. However, Mui stepper might be the one that you need: https://mui.com/material-ui/react-stepper/.

You can opt in for an alternativeLabel and add content with StepLabel.