Template in React Timeline component

27 Dec 202412 minutes to read

The Timeline component allows you to customize the appearance for each item by using the template to modify the dot items, templated contents, progress bar styling and more.

The template context receives the following information:

Type Purpose
item Indicates the current data of the Timeline item.
itemIndex Indicates the current index of the Timeline item.
import * as React from "react";
import * as ReactDom from "react-dom";
import { TimelineComponent, ItemsDirective, ItemDirective } from '@syncfusion/ej2-react-layouts';
import './index.css'

function App() {

    const projectMilestones = [
        { content: 'Kickoff meeting'},
        { content: 'Content approved'},
        { content: 'Design approved'},
        { content: 'Product delivered'}
    ];

    const getTemplate = (props) => {
        return (
            <div className={`template-container item-${props.itemIndex}`}>
                <div className="content-container">
                    <div className="timeline-content"> {props.item.content} </div>
                </div>
                <div className="content-connector"></div>
                <div className="progress-line">
                    <span className="indicator"></span>
                </div>
            </div>
        );
    }

    return (
        <div id='timeline' style={{ height: "150px", width: "600px", margin: '50px auto' }}>
            <TimelineComponent cssClass='custom-timeline' template={getTemplate} orientation='Horizontal' >
                <ItemsDirective>
                    {projectMilestones.map((item, index) => {
                        return <ItemDirective key={index} content={item.content} />
                    })}
                </ItemsDirective>
            </TimelineComponent>
        </div>
    );
}
export default App;
ReactDom.render(<App />, document.getElementById("element"));
import * as React from "react";
import * as ReactDom from "react-dom";
import { TimelineComponent, ItemsDirective, ItemDirective, TimelineItemModel } from '@syncfusion/ej2-react-layouts';

function App() {
    
    const projectMilestones: TimelineItemModel [] = [
        { content: 'Kickoff meeting'},
        { content: 'Content approved'},
        { content: 'Design approved'},
        { content: 'Product delivered'}
    ];
    
    const getTemplate = (props: any) => {
        return (
          <div className={`template-container item-${props.itemIndex}`}>
                <div className="content-container">
                    <div className="timeline-content"> {props.item.content} </div>
                </div>
                <div className="content-connector"></div>
                <div className="progress-line">
                    <span className="indicator"></span>
                </div>
            </div>
        );
    }

    return (
        <div id='timeline' style={{ height: "150px", width: "600px", margin: '50px auto' }}>
            <TimelineComponent cssClass='custom-timeline' template={getTemplate} orientation='Horizontal' >
                <ItemsDirective>
                    {projectMilestones.map((item, index) => {
                        return <ItemDirective key={index} content={item.content} />
                    })}
                </ItemsDirective>
            </TimelineComponent>
        </div>
    );
}
export default App;
ReactDom.render(<App />, document.getElementById("element"));
/* Represents the styles for loader */
#loader {
  color: #008cff;
  height: 40px;
  left: 45%;
  position: absolute;
  top: 45%;
  width: 30%;
}

.custom-timeline .e-timeline-item.e-item-template {
  align-items: flex-end;
}
.custom-timeline .e-timeline-items {
  justify-content: center;
}
.template-container .content-connector {
  position: absolute;
  left: 88%;
  width: 3px;
  height: 28px;
}
.template-container .content-container {
  padding: 8px;
  border-width: 1px;
  border-style: solid;
}
.content-container .timeline-content {
  font-size: 14px;
}

/* Color customizations - Progress line, connector line, dot border */
.item-0 .progress-line, .item-0 .content-connector { background-color: rgb(233, 93, 93); }
.item-1 .progress-line, .item-1 .content-connector { background-color: rgba(247, 179, 22, 0.907); }
.item-2 .progress-line, .item-2 .content-connector { background-color: rgb(60, 184, 60); }
.item-3 .progress-line, .item-3 .content-connector { background-color: rgb(153, 29, 230); }

.item-0 .progress-line .indicator, .item-0 .content-container { border-color: rgb(233, 93, 93); }
.item-1 .progress-line .indicator, .item-1 .content-container { border-color: rgba(247, 179, 22, 0.907); }
.item-2 .progress-line .indicator, .item-2 .content-container { border-color: rgb(60, 184, 60); }
.item-3 .progress-line .indicator, .item-3 .content-container { border-color: rgb(153, 29, 230); }

.item-0 .content-container { box-shadow: 2px 2px 8px rgb(233, 93, 93); }
.item-1 .content-container { box-shadow: 2px 2px 8px rgba(247, 179, 22, 0.907); }
.item-2 .content-container { box-shadow: 2px 2px 8px rgb(60, 184, 60); }
.item-3 .content-container { box-shadow: 2px 2px 8px rgb(153, 29, 230); }

/* START --- Customizing Dot and progress line */
.custom-timeline .template-container .indicator {
  position: absolute;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background-color: #fff;
  border-width: 6px;
  border-style: solid;
  left: 88%;
  transform: translate(-50%, -40%);
  cursor: pointer;
}

.progress-line {
  position: absolute; 
  height: 10px;
  width: 100%;
  left: 0;
  top: 50%;
}
/* END --- Customizing Icon and progress line */
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion EJ2 React Timeline Sample</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/29.2.4/ej2-layouts/styles/material.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='element' style="margin-top: 30px;">
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>