simple-table-core 3.4.2 → 3.5.2
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.
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/src/core/SimpleTableVanilla.d.ts +55 -0
- package/dist/cjs/src/core/rendering/RenderOrchestrator.d.ts +9 -0
- package/dist/cjs/src/core/rendering/TableRenderer.d.ts +4 -1
- package/dist/cjs/src/managers/AnimationCoordinator.d.ts +64 -0
- package/dist/cjs/src/types/TableRow.d.ts +6 -5
- package/dist/cjs/src/utils/accordionAnimation.d.ts +25 -0
- package/dist/cjs/src/utils/bodyCell/styling.d.ts +7 -0
- package/dist/cjs/src/utils/bodyCell/types.d.ts +11 -0
- package/dist/cjs/src/utils/headerCell/types.d.ts +18 -0
- package/dist/cjs/src/utils/rowUtils.d.ts +21 -2
- package/dist/cjs/src/utils/stickyParentsRenderer.d.ts +14 -0
- package/dist/cjs/stories/examples/BasicRowGrouping.d.ts +4 -0
- package/dist/cjs/stories/examples/CollapsibleColumnsExample.d.ts +4 -0
- package/dist/cjs/stories/examples/DynamicNestedTableExample.d.ts +2 -0
- package/dist/cjs/stories/examples/pinned-columns/PinnedColumns.d.ts +2 -0
- package/dist/cjs/stories/tests/17-NestedTablesTests.stories.d.ts +64 -6
- package/dist/cjs/stories/tests/43-CollapseExpandAnimationsTests.stories.d.ts +63 -0
- package/dist/cjs/stories/tests/testUtils.d.ts +5 -0
- package/dist/cjs/styles.css +1 -1
- package/dist/index.es.js +1 -1
- package/dist/src/core/SimpleTableVanilla.d.ts +55 -0
- package/dist/src/core/rendering/RenderOrchestrator.d.ts +9 -0
- package/dist/src/core/rendering/TableRenderer.d.ts +4 -1
- package/dist/src/managers/AnimationCoordinator.d.ts +64 -0
- package/dist/src/types/TableRow.d.ts +6 -5
- package/dist/src/utils/accordionAnimation.d.ts +25 -0
- package/dist/src/utils/bodyCell/styling.d.ts +7 -0
- package/dist/src/utils/bodyCell/types.d.ts +11 -0
- package/dist/src/utils/headerCell/types.d.ts +18 -0
- package/dist/src/utils/rowUtils.d.ts +21 -2
- package/dist/src/utils/stickyParentsRenderer.d.ts +14 -0
- package/dist/stories/examples/BasicRowGrouping.d.ts +4 -0
- package/dist/stories/examples/CollapsibleColumnsExample.d.ts +4 -0
- package/dist/stories/examples/DynamicNestedTableExample.d.ts +2 -0
- package/dist/stories/examples/pinned-columns/PinnedColumns.d.ts +2 -0
- package/dist/stories/tests/17-NestedTablesTests.stories.d.ts +64 -6
- package/dist/stories/tests/43-CollapseExpandAnimationsTests.stories.d.ts +63 -0
- package/dist/stories/tests/testUtils.d.ts +5 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/base.css +37 -2
- package/src/styles/themes/modern-light.css +12 -12
- package/src/styles/themes/theme-custom.css +2 -2
|
@@ -54,6 +54,26 @@ export declare class SimpleTableVanilla {
|
|
|
54
54
|
private scrollEndTimeoutId;
|
|
55
55
|
private lastScrollTop;
|
|
56
56
|
private isUpdating;
|
|
57
|
+
/**
|
|
58
|
+
* Active accordion axis for the next render. Set by row/column collapse-
|
|
59
|
+
* expand mutators (see {@link beginAccordionAnimation}) and consumed by the
|
|
60
|
+
* cell renderers via the render context. Cleared in {@link render} after
|
|
61
|
+
* each render so subsequent non-accordion renders (sort, scroll, etc.)
|
|
62
|
+
* don't re-trigger the size transitions.
|
|
63
|
+
*/
|
|
64
|
+
private pendingAccordionAxis;
|
|
65
|
+
/** Pending timeout id used to remove the accordion CSS class. */
|
|
66
|
+
private accordionCleanupTimerId;
|
|
67
|
+
/**
|
|
68
|
+
* Visible-leaf-headers key as of the last render that committed to the DOM.
|
|
69
|
+
* Used by `setHeaders` to detect hide/show/pin/unpin and trigger the
|
|
70
|
+
* accordion-horizontal animation. Comparing against `this.headers` directly
|
|
71
|
+
* doesn't work because the column editor mutates header objects in place
|
|
72
|
+
* (e.g. `header.hide = true`) BEFORE invoking setHeaders, so by the time
|
|
73
|
+
* setHeaders runs, the prev and next trees already point to the same
|
|
74
|
+
* mutated header instances.
|
|
75
|
+
*/
|
|
76
|
+
private lastRenderedVisibilityKey;
|
|
57
77
|
constructor(container: HTMLElement, config: SimpleTableConfig);
|
|
58
78
|
private applyAnimationsConfig;
|
|
59
79
|
private rebuildRowIndexMap;
|
|
@@ -79,7 +99,42 @@ export declare class SimpleTableVanilla {
|
|
|
79
99
|
* displaced columns slide smoothly out of the dragged column's way rather
|
|
80
100
|
* than snapping into place.
|
|
81
101
|
*/
|
|
102
|
+
/**
|
|
103
|
+
* Build a key summarizing the leaf columns that will paint (accessor +
|
|
104
|
+
* pinned section). Hidden leaves and excluded subtrees drop out; nested
|
|
105
|
+
* children are flattened so a parent collapse/expand counts as a
|
|
106
|
+
* visibility change at the leaf level too.
|
|
107
|
+
*/
|
|
108
|
+
private buildVisibilityKey;
|
|
109
|
+
/**
|
|
110
|
+
* True when the visible-leaf-set (or its pinned-section assignment) for
|
|
111
|
+
* `nextHeaders` differs from the last render that committed to the DOM.
|
|
112
|
+
*
|
|
113
|
+
* We deliberately compare against {@link lastRenderedVisibilityKey} rather
|
|
114
|
+
* than `this.headers`: the column editor mutates header objects in place
|
|
115
|
+
* before invoking setHeaders (e.g. `header.hide = true`, then
|
|
116
|
+
* `setHeaders(deepClone(headers))`), and `this.headers` shares those
|
|
117
|
+
* mutated references — so a prev-vs-next compare always reads the same
|
|
118
|
+
* state and reports no change. Comparing to the last-rendered key sees
|
|
119
|
+
* the user's actually-painted state and correctly detects hide/show and
|
|
120
|
+
* pin/unpin changes.
|
|
121
|
+
*/
|
|
122
|
+
private didColumnVisibilityChange;
|
|
82
123
|
private captureAnimationSnapshot;
|
|
124
|
+
/**
|
|
125
|
+
* Open the accordion animation window for the next render: capture a FLIP
|
|
126
|
+
* snapshot, mark the active axis so cell renderers initialize incoming
|
|
127
|
+
* cells at zero size, and add the CSS class that enables the size
|
|
128
|
+
* transitions on `.st-cell` / `.st-header-cell`.
|
|
129
|
+
*
|
|
130
|
+
* The CSS class is removed after `duration + ACCORDION_CLEANUP_BUFFER_MS`
|
|
131
|
+
* so non-accordion renders don't keep transitioning size on subsequent
|
|
132
|
+
* inline-style writes.
|
|
133
|
+
*
|
|
134
|
+
* No-op when animations are disabled (which already includes the
|
|
135
|
+
* prefers-reduced-motion check via {@link AnimationCoordinator.isEnabled}).
|
|
136
|
+
*/
|
|
137
|
+
private beginAccordionAnimation;
|
|
83
138
|
private initializeManagers;
|
|
84
139
|
mount(): void;
|
|
85
140
|
private setupManagers;
|
|
@@ -11,10 +11,19 @@ import { FilterManager } from "../../managers/FilterManager";
|
|
|
11
11
|
import { SelectionManager } from "../../managers/SelectionManager";
|
|
12
12
|
import { RowSelectionManager } from "../../managers/RowSelectionManager";
|
|
13
13
|
import type { AnimationCoordinator, CellPosition } from "../../managers/AnimationCoordinator";
|
|
14
|
+
import type { AccordionAxis } from "../../utils/accordionAnimation";
|
|
14
15
|
import { FlattenRowsResult } from "../../utils/rowFlattening";
|
|
15
16
|
import { ProcessRowsResult } from "../../utils/rowProcessing";
|
|
16
17
|
import { MergedColumnEditorConfig, ResolvedIcons } from "../initialization/TableInitializer";
|
|
17
18
|
export interface RenderContext {
|
|
19
|
+
/**
|
|
20
|
+
* Active accordion animation axis for this render. Set on row-grouping or
|
|
21
|
+
* nested-column collapse/expand toggles (see
|
|
22
|
+
* {@link SimpleTableVanilla.beginAccordionAnimation}). Cell renderers use it
|
|
23
|
+
* to initialize incoming cells at zero size in the named axis so the CSS
|
|
24
|
+
* size transition can grow them while sibling cells FLIP into place.
|
|
25
|
+
*/
|
|
26
|
+
accordionAxis?: AccordionAxis;
|
|
18
27
|
animationCoordinator?: AnimationCoordinator;
|
|
19
28
|
cellRegistry: Map<string, any>;
|
|
20
29
|
collapsedHeaders: Set<Accessor>;
|
|
@@ -8,7 +8,10 @@ import { FilterManager } from "../../managers/FilterManager";
|
|
|
8
8
|
import { SelectionManager } from "../../managers/SelectionManager";
|
|
9
9
|
import { RowSelectionManager } from "../../managers/RowSelectionManager";
|
|
10
10
|
import type { AnimationCoordinator, CellPosition } from "../../managers/AnimationCoordinator";
|
|
11
|
+
import type { AccordionAxis } from "../../utils/accordionAnimation";
|
|
11
12
|
export interface TableRendererDeps {
|
|
13
|
+
/** Accordion animation axis for the in-flight collapse/expand. See {@link RenderContext.accordionAxis}. */
|
|
14
|
+
accordionAxis?: AccordionAxis;
|
|
12
15
|
animationCoordinator?: AnimationCoordinator;
|
|
13
16
|
cellRegistry: Map<string, any>;
|
|
14
17
|
collapsedHeaders: Set<Accessor>;
|
|
@@ -56,7 +59,7 @@ export interface TableRendererDeps {
|
|
|
56
59
|
pinnedRightRef: {
|
|
57
60
|
current: HTMLDivElement | null;
|
|
58
61
|
};
|
|
59
|
-
positionOnlyBody?: boolean; /** When true,
|
|
62
|
+
positionOnlyBody?: boolean; /** When true, scroll path updates cell geometry only (no full content/selection refresh); row separators still sync. */
|
|
60
63
|
resolvedIcons: any;
|
|
61
64
|
rowSelectionManager: RowSelectionManager | null;
|
|
62
65
|
rowStateMap: Map<string | number, any>;
|
|
@@ -33,6 +33,14 @@ export declare class AnimationCoordinator {
|
|
|
33
33
|
private easing;
|
|
34
34
|
/** Pre-change positions for any cell we want to consider for animation. */
|
|
35
35
|
private snapshot;
|
|
36
|
+
/**
|
|
37
|
+
* One-shot synthetic origins for incoming cells that have no entry in the
|
|
38
|
+
* captured snapshot (e.g. rows/columns that did not exist in the pre-render
|
|
39
|
+
* state because they were inside a collapsed group). Used by accordion
|
|
40
|
+
* animations so a newly-visible cell unfolds from its parent's position
|
|
41
|
+
* rather than appearing in place. Cleared at the end of {@link play}.
|
|
42
|
+
*/
|
|
43
|
+
private incomingOrigins;
|
|
36
44
|
private inFlight;
|
|
37
45
|
/** Outgoing cells the renderer handed off; keyed per container so play() finds them. */
|
|
38
46
|
private retainedCells;
|
|
@@ -55,6 +63,19 @@ export declare class AnimationCoordinator {
|
|
|
55
63
|
setEasing(easing: string): void;
|
|
56
64
|
isEnabled(): boolean;
|
|
57
65
|
isInFlight(cellId: string): boolean;
|
|
66
|
+
getDuration(): number;
|
|
67
|
+
getEasing(): string;
|
|
68
|
+
/**
|
|
69
|
+
* Register synthetic pre-change origins for incoming cells that did not
|
|
70
|
+
* exist in the captured snapshot. {@link play} consults this map before
|
|
71
|
+
* giving up on a cell that has no `before` snapshot entry; matching cells
|
|
72
|
+
* FLIP from the override origin to their final position.
|
|
73
|
+
*
|
|
74
|
+
* The map is consumed by the next `play()` call and cleared, so callers
|
|
75
|
+
* must set it after `captureSnapshot` and before the render that creates
|
|
76
|
+
* the corresponding cells.
|
|
77
|
+
*/
|
|
78
|
+
setIncomingOrigins(origins: Map<string, CellPosition> | null): void;
|
|
58
79
|
/**
|
|
59
80
|
* Read scroller layout metrics for `container`, caching the result for the
|
|
60
81
|
* remainder of the current render cycle. Subsequent calls in the same
|
|
@@ -82,6 +103,27 @@ export declare class AnimationCoordinator {
|
|
|
82
103
|
* keep it for an out-animation.
|
|
83
104
|
*/
|
|
84
105
|
shouldRetain(cellId: string): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Whether the captured snapshot has an entry for the given cellId. The
|
|
108
|
+
* accordion expand path uses this to detect "newly visible" cells (no
|
|
109
|
+
* pre-change layout) so it can initialize them at zero size and let the
|
|
110
|
+
* CSS transition grow them to full size.
|
|
111
|
+
*/
|
|
112
|
+
hasSnapshotEntry(cellId: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* True when the snapshot has an entry for `cellId` AND the cell was
|
|
115
|
+
* rendered in `currentContainer` at snapshot time. Returns false when the
|
|
116
|
+
* cell came from a different container (cross-section pin/unpin) — its
|
|
117
|
+
* snapshot position is in another container's coordinate frame, so a
|
|
118
|
+
* FLIP applied locally would slide from a wrong visual origin and the
|
|
119
|
+
* destination renderer should treat the cell as fresh (accordion grow
|
|
120
|
+
* from 0 instead).
|
|
121
|
+
*
|
|
122
|
+
* Snapshot entries with `sourceContainer === null` (preLayouts /
|
|
123
|
+
* conceptual positions) are treated as same-container so the existing
|
|
124
|
+
* sort/reorder FLIP-from-off-screen behavior is preserved.
|
|
125
|
+
*/
|
|
126
|
+
hasSnapshotEntryInContainer(cellId: string, currentContainer: HTMLElement): boolean;
|
|
85
127
|
/**
|
|
86
128
|
* Hand a cell that the renderer would otherwise remove to the coordinator.
|
|
87
129
|
* The coordinator updates its absolute positioning to the post-change layout
|
|
@@ -112,6 +154,28 @@ export declare class AnimationCoordinator {
|
|
|
112
154
|
* doesn't pop into existence at a clipped FLIP entry point.
|
|
113
155
|
*/
|
|
114
156
|
claimRetainedForReuse(cellId: string, container: HTMLElement): HTMLElement | null;
|
|
157
|
+
/**
|
|
158
|
+
* Hand off a cell that the renderer would otherwise remove for an accordion
|
|
159
|
+
* shrink-out (column hide / pin-out from this section): the cell stays in
|
|
160
|
+
* place and its size in the named axis is animated to zero by the
|
|
161
|
+
* `.st-accordion-animating` CSS transition (width/height). Removed from the
|
|
162
|
+
* DOM after the transition completes.
|
|
163
|
+
*
|
|
164
|
+
* Used when there is no destination position for the cell in the current
|
|
165
|
+
* section's post-render layout — either because the column was hidden or
|
|
166
|
+
* because it moved to a different pinned section. In the moved-section
|
|
167
|
+
* case, the destination section creates a fresh cell that grows from zero
|
|
168
|
+
* width via the existing accordion incoming-cell path, so the visual
|
|
169
|
+
* effect is a synchronized shrink-here / grow-there pair rather than a
|
|
170
|
+
* cross-container slide (which would require translating coordinates
|
|
171
|
+
* between two different container coordinate frames).
|
|
172
|
+
*/
|
|
173
|
+
shrinkOutCell(args: {
|
|
174
|
+
cellId: string;
|
|
175
|
+
element: HTMLElement;
|
|
176
|
+
container: HTMLElement;
|
|
177
|
+
axis: "horizontal" | "vertical";
|
|
178
|
+
}): void;
|
|
115
179
|
/**
|
|
116
180
|
* Discard any retained cell with this id in the given container. Called by
|
|
117
181
|
* the renderer when it's about to create a fresh cell with the same id, so
|
|
@@ -11,11 +11,12 @@ type TableRow = {
|
|
|
11
11
|
rowId: (string | number)[];
|
|
12
12
|
/**
|
|
13
13
|
* Position-independent identity for the row, used as the basis for the
|
|
14
|
-
* cell DOM `id
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* cell DOM `id`, the animation coordinator's snapshot key, and **expand /
|
|
15
|
+
* collapse / row-loading state maps** ({@link expandStateKey}).
|
|
16
|
+
*
|
|
17
|
+
* Sort/filter reorder leaves this unchanged while positional `rowId` changes,
|
|
18
|
+
* so nested rows stay expanded after sort when this is supplied (via `getRowId`
|
|
19
|
+
* or WeakMap-backed fallback identities).
|
|
19
20
|
*/
|
|
20
21
|
stableRowKey?: string;
|
|
21
22
|
rowPath?: (string | number)[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active axis for the in-flight accordion animation. Set on the render
|
|
3
|
+
* context for one render after a collapse/expand toggle so cell renderers
|
|
4
|
+
* know which dimension to fold/unfold.
|
|
5
|
+
*
|
|
6
|
+
* - `"vertical"` — row group expand/collapse: incoming cells start at
|
|
7
|
+
* `height: 0` and CSS-transition to `rowHeight`.
|
|
8
|
+
* - `"horizontal"` — nested column expand/collapse: incoming cells start at
|
|
9
|
+
* `width: 0` and CSS-transition to their final width.
|
|
10
|
+
* - `null` — no accordion animation in progress (sort, reorder,
|
|
11
|
+
* scroll, etc.).
|
|
12
|
+
*/
|
|
13
|
+
export type AccordionAxis = "vertical" | "horizontal" | null;
|
|
14
|
+
/** CSS class applied to the table root during the animation window. */
|
|
15
|
+
export declare const ACCORDION_ANIMATION_CLASS = "st-accordion-animating";
|
|
16
|
+
/** Custom property names consumed by the accordion CSS transitions. */
|
|
17
|
+
export declare const ACCORDION_DURATION_VAR = "--st-accordion-duration";
|
|
18
|
+
export declare const ACCORDION_EASING_VAR = "--st-accordion-easing";
|
|
19
|
+
/** Window after which the accordion CSS class is removed (ms past duration). */
|
|
20
|
+
export declare const ACCORDION_CLEANUP_BUFFER_MS = 80;
|
|
21
|
+
/**
|
|
22
|
+
* Detect `prefers-reduced-motion: reduce`. Returns `false` outside the
|
|
23
|
+
* browser (SSR) so the call site doesn't have to guard.
|
|
24
|
+
*/
|
|
25
|
+
export declare const accordionPrefersReducedMotion: () => boolean;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
import type Row from "../../types/Row";
|
|
2
|
+
import type TableRow from "../../types/TableRow";
|
|
1
3
|
import { AbsoluteBodyCell, CellRenderContext } from "./types";
|
|
4
|
+
export interface CellLiveRef {
|
|
5
|
+
row: Row;
|
|
6
|
+
tableRow: TableRow;
|
|
7
|
+
}
|
|
8
|
+
export declare const cellLiveRefMap: WeakMap<HTMLElement, CellLiveRef>;
|
|
2
9
|
export declare const untrackCellByRow: (rowId: string, cellElement: HTMLElement) => void;
|
|
3
10
|
export declare const createBodyCellElement: (cell: AbsoluteBodyCell, context: CellRenderContext) => HTMLElement;
|
|
4
11
|
export declare const updateBodyCellPosition: (cellElement: HTMLElement, cell: AbsoluteBodyCell) => void;
|
|
@@ -8,6 +8,7 @@ import type RowState from "../../types/RowState";
|
|
|
8
8
|
import type { RowButton } from "../../types/RowButton";
|
|
9
9
|
import type { CustomTheme } from "../../types/CustomTheme";
|
|
10
10
|
import type { HeightOffsets } from "../infiniteScrollUtils";
|
|
11
|
+
import type { AccordionAxis } from "../accordionAnimation";
|
|
11
12
|
import type { VanillaEmptyStateRenderer, VanillaErrorStateRenderer, VanillaLoadingStateRenderer } from "../../types/RowStateRendererProps";
|
|
12
13
|
type SetStateAction<T> = T | ((prevState: T) => T);
|
|
13
14
|
type Dispatch<A> = (value: A) => void;
|
|
@@ -105,5 +106,15 @@ export interface CellRenderContext {
|
|
|
105
106
|
canExpandRowGroup?: (row: Row) => boolean;
|
|
106
107
|
isLoading?: boolean;
|
|
107
108
|
pinned?: "left" | "right";
|
|
109
|
+
/** Pinned section viewport width (px); used for row separators so they match the section, not the full table. */
|
|
110
|
+
pinnedSectionWidthPx?: number;
|
|
111
|
+
/**
|
|
112
|
+
* When set, this render is the post-state pass of a row-grouping (vertical)
|
|
113
|
+
* or nested-column (horizontal) expand/collapse. Newly-created cells whose
|
|
114
|
+
* cellId has no entry in the animation snapshot start at zero size in the
|
|
115
|
+
* named axis so the CSS transition can grow them to their final size while
|
|
116
|
+
* sibling rows/cells FLIP into their new positions.
|
|
117
|
+
*/
|
|
118
|
+
accordionAxis?: AccordionAxis;
|
|
108
119
|
}
|
|
109
120
|
export {};
|
|
@@ -3,6 +3,8 @@ import SortColumn from "../../types/SortColumn";
|
|
|
3
3
|
import { TableFilterState, FilterCondition } from "../../types/FilterTypes";
|
|
4
4
|
import { IconsConfig } from "../../types/IconsConfig";
|
|
5
5
|
import Row from "../../types/Row";
|
|
6
|
+
import type { AccordionAxis } from "../accordionAnimation";
|
|
7
|
+
import type { AnimationCoordinator } from "../../managers/AnimationCoordinator";
|
|
6
8
|
type SetStateAction<T> = T | ((prevState: T) => T);
|
|
7
9
|
type Dispatch<A> = (value: A) => void;
|
|
8
10
|
type MutableRefObject<T> = {
|
|
@@ -58,6 +60,8 @@ export interface HeaderRenderContext {
|
|
|
58
60
|
onSort: (accessor: Accessor) => void;
|
|
59
61
|
onTableHeaderDragEnd: (headers: HeaderObject[]) => void;
|
|
60
62
|
pinned?: "left" | "right";
|
|
63
|
+
/** Mirrors body context: pinned strip width for cache invalidation when only section width changes. */
|
|
64
|
+
pinnedSectionWidthPx?: number;
|
|
61
65
|
pinnedLeftRef: RefObject<HTMLDivElement>;
|
|
62
66
|
pinnedRightRef: RefObject<HTMLDivElement>;
|
|
63
67
|
reverse: boolean;
|
|
@@ -73,5 +77,19 @@ export interface HeaderRenderContext {
|
|
|
73
77
|
setSelectedCells: Dispatch<SetStateAction<Set<string>>>;
|
|
74
78
|
setSelectedColumns: Dispatch<SetStateAction<Set<number>>>;
|
|
75
79
|
sort: SortColumn | null;
|
|
80
|
+
/**
|
|
81
|
+
* Active accordion animation axis (parallel to {@link CellRenderContext.accordionAxis}).
|
|
82
|
+
* Used so newly-visible header cells (e.g. children of a just-expanded
|
|
83
|
+
* collapsible header) start at zero width and CSS-transition to their
|
|
84
|
+
* final width.
|
|
85
|
+
*/
|
|
86
|
+
accordionAxis?: AccordionAxis;
|
|
87
|
+
/**
|
|
88
|
+
* Animation coordinator (when enabled). The header renderer uses
|
|
89
|
+
* {@link AnimationCoordinator.hasSnapshotEntry} to detect cells that did
|
|
90
|
+
* not exist in the pre-render layout — those are the incoming cells
|
|
91
|
+
* driving the unfold animation.
|
|
92
|
+
*/
|
|
93
|
+
animationCoordinator?: AnimationCoordinator;
|
|
76
94
|
}
|
|
77
95
|
export {};
|
|
@@ -117,6 +117,24 @@ export declare const generateStableRowKey: (params: {
|
|
|
117
117
|
groupingKey?: string;
|
|
118
118
|
parentStableKey?: string | null;
|
|
119
119
|
}) => string;
|
|
120
|
+
/**
|
|
121
|
+
* Canonical string key for per-row expandable UI state: {@link expandedRows},
|
|
122
|
+
* {@link collapsedRows}, and entries in {@link rowStateMap} (loading/error/empty).
|
|
123
|
+
*
|
|
124
|
+
* Mirrors {@link TableRow.stableRowKey} whenever it is defined so expand state survives
|
|
125
|
+
* sort/filter reorder while positional `rowId` indices change.
|
|
126
|
+
* Falls back to {@link rowIdToString}(rowId) for synthetic rows without a stable key.
|
|
127
|
+
*/
|
|
128
|
+
export declare const expandStateKey: (tableRow: {
|
|
129
|
+
stableRowKey?: string;
|
|
130
|
+
rowId: (string | number)[];
|
|
131
|
+
}) => string;
|
|
132
|
+
/**
|
|
133
|
+
* Stable identity for full-width chrome rows (nested grid, loading/error state)
|
|
134
|
+
* under an expanded parent. Parent {@link expandStateKey} survives sort; path-based
|
|
135
|
+
* `rowId` does not, so SectionRenderer must key DOM maps on this instead.
|
|
136
|
+
*/
|
|
137
|
+
export declare const nestedChromeRowKey: (parentExpandStateKey: string | number, groupingKey: string | undefined) => string;
|
|
120
138
|
/**
|
|
121
139
|
* Get nested rows from a row based on the grouping path
|
|
122
140
|
*/
|
|
@@ -127,14 +145,15 @@ export declare const getNestedRows: (row: Row, groupingKey: string) => Row[];
|
|
|
127
145
|
export declare const hasNestedRows: (row: Row, groupingKey?: string) => boolean;
|
|
128
146
|
/**
|
|
129
147
|
* Determine if a row is expanded based on expandedDepths and manual row overrides
|
|
130
|
-
* @param
|
|
148
|
+
* @param expandStateRowId - Canonical key for expandable row state ({@link expandStateKey}).
|
|
149
|
+
* Matches keys in expandedRows/collapsedRows (stable across sort/filter when stableRowKey is used).
|
|
131
150
|
* @param depth - The depth level of the row (0-indexed)
|
|
132
151
|
* @param expandedDepths - Set of depth levels that are expanded
|
|
133
152
|
* @param expandedRows - Map of row IDs to their depths for rows that user wants expanded
|
|
134
153
|
* @param collapsedRows - Map of row IDs to their depths for rows that user wants collapsed
|
|
135
154
|
* @returns true if the row is expanded, false otherwise
|
|
136
155
|
*/
|
|
137
|
-
export declare const isRowExpanded: (
|
|
156
|
+
export declare const isRowExpanded: (expandStateRowId: string | number, depth: number, expandedDepths: Set<number>, expandedRows: Map<string, number>, collapsedRows: Map<string, number>) => boolean;
|
|
138
157
|
/**
|
|
139
158
|
* Flatten rows recursively based on row grouping configuration
|
|
140
159
|
* Now calculates ALL properties including position and isLastGroupRow
|
|
@@ -15,6 +15,20 @@ export interface StickyParentsContainerProps {
|
|
|
15
15
|
scrollTop: number;
|
|
16
16
|
scrollbarWidth: number;
|
|
17
17
|
stickyParents: TableRow[];
|
|
18
|
+
/**
|
|
19
|
+
* Global `colIndex` of the first leaf column in each sticky strip section,
|
|
20
|
+
* matching {@link SectionRenderer} body sections (pinned left, main, right).
|
|
21
|
+
*/
|
|
22
|
+
stickySectionColStart: {
|
|
23
|
+
left: number;
|
|
24
|
+
main: number;
|
|
25
|
+
right: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Row key (`stableRowKey` ?? `rowIdToString(rowId)`) → body slice `rowIndex`
|
|
29
|
+
* for the current `rowsToRender` band, so selection matches virtualized body cells.
|
|
30
|
+
*/
|
|
31
|
+
stickyBodyRowIndexByRowKey: Map<string, number>;
|
|
18
32
|
}
|
|
19
33
|
export interface StickyParentsRenderContext {
|
|
20
34
|
collapsedHeaders: Set<string>;
|
|
@@ -3,5 +3,9 @@ export declare const basicRowGroupingExampleDefaults: {
|
|
|
3
3
|
rowGrouping: readonly ["divisions", "departments"];
|
|
4
4
|
enableStickyParents: boolean;
|
|
5
5
|
height: string;
|
|
6
|
+
animations: {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
duration: number;
|
|
9
|
+
};
|
|
6
10
|
};
|
|
7
11
|
export declare function renderBasicRowGroupingExample(args?: Partial<UniversalVanillaArgs>): HTMLElement;
|
|
@@ -5,5 +5,9 @@ export declare const collapsibleColumnsExampleDefaults: {
|
|
|
5
5
|
selectableCells: boolean;
|
|
6
6
|
columnReordering: boolean;
|
|
7
7
|
height: string;
|
|
8
|
+
animations: {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
duration: number;
|
|
11
|
+
};
|
|
8
12
|
};
|
|
9
13
|
export declare function renderCollapsibleColumnsExample(args?: Partial<UniversalVanillaArgs>): HTMLElement;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type UniversalVanillaArgs } from "../vanillaStoryConfig";
|
|
2
2
|
export declare const dynamicNestedTableExampleDefaults: {
|
|
3
3
|
height: string;
|
|
4
|
+
expandAll: boolean;
|
|
5
|
+
autoExpandColumns: boolean;
|
|
4
6
|
};
|
|
5
7
|
export declare function renderDynamicNestedTableExample(args?: Partial<UniversalVanillaArgs>): HTMLElement;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type UniversalVanillaArgs } from "../../vanillaStoryConfig";
|
|
2
|
+
import type { Theme } from "../../../src/index";
|
|
2
3
|
export declare const pinnedColumnsExampleDefaults: {
|
|
3
4
|
rowGrouping: readonly ["stores"];
|
|
4
5
|
columnReordering: boolean;
|
|
@@ -7,5 +8,6 @@ export declare const pinnedColumnsExampleDefaults: {
|
|
|
7
8
|
editColumns: boolean;
|
|
8
9
|
height: string;
|
|
9
10
|
enableStickyParents: boolean;
|
|
11
|
+
theme: Theme;
|
|
10
12
|
};
|
|
11
13
|
export declare function renderPinnedColumnsExample(args?: Partial<UniversalVanillaArgs>): HTMLElement;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NESTED TABLES TESTS
|
|
3
|
-
*
|
|
3
|
+
* Rich deterministic data (marketing-style companies → divisions → teams), content assertions,
|
|
4
|
+
* and coverage for lazy load, multi-level nesting, sort, selection, filtering, pagination, collapse, and empty nested rows.
|
|
4
5
|
*/
|
|
5
6
|
import type { Meta } from "@storybook/html";
|
|
7
|
+
import { SimpleTableVanilla } from "../../src/index";
|
|
6
8
|
declare const meta: Meta;
|
|
7
9
|
export default meta;
|
|
8
10
|
export declare const BasicNestedTable: {
|
|
9
11
|
render: () => HTMLDivElement & {
|
|
10
|
-
_table?:
|
|
12
|
+
_table?: SimpleTableVanilla | undefined;
|
|
11
13
|
};
|
|
12
14
|
play: ({ canvasElement }: {
|
|
13
15
|
canvasElement: HTMLElement;
|
|
@@ -15,7 +17,7 @@ export declare const BasicNestedTable: {
|
|
|
15
17
|
};
|
|
16
18
|
export declare const NestedTableWithIndependentColumns: {
|
|
17
19
|
render: () => HTMLDivElement & {
|
|
18
|
-
_table?:
|
|
20
|
+
_table?: SimpleTableVanilla | undefined;
|
|
19
21
|
};
|
|
20
22
|
play: ({ canvasElement }: {
|
|
21
23
|
canvasElement: HTMLElement;
|
|
@@ -23,7 +25,7 @@ export declare const NestedTableWithIndependentColumns: {
|
|
|
23
25
|
};
|
|
24
26
|
export declare const NestedTableWithColumnResizing: {
|
|
25
27
|
render: () => HTMLDivElement & {
|
|
26
|
-
_table?:
|
|
28
|
+
_table?: SimpleTableVanilla | undefined;
|
|
27
29
|
};
|
|
28
30
|
play: ({ canvasElement }: {
|
|
29
31
|
canvasElement: HTMLElement;
|
|
@@ -31,7 +33,7 @@ export declare const NestedTableWithColumnResizing: {
|
|
|
31
33
|
};
|
|
32
34
|
export declare const NestedTableWithPagination: {
|
|
33
35
|
render: () => HTMLDivElement & {
|
|
34
|
-
_table?:
|
|
36
|
+
_table?: SimpleTableVanilla | undefined;
|
|
35
37
|
};
|
|
36
38
|
play: ({ canvasElement }: {
|
|
37
39
|
canvasElement: HTMLElement;
|
|
@@ -39,7 +41,63 @@ export declare const NestedTableWithPagination: {
|
|
|
39
41
|
};
|
|
40
42
|
export declare const NestedTableWithFiltering: {
|
|
41
43
|
render: () => HTMLDivElement & {
|
|
42
|
-
_table?:
|
|
44
|
+
_table?: SimpleTableVanilla | undefined;
|
|
45
|
+
};
|
|
46
|
+
play: ({ canvasElement }: {
|
|
47
|
+
canvasElement: HTMLElement;
|
|
48
|
+
}) => Promise<void>;
|
|
49
|
+
};
|
|
50
|
+
export declare const NestedTableLazyLoadDivisions: {
|
|
51
|
+
render: () => HTMLDivElement & {
|
|
52
|
+
_table?: SimpleTableVanilla | undefined;
|
|
53
|
+
};
|
|
54
|
+
play: ({ canvasElement }: {
|
|
55
|
+
canvasElement: HTMLElement;
|
|
56
|
+
}) => Promise<void>;
|
|
57
|
+
};
|
|
58
|
+
export declare const NestedTableThreeLevels: {
|
|
59
|
+
render: () => HTMLDivElement & {
|
|
60
|
+
_table?: SimpleTableVanilla | undefined;
|
|
61
|
+
};
|
|
62
|
+
play: ({ canvasElement }: {
|
|
63
|
+
canvasElement: HTMLElement;
|
|
64
|
+
}) => Promise<void>;
|
|
65
|
+
};
|
|
66
|
+
export declare const NestedTableExpandCollapse: {
|
|
67
|
+
render: () => HTMLDivElement & {
|
|
68
|
+
_table?: SimpleTableVanilla | undefined;
|
|
69
|
+
};
|
|
70
|
+
play: ({ canvasElement }: {
|
|
71
|
+
canvasElement: HTMLElement;
|
|
72
|
+
}) => Promise<void>;
|
|
73
|
+
};
|
|
74
|
+
export declare const NestedTableNestedSort: {
|
|
75
|
+
render: () => HTMLDivElement & {
|
|
76
|
+
_table?: SimpleTableVanilla | undefined;
|
|
77
|
+
};
|
|
78
|
+
play: ({ canvasElement }: {
|
|
79
|
+
canvasElement: HTMLElement;
|
|
80
|
+
}) => Promise<void>;
|
|
81
|
+
};
|
|
82
|
+
export declare const NestedTableRowSelection: {
|
|
83
|
+
render: () => HTMLDivElement & {
|
|
84
|
+
_table?: SimpleTableVanilla | undefined;
|
|
85
|
+
};
|
|
86
|
+
play: ({ canvasElement }: {
|
|
87
|
+
canvasElement: HTMLElement;
|
|
88
|
+
}) => Promise<void>;
|
|
89
|
+
};
|
|
90
|
+
export declare const NestedTableEmptyDivisions: {
|
|
91
|
+
render: () => HTMLDivElement & {
|
|
92
|
+
_table?: SimpleTableVanilla | undefined;
|
|
93
|
+
};
|
|
94
|
+
play: ({ canvasElement }: {
|
|
95
|
+
canvasElement: HTMLElement;
|
|
96
|
+
}) => Promise<void>;
|
|
97
|
+
};
|
|
98
|
+
export declare const NestedTableAutoExpandNested: {
|
|
99
|
+
render: () => HTMLDivElement & {
|
|
100
|
+
_table?: SimpleTableVanilla | undefined;
|
|
43
101
|
};
|
|
44
102
|
play: ({ canvasElement }: {
|
|
45
103
|
canvasElement: HTMLElement;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COLLAPSE / EXPAND ACCORDION ANIMATION TESTS
|
|
3
|
+
*
|
|
4
|
+
* Verifies the accordion-style animations on:
|
|
5
|
+
* - Nested column collapse / expand: incoming columns start at width 0 and
|
|
6
|
+
* CSS-transition to their final width while surviving columns FLIP-shift.
|
|
7
|
+
* - Row group collapse / expand: incoming rows start at height 0 and
|
|
8
|
+
* CSS-transition to rowHeight while surviving rows FLIP-shift.
|
|
9
|
+
*
|
|
10
|
+
* The mechanism reuses the existing FLIP `AnimationCoordinator` (no extra
|
|
11
|
+
* config) and is gated by `animations.enabled`. This file exercises the
|
|
12
|
+
* one-render window where:
|
|
13
|
+
* - Root has `.st-accordion-animating`.
|
|
14
|
+
* - Newly-visible cells carry inline `width: 0px` or `height: 0px`.
|
|
15
|
+
*/
|
|
16
|
+
import type { Meta } from "@storybook/html";
|
|
17
|
+
declare const meta: Meta;
|
|
18
|
+
export default meta;
|
|
19
|
+
export declare const ColumnExpand_AddsAccordionClass: {
|
|
20
|
+
tags: string[];
|
|
21
|
+
render: () => HTMLDivElement & {
|
|
22
|
+
_table?: import("../../src/index").SimpleTableVanilla | undefined;
|
|
23
|
+
};
|
|
24
|
+
play: ({ canvasElement }: {
|
|
25
|
+
canvasElement: HTMLElement;
|
|
26
|
+
}) => Promise<void>;
|
|
27
|
+
};
|
|
28
|
+
export declare const ColumnExpand_IncomingCellsStartAtZeroWidth: {
|
|
29
|
+
tags: string[];
|
|
30
|
+
render: () => HTMLDivElement & {
|
|
31
|
+
_table?: import("../../src/index").SimpleTableVanilla | undefined;
|
|
32
|
+
};
|
|
33
|
+
play: ({ canvasElement }: {
|
|
34
|
+
canvasElement: HTMLElement;
|
|
35
|
+
}) => Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
export declare const RowExpand_AddsAccordionClass: {
|
|
38
|
+
tags: string[];
|
|
39
|
+
render: () => HTMLDivElement & {
|
|
40
|
+
_table?: import("../../src/index").SimpleTableVanilla | undefined;
|
|
41
|
+
};
|
|
42
|
+
play: ({ canvasElement }: {
|
|
43
|
+
canvasElement: HTMLElement;
|
|
44
|
+
}) => Promise<void>;
|
|
45
|
+
};
|
|
46
|
+
export declare const RowExpand_IncomingCellsStartAtZeroHeight: {
|
|
47
|
+
tags: string[];
|
|
48
|
+
render: () => HTMLDivElement & {
|
|
49
|
+
_table?: import("../../src/index").SimpleTableVanilla | undefined;
|
|
50
|
+
};
|
|
51
|
+
play: ({ canvasElement }: {
|
|
52
|
+
canvasElement: HTMLElement;
|
|
53
|
+
}) => Promise<void>;
|
|
54
|
+
};
|
|
55
|
+
export declare const Disabled_NoAccordionClass: {
|
|
56
|
+
tags: string[];
|
|
57
|
+
render: () => HTMLDivElement & {
|
|
58
|
+
_table?: import("../../src/index").SimpleTableVanilla | undefined;
|
|
59
|
+
};
|
|
60
|
+
play: ({ canvasElement }: {
|
|
61
|
+
canvasElement: HTMLElement;
|
|
62
|
+
}) => Promise<void>;
|
|
63
|
+
};
|
|
@@ -25,6 +25,11 @@ export declare const rowExists: (container: HTMLElement, rowIndex: string) => bo
|
|
|
25
25
|
*/
|
|
26
26
|
export declare const getVirtualRows: (container: HTMLElement) => HTMLElement[][];
|
|
27
27
|
export declare const waitForTable: (timeout?: number) => Promise<void>;
|
|
28
|
+
/** Poll until predicate returns true or timeout (reduces flake vs fixed setTimeout). */
|
|
29
|
+
export declare function waitUntil(predicate: () => boolean, options?: {
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
intervalMs?: number;
|
|
32
|
+
}): Promise<void>;
|
|
28
33
|
export declare const validateBasicTableStructure: (canvasElement: HTMLElement) => Promise<void>;
|
|
29
34
|
export declare const validateColumnCount: (canvasElement: HTMLElement, expectedCount: number) => void;
|
|
30
35
|
export declare const validateRowCount: (canvasElement: HTMLElement, expectedCount: number) => void;
|