simple-table-core 3.0.13 → 3.2.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 (49) hide show
  1. package/README.md +22 -0
  2. package/dist/cjs/index.js +1 -1
  3. package/dist/cjs/src/core/SimpleTableVanilla.d.ts +25 -0
  4. package/dist/cjs/src/core/rendering/RenderOrchestrator.d.ts +4 -0
  5. package/dist/cjs/src/core/rendering/SectionRenderer.d.ts +35 -0
  6. package/dist/cjs/src/core/rendering/TableRenderer.d.ts +4 -0
  7. package/dist/cjs/src/index.d.ts +2 -1
  8. package/dist/cjs/src/managers/AnimationCoordinator.d.ts +142 -0
  9. package/dist/cjs/src/types/AnimationsConfig.d.ts +14 -0
  10. package/dist/cjs/src/types/SimpleTableConfig.d.ts +2 -0
  11. package/dist/cjs/src/types/SimpleTableProps.d.ts +2 -0
  12. package/dist/cjs/src/types/TableRow.d.ts +9 -0
  13. package/dist/cjs/src/utils/bodyCell/types.d.ts +6 -0
  14. package/dist/cjs/src/utils/bodyCellRenderer.d.ts +2 -1
  15. package/dist/cjs/src/utils/headerCell/styling.d.ts +2 -0
  16. package/dist/cjs/src/utils/rowUtils.d.ts +25 -0
  17. package/dist/cjs/stories/examples/BasicExample.d.ts +1 -0
  18. package/dist/cjs/stories/examples/sales-example/SalesExample.d.ts +3 -0
  19. package/dist/cjs/stories/tests/32-ThemesTests.stories.d.ts +19 -0
  20. package/dist/cjs/stories/tests/41-CellAnimationsTests.stories.d.ts +237 -0
  21. package/dist/cjs/stories/tests/42-CellAnimationsVirtualizationTests.stories.d.ts +251 -0
  22. package/dist/cjs/styles.css +1 -1
  23. package/dist/index.es.js +1 -1
  24. package/dist/src/core/SimpleTableVanilla.d.ts +25 -0
  25. package/dist/src/core/rendering/RenderOrchestrator.d.ts +4 -0
  26. package/dist/src/core/rendering/SectionRenderer.d.ts +35 -0
  27. package/dist/src/core/rendering/TableRenderer.d.ts +4 -0
  28. package/dist/src/index.d.ts +2 -1
  29. package/dist/src/managers/AnimationCoordinator.d.ts +142 -0
  30. package/dist/src/types/AnimationsConfig.d.ts +14 -0
  31. package/dist/src/types/SimpleTableConfig.d.ts +2 -0
  32. package/dist/src/types/SimpleTableProps.d.ts +2 -0
  33. package/dist/src/types/TableRow.d.ts +9 -0
  34. package/dist/src/utils/bodyCell/types.d.ts +6 -0
  35. package/dist/src/utils/bodyCellRenderer.d.ts +2 -1
  36. package/dist/src/utils/headerCell/styling.d.ts +2 -0
  37. package/dist/src/utils/rowUtils.d.ts +25 -0
  38. package/dist/stories/examples/BasicExample.d.ts +1 -0
  39. package/dist/stories/examples/sales-example/SalesExample.d.ts +3 -0
  40. package/dist/stories/tests/32-ThemesTests.stories.d.ts +19 -0
  41. package/dist/stories/tests/41-CellAnimationsTests.stories.d.ts +237 -0
  42. package/dist/stories/tests/42-CellAnimationsVirtualizationTests.stories.d.ts +251 -0
  43. package/dist/styles.css +1 -1
  44. package/package.json +27 -3
  45. package/src/styles/base.css +15 -0
  46. package/src/styles/themes/frost.css +3 -2
  47. package/src/styles/themes/modern-dark.css +3 -2
  48. package/src/styles/themes/modern-light.css +4 -3
  49. package/src/styles/themes/theme-custom.css +4 -3
@@ -35,6 +35,7 @@ export declare class SimpleTableVanilla {
35
35
  private cellRegistry;
36
36
  private headerRegistry;
37
37
  private rowIndexMap;
38
+ private animationCoordinator;
38
39
  private autoScaleManager;
39
40
  private dimensionManager;
40
41
  private scrollManager;
@@ -54,7 +55,31 @@ export declare class SimpleTableVanilla {
54
55
  private lastScrollTop;
55
56
  private isUpdating;
56
57
  constructor(container: HTMLElement, config: SimpleTableConfig);
58
+ private applyAnimationsConfig;
57
59
  private rebuildRowIndexMap;
60
+ private getBodyContainers;
61
+ private getHeaderContainers;
62
+ /**
63
+ * All cell-bearing containers — body sections AND header sections — that the
64
+ * animation coordinator needs to inspect. Headers participate in FLIP for
65
+ * column reorder so their cells slide to their new slot rather than
66
+ * teleporting.
67
+ */
68
+ private getAnimatableContainers;
69
+ /**
70
+ * Capture pre-change cell positions for the FLIP animation, including
71
+ * conceptual positions for cells outside the virtualization viewport so
72
+ * incoming cells can animate from off-screen on column reorder/sort. The
73
+ * `play` step that runs at the end of the next render consumes this
74
+ * snapshot to inverse-transform cells from their old visual positions and
75
+ * tween them to their new ones.
76
+ *
77
+ * Called on every layout-affecting state change — including the chain of
78
+ * mid-drag `setHeaders` calls that fire on each `dragover` swap — so that
79
+ * displaced columns slide smoothly out of the dragged column's way rather
80
+ * than snapping into place.
81
+ */
82
+ private captureAnimationSnapshot;
58
83
  private initializeManagers;
59
84
  mount(): void;
60
85
  private setupManagers;
@@ -10,10 +10,12 @@ import { SortManager } from "../../managers/SortManager";
10
10
  import { FilterManager } from "../../managers/FilterManager";
11
11
  import { SelectionManager } from "../../managers/SelectionManager";
12
12
  import { RowSelectionManager } from "../../managers/RowSelectionManager";
13
+ import type { AnimationCoordinator, CellPosition } from "../../managers/AnimationCoordinator";
13
14
  import { FlattenRowsResult } from "../../utils/rowFlattening";
14
15
  import { ProcessRowsResult } from "../../utils/rowProcessing";
15
16
  import { MergedColumnEditorConfig, ResolvedIcons } from "../initialization/TableInitializer";
16
17
  export interface RenderContext {
18
+ animationCoordinator?: AnimationCoordinator;
17
19
  cellRegistry: Map<string, any>;
18
20
  collapsedHeaders: Set<Accessor>;
19
21
  collapsedRows: Map<string, number>;
@@ -102,6 +104,8 @@ export declare class RenderOrchestrator {
102
104
  constructor();
103
105
  getCachedFlattenResult(): FlattenRowsResult | null;
104
106
  getLastProcessedResult(): ProcessRowsResult | null;
107
+ /** See {@link TableRenderer.getCurrentBodyLayouts}. */
108
+ getCurrentBodyLayouts(): Map<HTMLElement, Map<string, CellPosition>>;
105
109
  invalidateCache(type?: "body" | "header" | "context" | "all"): void;
106
110
  computeEffectiveHeaders(headers: HeaderObject[], config: SimpleTableConfig, customTheme: CustomTheme, containerWidth?: number): HeaderObject[];
107
111
  /**
@@ -2,6 +2,7 @@ import HeaderObject, { Accessor } from "../../types/HeaderObject";
2
2
  import { HeaderRenderContext } from "../../utils/headerCellRenderer";
3
3
  import { CellRenderContext } from "../../utils/bodyCellRenderer";
4
4
  import TableRow from "../../types/TableRow";
5
+ import type { AnimationCoordinator, CellPosition } from "../../managers/AnimationCoordinator";
5
6
  export interface HeaderSectionParams {
6
7
  headers: HeaderObject[];
7
8
  collapsedHeaders: Set<Accessor>;
@@ -29,6 +30,9 @@ export interface BodySectionParams {
29
30
  fullTableRows?: TableRow[];
30
31
  renderedStartIndex?: number;
31
32
  renderedEndIndex?: number;
33
+ /** When provided, body cell renderer hands outgoing cells to the coordinator
34
+ * for FLIP-style out-animation instead of removing them immediately. */
35
+ animationCoordinator?: AnimationCoordinator;
32
36
  }
33
37
  export declare class SectionRenderer {
34
38
  private headerSections;
@@ -36,6 +40,7 @@ export declare class SectionRenderer {
36
40
  private bodyCellsCache;
37
41
  private headerCellsCache;
38
42
  private contextCache;
43
+ private bodySectionSnapshots;
39
44
  private nextColIndexMap;
40
45
  private stateRowsMap;
41
46
  private nestedGridRowsMap;
@@ -57,5 +62,35 @@ export declare class SectionRenderer {
57
62
  * Get the next colIndex after rendering a section
58
63
  */
59
64
  getNextColIndex(sectionKey: string): number;
65
+ /**
66
+ * Build a per-section layout map covering every cell in the dataset (every
67
+ * row × every leaf header), not just the cells in the current virtualization
68
+ * band. Used by the animation coordinator: it needs positions for off-screen
69
+ * rows so that:
70
+ *
71
+ * - Cells that newly enter the visible band (e.g. row sorted from bottom
72
+ * to top) can FLIP in from their actual pre-change off-screen `top`.
73
+ * - Cells that leave the visible band (e.g. row sorted from top to
74
+ * bottom) can be retained and slid to their actual post-change
75
+ * off-screen `top` before being removed.
76
+ *
77
+ * The body container clips overflow so cells whose interpolated position
78
+ * falls outside the viewport simply aren't painted — the animation looks
79
+ * like a slide in from / out to the viewport edge.
80
+ */
81
+ getCurrentBodyLayouts(): Map<HTMLElement, Map<string, CellPosition>>;
82
+ /**
83
+ * Compute every cell position the section currently knows about (every row
84
+ * × every leaf header), including positions for off-screen rows, by using
85
+ * the most recent snapshot config for `sectionKey`. Returns null if no
86
+ * snapshot has been captured for this section yet.
87
+ */
88
+ getFullSectionLayout(sectionKey: string): Map<string, CellPosition> | null;
89
+ /**
90
+ * Refresh the per-section snapshot config so getCurrentBodyLayouts can
91
+ * recompute positions for any row × column combination the section
92
+ * currently knows about.
93
+ */
94
+ private captureSnapshotConfig;
60
95
  cleanup(): void;
61
96
  }
@@ -7,7 +7,9 @@ import { SortManager } from "../../managers/SortManager";
7
7
  import { FilterManager } from "../../managers/FilterManager";
8
8
  import { SelectionManager } from "../../managers/SelectionManager";
9
9
  import { RowSelectionManager } from "../../managers/RowSelectionManager";
10
+ import type { AnimationCoordinator, CellPosition } from "../../managers/AnimationCoordinator";
10
11
  export interface TableRendererDeps {
12
+ animationCoordinator?: AnimationCoordinator;
11
13
  cellRegistry: Map<string, any>;
12
14
  collapsedHeaders: Set<Accessor>;
13
15
  collapsedRows: Map<string, number>;
@@ -81,6 +83,8 @@ export declare class TableRenderer {
81
83
  constructor();
82
84
  private scheduleRender;
83
85
  invalidateCache(type?: "body" | "header" | "context" | "all"): void;
86
+ /** See {@link SectionRenderer.getCurrentBodyLayouts}. */
87
+ getCurrentBodyLayouts(): Map<HTMLElement, Map<string, CellPosition>>;
84
88
  renderHeader(container: HTMLElement, calculatedHeaderHeight: number, maxHeaderDepth: number, deps: TableRendererDeps): void;
85
89
  renderBody(container: HTMLElement, processedResult: any, deps: TableRendererDeps): void;
86
90
  renderFooter(container: HTMLElement, totalRows: number, currentPage: number, onPageChange: (page: number) => void, deps: TableRendererDeps): void;
@@ -42,8 +42,9 @@ import type { IconsConfig } from "./types/IconsConfig";
42
42
  import type { GetRowId, GetRowIdParams } from "./types/GetRowId";
43
43
  import type { SimpleTableConfig } from "./types/SimpleTableConfig";
44
44
  import type { SimpleTableProps } from "./types/SimpleTableProps";
45
+ import type { AnimationsConfig } from "./types/AnimationsConfig";
45
46
  import type { RowId } from "./types/RowId";
46
47
  import type { PinnedSectionsState } from "./types/PinnedSectionsState";
47
48
  export { SimpleTableVanilla };
48
49
  export { asRows } from "./utils/asRows";
49
- export type { Accessor, AggregationConfig, AggregationType, BoundingBox, Cell, CellChangeProps, CellClickProps, CellRenderer, CellRendererProps, CellValue, ChartOptions, ColumnEditorConfig, ColumnEditorCustomRenderer, ColumnEditorCustomRendererProps, ColumnEditorRowRenderer, ColumnEditorRowRendererComponents, ColumnEditorRowRendererProps, ColumnEditorSearchFunction, ColumnType, ColumnVisibilityState, Comparator, ComparatorProps, CustomTheme, CustomThemeProps, DragHandlerProps, EmptyStateRenderer, EmptyStateRendererProps, EnumOption, ErrorStateRenderer, ErrorStateRendererProps, ExportToCSVProps, ExportValueGetter, ExportValueProps, FilterCondition, FooterRendererProps, GetRowId, GetRowIdParams, IconsConfig, LoadingStateRenderer, LoadingStateRendererProps, HeaderDropdown, HeaderDropdownProps, HeaderObject, HeaderRenderer, HeaderRendererProps, HeaderRendererComponents, OnRowGroupExpandProps, OnSortProps, QuickFilterConfig, QuickFilterGetter, QuickFilterGetterProps, QuickFilterMode, Row, RowButtonProps, RowId, RowSelectionChangeProps, RowState, SetHeaderRenameProps, SharedTableProps, ShowWhen, SimpleTableConfig, SimpleTableProps, SortColumn, TableAPI, TableFilterState, TableHeaderProps, TableRowProps, Theme, PinnedSectionsState, UpdateDataProps, ValueFormatter, ValueFormatterProps, ValueGetter, ValueGetterProps, };
50
+ export type { Accessor, AggregationConfig, AggregationType, AnimationsConfig, BoundingBox, Cell, CellChangeProps, CellClickProps, CellRenderer, CellRendererProps, CellValue, ChartOptions, ColumnEditorConfig, ColumnEditorCustomRenderer, ColumnEditorCustomRendererProps, ColumnEditorRowRenderer, ColumnEditorRowRendererComponents, ColumnEditorRowRendererProps, ColumnEditorSearchFunction, ColumnType, ColumnVisibilityState, Comparator, ComparatorProps, CustomTheme, CustomThemeProps, DragHandlerProps, EmptyStateRenderer, EmptyStateRendererProps, EnumOption, ErrorStateRenderer, ErrorStateRendererProps, ExportToCSVProps, ExportValueGetter, ExportValueProps, FilterCondition, FooterRendererProps, GetRowId, GetRowIdParams, IconsConfig, LoadingStateRenderer, LoadingStateRendererProps, HeaderDropdown, HeaderDropdownProps, HeaderObject, HeaderRenderer, HeaderRendererProps, HeaderRendererComponents, OnRowGroupExpandProps, OnSortProps, QuickFilterConfig, QuickFilterGetter, QuickFilterGetterProps, QuickFilterMode, Row, RowButtonProps, RowId, RowSelectionChangeProps, RowState, SetHeaderRenameProps, SharedTableProps, ShowWhen, SimpleTableConfig, SimpleTableProps, SortColumn, TableAPI, TableFilterState, TableHeaderProps, TableRowProps, Theme, PinnedSectionsState, UpdateDataProps, ValueFormatter, ValueFormatterProps, ValueGetter, ValueGetterProps, };
@@ -0,0 +1,142 @@
1
+ export interface AnimationCoordinatorOptions {
2
+ duration?: number;
3
+ easing?: string;
4
+ }
5
+ export interface CellPosition {
6
+ left: number;
7
+ top: number;
8
+ width: number;
9
+ height: number;
10
+ }
11
+ /**
12
+ * FLIP-style animation coordinator for body cells with virtualization awareness.
13
+ *
14
+ * Triggered explicitly via {@link captureSnapshot} (before a layout-affecting
15
+ * change) and {@link play} (after the renderer has placed cells at their new
16
+ * positions).
17
+ *
18
+ * Three classes of cells participate in an animation:
19
+ * - Persistent cells (visible before AND after): the same DOM node moves to
20
+ * a new `top`/`left`; FLIP slides it from the old visual spot.
21
+ * - Incoming cells (off-screen before, in DOM after): the renderer creates
22
+ * them at their new position; if the snapshot has their pre-change
23
+ * position (computed for ALL rows, not just the band), FLIP slides them
24
+ * in from there. The portion that's outside the body's overflow clip is
25
+ * never painted, so cells appear to slide in from the viewport edge.
26
+ * - Outgoing cells (in DOM before, off-screen after): the renderer hands
27
+ * them to {@link retainCell} along with their post-change off-screen
28
+ * position; FLIP slides them out to that position, then removes them.
29
+ */
30
+ export declare class AnimationCoordinator {
31
+ private enabled;
32
+ private duration;
33
+ private easing;
34
+ /** Pre-change positions for any cell we want to consider for animation. */
35
+ private snapshot;
36
+ private inFlight;
37
+ /** Outgoing cells the renderer handed off; keyed per container so play() finds them. */
38
+ private retainedCells;
39
+ private prefersReducedMotion;
40
+ /**
41
+ * Per-render cache of scroller layout metrics. Reading
42
+ * `scrollHeight`/`clientHeight`/etc. after a style mutation forces a sync
43
+ * layout flush; without this cache, scaleFlipDistance() forces a fresh
44
+ * flush for every cell in the retain/play loops, turning a single sort
45
+ * into hundreds of layout passes (observed: 513ms in `msRemove` for ~287
46
+ * cells, growing across consecutive sorts as DOM size grows). The cache
47
+ * is cleared at the boundaries of a render cycle (captureSnapshot start
48
+ * and play end / cancel) since column count and section heights are
49
+ * stable within a single sort.
50
+ */
51
+ private scrollerMetricsCache;
52
+ constructor(opts?: AnimationCoordinatorOptions);
53
+ setEnabled(enabled: boolean): void;
54
+ setDuration(duration: number): void;
55
+ setEasing(easing: string): void;
56
+ isEnabled(): boolean;
57
+ isInFlight(cellId: string): boolean;
58
+ /**
59
+ * Read scroller layout metrics for `container`, caching the result for the
60
+ * remainder of the current render cycle. Subsequent calls in the same
61
+ * cycle (e.g. for every cell in a retain or play loop) skip the DOM read,
62
+ * which would otherwise force a synchronous layout flush after each style
63
+ * mutation in the loop.
64
+ */
65
+ private getScrollerMetrics;
66
+ private clearScrollerMetricsCache;
67
+ /**
68
+ * Capture pre-change positions for cells we may want to animate.
69
+ *
70
+ * @param args.containers Body containers; rendered cells are read from the DOM.
71
+ * @param args.preLayouts Optional per-container conceptual layout. Should
72
+ * include positions for ALL rows in the dataset (not just the visible
73
+ * band) so cells that newly enter the band can FLIP in from their actual
74
+ * pre-change location and cells that leave the band can FLIP out to it.
75
+ */
76
+ captureSnapshot(args: {
77
+ containers: Array<HTMLElement | null | undefined>;
78
+ preLayouts?: Map<HTMLElement, Map<string, CellPosition>>;
79
+ }): void;
80
+ /**
81
+ * The renderer asks before removing a cell whether the coordinator wants to
82
+ * keep it for an out-animation.
83
+ */
84
+ shouldRetain(cellId: string): boolean;
85
+ /**
86
+ * Hand a cell that the renderer would otherwise remove to the coordinator.
87
+ * The coordinator updates its absolute positioning to the post-change layout
88
+ * and will animate it from the snapshotted pre-change visual position to
89
+ * that new position during {@link play}, then remove it from the DOM.
90
+ *
91
+ * The new position can be off-screen (e.g. the row sorted to a position
92
+ * outside the visible band) — the body container's `overflow: hidden`
93
+ * naturally clips the cell as it slides past the viewport edge.
94
+ */
95
+ retainCell(args: {
96
+ cellId: string;
97
+ element: HTMLElement;
98
+ container: HTMLElement;
99
+ newPosition: CellPosition;
100
+ }): void;
101
+ /**
102
+ * Take ownership of a retained (outgoing) ghost element so the renderer can
103
+ * promote it back to a live cell — rather than tearing it down and creating
104
+ * a fresh node — when its row becomes visible again. Returns the element
105
+ * with its retained-only attributes/state stripped, or `null` if no ghost
106
+ * is currently retained for this id in the container.
107
+ *
108
+ * Reusing the ghost preserves DOM continuity: the next play() step reads
109
+ * the cell's mid-flight visual position from the snapshot (captured before
110
+ * the render) and FLIPs it from there to its new live destination, so the
111
+ * row glides instead of disappearing and a freshly created replacement
112
+ * doesn't pop into existence at a clipped FLIP entry point.
113
+ */
114
+ claimRetainedForReuse(cellId: string, container: HTMLElement): HTMLElement | null;
115
+ /**
116
+ * Discard any retained cell with this id in the given container. Called by
117
+ * the renderer when it's about to create a fresh cell with the same id, so
118
+ * we don't have two DOM nodes claiming the same logical slot.
119
+ */
120
+ discardRetainedIfPresent(cellId: string, container: HTMLElement): void;
121
+ /**
122
+ * Apply the FLIP invert + play step to every cell present in the snapshot
123
+ * that is now in the DOM (either as an actively rendered cell or as a
124
+ * retained cell). Clears the snapshot.
125
+ */
126
+ play(args: {
127
+ containers: Array<HTMLElement | null | undefined>;
128
+ }): void;
129
+ /**
130
+ * Cancel every in-flight transition and clear any armed snapshot. Active
131
+ * cells snap to their final positions; retained cells are removed from the
132
+ * DOM so we don't leak nodes.
133
+ */
134
+ cancel(): void;
135
+ destroy(): void;
136
+ private readPosition;
137
+ private startTransition;
138
+ private cancelInFlight;
139
+ private finalizeCell;
140
+ private finishElement;
141
+ private isCellRetained;
142
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Configuration for cell animations on sort and programmatic column reorder.
3
+ *
4
+ * The animation coordinator runs FLIP-style transitions when cells move between
5
+ * positions. All fields are optional; omit the prop entirely to use defaults.
6
+ */
7
+ export interface AnimationsConfig {
8
+ /** Master toggle. Defaults to `true`. When `false`, no other field has effect. */
9
+ enabled?: boolean;
10
+ /** Animation duration in milliseconds. Defaults to `240`. */
11
+ duration?: number;
12
+ /** CSS easing function. Defaults to `cubic-bezier(0.2, 0.8, 0.2, 1)`. */
13
+ easing?: string;
14
+ }
@@ -18,7 +18,9 @@ import { GetRowId } from "./GetRowId";
18
18
  import { ColumnEditorConfig } from "./ColumnEditorConfig";
19
19
  import { VanillaIconsConfig } from "./IconsConfig";
20
20
  import { QuickFilterConfig } from "./QuickFilterTypes";
21
+ import { AnimationsConfig } from "./AnimationsConfig";
21
22
  export interface SimpleTableConfig {
23
+ animations?: AnimationsConfig;
22
24
  autoExpandColumns?: boolean;
23
25
  canExpandRowGroup?: (row: Row) => boolean;
24
26
  cellUpdateFlash?: boolean;
@@ -18,7 +18,9 @@ import { GetRowId } from "./GetRowId";
18
18
  import { ColumnEditorConfig } from "./ColumnEditorConfig";
19
19
  import { IconsConfig } from "./IconsConfig";
20
20
  import { QuickFilterConfig } from "./QuickFilterTypes";
21
+ import { AnimationsConfig } from "./AnimationsConfig";
21
22
  export interface SimpleTableProps {
23
+ animations?: AnimationsConfig;
22
24
  autoExpandColumns?: boolean;
23
25
  canExpandRowGroup?: (row: Row) => boolean;
24
26
  cellUpdateFlash?: boolean;
@@ -9,6 +9,15 @@ type TableRow = {
9
9
  position: number;
10
10
  row: Row;
11
11
  rowId: (string | number)[];
12
+ /**
13
+ * Position-independent identity for the row, used as the basis for the
14
+ * cell DOM `id` and the animation coordinator's snapshot key. When
15
+ * `getRowId` is provided, this is `String(customId)` (optionally prefixed
16
+ * by grouping keys for nested rows). Lets the same DOM cell survive a
17
+ * sort, so FLIP can animate the row to its new position. Falls back to
18
+ * the positional rowId string when `getRowId` is absent.
19
+ */
20
+ stableRowKey?: string;
12
21
  rowPath?: (string | number)[];
13
22
  rowIndexPath?: number[];
14
23
  stateIndicator?: {
@@ -17,6 +17,12 @@ export interface AbsoluteBodyCell {
17
17
  rowIndex: number;
18
18
  colIndex: number;
19
19
  rowId: string;
20
+ /**
21
+ * Position-independent stable key (mirror of `tableRow.stableRowKey`),
22
+ * used to compute the cell DOM `id` and the animation snapshot key when
23
+ * `getRowId` is provided. Falls back to `rowId` (positional) when absent.
24
+ */
25
+ stableRowKey?: string;
20
26
  displayRowNumber: number;
21
27
  depth: number;
22
28
  isOdd: boolean;
@@ -1,5 +1,6 @@
1
1
  import { AbsoluteBodyCell, CellRenderContext } from "./bodyCell/types";
2
2
  import type TableRow from "../types/TableRow";
3
+ import type { AnimationCoordinator, CellPosition } from "../managers/AnimationCoordinator";
3
4
  export type { AbsoluteBodyCell, CellData, CellEditParams, CellClickParams, CellRegistryEntry, CellRenderContext, } from "./bodyCell/types";
4
5
  export { cleanupBodyCellRendering } from "./bodyCell/eventTracking";
5
- export declare const renderBodyCells: (container: HTMLElement, cells: AbsoluteBodyCell[], context: CellRenderContext, scrollLeft?: number, allRows?: TableRow[], positionOnly?: boolean) => void;
6
+ export declare const renderBodyCells: (container: HTMLElement, cells: AbsoluteBodyCell[], context: CellRenderContext, scrollLeft?: number, allRows?: TableRow[], positionOnly?: boolean, animationCoordinator?: AnimationCoordinator, fullCellLayout?: Map<string, CellPosition>) => void;
@@ -2,4 +2,6 @@ import { AbsoluteCell, HeaderRenderContext } from "./types";
2
2
  export declare const calculateHeaderCellClasses: (cell: AbsoluteCell, context: HeaderRenderContext, isLastMainAutoExpandColumn: boolean) => string;
3
3
  export declare const createHeaderCellElement: (cell: AbsoluteCell, context: HeaderRenderContext, isLastMainAutoExpandColumn: boolean) => HTMLElement;
4
4
  export declare const getLastHeaderIndex: (absoluteCells: AbsoluteCell[]) => number;
5
+ /** Replace sort/filter/collapse icons on an existing header cell, preserving label/drag handlers. */
6
+ export declare const refreshHeaderCellIcons: (cellElement: HTMLElement, header: AbsoluteCell["header"], context: HeaderRenderContext) => void;
5
7
  export declare const updateHeaderCellElement: (cellElement: HTMLElement, cell: AbsoluteCell, context: HeaderRenderContext, isLastMainAutoExpandColumn: boolean) => void;
@@ -92,6 +92,31 @@ export declare const generateRowId: (params: GenerateRowIdParams) => (string | n
92
92
  * @returns A string representation of the row ID
93
93
  */
94
94
  export declare const rowIdToString: (rowId: (string | number)[]) => string;
95
+ /**
96
+ * Generate a position-independent stable row key.
97
+ *
98
+ * Unlike `generateRowId`, the stable key never includes positional indices, so
99
+ * it survives sort/filter operations. It is used as the basis for the cell DOM
100
+ * `id` and the animation coordinator's snapshot key, allowing the same DOM
101
+ * element to be reused for the same logical row across re-orders (enabling
102
+ * FLIP-based sort animations).
103
+ *
104
+ * When `getRowId` is provided, the key is derived from the user-supplied id.
105
+ * When it is not, the key falls back to the row object's identity (via a
106
+ * WeakMap) so animations still work for plain row arrays. For nested rows the
107
+ * parent's stable key is included as a prefix so siblings of different parents
108
+ * do not collide.
109
+ */
110
+ export declare const generateStableRowKey: (params: {
111
+ getRowId?: GetRowId;
112
+ row: Row;
113
+ depth: number;
114
+ index: number;
115
+ rowPath: (string | number)[];
116
+ rowIndexPath: number[];
117
+ groupingKey?: string;
118
+ parentStableKey?: string | null;
119
+ }) => string;
95
120
  /**
96
121
  * Get nested rows from a row based on the grouping path
97
122
  */
@@ -6,6 +6,7 @@ export declare const basicExampleDefaults: {
6
6
  selectableCells: boolean;
7
7
  columnReordering: boolean;
8
8
  height: string;
9
+ useOddEvenRowBackground: boolean;
9
10
  };
10
11
  export declare function createBasicData(rowLength: number): Row[];
11
12
  export declare function renderBasicExample(args?: Partial<UniversalVanillaArgs>): HTMLElement;
@@ -1,5 +1,8 @@
1
1
  import { type UniversalVanillaArgs } from "../../vanillaStoryConfig";
2
2
  export declare const salesExampleDefaults: {
3
+ animations: {
4
+ enabled: boolean;
5
+ };
3
6
  columnResizing: boolean;
4
7
  columnReordering: boolean;
5
8
  selectableCells: boolean;
@@ -70,6 +70,25 @@ export declare const UseHoverRowBackground: {
70
70
  }) => Promise<void>;
71
71
  };
72
72
  export declare const UseOddEvenRowBackground: {
73
+ tags: string[];
74
+ render: () => HTMLDivElement & {
75
+ _table?: import("../../src/index").SimpleTableVanilla | undefined;
76
+ };
77
+ play: ({ canvasElement }: {
78
+ canvasElement: HTMLElement;
79
+ }) => Promise<void>;
80
+ };
81
+ export declare const UseOddEvenRowBackgroundDisabled: {
82
+ tags: string[];
83
+ render: () => HTMLDivElement & {
84
+ _table?: import("../../src/index").SimpleTableVanilla | undefined;
85
+ };
86
+ play: ({ canvasElement }: {
87
+ canvasElement: HTMLElement;
88
+ }) => Promise<void>;
89
+ };
90
+ export declare const UseOddEvenRowBackgroundVisualEffect: {
91
+ tags: string[];
73
92
  render: () => HTMLDivElement & {
74
93
  _table?: import("../../src/index").SimpleTableVanilla | undefined;
75
94
  };