Component Props

All props accepted by the <TempisTimeline> component.

TempisTimelineProps

PropTypeDefaultDescription
itemsTempisTimelineItem[]requiredTimeline items to display.
categoriesTempisTimelineCategory[]Item categories.
bandsTempisTimelineBand[]Timeline bands.
dependenciesTempisTimelineDependency[]Item dependencies rendered as connector arrows.
optionsTempisTimelineConfig{}Configuration options (see Options).
onItemClick(id: string | number) => voidItem click handler.
onItemDoubleClick(id: string | number) => voidItem double-click handler.
onItemContextClick(id: string | number, position: { x: number; y: number }) => voidItem right-click (context menu) handler. Receives viewport coordinates for positioning a custom menu.
onItemHover(id: string | number | null) => voidItem hover handler.
onSelectionChange(changes: SelectionChangeEvent[]) => voidSelection change handler.
onRangeChange(start: Date, end: Date) => voidRange change handler.
onGroupToggle(group: string, collapsed: boolean) => voidGroup collapse/expand handler. Fires when a group header is clicked.
classNamestringCSS class for the wrapper <div>.
wrapperStyleCSSPropertiesInline styles for the wrapper <div>.
widthstring | number"100%"Canvas width.
heightstring | number300Canvas height.

Reactive vs Structural

items, categories, and bands are reactive — changes are synced to the existing instance via useEffect without recreating it. The options prop is structural — when its serialised value changes, the entire timeline instance is destroyed and recreated.

The dependencies prop is also reactive, just like items, categories, and bands — changes are synced to the existing instance without a recreate.

Callbacks are stored in a ref and never trigger a recreate, so you can safely pass inline arrow functions.

Avoid putting callbacks inside the options object — use the dedicated callback props instead. Callbacks in options would trigger unnecessary recreates.

Example

import { TempisTimeline } from '@tempis/react';

function ProjectTimeline() {
  return (
    <TempisTimeline
      items={[
        { id: 1, label: 'Item 1', start: '2026-03-01', end: '2026-03-15', category: 'cat-a' },
        { id: 2, label: 'Item 2',  start: '2026-03-10', end: '2026-03-25', category: 'cat-b' },
      ]}
      categories={[
        { name: 'cat-a', label: 'Category A', style: { backgroundColor: '#6366f1' } },
        { name: 'cat-b', label: 'Category B', style: { backgroundColor: '#10b981' } },
      ]}
      options={{
        responsive: true,
        selection: 'single',
        legend: { position: 'top' },
        range: { start: '2026-02-25', end: '2026-04-01', position: 'bottom' }
      }}
      onItemClick={(id) => console.log('Clicked', id)}
      height={350}
    />
  );
}

Reactive Data

The items, categories, bands, and dependencies props are synced to the core instance via useEffect. When a prop changes, the component calls the corresponding setter on the existing instance — no destroy/recreate needed.

Dynamic Add / Remove

import { useState } from 'react';
import { TempisTimeline } from '@tempis/react';

function App() {
  const [items, setItems] = useState([
    { id: 1, label: 'Item 1', start: '2026-02-01', end: '2026-02-10' },
  ]);

  function addItem() {
    setItems(prev => [
      ...prev,
      { id: prev.length + 1, label: `Item ${prev.length + 1}`, start: '2026-02-12', end: '2026-02-20' }
    ]);
  }

  return (
    <div>
      <button onClick={addItem}>Add Item</button>
      <TempisTimeline
        items={items}
        options={{ responsive: true, range: { start: '2026-01-25', end: '2026-03-01', position: 'bottom' } }}
        height={300}
      />
    </div>
  );
}

Toggle Categories

import { useState } from 'react';
import { TempisTimeline } from '@tempis/react';

function App() {
  const allCategories = [
    { name: 'cat-a', label: 'Category A', style: { backgroundColor: '#6366f1' } },
    { name: 'cat-b', label: 'Category B', style: { backgroundColor: '#f43f5e' } },
  ];
  const [categories, setCategories] = useState(allCategories);

  return (
    <div>
      <button onClick={() => setCategories(prev =>
        prev.length === 2 ? prev.slice(0, 1) : allCategories
      )}>Toggle Category B</button>
      <TempisTimeline
        items={[
          { id: 1, label: 'Item 1', start: '2026-02-01', end: '2026-02-14', category: 'cat-a' },
          { id: 2, label: 'Item 2', start: '2026-02-05', end: '2026-02-12', category: 'cat-b' },
        ]}
        categories={categories}
        options={{ responsive: true, legend: { position: 'top' }, range: { start: '2026-01-25', end: '2026-03-01', position: 'bottom' } }}
        height={300}
      />
    </div>
  );
}