@taskctrl/canvas-grid 0.1.0
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/README.md +176 -0
- package/dist/CanvasGrid.d.ts +3 -0
- package/dist/canvas-grid.cjs.js +1 -0
- package/dist/canvas-grid.es.js +1685 -0
- package/dist/capture.d.ts +17 -0
- package/dist/core/ColumnEngine.d.ts +43 -0
- package/dist/core/HitTest.d.ts +8 -0
- package/dist/core/RenderScheduler.d.ts +11 -0
- package/dist/core/SelectionEngine.d.ts +15 -0
- package/dist/core/TreeEngine.d.ts +20 -0
- package/dist/core/ViewState.d.ts +48 -0
- package/dist/dom/AriaLiveRegion.d.ts +9 -0
- package/dist/dom/ColumnHeaders.d.ts +14 -0
- package/dist/dom/ColumnVisibilityMenu.d.ts +7 -0
- package/dist/dom/HoverPortal.d.ts +9 -0
- package/dist/dom/RowSidebar.d.ts +16 -0
- package/dist/helpers/DrawHelpers.d.ts +2 -0
- package/dist/index.d.ts +7 -0
- package/dist/layers/CellLayer.d.ts +14 -0
- package/dist/layers/GridLayer.d.ts +10 -0
- package/dist/layers/OverlayLayer.d.ts +22 -0
- package/dist/setupCanvas.d.ts +1 -0
- package/dist/types.d.ts +110 -0
- package/package.json +61 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TreeEngine } from './core/TreeEngine';
|
|
2
|
+
import { ColumnEngine } from './core/ColumnEngine';
|
|
3
|
+
import { SelectionEngine } from './core/SelectionEngine';
|
|
4
|
+
import { ColumnGroup, CaptureOptions } from './types';
|
|
5
|
+
import { GridLayerConfig } from './layers/GridLayer';
|
|
6
|
+
import { CellLayerConfig } from './layers/CellLayer';
|
|
7
|
+
export interface CaptureGridOptions extends CaptureOptions {
|
|
8
|
+
treeEngine: TreeEngine;
|
|
9
|
+
columnEngine: ColumnEngine;
|
|
10
|
+
selectionEngine: SelectionEngine;
|
|
11
|
+
columnGroups?: ColumnGroup[];
|
|
12
|
+
rowHeight: number;
|
|
13
|
+
sidebarWidth: number;
|
|
14
|
+
gridLayerConfig: GridLayerConfig;
|
|
15
|
+
cellLayerConfig: CellLayerConfig;
|
|
16
|
+
}
|
|
17
|
+
export declare function captureGrid(options: CaptureGridOptions): HTMLCanvasElement;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Column } from '../types';
|
|
2
|
+
export declare class ColumnEngine {
|
|
3
|
+
private readonly _columns;
|
|
4
|
+
constructor(columns: Column[]);
|
|
5
|
+
getVisibleColumns(): Column[];
|
|
6
|
+
/** Returns visible pinned-left columns, preserving order. */
|
|
7
|
+
getPinnedColumns(): Column[];
|
|
8
|
+
/** Returns visible non-pinned columns, preserving order. */
|
|
9
|
+
getScrollableColumns(): Column[];
|
|
10
|
+
/** Total width of all pinned-left columns. */
|
|
11
|
+
getPinnedWidth(): number;
|
|
12
|
+
getAllColumns(): Column[];
|
|
13
|
+
getTotalWidth(): number;
|
|
14
|
+
/**
|
|
15
|
+
* Returns X offset of a column in the logical layout:
|
|
16
|
+
* pinned columns come first (at offsets 0..pinnedWidth),
|
|
17
|
+
* scrollable columns follow (at offsets pinnedWidth..).
|
|
18
|
+
*/
|
|
19
|
+
getColumnX(colId: string): number;
|
|
20
|
+
/**
|
|
21
|
+
* Given an absolute X (i.e. accounting for scroll in scrollable region),
|
|
22
|
+
* returns the column id at that position. Pinned columns are checked first
|
|
23
|
+
* since they overlay scrollable content.
|
|
24
|
+
*/
|
|
25
|
+
getColumnAtX(x: number): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the visible range of SCROLLABLE columns only (pinned are always visible).
|
|
28
|
+
* scrollX is applied only to the scrollable portion (offset relative to pinnedWidth).
|
|
29
|
+
*/
|
|
30
|
+
getVisibleRange(scrollX: number, viewportWidth: number): {
|
|
31
|
+
startIndex: number;
|
|
32
|
+
endIndex: number;
|
|
33
|
+
};
|
|
34
|
+
/** Returns the range of pinned columns (always all of them). */
|
|
35
|
+
getPinnedRange(): {
|
|
36
|
+
startIndex: number;
|
|
37
|
+
endIndex: number;
|
|
38
|
+
};
|
|
39
|
+
resize(colId: string, newWidth: number): ColumnEngine;
|
|
40
|
+
reorder(colId: string, newIndex: number): ColumnEngine;
|
|
41
|
+
hide(colId: string): ColumnEngine;
|
|
42
|
+
show(colId: string): ColumnEngine;
|
|
43
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ViewState } from './ViewState';
|
|
2
|
+
import { TreeEngine } from './TreeEngine';
|
|
3
|
+
import { ColumnEngine } from './ColumnEngine';
|
|
4
|
+
export declare function hitTest(x: number, y: number, viewState: ViewState, treeEngine: TreeEngine, columnEngine: ColumnEngine): {
|
|
5
|
+
rowId: string | number;
|
|
6
|
+
colId: string;
|
|
7
|
+
} | null;
|
|
8
|
+
export declare function detectEdge(localX: number, colId: string, columnEngine: ColumnEngine): 'left' | 'right' | 'body';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LayerName } from '../types';
|
|
2
|
+
export declare class RenderScheduler {
|
|
3
|
+
private readonly _drawFn;
|
|
4
|
+
private _dirty;
|
|
5
|
+
private _rafId;
|
|
6
|
+
constructor(drawFn: (layer: LayerName) => void);
|
|
7
|
+
markDirty(layer: LayerName): void;
|
|
8
|
+
markAllDirty(): void;
|
|
9
|
+
destroy(): void;
|
|
10
|
+
private _flush;
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Selection } from '../types';
|
|
2
|
+
export declare class SelectionEngine {
|
|
3
|
+
private _selection;
|
|
4
|
+
constructor(initial?: Selection);
|
|
5
|
+
click(rowId: string | number, colId: string, allRowIds: Array<string | number>, allColIds: string[]): void;
|
|
6
|
+
ctrlClick(rowId: string | number, colId: string): void;
|
|
7
|
+
shiftClick(rowId: string | number, colId: string, allRowIds: Array<string | number>, allColIds: string[]): void;
|
|
8
|
+
selectRow(rowId: string | number, allColIds: string[]): void;
|
|
9
|
+
selectColumn(colId: string, allRowIds: Array<string | number>): void;
|
|
10
|
+
clear(): void;
|
|
11
|
+
isSelected(rowId: string | number, colId: string): boolean;
|
|
12
|
+
isRowSelected(rowId: string | number): boolean;
|
|
13
|
+
isColumnSelected(colId: string): boolean;
|
|
14
|
+
getSelection(): Selection;
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Row } from '../types';
|
|
2
|
+
export declare class TreeEngine {
|
|
3
|
+
private readonly _rows;
|
|
4
|
+
private readonly _expandedRows;
|
|
5
|
+
private readonly _flattenedRows;
|
|
6
|
+
private readonly _depthMap;
|
|
7
|
+
private readonly _childrenMap;
|
|
8
|
+
constructor(rows: Row[], expandedRows: Set<string | number>);
|
|
9
|
+
private _buildMaps;
|
|
10
|
+
private _buildFlattenedRows;
|
|
11
|
+
get flattenedRows(): readonly Row[];
|
|
12
|
+
getDepth(rowId: string | number): number;
|
|
13
|
+
hasChildren(rowId: string | number): boolean;
|
|
14
|
+
isExpanded(rowId: string | number): boolean;
|
|
15
|
+
toggle(rowId: string | number): Set<string | number>;
|
|
16
|
+
getVisibleRange(scrollTop: number, viewportHeight: number, rowHeight: number): {
|
|
17
|
+
startIndex: number;
|
|
18
|
+
endIndex: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
interface ViewStateProps {
|
|
2
|
+
scrollX?: number;
|
|
3
|
+
scrollY?: number;
|
|
4
|
+
canvasWidth?: number;
|
|
5
|
+
canvasHeight?: number;
|
|
6
|
+
rowHeight?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class ViewState {
|
|
9
|
+
scrollX: number;
|
|
10
|
+
scrollY: number;
|
|
11
|
+
canvasWidth: number;
|
|
12
|
+
canvasHeight: number;
|
|
13
|
+
rowHeight: number;
|
|
14
|
+
pinnedWidth: number;
|
|
15
|
+
private _columnOffsets;
|
|
16
|
+
private _columnWidths;
|
|
17
|
+
private _pinnedOffsets;
|
|
18
|
+
private _pinnedWidths;
|
|
19
|
+
private _scrollableOffsets;
|
|
20
|
+
private _scrollableWidths;
|
|
21
|
+
constructor(initial?: ViewStateProps);
|
|
22
|
+
update(partial: ViewStateProps): void;
|
|
23
|
+
setColumnOffsets(offsets: number[]): void;
|
|
24
|
+
setColumnWidths(widths: number[]): void;
|
|
25
|
+
setPinnedOffsets(offsets: number[], widths: number[]): void;
|
|
26
|
+
setScrollableOffsets(offsets: number[], widths: number[]): void;
|
|
27
|
+
rowToY(index: number): number;
|
|
28
|
+
yToRow(y: number): number;
|
|
29
|
+
/**
|
|
30
|
+
* Column index → canvas X pixel.
|
|
31
|
+
* When pinned param is provided, uses the separate pinned/scrollable arrays.
|
|
32
|
+
* - pinned columns: offset directly (no scrollX applied)
|
|
33
|
+
* - scrollable columns: offset - scrollX + pinnedWidth
|
|
34
|
+
* When pinned param is omitted, falls back to legacy behavior (single array).
|
|
35
|
+
*/
|
|
36
|
+
colToX(index: number, pinned?: boolean): number;
|
|
37
|
+
/**
|
|
38
|
+
* Canvas X pixel → column index (-1 if not found).
|
|
39
|
+
* When usePinnedLayout is true, checks pinned columns first, then scrollable.
|
|
40
|
+
* Returns { index, pinned } to distinguish which array was hit.
|
|
41
|
+
*/
|
|
42
|
+
xToColPinned(x: number): {
|
|
43
|
+
index: number;
|
|
44
|
+
pinned: boolean;
|
|
45
|
+
} | null;
|
|
46
|
+
xToCol(x: number): number;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface AriaLiveRegionProps {
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Visually hidden live region for screen reader announcements.
|
|
7
|
+
* Updates whenever `message` changes, which triggers aria-live to read it aloud.
|
|
8
|
+
*/
|
|
9
|
+
export declare function AriaLiveRegion({ message }: AriaLiveRegionProps): React.ReactElement;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ColumnEngine } from '../core/ColumnEngine';
|
|
3
|
+
import { ColumnGroup, HeaderOrientation } from '../types';
|
|
4
|
+
export interface ColumnHeadersProps {
|
|
5
|
+
columnEngine: ColumnEngine;
|
|
6
|
+
columnGroups?: ColumnGroup[];
|
|
7
|
+
scrollX: number;
|
|
8
|
+
orientation?: HeaderOrientation;
|
|
9
|
+
onColumnClick?: (colId: string, e: React.PointerEvent) => void;
|
|
10
|
+
onColumnResize?: (colId: string, newWidth: number) => void;
|
|
11
|
+
onColumnReorder?: (colId: string, newIndex: number) => void;
|
|
12
|
+
columnHeaderRenderer?: (colId: string, title: string) => React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export declare function ColumnHeaders({ columnEngine, columnGroups, scrollX, orientation, onColumnClick, onColumnResize, onColumnReorder, columnHeaderRenderer, }: ColumnHeadersProps): React.ReactElement;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ColumnEngine } from '../core/ColumnEngine';
|
|
3
|
+
export interface ColumnVisibilityMenuProps {
|
|
4
|
+
columnEngine: ColumnEngine;
|
|
5
|
+
onColumnVisibilityChange: (colId: string, visible: boolean) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function ColumnVisibilityMenu({ columnEngine, onColumnVisibilityChange, }: ColumnVisibilityMenuProps): React.ReactElement;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { TreeEngine } from '../core/TreeEngine';
|
|
3
|
+
import { SidebarRenderer } from '../types';
|
|
4
|
+
export interface RowSidebarProps {
|
|
5
|
+
treeEngine: TreeEngine;
|
|
6
|
+
width: number;
|
|
7
|
+
rowHeight: number;
|
|
8
|
+
scrollTop: number;
|
|
9
|
+
viewportHeight: number;
|
|
10
|
+
sidebarRenderer?: SidebarRenderer;
|
|
11
|
+
onToggle: (rowId: string | number) => void;
|
|
12
|
+
onRowClick?: (rowId: string | number, e: React.PointerEvent) => void;
|
|
13
|
+
hoveredRowId?: string | number | null;
|
|
14
|
+
onRowHover?: (rowId: string | number | null) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function RowSidebar({ treeEngine, width, rowHeight, scrollTop, viewportHeight, sidebarRenderer, onToggle, onRowClick, hoveredRowId, onRowHover, }: RowSidebarProps): React.ReactElement;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { CanvasGrid } from './CanvasGrid';
|
|
2
|
+
export { createDrawHelpers } from './helpers/DrawHelpers';
|
|
3
|
+
export { TreeEngine } from './core/TreeEngine';
|
|
4
|
+
export { ColumnEngine } from './core/ColumnEngine';
|
|
5
|
+
export { SelectionEngine } from './core/SelectionEngine';
|
|
6
|
+
export { ViewState } from './core/ViewState';
|
|
7
|
+
export type { Row, Column, ColumnGroup, CellBounds, CellState, CellData, CellRenderer, SidebarRenderer, DrawHelpers, HeaderOrientation, Selection, CanvasGridProps, LayerName, CaptureOptions, CanvasGridRef, } from './types';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViewState } from '../core/ViewState';
|
|
2
|
+
import { TreeEngine } from '../core/TreeEngine';
|
|
3
|
+
import { ColumnEngine } from '../core/ColumnEngine';
|
|
4
|
+
import { SelectionEngine } from '../core/SelectionEngine';
|
|
5
|
+
import { CellRenderer } from '../types';
|
|
6
|
+
export interface CellLayerConfig {
|
|
7
|
+
cellRenderer: CellRenderer;
|
|
8
|
+
getCellData: (rowId: string | number, colId: string) => unknown;
|
|
9
|
+
hoveredCell?: {
|
|
10
|
+
rowId: string | number;
|
|
11
|
+
colId: string;
|
|
12
|
+
} | null;
|
|
13
|
+
}
|
|
14
|
+
export declare function drawCellLayer(ctx: CanvasRenderingContext2D, viewState: ViewState, treeEngine: TreeEngine, columnEngine: ColumnEngine, selectionEngine: SelectionEngine, config: CellLayerConfig): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ViewState } from '../core/ViewState';
|
|
2
|
+
import { TreeEngine } from '../core/TreeEngine';
|
|
3
|
+
import { ColumnEngine } from '../core/ColumnEngine';
|
|
4
|
+
import { Row } from '../types';
|
|
5
|
+
export interface GridLayerConfig {
|
|
6
|
+
rowStyle?: (row: Row, depth: number) => {
|
|
7
|
+
backgroundColor?: string;
|
|
8
|
+
} | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function drawGridLayer(ctx: CanvasRenderingContext2D, viewState: ViewState, treeEngine: TreeEngine, columnEngine: ColumnEngine, config?: GridLayerConfig): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ViewState } from '../core/ViewState';
|
|
2
|
+
import { TreeEngine } from '../core/TreeEngine';
|
|
3
|
+
import { ColumnEngine } from '../core/ColumnEngine';
|
|
4
|
+
import { SelectionEngine } from '../core/SelectionEngine';
|
|
5
|
+
export interface OverlayLayerConfig {
|
|
6
|
+
hoveredCell?: {
|
|
7
|
+
rowId: string | number;
|
|
8
|
+
colId: string;
|
|
9
|
+
} | null;
|
|
10
|
+
hoveredRowId?: string | number | null;
|
|
11
|
+
/** When set, draws crosshair (full row + col highlight) for the selected cell */
|
|
12
|
+
selectedCell?: {
|
|
13
|
+
rowId: string | number;
|
|
14
|
+
colId: string;
|
|
15
|
+
} | null;
|
|
16
|
+
resizingColumn?: {
|
|
17
|
+
colId: string;
|
|
18
|
+
x: number;
|
|
19
|
+
};
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function drawOverlayLayer(ctx: CanvasRenderingContext2D, viewState: ViewState, treeEngine: TreeEngine, columnEngine: ColumnEngine, selectionEngine: SelectionEngine, config?: OverlayLayerConfig): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface Row {
|
|
3
|
+
id: string | number;
|
|
4
|
+
parentId?: string | number;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface Column {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
group?: string;
|
|
11
|
+
width: number;
|
|
12
|
+
minWidth?: number;
|
|
13
|
+
hidden?: boolean;
|
|
14
|
+
pinned?: 'left';
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface ColumnGroup {
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
color?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CellBounds {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}
|
|
28
|
+
export interface CellState {
|
|
29
|
+
selected: boolean;
|
|
30
|
+
hovered: boolean;
|
|
31
|
+
rowSelected: boolean;
|
|
32
|
+
colSelected: boolean;
|
|
33
|
+
filtered: boolean;
|
|
34
|
+
/** Tree info for the row this cell belongs to */
|
|
35
|
+
depth: number;
|
|
36
|
+
hasChildren: boolean;
|
|
37
|
+
expanded: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface CellData {
|
|
40
|
+
rowId: string | number;
|
|
41
|
+
colId: string;
|
|
42
|
+
data: unknown;
|
|
43
|
+
}
|
|
44
|
+
export interface DrawHelpers {
|
|
45
|
+
roundRect(x: number, y: number, w: number, h: number, r: number, fill: string): void;
|
|
46
|
+
fillText(text: string, x: number, y: number, maxWidth?: number): void;
|
|
47
|
+
truncateText(text: string, maxWidth: number): string;
|
|
48
|
+
badge(x: number, y: number, text: string, bg: string, fg: string): number;
|
|
49
|
+
progressBar(x: number, y: number, w: number, h: number, percent: number, color: string): void;
|
|
50
|
+
}
|
|
51
|
+
export type CellRenderer = (ctx: CanvasRenderingContext2D, cell: CellData, bounds: CellBounds, state: CellState, helpers: DrawHelpers) => void;
|
|
52
|
+
export type SidebarRenderer = (row: Row, depth: number, expanded: boolean, hasChildren: boolean) => React.ReactNode;
|
|
53
|
+
export type HeaderOrientation = 'horizontal' | 'vertical';
|
|
54
|
+
export interface Selection {
|
|
55
|
+
cells: Set<string>;
|
|
56
|
+
rows: Set<string | number>;
|
|
57
|
+
columns: Set<string>;
|
|
58
|
+
anchor?: {
|
|
59
|
+
rowId: string | number;
|
|
60
|
+
colId: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export type LayerName = 'grid' | 'cells' | 'overlay';
|
|
64
|
+
export interface CaptureOptions {
|
|
65
|
+
scale?: number;
|
|
66
|
+
}
|
|
67
|
+
export interface CanvasGridRef {
|
|
68
|
+
captureToCanvas(options?: CaptureOptions): HTMLCanvasElement;
|
|
69
|
+
}
|
|
70
|
+
export interface CanvasGridProps {
|
|
71
|
+
rows: Row[];
|
|
72
|
+
columns: Column[];
|
|
73
|
+
columnGroups?: ColumnGroup[];
|
|
74
|
+
getCellData: (rowId: string | number, colId: string) => unknown;
|
|
75
|
+
cellRenderer: CellRenderer;
|
|
76
|
+
sidebarRenderer?: SidebarRenderer;
|
|
77
|
+
sidebarHeaderRenderer?: () => React.ReactNode;
|
|
78
|
+
sidebarWidth?: number;
|
|
79
|
+
rowHeight?: number;
|
|
80
|
+
headerOrientation?: HeaderOrientation;
|
|
81
|
+
rowStyle?: (row: Row, depth: number) => {
|
|
82
|
+
backgroundColor?: string;
|
|
83
|
+
} | null;
|
|
84
|
+
selection?: Selection;
|
|
85
|
+
onSelectionChange?: (selection: Selection) => void;
|
|
86
|
+
onCellClick?: (rowId: string | number, colId: string, e: PointerEvent) => void;
|
|
87
|
+
onCellDoubleClick?: (rowId: string | number, colId: string, e: PointerEvent) => void;
|
|
88
|
+
onCellContextMenu?: (rowId: string | number, colId: string, e: PointerEvent) => void;
|
|
89
|
+
onCellHover?: (rowId: string | number | null, colId: string | null, e: PointerEvent) => void;
|
|
90
|
+
onRowHeaderClick?: (rowId: string | number, e: PointerEvent) => void;
|
|
91
|
+
onColumnHeaderClick?: (colId: string, e: PointerEvent) => void;
|
|
92
|
+
/** Custom React content to render inside a column header cell (e.g. filter icons) */
|
|
93
|
+
columnHeaderRenderer?: (colId: string, title: string) => React.ReactNode;
|
|
94
|
+
defaultExpandedRows?: (string | number)[];
|
|
95
|
+
onExpandChange?: (expandedRows: (string | number)[]) => void;
|
|
96
|
+
onColumnResize?: (colId: string, width: number) => void;
|
|
97
|
+
onColumnReorder?: (colId: string, newIndex: number) => void;
|
|
98
|
+
onColumnVisibilityChange?: (colId: string, visible: boolean) => void;
|
|
99
|
+
onTreeToggle?: (rowId: string | number) => void;
|
|
100
|
+
onLoadMore?: () => void;
|
|
101
|
+
hasMore?: boolean;
|
|
102
|
+
loading?: boolean;
|
|
103
|
+
showColumnVisibilityMenu?: boolean;
|
|
104
|
+
hoverContent?: React.ReactNode;
|
|
105
|
+
hoverPosition?: {
|
|
106
|
+
left: number;
|
|
107
|
+
top: number;
|
|
108
|
+
};
|
|
109
|
+
ariaLabel?: string;
|
|
110
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@taskctrl/canvas-grid",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tree-structured, virtualized data grid rendered on stacked HTML canvas layers for React",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "TaskCtrl AS",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/TaskCtrl-As/canvas-grid.git"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/canvas-grid.cjs.js",
|
|
13
|
+
"module": "dist/canvas-grid.es.js",
|
|
14
|
+
"types": "dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/canvas-grid.es.js",
|
|
18
|
+
"require": "./dist/canvas-grid.cjs.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": ">=17.0.0",
|
|
31
|
+
"react-dom": ">=17.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@storybook/react": "^10.4.1",
|
|
35
|
+
"@storybook/react-vite": "^10.4.1",
|
|
36
|
+
"@types/react": "^18.3.0",
|
|
37
|
+
"@types/react-dom": "^18.3.0",
|
|
38
|
+
"@vitejs/plugin-react": "^4.0.0",
|
|
39
|
+
"jsdom": "^26.0.0",
|
|
40
|
+
"react": "^18.3.0",
|
|
41
|
+
"react-dom": "^18.3.0",
|
|
42
|
+
"storybook": "^10.4.1",
|
|
43
|
+
"typescript": "^5.5.0",
|
|
44
|
+
"vite": "^6.0.0",
|
|
45
|
+
"vite-plugin-dts": "^5.0.1",
|
|
46
|
+
"vitest": "^3.0.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "vite build",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"local": "yarn build && npx -y yalc push --sig",
|
|
53
|
+
"local:watch": "LOCAL_DEV=1 vite build --watch",
|
|
54
|
+
"prepublishOnly": "yarn build",
|
|
55
|
+
"release": "yarn release:patch",
|
|
56
|
+
"release:patch": "npm version patch -m \"chore: release v%s\" && git push origin HEAD --follow-tags",
|
|
57
|
+
"release:minor": "npm version minor -m \"chore: release v%s\" && git push origin HEAD --follow-tags",
|
|
58
|
+
"release:major": "npm version major -m \"chore: release v%s\" && git push origin HEAD --follow-tags",
|
|
59
|
+
"release:beta": "npm version prerelease --preid=beta -m \"chore: release v%s\" && git push origin HEAD --follow-tags"
|
|
60
|
+
}
|
|
61
|
+
}
|