Detail renderer
`GanttDetailRenderer` and `GanttDetailRenderProps`, the types behind `renderDetail`
renderDetail replaces the body of the detail panel. Its types are exported from
@jaeungkim/gantt-chart. Detail panel covers the behaviour and worked
examples.
import type {
GanttDetailRenderer,
GanttDetailRenderProps,
Task,
} from '@jaeungkim/gantt-chart';Task and TaskTransformed are documented in Task and task types and GanttScaleKey in
Scale and theme types. ReactNode is a type from react.
GanttDetailRenderer
/** Props handed to a `renderDetail` override */
export interface GanttDetailRenderProps {
task: TaskTransformed;
/** Closes the panel - wire it to your own close control */
close: () => void;
scale: GanttScaleKey;
/**
* Patches the open task through the chart's normal commit path (the store, then
* `onTasksChange`), so a custom body can commit edits in uncontrolled mode. Applies NO
* permission checks - a custom body enforces its own rules.
*/
update: (patch: Partial<Omit<Task, 'id'>>) => void;
}
export type GanttDetailRenderer = (props: GanttDetailRenderProps) => ReactNode;Fields
| Field | Type | Value |
|---|---|---|
task | TaskTransformed | The open task, as the chart transformed it |
close | () => void | Closes the panel. The built-in close button calls the same function |
scale | GanttScaleKey | The scale currently selected |
update | (patch: Partial<Omit<Task, 'id'>>) => void | Patches the open task through the chart's commit path |
Example
const renderDetail: GanttDetailRenderer = ({ task, close, scale, update }) => (
<>
<button type="button" onClick={close} aria-label="Close task details">
Close
</button>
<h2>{task.name}</h2>
<p>
{task.startDate.slice(0, 10)} to {task.endDate.slice(0, 10)} ({scale})
</p>
<button type="button" onClick={() => update({ progress: 100 })}>
Mark done
</button>
</>
);Constraints
The renderer supplies the panel's children, so there is no props bag to spread. No other part of the chart accepts a custom renderer.
- The chart renders the
<aside class="gantt-detail" role="complementary" aria-label="Task details">element itself. The--gantt-detail-widthcustom property sets its width (320px). The renderer does not change it. - The built-in close button is not carried over into a custom body.
closecalls the same function that button calls.Escapecloses the panel from anywhere on the page, even when the body renders no close control. - Returning
nullorundefinedrenders an empty panel, not the default body. - Passing the renderer turns the panel on when
showDetailis omitted. An explicitshowDetail={false}keeps it off. - The renderer always receives a task. Closing the panel does not unmount it immediately. The panel
keeps the last task through the 200ms close transition, and a 400ms timer releases it if
transitionendnever fires. A body with mount side effects gets extra render passes while the panel slides shut. The<aside>leaves the DOM after that transition. updateuses the same commit path as the built-in body's inputs. It writes the task to the store and callsonTasksChange. An edit applies in uncontrolled mode, so your app does not have to passtasksback.updateapplies no checks of its own. The interaction flags, the date clamping and the progress normalization gate the built-in body only. A patch passed here reaches the store andonTasksChangeas given, so a custom body enforces its own rules.- The patch cannot change the task's
id. The type omits it, and the patch applies to the open task. - The default body shows the name, the dates and the duration. Progress and predecessors appear only when the task has them. No prop adds a row or translates the captions, so other fields reach the panel only through the renderer.
Every prop named here is indexed in GanttProps.