Scale and theme types
The scale keys, the format overrides, the theme values and the holiday shape
Five types describe how the timeline is measured and how the chart is painted. GanttScaleKey
names one of the five scales. GanttScaleFormat and GanttFormatOverrides replace the labels of
a scale, GanttTheme selects the palette, and Holiday marks a day off beyond the weekend. All
five are exported from the package root.
import type {
GanttScaleKey,
GanttScaleFormat,
GanttFormatOverrides,
GanttTheme,
Holiday,
} from '@jaeungkim/gantt-chart';GanttScaleKey
export type GanttScaleKey = 'day' | 'week' | 'month' | 'quarter' | 'year';The declaration order is the scale order, finest first. Ctrl/Cmd + ArrowUp moves one scale finer
and Ctrl/Cmd + ArrowDown one scale coarser, clamped at both ends. Ctrl/Cmd + wheel moves through the
same order when zoomOnWheel is on. defaultScale takes one of these values and defaults to
'month'.
The chart renders no scale picker of its own and does not keep the scale across a remount. Render
your own picker and drive it through setScale on the ref. onScaleChange reports every change,
including the wheel and keyboard ones. See GanttHandle.
formats is keyed by this type, and GanttDetailRenderProps.scale carries it. See
Detail renderer.
Per-scale configuration
Each key maps to one row of a fixed table. The row sets the header cell labels, the time one tick covers, and the pixels one drag step is worth. The timeline lists what each scale shows. This page describes the shape of one row:
export interface GanttScaleConfig {
labelUnit: GanttLabelUnit;
tickUnit: 'minute' | 'hour' | 'day' | 'week' | 'month';
unitPerTick: number;
/** Boundary the first cell snaps to, when a cell holds more than one tickUnit */
tickAlign?: GanttLabelUnit;
dragStepUnit: 'minute' | 'hour' | 'day' | 'week';
dragStepAmount: number;
basePxPerDragStep: number;
formatTickLabel: (date: Dayjs) => string;
formatHeaderLabel: (date: Dayjs) => string;
}/** Unit the top header row groups by ('quarter' has no dayjs equivalent - see core/dates) */
export type GanttLabelUnit =
| 'hour'
| 'day'
| 'week'
| 'month'
| 'quarter'
| 'year';GanttScaleConfig, GanttLabelUnit and the GANTT_SCALE_CONFIG object itself are module-internal
and not exported from the package. The table cannot be imported, extended or replaced, and no prop
adds a sixth scale. Tick widths are derived from basePxPerDragStep / dragStepAmount.
The timeline lists the resulting pixels per day, and Editing tasks
has the drag grid the same two fields define.
Built-in labels
formatTickLabel and formatHeaderLabel are the last layer of the label chain. They produce the
labels when neither a formats override nor a locale applies.
| scale | formatTickLabel | formatHeaderLabel | tooltip format string | readout format string |
|---|---|---|---|---|
day | d.format('HH') | d.format('MMM D, YYYY') | 'MMM D, YYYY HH:mm [UTC]' | 'HH:mm [UTC]' |
week | d.format('D') | d.format('MMM YYYY') | 'MMM D, YYYY' | 'MMM D' |
month | d.format('MMM D') | d.format('MMM YYYY') | 'MMM D, YYYY' | 'MMM D' |
quarter | d.format('MMM') | `Q${quarterOfYear(d)} ${d.format('YYYY')}` | 'MMM YYYY' | 'MMM YYYY' |
year | d.format('MMM') | d.format('YYYY') | 'MMM YYYY' | 'MMM YYYY' |
With firstDayOfWeek set, the week scale takes its header from the day row.
The tooltip and readout strings are in separate DATE_FORMATS and RANGE_FORMATS constants,
neither exported. [UTC] in the two day strings is a dayjs escaped literal, not a resolved
zone name.
The tooltip string is the chart's general-purpose date label. The hover tooltip, the bar's ARIA
label, the drag and keyboard announcements and the built-in detail panel's Start and End fields all
print it. The panel prints it only where those two fields are not editable. An editable field is a
native <input type="date"> showing YYYY-MM-DD. See Detail panel.
The readout string is the compact per-scale variant used by the header drag readout. Where the chart writes the readout and why the shorter strings drop the year are in Locale and date formats.
GanttScaleFormat
/**
* Replaces the generated labels of one scale
* Every entry is optional - whatever is left out keeps the built-in (or locale) label
*/
export interface GanttScaleFormat {
/** Bottom header row - one label per tick */
tick?: (date: Dayjs) => string;
/** Top header row - one label per group */
header?: (date: Dayjs) => string;
/**
* Every date the chart writes as a single date: the bar's hover tooltip, its live drag readout
* and aria-label, the header's drag guide labels (through `edge` and `range`, which follow this
* slot), and the detail panel's Start and End where they are not editable - an editable date is
* a native `<input type="date">` and never reaches a formatter.
*/
tooltip?: (date: Dayjs) => string;
}| Field | Type | Required | Applies to |
|---|---|---|---|
tick | (date: Dayjs) => string | no | one label per tick, bottom header row |
header | (date: Dayjs) => string | no | one label per group, top header row |
tooltip | (date: Dayjs) => string | no | every date off the header rows: the hover tooltip, the bar's ARIA label, the drag and keyboard announcements, and the built-in detail panel's dates where they are not editable |
The three slots are resolved independently. Supplying header alone leaves tick and tooltip on
the locale or built-in labels.
A tooltip override also formats each end of the header drag readout. Without one, the readout
keeps the compact per-scale strings in the readout column under Built-in labels.
GanttFormatOverrides
/** Per-scale label overrides, e.g. `{ quarter: { header: (d) => ... } }` */
export type GanttFormatOverrides = Partial<
Record<GanttScaleKey, GanttScaleFormat>
>;This is the type of the formats prop. A scale left out of the record keeps its resolved labels.
const formats: GanttFormatOverrides = {
quarter: {
header: (d) => `${d.year()} Q${Math.floor(d.month() / 3) + 1}`,
},
month: {
tooltip: (d) => d.format('YYYY-MM-DD'),
},
};formats is declared at module scope so the object keeps the same identity across renders.
Locale and date formats covers which layer wins for each of the three labels and why
identity matters.
GanttTheme
/** Chart theme - 'system' follows the OS setting; omit the prop to follow the host page's `color-scheme`. */
export type GanttTheme = 'light' | 'dark' | 'system';This is the type of the theme prop, which has no default. The resolved value is written to
data-theme on the container, and the stylesheet reads that attribute. How each value resolves and
what the palette holds are in Theming.
GanttTheme is a three-value union, and every color is a CSS custom property. There is no theme
object or token prop.
Holiday
/** A day off beyond the weekend. A bare `YYYY-MM-DD` string is the same thing with no label. */
export interface Holiday {
/** UTC `YYYY-MM-DD` */
date: string;
/** Inclusive last day - omit for a single day */
endDate?: string;
/** Written in the tick row over the holiday's band, when the band is wide enough to hold it */
label?: string;
/** Any CSS colour. Tinted onto the grid at the weekend shade's weight, never painted over it. */
color?: string;
}| Field | Type | Required | Meaning |
|---|---|---|---|
date | string | yes | the first day off, as a UTC YYYY-MM-DD string |
endDate | string | no | inclusive last day of the span; omit for a single day |
label | string | no | text written in the tick row over the holiday's band |
color | string | no | any CSS color, tinted onto the grid at the weekend shade's weight |
What the chart draws for a holiday, when the label appears and how the entries are supplied are in The timeline.
Notes
How the three slots resolve, what each formatter receives, and the identity rule are in Locale and date formats.
GanttScaleFormatfunctions must return astring. There is noReactNodeescape hatch, and no prop replaces a header cell. A header cell is text. Style one with CSS on.gantt-top-groupand.gantt-bottom-cell.- The chart's UTC
dayjsinstance is not exported from the package. An override that needs the same instance importsdayjsand itsutcplugin directly.