Headless components for building custom timelines for React. Headless means it doesn't provide any UI or styles for the timeline but only handles the logic. Supports both horizontal and vertical timelines.
- ⚡️ Highly performant and efficient
- 🔒 Type safe - written in TypeScript
- 🫧 Doesn't render any UI nor styles - it's totally up to you how you're going to style your timeline
- 🧩 Supports horizontal and vertical timelines
- 🏃 Small bundle size
See what this library does and doesn't for you and decide whether it's a good fit for you or not.
👍 What it does for you:
- It handles the timeline logic
- It helps you render timeline components in correct position and size
👎 What it doesn't for you:
- It doesn't provide any pre-styled UI components for you (no need to overwrite styles to make timeline looks like in designer's dream)
Still not sure? Check some examples ⬇️
npm install react-headless-timeline
import Timeline from 'react-headless-timeline';
function App() {
const timelineConfig = {
startDate: new Date(1651201447127), // 29th Apr 2022 05:04:07 CET
endDate: new Date(1651221447127), // 29th Apr 2022 10:37:27 CET
}
const events = [
{
startDate: new Date(1651204649127), // 29th Apr 2022 05:57:29 CET
endDate: new Date(1651214649127), // 29th Apr 2022 08:44:09 CET
},
];
return (
<Timeline.Provider {...timelineConfig}>
<>
<Timeline.Headers
render={({ headers, getHeaderStyles }) => (
<div style={{ position: 'relative', width: '100%', height: 30 }}>
{headers.map((header) => (
<span key={header.getTime()} style={getHeaderStyles(header)}>
{header.getTime()}
</span>
))}
</div>
)}
/>
<Timeline.Events
render={({ getEventStyles }) => (
<div style={{ position: 'relative', width: '100%', height: 30 }}>
{events.map((evt, i) => (
<span key={i} style={getEventStyles(evt)}>
Event
</span>
))}
</div>
)}
/>
</>
</Timeline.Provider>
);
}
-
Core timeline component. You have to wrap all of your timeline components inside provider.
Props: (* - these are required)
Name Type Default Description startDate * Date
endDate * Date
direction "horizontal"
/"vertical"
"horizontal"
Determines timeline direction Example:
import Timeline from 'react-headless-timeline'; // ... <Timeline.Provider startDate={startDate} endDate={endDate} direction="horizontal"> {children} </Timeline.Provider>
Other examples: See all ⬇️
-
Provides headers and helper function to generate headers CSS styles (size and position).
Props: (* - these are required)
Name Type Default Description cells number
2 Determines how many headers/cells you want to render. For example if you have a timeline with startDate
set to today 10AM andendDate
set to today 4PM, by default headers will be an array withstartDate
andendDate
. But let's say you want to display headers every 1 hour, you should then set cells to7
- [10AM, 11AM, 12AM, 1PM, 2PM, 3PM, 4PM]. The minimum value is 2render * function
Render your UI inside this function. See example below... Example:
import Timeline from 'react-headless-timeline'; // ... <Timeline.Headers render={({ headers, getHeaderStyles }) => ( <div> {headers.map((header) => ( <span key={header.getTime()} style={getHeaderStyles(header)}> {header.getTime()} </span> ))} </div> )} />
Other examples: See all ⬇️
-
Provides helper function to generate event CSS styles (size and position).
Props: (* - these are required)
Name Type Default Description render * function
Render your UI inside this function. See example below... Example:
import Timeline from 'react-headless-timeline'; // ... <Timeline.Events render={({ getEventStyles }) => ( <div> {events.map((evt, i) => ( <span key={i} style={getEventStyles(evt)}> Event </span> ))} </div> )} />
Other examples: See all ⬇️
-
Provides current time indicator with updates (re-renders) every second or full minute. This component will re-render itself.
Update every full minute means update at 10:45:00, 10:46:00 and so on...
Props: (* - these are required)
Name Type Default Description updateInterval "second"
/"minute"
"minute"
Determines update interval. In most cases you'll want to use "minute"
option to limit re-rendersrender * function
Render your UI inside this function. See example below... Example:
import Timeline from 'react-headless-timeline'; // ... <Timeline.Indicators.CurrentTime render={({ currentTime, styles }) => ( <div style={{ height: '100%', ...styles }}> <StyledHeader>{currentTime.getTime()}</StyledHeader> </div> )} />
Other examples:
-
This indicator exposes function to position your component properly. It's useful for events without end date.
Props: (* - these are required)
Name Type Default Description render * function
Render your UI inside this function. See example below... Example:
import Timeline from 'react-headless-timeline'; // ... <Timeline.Indicators.Time render={({ getIndicatorStyles }) => ( <div style={{ height: '100%', ...getIndicatorStyles(date) }}> <StyledHeader> {label} </StyledHeader> </div> )} />
Other examples:
- You should use CSS
box-sizing: border-box
on your timeline components to prevent sizing bugs.
- Basic horizontal
- Basic vertical
- Horizontal with current time indicator
- Horizontal with multiple events
- Horizontal with multiple events and time indicators
- Vertical with current time indicator
- Vertical with multiple events
- Advanced horizontal work log:
- Create detailed documentation
- Add more advanced examples of usage of
react-headless-timeline
- (?) Add support for overflow timelines
- (?) Add possibility to create virtualized timelines