Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/svar-widgets/react-gantt/llms.txt

Use this file to discover all available pages before exploring further.

SVAR Gantt ships three companion menu components — <Toolbar>, <ContextMenu>, and <HeaderMenu> — that all connect to the Gantt through the shared api prop.

Toolbar

<Toolbar> renders a row of action buttons above (or anywhere around) the chart.

Basic setup

1

Capture the API from Gantt

import { useState } from 'react';
import { Gantt, Toolbar } from '@svar-ui/react-gantt';

const [api, setApi] = useState();
2

Pass the API to Toolbar

<Toolbar api={api} />
<Gantt init={setApi} tasks={tasks} scales={scales} />
The toolbar renders default buttons (add task, indent/outdent, move up/down, delete, undo/redo when enabled) and automatically disables buttons that require a selection when nothing is selected.

Default toolbar buttons

Call getToolbarButtons() to retrieve the default button descriptors. Each button has an id that maps directly to a Gantt action name.
import { getToolbarButtons } from '@svar-ui/react-gantt';

// All buttons, including optional undo/split-task buttons:
const all = getToolbarButtons({ undo: true, splitTasks: true });

// Default set (no undo, no split):
const defaults = getToolbarButtons();
Button idAction triggered
add-taskadd-task
indent-taskindent-task
outdent-taskoutdent-task
move-task:upmove-task (mode: up)
move-task:downmove-task (mode: down)
delete-taskdelete-task
undoundo
redoredo

Customising toolbar buttons

Filter out unwanted buttons, add your own, and pass the result as the items prop.
import { Toolbar, getToolbarButtons } from '@svar-ui/react-gantt';

const items = [
  // Keep all default buttons except indent/outdent.
  ...getToolbarButtons().filter((b) => !b.id?.includes('indent')),
  // Add a custom button with its own handler.
  {
    id: 'my-action',
    comp: 'icon',
    icon: 'wxi-star',
    handler: () => console.log('custom action'),
  },
];

<Toolbar api={api} items={items} />

Fully custom toolbar

For full control, skip <Toolbar> entirely and build your own toolbar with standard React state and api.exec(). Subscribe to the reactive state store to track selection changes:
import { useState, useEffect } from 'react';
import { Gantt } from '@svar-ui/react-gantt';

function MyToolbar({ api }) {
  const [selected, setSelected] = useState([]);

  useEffect(() => {
    if (!api) return;
    const unsub = api.getReactiveState().selected.subscribe((v) => {
      setSelected(v ?? []);
    });
    return () => unsub?.();
  }, [api]);

  function handleAdd() {
    api.exec('add-task', {
      task: { text: 'New task' },
      target: selected[0],
      mode: 'after',
    });
  }

  function handleDelete() {
    selected.forEach((id) => api.exec('delete-task', { id }));
  }

  return (
    <div>
      <button onClick={handleAdd}>Add task</button>
      {selected.length > 0 && (
        <button onClick={handleDelete}>Delete task</button>
      )}
    </div>
  );
}

Context menu

<ContextMenu> wraps the <Gantt> as a child and shows a right-click menu on task rows.

Basic setup

import { Gantt, ContextMenu, Editor } from '@svar-ui/react-gantt';

<ContextMenu api={api}>
  <Gantt init={setApi} tasks={tasks} scales={scales} />
</ContextMenu>
{api && <Editor api={api} />}
The default menu includes add above/below/child, cut/copy/paste, and delete options.

Default menu options

import { getMenuOptions } from '@svar-ui/react-gantt';

const defaults = getMenuOptions();
Common option id values you can reference:
idDescription
add-task:beforeAdd task above
add-task:afterAdd task below
add-task:childAdd child task
cut-taskCut task
copy-taskCopy task
paste-taskPaste task
delete-taskDelete task

Customising menu options

Pass a custom options array to replace the defaults. Mix default options (looked up by id) with your own:
import { ContextMenu, getMenuOptions } from '@svar-ui/react-gantt';

const builtins = getMenuOptions();
const keepIds = ['cut-task', 'copy-task', 'paste-task', 'delete-task'];

const options = [
  { id: 'add-task:after', text: 'Add below', icon: 'wxi-plus' },
  ...builtins.filter((op) => keepIds.includes(op.id)),
  {
    id: 'my-action',
    text: 'My action',
    icon: 'wxi-star',
    handler: (action) => console.log('custom', action),
  },
];

function handleClick({ context, action }) {
  if (!action.handler) {
    console.log(`'${action.id}' clicked for task '${context.id}'`);
  }
}

<ContextMenu api={api} options={options} onClick={handleClick}>
  <Gantt init={setApi} tasks={tasks} scales={scales} />
</ContextMenu>

Filtering menu items per task

Use the filter prop to show or hide menu items based on the right-clicked task:
<ContextMenu
  api={api}
  filter={(option, task) => {
    // Hide "add child" for milestones.
    if (task.type === 'milestone') {
      const [base, mode] = (option.id ?? '').split(':');
      if (base === 'add-task' && mode === 'child') return false;
    }
    return true;
  }}
>
  <Gantt init={setApi} tasks={tasks} scales={scales} />
</ContextMenu>
The resolver prop controls which tasks trigger the menu. Return false to suppress the menu for a given task id:
<ContextMenu
  api={api}
  resolver={(id) => id > 2} // Only show menu for tasks with id > 2.
>
  ...
</ContextMenu>

HeaderMenu

<HeaderMenu> wraps the Gantt (or any grid-based widget) and adds a right-click menu on column headers for toggling column visibility.
import { Gantt, HeaderMenu } from '@svar-ui/react-gantt';

<HeaderMenu api={api}>
  <Gantt init={setApi} tasks={tasks} scales={scales} />
</HeaderMenu>
Pass a columns array to control which columns appear in the visibility toggle list:
<HeaderMenu
  api={api}
  columns={[
    { id: 'text',     header: 'Name' },
    { id: 'start',   header: 'Start' },
    { id: 'duration', header: 'Duration' },
  ]}
>
  <Gantt init={setApi} tasks={tasks} scales={scales} />
</HeaderMenu>

Intercepting actions (onaction)

All toolbar and context menu built-in actions route through api.exec(). You can intercept them before they execute using api.intercept():
const init = (api) => {
  setApi(api);

  // Block delete when a condition is not met.
  api.intercept('delete-task', ({ id }) => {
    const task = api.getTask(id);
    if (task.locked) {
      alert('This task cannot be deleted.');
      return false; // Returning false cancels the action.
    }
  });
};
See Event Handling for a full reference to api.intercept(), api.on(), and api.exec().

Props reference

Toolbar

PropTypeDefaultDescription
apiIApinullGantt API instance.
itemsarray[]Button descriptors. Falls back to getToolbarButtons() when empty.

ContextMenu

PropTypeDefaultDescription
apiIApinullGantt API instance.
optionsarray[]Menu item descriptors. Falls back to getMenuOptions() when empty.
resolverfunctionnull(id, ev) => task | boolean — controls which tasks get a menu.
filterfunctionnull(item, task) => boolean — per-task menu item visibility.
onClickfunction({ context, action }) => void — called when a menu item is clicked.
atstring'point'Positioning strategy for the menu popup.

HeaderMenu

PropTypeDefaultDescription
apiIApiGantt API instance used to resolve the table API.
columnsarraynullColumn descriptors to display in the visibility toggle.