GanttHandle
The methods the `ref` handle exposes, and the option types they take
GanttHandle is the object a ref on the chart receives. It combines GanttScrollApi,
GanttDetailApi and GanttTaskCreateApi, so it carries the scroll and zoom methods, the two
detail panel methods and addTask. All five types on this page are type-only exports of the
package.
import type {
GanttDetailApi,
GanttHandle,
GanttScrollApi,
GanttScrollOptions,
GanttTaskCreateApi,
} from '@jaeungkim/gantt-chart';GanttHandle
/** Imperative API exposed through the ref */
export interface GanttHandle
extends GanttScrollApi,
GanttDetailApi,
GanttTaskCreateApi {}It declares no member of its own. Every method below is defined in one of the three interfaces it
extends. The chart builds the handle by spreading the scroll API and adding the two detail methods
and addTask.
Members
| Member | Signature | Effect |
|---|---|---|
scrollToDate | (date: string | Date | Dayjs, options?: GanttScrollOptions) => void | Scrolls horizontally so the date lands at the requested position. Does nothing when the date is outside the rendered timeline. |
scrollToToday | (options?: GanttScrollOptions) => void | scrollToDate with the current instant. |
scrollToTask | (taskId: string, options?: GanttScrollOptions) => void | Scrolls horizontally to the task's bar, and vertically only when its row is off screen. Does nothing for an id that no row shows. |
setScale | (scale: GanttScaleKey) => void | Switches the scale and keeps the centre date in place. |
zoomToFit | () => void | Switches to the finest scale at which the whole project fits the timeline width and pins the earliest task date to the left edge. |
getScrollElement | () => HTMLDivElement | null | Returns the chart's scroll container element, or null when the chart is not mounted. |
openDetail | (taskId: string) => void | Opens the detail panel on that task. Does nothing for an id that names no task, or while the panel is off. |
closeDetail | () => void | Closes the detail panel. |
addTask | () => void | Calls onTaskCreate with a draft one tick long at today, snapped to the current scale. Does nothing while task creation is off. |
Every method except getScrollElement returns void.
GanttScrollApi
/** Imperative scroll and zoom API */
export interface GanttScrollApi {
/** Scroll horizontally to a given date */
scrollToDate: (date: string | Date | Dayjs, options?: GanttScrollOptions) => void;
/** Scroll horizontally to today */
scrollToToday: (options?: GanttScrollOptions) => void;
/** Scroll horizontally and vertically to a given task */
scrollToTask: (taskId: string, options?: GanttScrollOptions) => void;
/** Switches the scale, keeping the centre date centred; an unknown key is ignored */
setScale: (scale: GanttScaleKey) => void;
/** Switches to the finest scale the whole project fits at and scrolls it into view (no-op with no tasks) */
zoomToFit: () => void;
/** The scroll container DOM node (null when unavailable) */
getScrollElement: () => HTMLDivElement | null;
}Dayjs is the object type from dayjs. The package does not re-export it, so import it from
dayjs. A plain string or Date is accepted and parsed as UTC. See Task data.
GanttScaleKey is the union of the five scale keys, listed in
Scale and theme types. The scale table that setScale checks its argument against is
internal and not exported.
GanttDetailApi
/** Opening and closing the detail panel from outside the chart */
export interface GanttDetailApi {
/** Opens the detail panel on a task; unknown ids and a panel-less chart (no `renderDetail`/`showDetail`) are ignored */
openDetail: (taskId: string) => void;
/** Closes the detail panel */
closeDetail: () => void;
}The panel is on when showDetail is true. With showDetail omitted, it is on when
renderDetail is given. Both props, and the rest of the detail surface, are in
GanttProps. While the panel is off, both methods do nothing, so a toolbar button wired
to openDetail needs no guard.
GanttTaskCreateApi
/** Proposing a new task from outside the chart */
export interface GanttTaskCreateApi {
/** Sends a one-tick draft at today to `onTaskCreate`, as the "Add task" button does; no-op without `onTaskCreate` or with `allowTaskCreate` false */
addTask: () => void;
}addTask() is the ref counterpart of the Add task button under the task list. It sends the
same draft to the same callback and does nothing while creation is off. When today is outside the
rendered timeline, the draft moves to the first tick. The row appears when the tasks array your
onTaskCreate builds includes it. Creating tasks describes the draft and what
turns creation off.
GanttScrollOptions
/** Options for the scrollTo* methods */
export interface GanttScrollOptions {
/** Whether to animate the scroll (default true) */
smooth?: boolean;
/** Where the target lands inside the viewport (default 'center') */
align?: "start" | "center";
}| Field | Type | Default | Effect |
|---|---|---|---|
smooth | boolean | true | false scrolls with behavior: "auto". Any other value, undefined included, animates with behavior: "smooth". |
align | "start" | "center" | "center" | "start" puts the target at the left edge of the timeline area. "center" centres it in the timeline area, measured against the width that remains beside the task list pane. |
Horizontal targets are clamped with Math.max(0, ...), so a target left of the timeline origin
scrolls to 0.
align applies to the horizontal axis only. When scrollToTask scrolls vertically, it always
centres the row.
Imperative API shows the handle attached to a toolbar.
Early calls
ref.current is null until React commits the chart, and null again after it unmounts. A read
during the parent's render sees null. By the time the parent's useEffect or
useLayoutEffect runs, the handle is set. Guard with ?. rather than !.
After the handle exists, the methods tolerate calls made before their data is ready. Each case below returns without throwing and without a console warning.
| Call | Condition | Result |
|---|---|---|
scrollToDate | the timeline has no ticks, or the date is before the first tick or past the end of the last | no scroll |
scrollToToday | today is outside the rendered range | no scroll |
scrollToTask | no row shows the id, because it is unknown or hidden under a collapsed parent | no scroll |
setScale | the key is not one of the five scales | no scale change |
setScale | the scroll container is not mounted, or the centre of the timeline area is not over a tick | the scale changes, with no anchor |
zoomToFit | tasks is empty, or the scroll container is not mounted | no scale change, no scroll |
getScrollElement | the chart is not mounted | null |
openDetail | the id names no task in tasks | no open |
openDetail | the panel is off, with neither renderDetail nor showDetail turning it on | no open |
closeDetail | the panel is off, or already closed | nothing, and no onDetailChange |
addTask | onTaskCreate is not given, allowTaskCreate is false, or readOnly is set without an overriding allowTaskCreate | no draft, no callback |
addTask | the timeline has no ticks, because there are no tasks and no window pinned with visibleStart and visibleEnd | no draft, no callback |
Notes
- The handle is rebuilt whenever the scroll API, either detail method or
addTaskchanges identity.getScrollElementreads the ref on each call, so a handle captured earlier returns the current element. scrollToDateandscrollToTodaynever changescrollTop. OnlyscrollToTaskscrolls vertically, and only when the target row is outside the viewport.- No prop sets the scale after mount.
setScalesets an exact scale from code.defaultScaleis read once when the store is created, so a later change to it is ignored. - The chart renders no scale picker. A picker in your app calls
setScale. TheonScaleChangeprop in GanttProps reports the change back, whichever source made it. zoomToFittakes noGanttScrollOptions. Its scroll is instant, with no animation.zoomToFittries the five scales in the orderday,week,month,quarter,year, and falls back toyearwhen the project fits none of them. See The timeline.- Row height for the vertical
scrollToTaskmath is a fixed 38px. openDetailresolves the id against every task, collapsed rows included.scrollToTaskneeds the row to be rendered. Collapsing a parent hides the row without closing the panel that describes it.- With
detailTaskIdgiven, the chart is controlled and the two detail methods change nothing on their own. They report the request throughonDetailChangeand wait for the prop to follow. Without it they move the panel themselves and fireonDetailChangetoo. addTaskdoes not scroll or change the scale. It callsonTaskCreateand the chart never writes totasks.- Imperative API covers these methods in use.