apexgantt 3.14.0 → 3.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/apexgantt.d.ts +946 -28
  2. package/package.json +1 -1
package/apexgantt.d.ts CHANGED
@@ -1,4 +1,14 @@
1
- import { TextDirection } from '@apex/commons';
1
+ declare abstract class BaseChart {
2
+ /** @internal */
3
+ protected element: HTMLElement;
4
+ /** Destroys the chart instance and cleans up DOM resources. */
5
+ destroy(): void;
6
+ /** Returns the unique identifier for this chart instance. */
7
+ getInstanceId(): string;
8
+ }
9
+
10
+ declare type TextDirection = 'ltr' | 'rtl' | 'auto';
11
+
2
12
 
3
13
  declare interface AccessibilityOptions {
4
14
  readonly taskListAriaLabel?: string;
@@ -82,6 +92,34 @@ declare class ApexGantt extends BaseChart {
82
92
  private needsAutoFitZoom;
83
93
  private arrowLink;
84
94
  private dataManager;
95
+ /** Active sort criteria. Empty array = natural (input) order. */
96
+ private sortCriteria;
97
+ /** Active filter predicate, or null when no filter is applied. */
98
+ private activeFilter;
99
+ /** Current text in the built-in quick-filter box; preserved across re-renders. */
100
+ private quickFilterQuery;
101
+ /** Caret position to restore in the quick-filter box after a filter re-render. */
102
+ private quickFilterCaret;
103
+ /** Active structured filter rules (advanced filter builder), or null. */
104
+ private filterRuleSet;
105
+ /** Open/closed state of the filter-builder popover, preserved across re-renders. */
106
+ private filterBuilderOpen;
107
+ /** In-progress (uncommitted) rule set being edited in the filter-builder popover (mutable working copy). */
108
+ private filterBuilderDraft;
109
+ /** Active grouping criterion (normalized), or null when not grouping. */
110
+ private groupCriterion;
111
+ /** Manual per-column pixel widths set by resizing a header (or `setColumnWidth`); empty = all auto. */
112
+ private columnWidthOverrides;
113
+ /** User-chosen column order (keys left-to-right) from a header drag or `setColumnOrder`; null = configured order. */
114
+ private columnOrder;
115
+ /** Pending debounce timer for the opt-in localStorage state-persistence layer. */
116
+ private persistTimer;
117
+ /** Listener (shared by selection + scroll) that schedules a persist; null until attached. */
118
+ private persistChangeHandler;
119
+ /** Whether we've attempted the one-time restore of persisted state on first render. */
120
+ private stateRestoreAttempted;
121
+ /** True while `setState()` is applying state, so nested renders don't re-persist mid-flight. */
122
+ private isApplyingState;
85
123
  private stateManager;
86
124
  private history;
87
125
  /**
@@ -96,6 +134,19 @@ declare class ApexGantt extends BaseChart {
96
134
  * since the rewriters can't tell which columns are custom.
97
135
  */
98
136
  private buildColumnRefreshContext;
137
+ /**
138
+ * Fit-to-content pixel widths per column when `autoSizeColumns` is on, else
139
+ * `undefined` (columns fall back to `minWidth` + `flexGrow`). Measured against
140
+ * the resolved fonts so the estimate matches what the browser will render.
141
+ */
142
+ private computeAutoColumnWidths;
143
+ /**
144
+ * Task-list panel width: the configured `tasksContainerWidth`, grown to the
145
+ * total of the auto-sized columns (+ checkbox + borders) so content never
146
+ * clips. Never shrinks below the configured width, so wider layouts keep
147
+ * distributing the extra space via `flexGrow`.
148
+ */
149
+ private effectivePanelWidth;
99
150
  /**
100
151
  * Project date span padded for the current bar-label leading pad. When the
101
152
  * `barLabel.position` is `'left'` (or the user sets an explicit
@@ -156,6 +207,8 @@ declare class ApexGantt extends BaseChart {
156
207
  private selectionManager;
157
208
  private dependencyEditManager;
158
209
  private dependencyDrawManager;
210
+ private drawTaskManager;
211
+ private scrollButtonsManager;
159
212
  private virtualScrollCoordinator;
160
213
  private readonly columnRenderManager;
161
214
  /** MediaQueryList for prefers-reduced-motion. Updated dynamically. */
@@ -317,6 +370,22 @@ declare class ApexGantt extends BaseChart {
317
370
  * ```
318
371
  */
319
372
  updateTask(taskId: string, updatedTask: Partial<Task>): void;
373
+ /**
374
+ * Split a task into separate worked segments at `at`, producing a gap on the
375
+ * timeline. The segment containing `at` is cut so its first piece ends at `at`
376
+ * and the rest resumes at `resumeAt` (default: the next day — pass a later
377
+ * `resumeAt` to open a wider gap). A task with no segments yet is treated as a
378
+ * single span. Routed through `updateTask`, so it is validated, undoable, and
379
+ * emits `taskUpdate`. No-op on milestones, summary bars, or when `at` does not
380
+ * fall strictly inside a worked span.
381
+ *
382
+ * @example gantt.splitTask('t3', '2026-06-10', { resumeAt: '2026-06-14' });
383
+ */
384
+ splitTask(taskId: string, at: string, options?: {
385
+ resumeAt?: string;
386
+ }): void;
387
+ /** Whether a task is currently split into multiple worked segments. */
388
+ isSplit(taskId: string): boolean;
320
389
  /**
321
390
  * Insert a new task into the chart and re-render. The operation is
322
391
  * recorded in the undo history.
@@ -481,6 +550,258 @@ declare class ApexGantt extends BaseChart {
481
550
  undo: number;
482
551
  redo: number;
483
552
  };
553
+ /**
554
+ * Normalize the `sortBy` option into a criteria array. `undefined` →
555
+ * start-time ascending (preserves historical load behaviour); an explicit
556
+ * `[]` → natural (input) order.
557
+ */
558
+ private normalizeSortBy;
559
+ /** Build the active comparator from `sortCriteria` and push it to the data layer. */
560
+ private rebuildSort;
561
+ /** Apply the initial `sortBy` / `filterBy` / `filterRules` options at construction. */
562
+ private applyInitialSortAndFilter;
563
+ /**
564
+ * Re-apply the active filter after an `update()` rebuilt the data + options.
565
+ * Precedence: a new option in this call wins; otherwise rules > quick-filter >
566
+ * predicate. The predicate is recompiled so changed columns/format apply.
567
+ */
568
+ private reapplyFilterAfterUpdate;
569
+ /** Shared filter-evaluation context (date format + calendar). */
570
+ private filterContext;
571
+ /** Compile a structured rule set into a predicate using the current columns/context. */
572
+ private compileRules;
573
+ /** Normalize the `groupBy` option/argument into a {@link GroupCriterion} or null. */
574
+ private normalizeGroupBy;
575
+ /** Push the active grouping criterion (with its resolved column + none-label) to the data layer. */
576
+ private rebuildGrouping;
577
+ /** Apply the initial `groupBy` option at construction. */
578
+ private applyInitialGrouping;
579
+ /** Re-apply grouping after an `update()` rebuilt the data + options. */
580
+ private reapplyGroupingAfterUpdate;
581
+ /**
582
+ * Group the task list by a field. While grouping is active the parent/child
583
+ * tree is suspended and every task appears flat under a collapsible group
584
+ * header (label + member count). Pass a {@link GroupCriterion} for custom value
585
+ * extraction / labelling / order, or a bare column key. Re-renders and emits
586
+ * `groupChange`.
587
+ *
588
+ * @example gantt.groupBy(ColumnKey.Progress);
589
+ * @example gantt.groupBy({ field: 'status', direction: 'desc' });
590
+ */
591
+ groupBy(criterion: GroupCriterion | ColumnKey | string): void;
592
+ /** Clear the active grouping and restore the parent/child tree view. Emits `groupChange`. */
593
+ clearGrouping(): void;
594
+ /** The active grouping criterion, or `null` when not grouping. */
595
+ getGroupBy(): GroupCriterion | null;
596
+ /** Whether grouping is currently active. */
597
+ isGrouping(): boolean;
598
+ private dispatchGroupChange;
599
+ /**
600
+ * Apply a sort to the task list. Hierarchy-preserving: siblings are reordered
601
+ * within each parent (a child never leaves its parent). Pass one or more
602
+ * {@link SortCriterion}; an empty array clears the sort (natural input order).
603
+ * Re-renders and emits `sortChange`.
604
+ *
605
+ * @example gantt.sort({ key: ColumnKey.Name, direction: 'asc' });
606
+ */
607
+ sort(criteria: SortCriterion | SortCriterion[]): void;
608
+ /** Clear the active sort and return to natural (input) order. Emits `sortChange`. */
609
+ clearSort(): void;
610
+ /** The currently active sort criteria (empty array = natural order). */
611
+ getSort(): SortCriterion[];
612
+ /**
613
+ * Toggle the sort on a column through ascending → descending → none. Backs the
614
+ * column-header click UX. No-op when the column is not sortable. Emits
615
+ * `sortChange`.
616
+ *
617
+ * With `append: true` (Shift+click) the column is added as an additional sort
618
+ * key — the existing keys are kept and this key cycles ascending → descending
619
+ * → removed, so you can sort by several columns at once (first key wins, ties
620
+ * break on the next). Without it, the sort is replaced by this single key.
621
+ */
622
+ toggleSort(key: ColumnKey | string, opts?: {
623
+ append?: boolean;
624
+ }): void;
625
+ /**
626
+ * Apply a filter to the task list. A task is kept when it matches the
627
+ * predicate or has a matching descendant, so ancestors of matches stay
628
+ * visible. Filtering is view-only — it changes which rows render but not the
629
+ * tree, WBS, or task data. Re-renders and emits `filterChange`.
630
+ *
631
+ * @example gantt.filter((task) => task.progress < 100);
632
+ */
633
+ filter(predicate: TaskFilterPredicate): void;
634
+ /** Clear the active filter so every row is shown again. Emits `filterChange`. */
635
+ clearFilter(): void;
636
+ /** Whether a filter is currently active. */
637
+ isFiltered(): boolean;
638
+ /**
639
+ * Apply a structured filter (advanced filter builder): a {@link FilterRuleSet}
640
+ * of conditions combined with `'all'` (AND) or `'any'` (OR), compiled to the
641
+ * same view-only filter as `gantt.filter()`. Pass `null` (or an empty rule
642
+ * list) to clear. Re-renders and emits `filterChange`.
643
+ *
644
+ * @example gantt.setFilterRules({ match: 'all', rules: [{ field: ColumnKey.Progress, operator: 'lt', value: 100 }] });
645
+ */
646
+ setFilterRules(ruleSet: FilterRuleSet | null): void;
647
+ /** The active structured filter rules, or `null` when none are set. */
648
+ getFilterRules(): FilterRuleSet | null;
649
+ /**
650
+ * Commit a column resize coming from a header-handle drag. The `Tasks` view
651
+ * already updated the live grid template during the drag, so we only sync the
652
+ * authoritative override map (so it survives the next full render), persist,
653
+ * and emit `columnResize`. `width` is `null` when the column was reset.
654
+ */
655
+ private handleColumnResize;
656
+ private dispatchColumnResize;
657
+ /**
658
+ * Pin a task-list column to an exact pixel width (the other columns absorb the
659
+ * remaining panel space). Mirrors dragging the column-header resize handle.
660
+ * Re-renders and emits `columnResize`.
661
+ *
662
+ * @example gantt.setColumnWidth(ColumnKey.Name, 260);
663
+ */
664
+ setColumnWidth(key: ColumnKey | string, width: number): void;
665
+ /**
666
+ * Clear the manual width of one column (pass its `key`) or of every column
667
+ * (omit the argument), returning them to their auto/flex width. Re-renders and
668
+ * emits `columnResize`.
669
+ */
670
+ resetColumnWidths(key?: ColumnKey | string): void;
671
+ /** The active manual column-width overrides as a plain object (key → pixels). */
672
+ getColumnWidths(): Record<string, number>;
673
+ /**
674
+ * Commit a column reorder coming from a header drag: store the new key order,
675
+ * re-render so the grid reflects it, persist, and emit `columnReorder`.
676
+ */
677
+ private handleColumnReorder;
678
+ private dispatchColumnReorder;
679
+ /**
680
+ * Set the left-to-right order of the task-list columns by key. Keys you list
681
+ * are placed first in that order; any visible columns you omit keep their
682
+ * relative position at the end. Mirrors dragging a column header. Re-renders
683
+ * and emits `columnReorder`.
684
+ *
685
+ * @example gantt.setColumnOrder([ColumnKey.Name, ColumnKey.Progress, ColumnKey.StartTime]);
686
+ */
687
+ setColumnOrder(order: Array<ColumnKey | string>): void;
688
+ /** The current column order as an array of keys (left-to-right), reflecting any reorder. */
689
+ getColumnOrder(): string[];
690
+ /**
691
+ * Scroll the timeline (and, if needed, the row list) so a task's bar is in
692
+ * view, using nearest-edge alignment (the minimum scroll that reveals it).
693
+ * Backs the per-row scroll chevrons; call it directly to "locate" a task from
694
+ * search results, selection, or your own toolbar button.
695
+ *
696
+ * @returns `true` when a scroll was applied, `false` when the task is unknown
697
+ * or already fully visible.
698
+ *
699
+ * @example gantt.scrollToTask('task-42');
700
+ */
701
+ scrollToTask(taskId: string): boolean;
702
+ /**
703
+ * Capture the current UI view state — zoom, scroll, collapse, selection, sort,
704
+ * and filter — as a serializable object. Pair with {@link setState} to save
705
+ * and restore "where the user left off" (e.g. to your own backend), or set the
706
+ * `persistState` option to have the Gantt do it via localStorage.
707
+ *
708
+ * @example const saved = gantt.getState(); // JSON-serializable
709
+ */
710
+ getState(): GanttUiState;
711
+ /**
712
+ * Restore a UI view state produced by {@link getState}. Any omitted field is
713
+ * left untouched, so a partial state (e.g. `{ sort: [...] }`) applies just that
714
+ * slice. Re-renders once, then emits `sortChange` / `filterChange` for the
715
+ * parts that changed (pass `{ silent: true }` to suppress those events).
716
+ *
717
+ * @example gantt.setState(savedState);
718
+ */
719
+ setState(state: Partial<GanttUiState>, opts?: {
720
+ silent?: boolean;
721
+ }): void;
722
+ /** Apply the `sort` slice of a {@link GanttUiState} to the data layer (no render). */
723
+ private applySortState;
724
+ /** Apply the `columnWidths` slice of a {@link GanttUiState} (no render). Omitted → untouched; `{}` → cleared. */
725
+ private applyColumnWidthsState;
726
+ /** Apply the `group` slice of a {@link GanttUiState} to the data layer (no render). */
727
+ private applyGroupState;
728
+ /** Apply the `filterRules` / `quickFilter` slice of a {@link GanttUiState} (no render). */
729
+ private applyFilterState;
730
+ /** Restore scroll offsets after a render (deferred so the DOM has laid out). */
731
+ private applyScrollState;
732
+ /** Resolve the persistence config, or `null` when disabled / storage is unavailable (SSR). */
733
+ private resolvePersistence;
734
+ /** Debounced write of the current state to storage; no-op when persistence is off. */
735
+ private schedulePersist;
736
+ /** Serialize and store the current state immediately (used by the debounce). */
737
+ private writePersistedState;
738
+ /**
739
+ * Read and apply any persisted state. Returns `true` when state was restored
740
+ * (the caller's render pass is superseded by the one inside `setState`).
741
+ */
742
+ private restorePersistedState;
743
+ /**
744
+ * Attach the persistence listeners once. Selection and scroll change without a
745
+ * full `render()`, so we save on those directly; `this.element` persists across
746
+ * renders and scroll bubbles in the capture phase, so a single set suffices.
747
+ */
748
+ private attachPersistenceListeners;
749
+ /** One-time restore + listener attach on the first render. Returns true when state was restored. */
750
+ private maybeRestorePersistedStateOnce;
751
+ /** Remove persistence listeners and cancel the pending write. Called from `destroy()`. */
752
+ private detachPersistence;
753
+ /**
754
+ * Auto-fit zoom on first render: once the container has a measurable width and
755
+ * (usually) data, pick a zoom that shows the whole project span.
756
+ */
757
+ private applyAutoFitZoomIfNeeded;
758
+ /**
759
+ * Diff the previously-visible and now-visible task IDs so only rows whose
760
+ * visibility changed (collapse/expand) get their arrows delayed. Returns
761
+ * `undefined` on the first render (no previous set) to fade the whole SVG.
762
+ */
763
+ private computeChangedVisibleIds;
764
+ /** Localized label for the toolbar export button, matching the active `exportFormat`. */
765
+ private exportButtonLabel;
766
+ /**
767
+ * Export the chart and trigger a download. `svg` is vector; `png` and `pdf`
768
+ * rasterize the chart (the PDF embeds the raster on a single page). Defaults
769
+ * to the configured `exportFormat`. Under row virtualization the full dataset
770
+ * is expanded for the snapshot and restored afterward.
771
+ *
772
+ * @param format Output format; defaults to `options.exportFormat` (`'svg'`).
773
+ * @returns Resolves once the download has been triggered.
774
+ *
775
+ * @example await gantt.exportChart('png');
776
+ */
777
+ exportChart(format?: GanttExportFormat): Promise<void>;
778
+ private dispatchSortChange;
779
+ private dispatchFilterChange;
780
+ /** Build the built-in quick-filter search input for the toolbar. */
781
+ private buildQuickFilterInput;
782
+ /**
783
+ * Apply the quick-filter query: set the matching predicate (or clear it when
784
+ * empty), re-render, and restore focus + caret to the search box (a full
785
+ * re-render rebuilds the toolbar, so the input is recreated each keystroke).
786
+ */
787
+ private applyQuickFilter;
788
+ /** Build a name/field-contains predicate from the quick-filter query (null when blank). */
789
+ private buildQuickFilterPredicate;
790
+ private restoreQuickFilterFocus;
791
+ /**
792
+ * Build the "Filter" toolbar control: a button (with an active-rule count
793
+ * badge) and, when open, the rule-composer popover. Rebuilt on every toolbar
794
+ * render from `filterBuilderOpen` / `filterBuilderDraft`, so its state
795
+ * survives re-renders.
796
+ */
797
+ private buildFilterBuilder;
798
+ /** Toggle the popover, seeding the draft from the committed rules when opening. */
799
+ private toggleFilterBuilder;
800
+ private cloneRuleSet;
801
+ /** Build the popover body: match selector, rule rows, add button, and footer. */
802
+ private buildFilterPopover;
803
+ /** Build one condition row: field select, operator select, and a typed value input. */
804
+ private buildFilterRow;
484
805
  /**
485
806
  * Wire a global keydown listener on the root element so Ctrl/Cmd+Z and
486
807
  * Ctrl+Y / Ctrl/Cmd+Shift+Z work anywhere inside the chart (timeline body,
@@ -516,6 +837,17 @@ declare class ApexGantt extends BaseChart {
516
837
  * entries. Picks placeholder dates from the current project span so the
517
838
  * bar is visible at the default zoom.
518
839
  */
840
+ /** Snap step in ms for the active snap unit/value (day / hour / minute). */
841
+ private snapStepMs;
842
+ /**
843
+ * Create a task from a draw-on-empty-timeline gesture. `startX` / `endX` are
844
+ * content-space pixel offsets (the gesture's two edges); we reverse them
845
+ * through the current geometry to dates, snap to the snap unit, and add a task
846
+ * spanning that range. Day-only formats render the end inclusive, so an
847
+ * N-unit sweep lands `end = start + (N-1)` units. Row index is not used for
848
+ * placement — the new root task sorts into position by its dates like any add.
849
+ */
850
+ private commitDrawnTask;
519
851
  private addPlaceholderTask;
520
852
  /**
521
853
  * Toolbar "+ Add task" handler. Inserts a new root-level placeholder task.
@@ -658,6 +990,34 @@ export declare interface Assignee {
658
990
  readonly color?: string;
659
991
  }
660
992
 
993
+ /**
994
+ * Built-in column renderer that shows a stacked row of circular avatars for a
995
+ * task's assignees, with an overflow indicator (`+N`) when the count exceeds
996
+ * `max`. Falls back to colored initials when an assignee has no `avatarUrl`.
997
+ *
998
+ * @example
999
+ * ```ts
1000
+ * import { ApexGantt, ColumnKey, renderers } from '@apexcharts/apexgantt';
1001
+ *
1002
+ * new ApexGantt('#chart', {
1003
+ * series,
1004
+ * columnConfig: [
1005
+ * { key: ColumnKey.Name, title: 'Task' },
1006
+ * {
1007
+ * key: 'assignees',
1008
+ * title: 'Assigned',
1009
+ * render: renderers.avatars({
1010
+ * accessor: (task) => task.assignees,
1011
+ * max: 4,
1012
+ * size: 24,
1013
+ * }),
1014
+ * },
1015
+ * ],
1016
+ * });
1017
+ * ```
1018
+ */
1019
+ declare function avatars(options: AvatarsRendererOptions): ColumnRenderer;
1020
+
661
1021
  /**
662
1022
  * Configuration for the {@link avatars} column renderer.
663
1023
  */
@@ -733,14 +1093,6 @@ export declare type BarLabelPosition = 'inside' | 'left' | 'right' | 'auto';
733
1093
  */
734
1094
  export declare type BarLabelRenderer = (task: Task) => string | HTMLElement | null | undefined;
735
1095
 
736
- declare abstract class BaseChart {
737
- /* Excluded from this release type: element */
738
- /** Destroys the chart instance and cleans up DOM resources. */
739
- destroy(): void;
740
- /** Returns the unique identifier for this chart instance. */
741
- getInstanceId(): string;
742
- }
743
-
744
1096
  /**
745
1097
  * Planned (baseline) dates for a task, used to visualise schedule variance.
746
1098
  *
@@ -768,11 +1120,13 @@ export declare interface BaselineOptions {
768
1120
  */
769
1121
  readonly enabled: boolean;
770
1122
  /**
771
- * Primary baseline color. When `striped` is true this paints the stripes;
772
- * otherwise it fills the whole bar.
773
- * @default '#9E9E9E'
1123
+ * Baseline color. When `striped` is true this paints the stripes; otherwise
1124
+ * it fills the whole bar. When omitted, the baseline uses the task bar's
1125
+ * progress shade (the darker tone of the bar drawn above), so a baseline
1126
+ * reads as the planned twin of its bar. Set an explicit color to override.
1127
+ * @default the bar's progress color (task `barBackgroundColor`, darkened)
774
1128
  */
775
- readonly color: string;
1129
+ readonly color?: string;
776
1130
  /**
777
1131
  * Fill the baseline bar with thick diagonal stripes that alternate between
778
1132
  * `color` and `stripeColor`, instead of a flat fill.
@@ -913,12 +1267,18 @@ export declare interface CalendarOptions {
913
1267
  * and in what order.
914
1268
  */
915
1269
  export declare enum ColumnKey {
1270
+ Assignees = "assignees",
1271
+ BaselineEnd = "baselineEnd",
1272
+ BaselineStart = "baselineStart",
1273
+ BaselineVariance = "baselineVariance",
916
1274
  Duration = "duration",
917
1275
  EndTime = "endTime",
918
1276
  Name = "name",
1277
+ Predecessors = "predecessors",
919
1278
  Progress = "progress",
920
1279
  ProgressRing = "progressRing",
921
1280
  StartTime = "startTime",
1281
+ Successors = "successors",
922
1282
  Wbs = "wbs"
923
1283
  }
924
1284
 
@@ -944,22 +1304,77 @@ export declare interface ColumnListItem {
944
1304
  readonly key: ColumnKey | string;
945
1305
  readonly title: string;
946
1306
  readonly minWidth?: string;
1307
+ /**
1308
+ * Upper bound for auto-sized column width (e.g. `'240px'`). Caps how wide the
1309
+ * column grows to fit content when `autoSizeColumns` is on, so one long value
1310
+ * can't dominate the panel. Ignored when auto-sizing is off. @default '320px'
1311
+ */
1312
+ readonly maxWidth?: string;
947
1313
  readonly flexGrow?: number;
948
1314
  readonly visible?: boolean;
1315
+ /**
1316
+ * Whether this column can be resized by dragging the handle at its header's
1317
+ * trailing edge (requires the `resizableColumns` option). Set `false` to lock
1318
+ * a single column at its auto/configured width. @default true
1319
+ */
1320
+ readonly resizable?: boolean;
949
1321
  /**
950
1322
  * Custom cell renderer. Required for custom columns; ignored for built-in
951
1323
  * columns (built-ins use the library's internal renderer).
952
1324
  */
953
1325
  readonly render?: ColumnRenderer;
954
1326
  /**
955
- * Extracts the underlying value of the cell from the task. Used by future
956
- * sort/filter features and by SVG export. Optional.
1327
+ * Extracts the underlying value of the cell from the task. Used by sorting,
1328
+ * filtering, and SVG export. Optional for built-in columns (they have native
1329
+ * extractors); for a custom column it is what makes the column sortable.
957
1330
  */
958
1331
  readonly accessor?: (task: Task) => unknown;
1332
+ /**
1333
+ * Whether the column participates in sorting (header click + the `sortBy`
1334
+ * option / `gantt.sort()` API). Defaults to `true` for built-in value
1335
+ * columns, `false` for the `Wbs` column, and `true` for custom columns only
1336
+ * when an `accessor` or `comparator` is supplied.
1337
+ */
1338
+ readonly sortable?: boolean;
1339
+ /**
1340
+ * Custom sort comparator for this column. When provided it takes precedence
1341
+ * over `accessor`-based comparison. Receives two tasks and returns a negative
1342
+ * / zero / positive number (ascending order); the active sort direction is
1343
+ * applied on top. Stable: equal results fall back to natural (input) order.
1344
+ */
1345
+ readonly comparator?: TaskComparator;
959
1346
  }
960
1347
 
961
1348
  declare interface ColumnOptions {
962
1349
  readonly columnConfig?: ColumnListItem[];
1350
+ /**
1351
+ * Initial sort applied to the task list. One or more {@link SortCriterion}
1352
+ * (or a single criterion). Sorting is hierarchy-preserving: siblings are
1353
+ * reordered within each parent, never flattened. Omit for the default
1354
+ * (start-time ascending); pass `[]` for natural (input) order.
1355
+ * @default [{ key: ColumnKey.StartTime, direction: 'asc' }]
1356
+ */
1357
+ readonly sortBy?: SortCriterion | SortCriterion[];
1358
+ /**
1359
+ * Initial filter applied to the task list. A predicate run against each task;
1360
+ * a task is kept when it matches or has a matching descendant (ancestors of
1361
+ * matches stay visible). Omit for no filter. @default undefined
1362
+ */
1363
+ readonly filterBy?: TaskFilterPredicate;
1364
+ /**
1365
+ * Initial structured filter (advanced filter builder). A {@link FilterRuleSet}
1366
+ * of conditions combined with `'all'` (AND) / `'any'` (OR), compiled to the
1367
+ * same view-only filter as `filterBy`. Takes precedence over `filterBy` when
1368
+ * both are set. @default undefined
1369
+ */
1370
+ readonly filterRules?: FilterRuleSet;
1371
+ /**
1372
+ * Initial grouping applied to the task list. A {@link GroupCriterion} (or a
1373
+ * bare column key). When set, the parent/child tree is suspended and tasks are
1374
+ * bucketed under collapsible group headers. Omit for no grouping.
1375
+ * @default undefined
1376
+ */
1377
+ readonly groupBy?: GroupCriterion | ColumnKey | string;
963
1378
  }
964
1379
 
965
1380
  /**
@@ -1005,16 +1420,59 @@ export declare interface ColumnRenderContext {
1005
1420
  */
1006
1421
  export declare type ColumnRenderer = (ctx: ColumnRenderContext, el: HTMLElement) => void | string | (() => void);
1007
1422
 
1423
+ /**
1424
+ * Detail for the `columnReorder` event, fired when task-list columns are
1425
+ * reordered by dragging a column header, or via `gantt.setColumnOrder()`.
1426
+ */
1427
+ export declare interface ColumnReorderEventDetail {
1428
+ /** Column keys in their new left-to-right order (visible columns only). */
1429
+ order: string[];
1430
+ /** Key of the column that was moved (the dragged column); `null` for a bulk `setColumnOrder`. */
1431
+ movedKey: string | null;
1432
+ timestamp: number;
1433
+ }
1434
+
1435
+ /**
1436
+ * Detail for the `columnResize` event, fired when a task-list column is resized
1437
+ * by dragging its header handle, via `gantt.setColumnWidth()`, or reset via
1438
+ * `gantt.resetColumnWidths()`.
1439
+ */
1440
+ export declare interface ColumnResizeEventDetail {
1441
+ /** Key of the column that changed. */
1442
+ key: string;
1443
+ /** New pixel width, or `null` when the column was reset to its auto width. */
1444
+ width: number | null;
1445
+ /** All active manual column-width overrides after the change (key → pixels). */
1446
+ widths: Record<string, number>;
1447
+ timestamp: number;
1448
+ }
1449
+
1008
1450
  declare interface CommonOptions {
1009
1451
  readonly backgroundColor: string;
1010
1452
  readonly borderColor: string;
1011
1453
  readonly canvasStyle: string;
1012
1454
  readonly enableExport: boolean;
1455
+ /** Format the toolbar export button produces. @default 'svg' */
1456
+ readonly exportFormat: GanttExportFormat;
1013
1457
  readonly enableResize: boolean;
1014
1458
  readonly headerBackground: string;
1015
1459
  readonly height: number | string;
1016
1460
  readonly inputDateFormat: string;
1017
1461
  readonly pixelsPerDay?: number;
1462
+ /**
1463
+ * Persist the UI view state (zoom, scroll, sort, filter, collapse, selection)
1464
+ * to `localStorage` and restore it on load. `true` uses the default key;
1465
+ * an object customizes it. @default false
1466
+ */
1467
+ readonly persistState: boolean | GanttStatePersistenceOptions;
1468
+ /**
1469
+ * Auto-size task-list columns to fit their header + cell content, growing the
1470
+ * panel so nothing clips. Set `false` to distribute the panel width by
1471
+ * `flexGrow` (legacy behavior). @default true
1472
+ */
1473
+ readonly autoSizeColumns: boolean;
1474
+ readonly resizableColumns: boolean;
1475
+ readonly reorderableColumns: boolean;
1018
1476
  readonly tasksContainerWidth: number;
1019
1477
  readonly width: number | string;
1020
1478
  }
@@ -1233,6 +1691,49 @@ export declare type DependencyType = 'FF' | 'FS' | 'SF' | 'SS';
1233
1691
  */
1234
1692
  export declare function escapeHtml(value: unknown): string;
1235
1693
 
1694
+ /**
1695
+ * Detail for the `filterChange` event, fired when the active filter changes via
1696
+ * `gantt.filter()` / `gantt.clearFilter()`.
1697
+ */
1698
+ export declare interface FilterChangeEventDetail {
1699
+ /** Whether a filter is active after the change. */
1700
+ active: boolean;
1701
+ /** Number of rows visible under the active filter (visible task count). */
1702
+ visibleCount: number;
1703
+ timestamp: number;
1704
+ }
1705
+
1706
+ /**
1707
+ * Comparison operators for a structured {@link FilterRule}. Which operators are
1708
+ * valid depends on the column's value type (text / number / date); see the
1709
+ * filter builder. `isEmpty` / `notEmpty` apply to any type and ignore `value`.
1710
+ */
1711
+ export declare type FilterOperator = 'contains' | 'notContains' | 'equals' | 'notEquals' | 'startsWith' | 'endsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'before' | 'after' | 'on' | 'isEmpty' | 'notEmpty';
1712
+
1713
+ /** A single structured filter condition: compare a column's value with `value`. */
1714
+ export declare interface FilterRule {
1715
+ /** Column key whose value is tested (a `ColumnKey` or a custom column id). */
1716
+ readonly field: ColumnKey | string;
1717
+ /** Comparison operator. */
1718
+ readonly operator: FilterOperator;
1719
+ /**
1720
+ * Comparison operand. A number for number columns, a `YYYY-MM-DD` string for
1721
+ * date columns, free text otherwise. Ignored by `isEmpty` / `notEmpty`.
1722
+ */
1723
+ readonly value?: string | number;
1724
+ }
1725
+
1726
+ /**
1727
+ * A set of {@link FilterRule}s combined with boolean logic. Compiles to a
1728
+ * {@link TaskFilterPredicate} and backs the advanced filter builder.
1729
+ */
1730
+ export declare interface FilterRuleSet {
1731
+ /** `'all'` = every rule must match (AND); `'any'` = at least one (OR). */
1732
+ readonly match: 'all' | 'any';
1733
+ /** The rules to evaluate. An empty list means "no filter". */
1734
+ readonly rules: FilterRule[];
1735
+ }
1736
+
1236
1737
  declare interface FontOptions {
1237
1738
  readonly fontColor: string;
1238
1739
  readonly fontFamily: string;
@@ -1356,6 +1857,16 @@ export declare interface GanttEventMap {
1356
1857
  dependencyArrowUpdate: CustomEvent<DependencyArrowUpdateDetail>;
1357
1858
  /** Fires after a record/undo/redo/clear mutates the history stack. */
1358
1859
  historyChange: CustomEvent<HistoryChangeEventDetail>;
1860
+ /** Fires after the active sort changes (API or header click). */
1861
+ sortChange: CustomEvent<SortChangeEventDetail>;
1862
+ /** Fires after the active filter changes. */
1863
+ filterChange: CustomEvent<FilterChangeEventDetail>;
1864
+ /** Fires after the active grouping changes (API). */
1865
+ groupChange: CustomEvent<GroupChangeEventDetail>;
1866
+ /** Fires after a task-list column is resized (header drag or API). */
1867
+ columnResize: CustomEvent<ColumnResizeEventDetail>;
1868
+ /** Fires after task-list columns are reordered (header drag or API). */
1869
+ columnReorder: CustomEvent<ColumnReorderEventDetail>;
1359
1870
  }
1360
1871
 
1361
1872
  export declare const GanttEvents: {
@@ -1419,8 +1930,31 @@ export declare const GanttEvents: {
1419
1930
  * emits after the undo/redo stack changes — record, undo, redo, or clear
1420
1931
  */
1421
1932
  readonly HISTORY_CHANGE: "historyChange";
1933
+ /**
1934
+ * emits after the active sort changes (via API or column-header click)
1935
+ */
1936
+ readonly SORT_CHANGE: "sortChange";
1937
+ /**
1938
+ * emits after the active filter changes
1939
+ */
1940
+ readonly FILTER_CHANGE: "filterChange";
1941
+ /**
1942
+ * emits after the active grouping changes (via API)
1943
+ */
1944
+ readonly GROUP_CHANGE: "groupChange";
1945
+ /**
1946
+ * emits after a task-list column is resized (header drag or API)
1947
+ */
1948
+ readonly COLUMN_RESIZE: "columnResize";
1949
+ /**
1950
+ * emits after task-list columns are reordered (header drag or API)
1951
+ */
1952
+ readonly COLUMN_REORDER: "columnReorder";
1422
1953
  };
1423
1954
 
1955
+ /** Supported export formats. `svg` is vector; `png`/`pdf` rasterize the SVG. */
1956
+ export declare type GanttExportFormat = 'svg' | 'png' | 'pdf';
1957
+
1424
1958
  /**
1425
1959
  * Every user-facing string the Gantt generates internally (toolbar, context
1426
1960
  * menu, task form, validation, baseline tooltip, add-task row, and bar
@@ -1437,8 +1971,40 @@ export declare interface GanttMessages {
1437
1971
  readonly undo: string;
1438
1972
  /** Redo toolbar button. @default 'Redo (Ctrl+Y)' */
1439
1973
  readonly redo: string;
1440
- /** Export toolbar button. @default 'Export as SVG' */
1974
+ /** Export toolbar button (SVG format). @default 'Export as SVG' */
1441
1975
  readonly exportAsSvg: string;
1976
+ /** Export toolbar button (PNG format). @default 'Export as PNG' */
1977
+ readonly exportAsPng: string;
1978
+ /** Export toolbar button (PDF format). @default 'Export as PDF' */
1979
+ readonly exportAsPdf: string;
1980
+ /** Placeholder for the built-in quick-filter search box. @default 'Search tasks…' */
1981
+ readonly quickFilterPlaceholder: string;
1982
+ /** Advanced filter builder: toolbar button label. @default 'Filter' */
1983
+ readonly filterButton: string;
1984
+ /** Filter builder: popover heading. @default 'Filter tasks' */
1985
+ readonly filterHeading: string;
1986
+ /** Filter builder: match-mode label. @default 'Match' */
1987
+ readonly filterMatchLabel: string;
1988
+ /** Filter builder: match-all (AND) option. @default 'All' */
1989
+ readonly filterMatchAll: string;
1990
+ /** Filter builder: match-any (OR) option. @default 'Any' */
1991
+ readonly filterMatchAny: string;
1992
+ /** Filter builder: add-condition button. @default '+ Add condition' */
1993
+ readonly filterAddCondition: string;
1994
+ /** Filter builder: apply button. @default 'Apply' */
1995
+ readonly filterApply: string;
1996
+ /** Filter builder: clear button. @default 'Clear' */
1997
+ readonly filterClear: string;
1998
+ /** Filter builder: remove-condition button aria-label. @default 'Remove condition' */
1999
+ readonly filterRemoveCondition: string;
2000
+ /** Filter builder: empty-state text shown when no conditions exist. @default 'No conditions yet.' */
2001
+ readonly filterNoConditions: string;
2002
+ /** Filter builder: human-readable label for a comparison operator. */
2003
+ readonly filterOperatorLabel: (operator: FilterOperator) => string;
2004
+ /** Group header label for tasks whose group value is empty. @default '(None)' */
2005
+ readonly groupNone: string;
2006
+ /** Group header member-count label, e.g. `(3)`. @default `(n)` => `(${n})` */
2007
+ readonly groupCountLabel: (count: number) => string;
1442
2008
  /** Alert when export cannot find the chart. @default 'Export failed: Chart not found. Please refresh and try again.' */
1443
2009
  readonly exportFailedNoChart: string;
1444
2010
  /** Generic export-failure alert. @default 'Export failed. Please check the console for details.' */
@@ -1524,6 +2090,15 @@ declare interface GanttRowOptions {
1524
2090
  readonly rowHeight: number;
1525
2091
  }
1526
2092
 
2093
+ /**
2094
+ * Configuration for opt-in localStorage persistence of the {@link GanttUiState}.
2095
+ * Pass `persistState: true` for the defaults, or an object to customize the key.
2096
+ */
2097
+ export declare interface GanttStatePersistenceOptions {
2098
+ /** localStorage key under which the state is saved. @default 'apexgantt-state' */
2099
+ key?: string;
2100
+ }
2101
+
1527
2102
  /**
1528
2103
  * Complete color palette for the chart UI.
1529
2104
  *
@@ -1580,6 +2155,62 @@ export declare interface GanttTheme {
1580
2155
  readonly splitBarHandleColor: string;
1581
2156
  }
1582
2157
 
2158
+ /**
2159
+ * A serializable snapshot of the Gantt's view state: everything that is a
2160
+ * user's "where I left off" rather than the task data itself. Produced by
2161
+ * `gantt.getState()` and consumed by `gantt.setState()`; also what the opt-in
2162
+ * localStorage persistence layer reads and writes.
2163
+ *
2164
+ * Every field is optional on input to `setState()` so a partial state (e.g.
2165
+ * only `sort`) applies just that slice and leaves the rest untouched.
2166
+ */
2167
+ export declare interface GanttUiState {
2168
+ /** Schema version; set to {@link GANTT_STATE_VERSION} by `getState()`. */
2169
+ version: number;
2170
+ /** Zoom level as pixels-per-day (same unit as the `pixelsPerDay` option). */
2171
+ zoom?: number;
2172
+ /** Scroll offsets in pixels: `horizontal` = timeline, `vertical` = grid rows. */
2173
+ scroll?: {
2174
+ horizontal: number;
2175
+ vertical: number;
2176
+ };
2177
+ /** IDs of collapsed summary rows. Rows not listed are expanded. */
2178
+ collapsed?: string[];
2179
+ /** IDs of selected task rows (requires `enableSelection`). */
2180
+ selected?: string[];
2181
+ /** Active sort criteria; an empty array means natural (input) order. */
2182
+ sort?: Array<{
2183
+ key: string;
2184
+ direction: 'asc' | 'desc';
2185
+ }>;
2186
+ /** Active advanced-filter rule set, or `null` when no structured filter is set. */
2187
+ filterRules?: FilterRuleSet | null;
2188
+ /** Text in the built-in quick-filter box. */
2189
+ quickFilter?: string;
2190
+ /**
2191
+ * Active grouping: the field grouped by and header order, or `null` when not
2192
+ * grouping. Only the serializable parts are stored — a custom `accessor` /
2193
+ * `label` on the criterion is not persisted (restore falls back to the
2194
+ * column's own accessor).
2195
+ */
2196
+ group?: {
2197
+ field: string;
2198
+ direction?: 'asc' | 'desc';
2199
+ } | null;
2200
+ /**
2201
+ * Manual per-column pixel widths set by resizing a column header (or
2202
+ * `gantt.setColumnWidth()`), keyed by column key. Columns not listed keep
2203
+ * their auto/flex width. Omitted (or empty) when no column has been resized.
2204
+ */
2205
+ columnWidths?: Record<string, number>;
2206
+ /**
2207
+ * Column keys in their user-chosen left-to-right order (from dragging a
2208
+ * column header or `gantt.setColumnOrder()`). Omitted when the order has not
2209
+ * been changed from the configured/default order.
2210
+ */
2211
+ columnOrder?: string[];
2212
+ }
2213
+
1583
2214
  /**
1584
2215
  * Top-level configuration object for `ApexGantt`.
1585
2216
  *
@@ -1648,7 +2279,7 @@ export declare interface GanttUserOptions {
1648
2279
  /**
1649
2280
  * Fill color for summary (group) bars. Renders distinct from regular task
1650
2281
  * bars to make the parent/child hierarchy visually obvious.
1651
- * @default '#B9CECE' (light) / '#8FBCBC' (dark)
2282
+ * @default '#94A3B8' (light) / '#8FBCBC' (dark)
1652
2283
  */
1653
2284
  readonly summaryBarColor?: string;
1654
2285
  /**
@@ -1670,7 +2301,7 @@ export declare interface GanttUserOptions {
1670
2301
  * and HTML hover tooltip (`tooltipTemplate`).
1671
2302
  */
1672
2303
  readonly dependencies?: DependencyOptions;
1673
- /** Color of the cell and row divider lines. @default '#eff0f0' */
2304
+ /** Color of the cell and row divider lines. @default '#E5E7EB' (light) / '#3A3A3A' (dark) */
1674
2305
  readonly borderColor?: string;
1675
2306
  /** Arbitrary CSS injected onto the root container element. */
1676
2307
  readonly canvasStyle?: string;
@@ -1687,7 +2318,7 @@ export declare interface GanttUserOptions {
1687
2318
  * @default false
1688
2319
  */
1689
2320
  readonly enableCrosshair?: boolean;
1690
- /** Color of the crosshair line and label background. @default '#87B7FE' (light) / '#818CF8' (dark) */
2321
+ /** Color of the crosshair line and label background. @default '#3B82F6' (light) / '#818CF8' (dark) */
1691
2322
  readonly crosshairColor?: string;
1692
2323
  /**
1693
2324
  * Custom formatter for the crosshair label text. Receives the date under the
@@ -1696,12 +2327,44 @@ export declare interface GanttUserOptions {
1696
2327
  * month/quarter/year tiers and `'MM/DD HH:mm'` for hour/minute tiers.
1697
2328
  */
1698
2329
  readonly crosshairLabelFormat?: CrosshairLabelFormatter;
1699
- /** Border color for all cells in the task table and timeline grid. @default '#D0D7DE' */
2330
+ /** Border color for all cells in the task table and timeline grid. @default '#EDEFF2' (light) / '#3A3A3A' (dark) */
1700
2331
  readonly cellBorderColor?: string;
1701
2332
  /** CSS border-width for all cell lines, e.g. `'1px'`. @default '1px' */
1702
2333
  readonly cellBorderWidth?: string;
1703
2334
  /** Custom column definitions for the task-list panel. When omitted, all default columns are shown. */
1704
2335
  readonly columnConfig?: ColumnListItem[];
2336
+ /**
2337
+ * Initial sort for the task list. One or more {@link SortCriterion}.
2338
+ * Hierarchy-preserving: siblings are sorted within each parent. Omit for the
2339
+ * default (start-time ascending); pass `[]` for natural (input) order.
2340
+ * @default [{ key: ColumnKey.StartTime, direction: 'asc' }]
2341
+ */
2342
+ readonly sortBy?: SortCriterion | SortCriterion[];
2343
+ /**
2344
+ * Initial filter for the task list. A predicate run against each task; a task
2345
+ * is kept when it matches or has a matching descendant. @default undefined
2346
+ */
2347
+ readonly filterBy?: TaskFilterPredicate;
2348
+ /**
2349
+ * Initial structured filter (advanced filter builder): a {@link FilterRuleSet}
2350
+ * of conditions combined with `'all'` / `'any'`. Takes precedence over
2351
+ * `filterBy` when both are set. @default undefined
2352
+ */
2353
+ readonly filterRules?: FilterRuleSet;
2354
+ /**
2355
+ * Initial grouping: a {@link GroupCriterion} or a bare column key. When set,
2356
+ * the parent/child tree is suspended and tasks are bucketed under collapsible
2357
+ * group headers, ordered and labelled by the criterion. Also available at
2358
+ * runtime via `gantt.groupBy()` / `gantt.clearGrouping()`. @default undefined
2359
+ */
2360
+ readonly groupBy?: GroupCriterion | ColumnKey | string;
2361
+ /**
2362
+ * Show a built-in advanced filter builder in the toolbar — a "Filter" button
2363
+ * that opens a popover for composing field/operator/value conditions combined
2364
+ * with All (AND) / Any (OR). Drives the same view-only filter as
2365
+ * `gantt.setFilterRules()`. @default false
2366
+ */
2367
+ readonly enableFilterBuilder?: boolean;
1705
2368
  /**
1706
2369
  * Whether to draw vertical lines between timeline columns (the cell
1707
2370
  * dividers in the header and body grid). Set to `false` for a cleaner
@@ -1730,8 +2393,48 @@ export declare interface GanttUserOptions {
1730
2393
  readonly enableInlineEdit?: boolean;
1731
2394
  /** Enable row selection (click, Ctrl+Click, Shift+Click, keyboard). @default false */
1732
2395
  readonly enableSelection?: boolean;
1733
- /** Show the SVG export button in the toolbar. @default true */
2396
+ /** Show the export button in the toolbar. @default true */
1734
2397
  readonly enableExport?: boolean;
2398
+ /**
2399
+ * Format produced by the toolbar export button: `'svg'` (vector), `'png'`
2400
+ * (raster), or `'pdf'` (single-page, image-based). Any format is also
2401
+ * available programmatically via `gantt.exportChart(format)`. @default 'svg'
2402
+ */
2403
+ readonly exportFormat?: GanttExportFormat;
2404
+ /**
2405
+ * Persist and restore the UI view state (zoom, scroll, sort, filter, collapse,
2406
+ * selection) via `localStorage`. Pass `true` to enable with the default key
2407
+ * (`'apexgantt-state'`), or an object to set a custom key. Restored on the
2408
+ * first `render()`; saved (debounced) whenever the view changes. State is also
2409
+ * available programmatically via `gantt.getState()` / `gantt.setState()`.
2410
+ * @default false
2411
+ */
2412
+ readonly persistState?: boolean | GanttStatePersistenceOptions;
2413
+ /**
2414
+ * Auto-size each task-list column to fit its header title and cell content,
2415
+ * growing the task-list panel (never below `tasksContainerWidth`) so nothing
2416
+ * is clipped. `flexGrow` still distributes any extra width, `minWidth` is a
2417
+ * floor, and `maxWidth` (per column, default `320px`) is the ceiling. Set to
2418
+ * `false` for the legacy behavior where the panel width is split purely by
2419
+ * `flexGrow`. @default true
2420
+ */
2421
+ readonly autoSizeColumns?: boolean;
2422
+ /**
2423
+ * Allow individual task-list columns to be resized by dragging the handle at
2424
+ * the trailing edge of each column header. A resized column is pinned to its
2425
+ * chosen pixel width (the other columns absorb the remaining space), so users
2426
+ * can keep some columns wide and others thin. Double-click a handle to reset
2427
+ * that column to its auto width. Opt a single column out with
2428
+ * `columnConfig[].resizable: false`. @default true
2429
+ */
2430
+ readonly resizableColumns?: boolean;
2431
+ /**
2432
+ * Allow columns to be reordered by dragging a column header left or right onto
2433
+ * another column. The new order is reflected in the grid, included in
2434
+ * `getState()` / `setState()`, and emitted as a `columnReorder` event. Also
2435
+ * available programmatically via `gantt.setColumnOrder()`. @default true
2436
+ */
2437
+ readonly reorderableColumns?: boolean;
1735
2438
  /** Allow the task-list panel to be resized by dragging the divider. @default true */
1736
2439
  readonly enableResize?: boolean;
1737
2440
  /** Allow tasks to be reordered by dragging rows in the task list. @default true */
@@ -1798,6 +2501,22 @@ export declare interface GanttUserOptions {
1798
2501
  * @default false
1799
2502
  */
1800
2503
  readonly enableAddTaskRow?: boolean;
2504
+ /**
2505
+ * Allow creating a task by dragging across an empty stretch of the timeline:
2506
+ * press on an empty row, drag horizontally to sweep out the date range, and
2507
+ * release to add a task with those (snapped) start/end dates. Off by default
2508
+ * so an existing chart's empty-area drags stay inert; enable it to match
2509
+ * "draw a new bar" from dedicated project tools. Respects `beforeTaskAdd` and
2510
+ * is recorded in undo history like any other add. @default false
2511
+ */
2512
+ readonly enableDrawTask?: boolean;
2513
+ /**
2514
+ * Show a small chevron at the edge of a task's row when that task's bar is
2515
+ * scrolled out of the visible timeline window; clicking it scrolls the bar
2516
+ * into view. Also available programmatically via `gantt.scrollToTask()`.
2517
+ * @default true
2518
+ */
2519
+ readonly enableScrollButtons?: boolean;
1801
2520
  /**
1802
2521
  * Configures the undo/redo history stack. Every mutating call (drag, resize,
1803
2522
  * inline / dialog edit, add, delete, move, dependency change) is recorded
@@ -1813,15 +2532,15 @@ export declare interface GanttUserOptions {
1813
2532
  readonly history?: Partial<HistoryOptions>;
1814
2533
  /** Show a tooltip on task-bar hover. @default true */
1815
2534
  readonly enableTooltip?: boolean;
1816
- /** Color for all text in the chart. @default '#000000' */
2535
+ /** Color for all text in the chart. @default '#1F2933' (light) / '#E0E0E0' (dark) */
1817
2536
  readonly fontColor?: string;
1818
- /** CSS font-family for the chart. Falls back to the page default when empty. */
2537
+ /** CSS font-family for the chart. @default 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif' */
1819
2538
  readonly fontFamily?: string;
1820
2539
  /** CSS font-size for the chart, e.g. `'14px'`. @default '14px' */
1821
2540
  readonly fontSize?: string;
1822
2541
  /** CSS font-weight for the chart. @default '400' */
1823
2542
  readonly fontWeight?: string;
1824
- /** Background color of the timeline and task-list header row. @default '#f3f3f3' */
2543
+ /** Background color of the timeline and task-list header row. @default '#F8F9FB' (light) / '#2A2A2A' (dark) */
1825
2544
  readonly headerBackground?: string;
1826
2545
  /** Height of the chart. Accepts a pixel number or a CSS string. @default 500 */
1827
2546
  readonly height?: number | string;
@@ -1829,7 +2548,7 @@ export declare interface GanttUserOptions {
1829
2548
  readonly inputDateFormat?: string;
1830
2549
  /** Alternating row background colors. The pattern cycles automatically. @default ['#FFFFFF'] */
1831
2550
  readonly rowBackgroundColors?: readonly string[];
1832
- /** Height of each task row in pixels. @default 28 */
2551
+ /** Height of each task row in pixels. @default 40 */
1833
2552
  readonly rowHeight?: number;
1834
2553
  /** Task data array. Required. Each item must satisfy `TaskInput`, or use `parsing` to map custom field names. */
1835
2554
  readonly series: TaskInput[] | Record<string, unknown>[];
@@ -1837,7 +2556,7 @@ export declare interface GanttUserOptions {
1837
2556
  readonly tasksContainerWidth?: number;
1838
2557
  /** Background color of the hover tooltip. @default '#FFFFFF' */
1839
2558
  readonly tooltipBGColor?: string;
1840
- /** Border color of the hover tooltip. @default '#BCBCBC' */
2559
+ /** Border color of the hover tooltip. @default '#E5E7EB' (light) / '#444444' (dark) */
1841
2560
  readonly tooltipBorderColor?: string;
1842
2561
  /** HTML `id` for the tooltip container element. @default 'apexgantt-tooltip-container' */
1843
2562
  readonly tooltipId?: string;
@@ -1898,6 +2617,15 @@ export declare interface GanttUserOptions {
1898
2617
  * @default []
1899
2618
  */
1900
2619
  readonly toolbarItems?: ToolbarItem[];
2620
+ /**
2621
+ * Show a built-in quick-filter search box in the toolbar. Typing filters the
2622
+ * task list to rows whose configured fields contain the query (ancestors of
2623
+ * matches stay visible); clearing it removes the filter. Drives the same
2624
+ * view-only filter as `gantt.filter()`. @default false
2625
+ */
2626
+ readonly enableQuickFilter?: boolean;
2627
+ /** Fine-tunes the built-in quick-filter search box (placeholder, fields, case-sensitivity). */
2628
+ readonly quickFilter?: QuickFilterOptions;
1901
2629
  /** `aria-label` for the task-list table, used by screen readers. @default 'Task list' */
1902
2630
  readonly taskListAriaLabel?: string;
1903
2631
  /**
@@ -1951,6 +2679,42 @@ export declare interface GanttUserOptions {
1951
2679
 
1952
2680
  export declare function getTheme(mode: ThemeMode): GanttTheme;
1953
2681
 
2682
+ /**
2683
+ * Detail for the `groupChange` event, fired when the active grouping changes via
2684
+ * `gantt.groupBy()` / `gantt.clearGrouping()`.
2685
+ */
2686
+ export declare interface GroupChangeEventDetail {
2687
+ /** Whether grouping is active after the change. */
2688
+ active: boolean;
2689
+ /** The field being grouped by, or `null` when grouping was cleared. */
2690
+ field: string | null;
2691
+ /** Number of groups produced by the active grouping (0 when cleared). */
2692
+ groupCount: number;
2693
+ timestamp: number;
2694
+ }
2695
+
2696
+ /**
2697
+ * Describes how to group the task grid by a field. When active, the parent/child
2698
+ * tree is suspended and every task appears flat under a collapsible group header.
2699
+ *
2700
+ * Pass a bare `ColumnKey`/string to `gantt.groupBy()` (or the `groupBy` option)
2701
+ * to group by that column's value, or this object form to customize how the
2702
+ * group value is extracted, labelled, and ordered.
2703
+ */
2704
+ export declare interface GroupCriterion {
2705
+ /** Column key whose value tasks are grouped by (a `ColumnKey` or custom column id). */
2706
+ readonly field: ColumnKey | string;
2707
+ /**
2708
+ * Extract the raw group value from a task. Overrides the column's `accessor`.
2709
+ * Tasks with an equal value (by `String(value)`) land in the same group.
2710
+ */
2711
+ readonly accessor?: (task: Task) => unknown;
2712
+ /** Format a raw group value into the header label. Defaults to `String(value)`. */
2713
+ readonly label?: (value: unknown) => string;
2714
+ /** Order of the group headers by key. @default 'asc' */
2715
+ readonly direction?: SortDirection;
2716
+ }
2717
+
1954
2718
  /**
1955
2719
  * Detail payload for the `historyChange` event.
1956
2720
  *
@@ -2029,6 +2793,8 @@ declare interface InteractiveOptions {
2029
2793
  readonly enableTaskCRUDToolbar: boolean;
2030
2794
  readonly enableContextMenu: boolean;
2031
2795
  readonly enableAddTaskRow: boolean;
2796
+ readonly enableDrawTask: boolean;
2797
+ readonly enableScrollButtons: boolean;
2032
2798
  readonly history: HistoryOptions;
2033
2799
  readonly snapUnit: SnapUnit;
2034
2800
  readonly snapValue: number;
@@ -2131,6 +2897,36 @@ export declare type ParsingValue = string | {
2131
2897
  transform?: (value: unknown) => unknown;
2132
2898
  };
2133
2899
 
2900
+ /**
2901
+ * Built-in column renderer that draws an SVG progress ring for the task's
2902
+ * completion percentage, with an optional centered numeric label.
2903
+ *
2904
+ * Reads from `task.progress` by default; override with `accessor` for
2905
+ * computed values.
2906
+ *
2907
+ * @example
2908
+ * ```ts
2909
+ * import { ApexGantt, ColumnKey, renderers } from '@apexcharts/apexgantt';
2910
+ *
2911
+ * new ApexGantt('#chart', {
2912
+ * series,
2913
+ * columnConfig: [
2914
+ * { key: ColumnKey.Name, title: 'Task' },
2915
+ * {
2916
+ * key: 'progressRing',
2917
+ * title: '%',
2918
+ * render: renderers.progressRing({
2919
+ * size: 28,
2920
+ * strokeWidth: 3,
2921
+ * progressColor: (_task, value) => value > 80 ? '#22C55E' : value >= 40 ? '#3B82F6' : '#EF4444',
2922
+ * }),
2923
+ * },
2924
+ * ],
2925
+ * });
2926
+ * ```
2927
+ */
2928
+ declare function progressRing(options?: ProgressRingRendererOptions): ColumnRenderer;
2929
+
2134
2930
  /**
2135
2931
  * Configuration for the {@link progressRing} column renderer.
2136
2932
  */
@@ -2154,14 +2950,35 @@ export declare interface ProgressRingRendererOptions {
2154
2950
  readonly labelColor?: string;
2155
2951
  }
2156
2952
 
2157
- export declare namespace renderers {
2158
- {
2953
+ /**
2954
+ * Configures the built-in quick-filter search box (enabled via
2955
+ * `enableQuickFilter`).
2956
+ */
2957
+ export declare interface QuickFilterOptions {
2958
+ /**
2959
+ * Placeholder text for the search input. Falls back to the localized
2960
+ * `quickFilterPlaceholder` message when omitted.
2961
+ */
2962
+ readonly placeholder?: string;
2963
+ /**
2964
+ * Task string fields matched against the query. @default ['name']
2965
+ */
2966
+ readonly fields?: ReadonlyArray<keyof Task | string>;
2967
+ /**
2968
+ * Match case-sensitively. @default false
2969
+ */
2970
+ readonly caseSensitive?: boolean;
2971
+ }
2972
+
2973
+ declare namespace renderers {
2974
+ export {
2159
2975
  avatars,
2160
2976
  AvatarsRendererOptions,
2161
2977
  progressRing,
2162
2978
  ProgressRingRendererOptions
2163
2979
  }
2164
2980
  }
2981
+ export { renderers }
2165
2982
 
2166
2983
  /**
2167
2984
  * Detail payload for the `selectionChange` event.
@@ -2182,6 +2999,33 @@ declare interface SelectionOptions {
2182
2999
 
2183
3000
  export declare type SnapUnit = 'day' | 'hour' | 'minute';
2184
3001
 
3002
+ /**
3003
+ * Detail for the `sortChange` event, fired when the active sort changes via
3004
+ * `gantt.sort()` / `gantt.clearSort()` or a column-header click.
3005
+ */
3006
+ export declare interface SortChangeEventDetail {
3007
+ /** Active sort criteria after the change. Empty array = natural (input) order. */
3008
+ criteria: ReadonlyArray<{
3009
+ key: string;
3010
+ direction: 'asc' | 'desc';
3011
+ }>;
3012
+ timestamp: number;
3013
+ }
3014
+
3015
+ /**
3016
+ * A single sort key: which column to sort by and in which direction.
3017
+ * Multiple criteria sort by the first key, breaking ties with the next.
3018
+ */
3019
+ export declare interface SortCriterion {
3020
+ /** Column key to sort by (a `ColumnKey` or a custom column id). */
3021
+ readonly key: ColumnKey | string;
3022
+ /** Sort direction. @default 'asc' */
3023
+ readonly direction?: SortDirection;
3024
+ }
3025
+
3026
+ /** Sort direction for a {@link SortCriterion}. */
3027
+ export declare type SortDirection = 'asc' | 'desc';
3028
+
2185
3029
  /**
2186
3030
  * Resolved task object used internally and returned from selection/event APIs.
2187
3031
  *
@@ -2201,6 +3045,16 @@ export declare interface Task extends TaskInput {
2201
3045
  * tree changes; render via the `ColumnKey.Wbs` column or read directly.
2202
3046
  */
2203
3047
  readonly wbs?: string;
3048
+ /**
3049
+ * Comma-separated references to this task's predecessors (the tasks it depends
3050
+ * on), by WBS code with a non-`FS` type and non-zero lag suffix (e.g.
3051
+ * `'1.2, 3SS+2d'`). Derived by `DataManager` from the dependency list and
3052
+ * refreshed whenever the tree, sort, or dependencies change. Render via the
3053
+ * `ColumnKey.Predecessors` column.
3054
+ */
3055
+ readonly predecessors?: string;
3056
+ /** Comma-separated references to this task's successors (tasks that depend on it); see {@link predecessors}. */
3057
+ readonly successors?: string;
2204
3058
  /** Resolved progress value (0–100). Always present; defaults to `0`. */
2205
3059
  readonly progress: number;
2206
3060
  /** Resolved task type. Always present; defaults to `TaskType.Task`. */
@@ -2219,6 +3073,19 @@ export declare interface Task extends TaskInput {
2219
3073
  * when `showSummaryBar` is `true`; equals the latest `endTime` among all descendants.
2220
3074
  */
2221
3075
  readonly summaryEnd?: string;
3076
+ /**
3077
+ * View-only flag marking a synthetic group-header row produced while grouping
3078
+ * is active (`gantt.groupBy(...)`). Group headers are never stored in the data
3079
+ * model — they exist only in the flat render list — so real-task queries,
3080
+ * selection, and dependencies never see them.
3081
+ */
3082
+ readonly isGroup?: boolean;
3083
+ /** Stable key of the group this header represents (group rows only). */
3084
+ readonly groupKey?: string;
3085
+ /** Display label for the group header (group rows only). */
3086
+ readonly groupLabel?: string;
3087
+ /** Number of member tasks in the group (group rows only). */
3088
+ readonly groupCount?: number;
2222
3089
  }
2223
3090
 
2224
3091
  /**
@@ -2235,6 +3102,12 @@ export declare interface TaskAddedEventDetail {
2235
3102
  timestamp: number;
2236
3103
  }
2237
3104
 
3105
+ /**
3106
+ * Comparator over two tasks returning negative / zero / positive (ascending).
3107
+ * Used by `ColumnListItem.comparator` and internally by the sort engine.
3108
+ */
3109
+ export declare type TaskComparator = (a: Task, b: Task) => number;
3110
+
2238
3111
  /**
2239
3112
  * Detail payload for the `taskDeleted` event.
2240
3113
  *
@@ -2301,6 +3174,13 @@ export declare interface TaskDraggedEventDetail {
2301
3174
  timestamp: number;
2302
3175
  }
2303
3176
 
3177
+ /**
3178
+ * Predicate deciding whether a task matches an active filter. A task is kept
3179
+ * when it matches OR has a descendant that matches (ancestors of matches stay
3180
+ * visible so the tree context is preserved).
3181
+ */
3182
+ export declare type TaskFilterPredicate = (task: Task) => boolean;
3183
+
2304
3184
  /**
2305
3185
  * Raw task data shape passed to `new ApexGantt()` via `GanttUserOptions.series`
2306
3186
  * or to `DataParser.parse()`.
@@ -2391,6 +3271,14 @@ export declare interface TaskInput {
2391
3271
  * column is configured via `columnConfig`.
2392
3272
  */
2393
3273
  readonly assignees?: readonly Assignee[];
3274
+ /**
3275
+ * Worked spans of a split task. When two or more are provided, the task
3276
+ * renders as separate bar pieces with gaps between them, and its
3277
+ * `startTime`/`endTime` are derived from the segments (first start → last end).
3278
+ * Omit (or provide fewer than two) for a normal contiguous task.
3279
+ * Split a task at runtime via `gantt.splitTask()`.
3280
+ */
3281
+ readonly segments?: readonly TaskSegment[];
2394
3282
  }
2395
3283
 
2396
3284
  /**
@@ -2438,6 +3326,22 @@ export declare interface TaskResizedEventDetail {
2438
3326
  timestamp: number;
2439
3327
  }
2440
3328
 
3329
+ /**
3330
+ * One worked span of a split task. A task with two or more `segments` renders as
3331
+ * separate bar pieces with gaps between them (e.g. work Mon–Wed, pause, resume
3332
+ * Fri). Dates are strings parsed with `GanttUserOptions.inputDateFormat`.
3333
+ *
3334
+ * The task's own `startTime`/`endTime` remain the overall envelope (first
3335
+ * segment start → last segment end) and are derived automatically from the
3336
+ * segments, so summary rollups, dependencies, and the timeline all keep working.
3337
+ */
3338
+ export declare interface TaskSegment {
3339
+ /** Start date of this worked span. */
3340
+ readonly start: string;
3341
+ /** End date of this worked span. */
3342
+ readonly end: string;
3343
+ }
3344
+
2441
3345
  /**
2442
3346
  * Discriminates how a task is rendered in the timeline.
2443
3347
  *
@@ -2574,6 +3478,20 @@ export declare type ToolbarItem = ToolbarButton | ToolbarSelect | ToolbarSeparat
2574
3478
 
2575
3479
  declare interface ToolbarOptions {
2576
3480
  readonly toolbarItems: ToolbarItem[];
3481
+ /**
3482
+ * Show a built-in quick-filter search box in the toolbar. As the user types,
3483
+ * the task list is filtered to rows whose configured fields contain the
3484
+ * query (ancestors of matches stay visible). Drives the same view-only filter
3485
+ * as `gantt.filter()`. @default false
3486
+ */
3487
+ readonly enableQuickFilter: boolean;
3488
+ /** Fine-tunes the built-in quick-filter search box. See {@link QuickFilterOptions}. */
3489
+ readonly quickFilter?: QuickFilterOptions;
3490
+ /**
3491
+ * Show the built-in advanced filter builder (a "Filter" toolbar button that
3492
+ * opens a rule-composer popover). @default false
3493
+ */
3494
+ readonly enableFilterBuilder: boolean;
2577
3495
  }
2578
3496
 
2579
3497
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apexgantt",
3
- "version": "3.14.0",
3
+ "version": "3.14.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/apexcharts/apexgantt"