- Prop
rows- Type
CoreGanttRow[]- Default
- —
- Requirement
- required
- Description
- —
Docs Components Advanced
Gantt
React example follows below.
Vue example follows below.
Angular example follows below.
Svelte example follows below.
Solid example follows below.
- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
/** * Gantt's pinned demo state (CSP-D3). * * Deliberately overlapping spans: `start`/`end` are quarter fractions on the * default four-column axis, and every pair of adjacent rows shares part of * its range, so the demo proves each row draws its own independent track * rather than a single shared timeline. `today` sits inside that overlap * (2.35 of 4 = 58.75%) so the marker rule lands mid-chart, not on a divider. * * `bar`, not `color`: the fixture set forbids a `color` key (it is one of the * theme-coupled names the proof test rejects), while `GanttRow`'s own field * is called `color`. `ganttRows()` below does that one rename, once, instead * of five demo files each spreading their own mapping. */const ganttFixture = { id: "gantt", labelHeading: "Workstream", today: 2.35, rows: [ { name: "Ledger v2 rewrite", sub: "platform", start: 0, end: 1.9, bar: "var(--accent)" }, { name: "Billing migration", sub: "payments", start: 1.2, end: 2.8, bar: "var(--vs-info)" }, { name: "Fraud rules engine", sub: "risk", start: 2.4, end: 4, bar: "var(--vs-warning)" }, { name: "Partner API GA", sub: "integrations", start: 0.6, end: 3.2, bar: "var(--vs-success)" }, ],} satisfies { id: string; labelHeading: string; today: number; rows: { name: string; sub: string; start: number; end: number; bar: string }[];}; /** Fixture rows in the shape every adapter's `rows` prop takes. */function ganttRows(): { name: string; sub: string; start: number; end: number; color: string;}[] { return ganttFixture.rows.map(({ bar, ...row }) => ({ ...row, color: bar }));} import { Gantt } from "@grassroot/ui-react/advanced"; export default function GanttDemo() { return ( <div className="w-full min-w-0"> <Gantt rows={ganttRows()} today={ganttFixture.today} labelHeading={ganttFixture.labelHeading} /> </div> );}- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
<script setup lang="ts">/** * Gantt's pinned demo state (CSP-D3). * * Deliberately overlapping spans: `start`/`end` are quarter fractions on the * default four-column axis, and every pair of adjacent rows shares part of * its range, so the demo proves each row draws its own independent track * rather than a single shared timeline. `today` sits inside that overlap * (2.35 of 4 = 58.75%) so the marker rule lands mid-chart, not on a divider. * * `bar`, not `color`: the fixture set forbids a `color` key (it is one of the * theme-coupled names the proof test rejects), while `GanttRow`'s own field * is called `color`. `ganttRows()` below does that one rename, once, instead * of five demo files each spreading their own mapping. */const ganttFixture = { id: "gantt", labelHeading: "Workstream", today: 2.35, rows: [ { name: "Ledger v2 rewrite", sub: "platform", start: 0, end: 1.9, bar: "var(--accent)" }, { name: "Billing migration", sub: "payments", start: 1.2, end: 2.8, bar: "var(--vs-info)" }, { name: "Fraud rules engine", sub: "risk", start: 2.4, end: 4, bar: "var(--vs-warning)" }, { name: "Partner API GA", sub: "integrations", start: 0.6, end: 3.2, bar: "var(--vs-success)" }, ],} satisfies { id: string; labelHeading: string; today: number; rows: { name: string; sub: string; start: number; end: number; bar: string }[];}; /** Fixture rows in the shape every adapter's `rows` prop takes. */function ganttRows(): { name: string; sub: string; start: number; end: number; color: string;}[] { return ganttFixture.rows.map(({ bar, ...row }) => ({ ...row, color: bar }));} import { Gantt } from "@grassroot/ui-vue";const rows = ganttRows();</script> <template> <div class="w-full min-w-0"> <Gantt :rows="rows" :today="ganttFixture.today" :label-heading="ganttFixture.labelHeading" /> </div></template>- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
import { Component } from "@angular/core";/** * Gantt's pinned demo state (CSP-D3). * * Deliberately overlapping spans: `start`/`end` are quarter fractions on the * default four-column axis, and every pair of adjacent rows shares part of * its range, so the demo proves each row draws its own independent track * rather than a single shared timeline. `today` sits inside that overlap * (2.35 of 4 = 58.75%) so the marker rule lands mid-chart, not on a divider. * * `bar`, not `color`: the fixture set forbids a `color` key (it is one of the * theme-coupled names the proof test rejects), while `GanttRow`'s own field * is called `color`. `ganttRows()` below does that one rename, once, instead * of five demo files each spreading their own mapping. */const ganttFixture = { id: "gantt", labelHeading: "Workstream", today: 2.35, rows: [ { name: "Ledger v2 rewrite", sub: "platform", start: 0, end: 1.9, bar: "var(--accent)" }, { name: "Billing migration", sub: "payments", start: 1.2, end: 2.8, bar: "var(--vs-info)" }, { name: "Fraud rules engine", sub: "risk", start: 2.4, end: 4, bar: "var(--vs-warning)" }, { name: "Partner API GA", sub: "integrations", start: 0.6, end: 3.2, bar: "var(--vs-success)" }, ],} satisfies { id: string; labelHeading: string; today: number; rows: { name: string; sub: string; start: number; end: number; bar: string }[];}; /** Fixture rows in the shape every adapter's `rows` prop takes. */function ganttRows(): { name: string; sub: string; start: number; end: number; color: string;}[] { return ganttFixture.rows.map(({ bar, ...row }) => ({ ...row, color: bar }));} import { GrassrootGantt } from "@grassroot/ui-angular"; // Every input is a `[property]` binding, never a static attribute — Angular// leaves static template attributes on the host element in the rendered DOM,// where the other four frameworks have nothing.@Component({ selector: "app-gantt-demo", standalone: true, imports: [GrassrootGantt], host: { style: "display: contents" }, template: ` <div class="w-full min-w-0"> <grassroot-gantt [rows]="rows" [today]="today" [labelHeading]="labelHeading" /> </div> `,})export class GanttDemoComponent { protected readonly rows = ganttRows(); protected readonly today = ganttFixture.today; protected readonly labelHeading = ganttFixture.labelHeading;} export default GanttDemoComponent;- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
<script lang="ts"> /** * Gantt's pinned demo state (CSP-D3). * * Deliberately overlapping spans: `start`/`end` are quarter fractions on the * default four-column axis, and every pair of adjacent rows shares part of * its range, so the demo proves each row draws its own independent track * rather than a single shared timeline. `today` sits inside that overlap * (2.35 of 4 = 58.75%) so the marker rule lands mid-chart, not on a divider. * * `bar`, not `color`: the fixture set forbids a `color` key (it is one of the * theme-coupled names the proof test rejects), while `GanttRow`'s own field * is called `color`. `ganttRows()` below does that one rename, once, instead * of five demo files each spreading their own mapping. */ const ganttFixture = { id: "gantt", labelHeading: "Workstream", today: 2.35, rows: [ { name: "Ledger v2 rewrite", sub: "platform", start: 0, end: 1.9, bar: "var(--accent)" }, { name: "Billing migration", sub: "payments", start: 1.2, end: 2.8, bar: "var(--vs-info)" }, { name: "Fraud rules engine", sub: "risk", start: 2.4, end: 4, bar: "var(--vs-warning)" }, { name: "Partner API GA", sub: "integrations", start: 0.6, end: 3.2, bar: "var(--vs-success)" }, ], } satisfies { id: string; labelHeading: string; today: number; rows: { name: string; sub: string; start: number; end: number; bar: string }[]; }; /** Fixture rows in the shape every adapter's `rows` prop takes. */ function ganttRows(): { name: string; sub: string; start: number; end: number; color: string; }[] { return ganttFixture.rows.map(({ bar, ...row }) => ({ ...row, color: bar })); } import { Gantt } from "@grassroot/ui-svelte";</script> <div class="w-full min-w-0"> <Gantt rows={ganttRows()} today={ganttFixture.today} labelHeading={ganttFixture.labelHeading} /></div>- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
/** @jsxImportSource solid-js *//** * Gantt's pinned demo state (CSP-D3). * * Deliberately overlapping spans: `start`/`end` are quarter fractions on the * default four-column axis, and every pair of adjacent rows shares part of * its range, so the demo proves each row draws its own independent track * rather than a single shared timeline. `today` sits inside that overlap * (2.35 of 4 = 58.75%) so the marker rule lands mid-chart, not on a divider. * * `bar`, not `color`: the fixture set forbids a `color` key (it is one of the * theme-coupled names the proof test rejects), while `GanttRow`'s own field * is called `color`. `ganttRows()` below does that one rename, once, instead * of five demo files each spreading their own mapping. */const ganttFixture = { id: "gantt", labelHeading: "Workstream", today: 2.35, rows: [ { name: "Ledger v2 rewrite", sub: "platform", start: 0, end: 1.9, bar: "var(--accent)" }, { name: "Billing migration", sub: "payments", start: 1.2, end: 2.8, bar: "var(--vs-info)" }, { name: "Fraud rules engine", sub: "risk", start: 2.4, end: 4, bar: "var(--vs-warning)" }, { name: "Partner API GA", sub: "integrations", start: 0.6, end: 3.2, bar: "var(--vs-success)" }, ],} satisfies { id: string; labelHeading: string; today: number; rows: { name: string; sub: string; start: number; end: number; bar: string }[];}; /** Fixture rows in the shape every adapter's `rows` prop takes. */function ganttRows(): { name: string; sub: string; start: number; end: number; color: string;}[] { return ganttFixture.rows.map(({ bar, ...row }) => ({ ...row, color: bar }));} import { Gantt } from "@grassroot/ui-solid"; export default function GanttDemo() { return ( <div class="w-full min-w-0"> <Gantt rows={ganttRows()} today={ganttFixture.today} labelHeading={ganttFixture.labelHeading} /> </div> );}Installation
API Reference
Import
import { Gantt } from "@grassroot/ui-react/advanced";
Props
Prop
Type
Default
Requirement
Description
rowsCoreGanttRow[]—
required
—
columnsstring[] | undefined["Q1","Q2","Q3","Q4"]optional
Column tick labels across the top.
todaynumber | undefined—
optional
"Today" position as a fraction across the axis (0..units).
labelHeadingstring | undefined"Workstream"optional
Heading for the first (label) column.
getRowId((row: GanttRow, index: number) => string) | undefined—
optional
Stable row id.
stepnumber | undefined1optional
Axis unit for keyboard nudges.
onRangeChange((detail: GanttRangeChangeDetail) => void) | undefined—
optional
—
- Prop
columns- Type
string[] | undefined- Default
["Q1","Q2","Q3","Q4"]- Requirement
- optional
- Description
- Column tick labels across the top.
- Prop
today- Type
number | undefined- Default
- —
- Requirement
- optional
- Description
- "Today" position as a fraction across the axis (0..units).
- Prop
labelHeading- Type
string | undefined- Default
"Workstream"- Requirement
- optional
- Description
- Heading for the first (label) column.
- Prop
getRowId- Type
((row: GanttRow, index: number) => string) | undefined- Default
- —
- Requirement
- optional
- Description
- Stable row id.
- Prop
step- Type
number | undefined- Default
1- Requirement
- optional
- Description
- Axis unit for keyboard nudges.
- Prop
onRangeChange- Type
((detail: GanttRangeChangeDetail) => void) | undefined- Default
- —
- Requirement
- optional
- Description
- —
Events
| Event | Payload |
|---|---|
onRangeChange | ((detail: GanttRangeChangeDetail) => void) | undefined |
Native attributes
Standard DOM and ARIA attributes not listed above spread onto the root element.
Import
import { Gantt } from "@grassroot/ui-vue";
Props
Prop
Type
Default
Requirement
rowsCoreGanttRow[]—
required
columnsstring[] | undefined() => [...DEFAULT_GANTT_COLUMNS]optional
todaynumber | undefined—
optional
labelHeadingstring | undefined"Workstream"optional
getRowId((row: GanttRow, index: number) => string) | undefined—
optional
stepnumber | undefined—
optional
- Prop
rows- Type
CoreGanttRow[]- Default
- —
- Requirement
- required
- Prop
columns- Type
string[] | undefined- Default
() => [...DEFAULT_GANTT_COLUMNS]- Requirement
- optional
- Prop
today- Type
number | undefined- Default
- —
- Requirement
- optional
- Prop
labelHeading- Type
string | undefined- Default
"Workstream"- Requirement
- optional
- Prop
getRowId- Type
((row: GanttRow, index: number) => string) | undefined- Default
- —
- Requirement
- optional
- Prop
step- Type
number | undefined- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
rangeChange | [detail: GanttRangeChangeDetail] |
Import
import { Component } from "@angular/core";
import { GrassrootGantt } from "@grassroot/ui-angular";
Props
Prop
Type
Default
Requirement
rowsGanttRow[]—
required
columnsstring[]DEFAULT_COLUMNSoptional
todaynumber | undefinedundefinedoptional
labelHeadingstring"Workstream"optional
getRowId(row: GanttRow, index: number) => string—
optional
stepnumber | undefinedundefinedoptional
- Prop
rows- Type
GanttRow[]- Default
- —
- Requirement
- required
- Prop
columns- Type
string[]- Default
DEFAULT_COLUMNS- Requirement
- optional
- Prop
today- Type
number | undefined- Default
undefined- Requirement
- optional
- Prop
labelHeading- Type
string- Default
"Workstream"- Requirement
- optional
- Prop
getRowId- Type
(row: GanttRow, index: number) => string- Default
- —
- Requirement
- optional
- Prop
step- Type
number | undefined- Default
undefined- Requirement
- optional
Events
| Event | Payload |
|---|---|
rangeChange | GanttRangeChangeDetail |
Import
import { Gantt } from "@grassroot/ui-svelte";
Props
Prop
Type
Default
Requirement
rowsGanttRow[]—
required
columnsstring[]—
optional
todaynumber—
optional
labelHeadingstring"Workstream"optional
classNamestring—
optional
getRowId(row: GanttRow, index: number) => string—
optional
stepnumber—
optional
onRangeChange(detail: GanttRangeChangeDetail) => void—
optional
- Prop
rows- Type
GanttRow[]- Default
- —
- Requirement
- required
- Prop
columns- Type
string[]- Default
- —
- Requirement
- optional
- Prop
today- Type
number- Default
- —
- Requirement
- optional
- Prop
labelHeading- Type
string- Default
"Workstream"- Requirement
- optional
- Prop
className- Type
string- Default
- —
- Requirement
- optional
- Prop
getRowId- Type
(row: GanttRow, index: number) => string- Default
- —
- Requirement
- optional
- Prop
step- Type
number- Default
- —
- Requirement
- optional
- Prop
onRangeChange- Type
(detail: GanttRangeChangeDetail) => void- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onRangeChange | (detail: GanttRangeChangeDetail) => void |
Import
import { Gantt } from "@grassroot/ui-solid";
Props
Prop
Type
Default
Requirement
rowsGanttRow[]—
required
columnsstring[]—
optional
todaynumber—
optional
labelHeadingstring—
optional
classNamestring—
optional
getRowId(row: GanttRow, index: number) => string—
optional
stepnumber—
optional
onRangeChange(detail: GanttRangeChangeDetail) => void—
optional
- Prop
rows- Type
GanttRow[]- Default
- —
- Requirement
- required
- Prop
columns- Type
string[]- Default
- —
- Requirement
- optional
- Prop
today- Type
number- Default
- —
- Requirement
- optional
- Prop
labelHeading- Type
string- Default
- —
- Requirement
- optional
- Prop
className- Type
string- Default
- —
- Requirement
- optional
- Prop
getRowId- Type
(row: GanttRow, index: number) => string- Default
- —
- Requirement
- optional
- Prop
step- Type
number- Default
- —
- Requirement
- optional
- Prop
onRangeChange- Type
(detail: GanttRangeChangeDetail) => void- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onRangeChange | (detail: GanttRangeChangeDetail) => void |
Native attributes
Standard DOM and ARIA attributes not listed above spread onto the root element.