gp-grid-react 0.5.3 → 0.7.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 +5 -3
- package/dist/index.d.ts +394 -52
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# gp-grid-react 🏁 🏎️
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
|
-
<a href="https://gp-grid
|
|
4
|
+
<a href="https://www.gp-grid.io">
|
|
5
5
|
<picture>
|
|
6
6
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/GioPat/gp-grid-docs/refs/heads/master/public/logo-light.svg"/>
|
|
7
7
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/GioPat/gp-grid-docs/refs/heads/master/public/logo-dark.svg"/>
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
</a>
|
|
11
11
|
<div align="center">
|
|
12
12
|
Logo by <a href="https://github.com/camillo18tre">camillo18tre ❤️</a>
|
|
13
|
-
<h4><a href="https://gp-grid
|
|
13
|
+
<h4><a href="https://www.gp-grid.io/">🎮 Demo</a> • <a href="https://www.gp-grid.io/docs/react">📖 Documentation</a>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
+
[](https://deepwiki.com/GioPat/gp-grid)
|
|
18
|
+
|
|
17
19
|
A high-performance, feature lean React data grid component built to manage grids with huge amount (millions) of rows. It's based on its core dependency: `gp-grid-core`, featuring virtual scrolling, cell selection, sorting, filtering, editing, and Excel-like fill handle.
|
|
18
20
|
|
|
19
21
|
## Table of Contents
|
|
@@ -29,7 +31,7 @@ A high-performance, feature lean React data grid component built to manage grids
|
|
|
29
31
|
|
|
30
32
|
## Features
|
|
31
33
|
|
|
32
|
-
- **Virtual Scrolling**: Efficiently handles
|
|
34
|
+
- **Virtual Scrolling**: Efficiently handles millions of rows through slot-based recycling
|
|
33
35
|
- **Cell Selection**: Single cell, range selection, Shift+click extend, Ctrl+click toggle
|
|
34
36
|
- **Multi-Column Sorting**: Click to sort, Shift+click for multi-column sort
|
|
35
37
|
- **Column Filtering**: Built-in filter row with debounced input
|
package/dist/index.d.ts
CHANGED
|
@@ -60,6 +60,81 @@ interface FillHandleState {
|
|
|
60
60
|
targetCol: number;
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
|
+
//#region ../core/src/types/highlighting.d.ts
|
|
64
|
+
/**
|
|
65
|
+
* Minimal column info for highlighting context.
|
|
66
|
+
* Uses structural typing to avoid circular dependency with columns.ts.
|
|
67
|
+
*/
|
|
68
|
+
interface HighlightColumnInfo {
|
|
69
|
+
field: string;
|
|
70
|
+
colId?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Unified context for row, column, and cell highlighting.
|
|
74
|
+
*
|
|
75
|
+
* - Row context: `rowIndex` is set, `colIndex` is null
|
|
76
|
+
* - Column context: `colIndex` is set, `rowIndex` is null
|
|
77
|
+
* - Cell context: both `rowIndex` and `colIndex` are set
|
|
78
|
+
*/
|
|
79
|
+
interface HighlightContext<TData = Record<string, unknown>> {
|
|
80
|
+
/** Row index. Null for column-only context. */
|
|
81
|
+
rowIndex: number | null;
|
|
82
|
+
/** Column index. Null for row-only context. */
|
|
83
|
+
colIndex: number | null;
|
|
84
|
+
/** Column definition. Present for column and cell contexts. */
|
|
85
|
+
column?: HighlightColumnInfo;
|
|
86
|
+
/** Row data. Present for row and cell contexts. */
|
|
87
|
+
rowData?: TData;
|
|
88
|
+
/** Currently hovered cell position, null if not hovering */
|
|
89
|
+
hoverPosition: CellPosition | null;
|
|
90
|
+
/** Currently active (focused) cell position */
|
|
91
|
+
activeCell: CellPosition | null;
|
|
92
|
+
/** Current selection range */
|
|
93
|
+
selectionRange: CellRange | null;
|
|
94
|
+
/** Whether this row/column/cell is hovered (respects hoverScope) */
|
|
95
|
+
isHovered: boolean;
|
|
96
|
+
/** Whether this row/column contains or is the active cell */
|
|
97
|
+
isActive: boolean;
|
|
98
|
+
/** Whether this row/column/cell overlaps or is in the selection range */
|
|
99
|
+
isSelected: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Grid-level highlighting options.
|
|
103
|
+
* Hover tracking is automatically enabled when any highlighting callback is defined.
|
|
104
|
+
* Each callback type has its own natural interpretation of `isHovered`:
|
|
105
|
+
* - computeRowClasses: isHovered = mouse is on any cell in this row
|
|
106
|
+
* - computeColumnClasses: isHovered = mouse is on any cell in this column
|
|
107
|
+
* - computeCellClasses: isHovered = mouse is on this exact cell
|
|
108
|
+
*
|
|
109
|
+
* For a crosshair effect, implement both computeRowClasses and computeColumnClasses.
|
|
110
|
+
*/
|
|
111
|
+
interface HighlightingOptions<TData = Record<string, unknown>> {
|
|
112
|
+
/**
|
|
113
|
+
* Row-level class callback.
|
|
114
|
+
* Classes returned are applied to the row container element.
|
|
115
|
+
* Context has `rowIndex` set, `colIndex` is null.
|
|
116
|
+
* `isHovered` is true when the mouse is on any cell in this row.
|
|
117
|
+
* @returns Array of CSS class names
|
|
118
|
+
*/
|
|
119
|
+
computeRowClasses?: (context: HighlightContext<TData>) => string[];
|
|
120
|
+
/**
|
|
121
|
+
* Column-level class callback.
|
|
122
|
+
* Classes returned are applied to all cells in that column (not header).
|
|
123
|
+
* Context has `colIndex` set, `rowIndex` is null.
|
|
124
|
+
* `isHovered` is true when the mouse is on any cell in this column.
|
|
125
|
+
* @returns Array of CSS class names
|
|
126
|
+
*/
|
|
127
|
+
computeColumnClasses?: (context: HighlightContext<TData>) => string[];
|
|
128
|
+
/**
|
|
129
|
+
* Cell-level class callback.
|
|
130
|
+
* Classes returned are applied to individual cells for fine-grained control.
|
|
131
|
+
* Context has both `rowIndex` and `colIndex` set.
|
|
132
|
+
* `isHovered` is true only when the mouse is on this exact cell.
|
|
133
|
+
* @returns Array of CSS class names
|
|
134
|
+
*/
|
|
135
|
+
computeCellClasses?: (context: HighlightContext<TData>) => string[];
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
63
138
|
//#region ../core/src/types/columns.d.ts
|
|
64
139
|
/** Column definition */
|
|
65
140
|
interface ColumnDefinition {
|
|
@@ -73,10 +148,26 @@ interface ColumnDefinition {
|
|
|
73
148
|
sortable?: boolean;
|
|
74
149
|
/** Whether column is filterable. Default: true */
|
|
75
150
|
filterable?: boolean;
|
|
151
|
+
/** Whether column is hidden. Hidden columns are not rendered but still exist in the definition. Default: false */
|
|
152
|
+
hidden?: boolean;
|
|
76
153
|
/** Renderer key for adapter lookup, or inline renderer function */
|
|
77
154
|
cellRenderer?: string;
|
|
78
155
|
editRenderer?: string;
|
|
79
156
|
headerRenderer?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Per-column override for column-level highlighting.
|
|
159
|
+
* If defined, overrides grid-level computeColumnClasses for this column.
|
|
160
|
+
* Context has `colIndex` set, `rowIndex` is null.
|
|
161
|
+
* @returns Array of CSS class names to apply to all cells in this column
|
|
162
|
+
*/
|
|
163
|
+
computeColumnClasses?: (context: HighlightContext) => string[];
|
|
164
|
+
/**
|
|
165
|
+
* Per-column override for cell-level highlighting.
|
|
166
|
+
* If defined, overrides grid-level computeCellClasses for cells in this column.
|
|
167
|
+
* Context has both `rowIndex` and `colIndex` set.
|
|
168
|
+
* @returns Array of CSS class names to apply to individual cells
|
|
169
|
+
*/
|
|
170
|
+
computeCellClasses?: (context: HighlightContext) => string[];
|
|
80
171
|
}
|
|
81
172
|
//#endregion
|
|
82
173
|
//#region ../core/src/types/filters.d.ts
|
|
@@ -188,6 +279,11 @@ interface SetActiveCellInstruction {
|
|
|
188
279
|
type: "SET_ACTIVE_CELL";
|
|
189
280
|
position: CellPosition | null;
|
|
190
281
|
}
|
|
282
|
+
/** Set hover position instruction (for highlighting) */
|
|
283
|
+
interface SetHoverPositionInstruction {
|
|
284
|
+
type: "SET_HOVER_POSITION";
|
|
285
|
+
position: CellPosition | null;
|
|
286
|
+
}
|
|
191
287
|
/** Set selection range instruction */
|
|
192
288
|
interface SetSelectionRangeInstruction {
|
|
193
289
|
type: "SET_SELECTION_RANGE";
|
|
@@ -297,19 +393,20 @@ interface DataErrorInstruction {
|
|
|
297
393
|
/** Rows added instruction */
|
|
298
394
|
interface RowsAddedInstruction {
|
|
299
395
|
type: "ROWS_ADDED";
|
|
396
|
+
indices: number[];
|
|
300
397
|
count: number;
|
|
301
398
|
totalRows: number;
|
|
302
399
|
}
|
|
303
400
|
/** Rows removed instruction */
|
|
304
401
|
interface RowsRemovedInstruction {
|
|
305
402
|
type: "ROWS_REMOVED";
|
|
306
|
-
|
|
403
|
+
indices: number[];
|
|
307
404
|
totalRows: number;
|
|
308
405
|
}
|
|
309
406
|
/** Rows updated instruction */
|
|
310
407
|
interface RowsUpdatedInstruction {
|
|
311
408
|
type: "ROWS_UPDATED";
|
|
312
|
-
|
|
409
|
+
indices: number[];
|
|
313
410
|
}
|
|
314
411
|
/** Transaction processed instruction */
|
|
315
412
|
interface TransactionProcessedInstruction {
|
|
@@ -322,6 +419,7 @@ interface TransactionProcessedInstruction {
|
|
|
322
419
|
type GridInstruction = /** Slot lifecycle */
|
|
323
420
|
CreateSlotInstruction | DestroySlotInstruction | AssignSlotInstruction | MoveSlotInstruction
|
|
324
421
|
/** Selection */ | SetActiveCellInstruction | SetSelectionRangeInstruction | UpdateVisibleRangeInstruction
|
|
422
|
+
/** Highlighting */ | SetHoverPositionInstruction
|
|
325
423
|
/** Editing */ | StartEditInstruction | StopEditInstruction | CommitEditInstruction
|
|
326
424
|
/** Layout */ | SetContentSizeInstruction | UpdateHeaderInstruction
|
|
327
425
|
/** Filter popup */ | OpenFilterPopupInstruction | CloseFilterPopupInstruction
|
|
@@ -330,8 +428,6 @@ CreateSlotInstruction | DestroySlotInstruction | AssignSlotInstruction | MoveSlo
|
|
|
330
428
|
/** Transactions */ | RowsAddedInstruction | RowsRemovedInstruction | RowsUpdatedInstruction | TransactionProcessedInstruction;
|
|
331
429
|
/** Instruction listener: Single instruction Listener that receives a single instruction, used by frameworks to update their state */
|
|
332
430
|
type InstructionListener = (instruction: GridInstruction) => void;
|
|
333
|
-
/** Batch instruction listener: Batch instruction Listener that receives an array of instructions, used by frameworks to update their state */
|
|
334
|
-
type BatchInstructionListener = (instructions: GridInstruction[]) => void;
|
|
335
431
|
//#endregion
|
|
336
432
|
//#region ../core/src/types/renderers.d.ts
|
|
337
433
|
/** Cell renderer params */
|
|
@@ -405,6 +501,8 @@ interface GridCoreOptions<TData = Row> {
|
|
|
405
501
|
transactionDebounceMs?: number;
|
|
406
502
|
/** Function to extract unique ID from row. Required for mutations. */
|
|
407
503
|
getRowId?: (row: TData) => RowId;
|
|
504
|
+
/** Row/column/cell highlighting configuration */
|
|
505
|
+
highlighting?: HighlightingOptions<TData>;
|
|
408
506
|
}
|
|
409
507
|
//#endregion
|
|
410
508
|
//#region ../core/src/types/input.d.ts
|
|
@@ -485,10 +583,16 @@ interface InputHandlerDeps {
|
|
|
485
583
|
getHeaderHeight: () => number;
|
|
486
584
|
/** Get row height */
|
|
487
585
|
getRowHeight: () => number;
|
|
488
|
-
/** Get column positions array */
|
|
586
|
+
/** Get column positions array (indexed by visible column) */
|
|
489
587
|
getColumnPositions: () => number[];
|
|
490
|
-
/** Get column count */
|
|
588
|
+
/** Get visible column count */
|
|
491
589
|
getColumnCount: () => number;
|
|
590
|
+
/**
|
|
591
|
+
* Convert visible column index to original column index.
|
|
592
|
+
* Used when columns can be hidden. Returns the original index for selection tracking.
|
|
593
|
+
* If not provided, visible index is used directly (no hidden columns).
|
|
594
|
+
*/
|
|
595
|
+
getOriginalColumnIndex?: (visibleIndex: number) => number;
|
|
492
596
|
}
|
|
493
597
|
/** Current drag state for UI rendering */
|
|
494
598
|
interface DragState {
|
|
@@ -505,6 +609,12 @@ interface DragState {
|
|
|
505
609
|
} | null;
|
|
506
610
|
}
|
|
507
611
|
//#endregion
|
|
612
|
+
//#region ../core/src/utils/event-emitter.d.ts
|
|
613
|
+
/**
|
|
614
|
+
* Batch instruction listener for efficient state updates
|
|
615
|
+
*/
|
|
616
|
+
type BatchInstructionListener = (instructions: GridInstruction[]) => void;
|
|
617
|
+
//#endregion
|
|
508
618
|
//#region ../core/src/selection.d.ts
|
|
509
619
|
type Direction = "up" | "down" | "left" | "right";
|
|
510
620
|
interface SelectionManagerOptions {
|
|
@@ -520,10 +630,10 @@ interface SelectionManagerOptions {
|
|
|
520
630
|
declare class SelectionManager {
|
|
521
631
|
private state;
|
|
522
632
|
private options;
|
|
523
|
-
private
|
|
524
|
-
|
|
525
|
-
onInstruction(listener: InstructionListener): () => void;
|
|
633
|
+
private emitter;
|
|
634
|
+
onInstruction: (listener: InstructionListener) => () => void;
|
|
526
635
|
private emit;
|
|
636
|
+
constructor(options: SelectionManagerOptions);
|
|
527
637
|
getState(): SelectionState;
|
|
528
638
|
getActiveCell(): CellPosition | null;
|
|
529
639
|
getSelectionRange(): CellRange | null;
|
|
@@ -588,10 +698,10 @@ interface FillManagerOptions {
|
|
|
588
698
|
declare class FillManager {
|
|
589
699
|
private state;
|
|
590
700
|
private options;
|
|
591
|
-
private
|
|
592
|
-
|
|
593
|
-
onInstruction(listener: InstructionListener): () => void;
|
|
701
|
+
private emitter;
|
|
702
|
+
onInstruction: (listener: InstructionListener) => () => void;
|
|
594
703
|
private emit;
|
|
704
|
+
constructor(options: FillManagerOptions);
|
|
595
705
|
getState(): FillHandleState | null;
|
|
596
706
|
isActive(): boolean;
|
|
597
707
|
/**
|
|
@@ -648,6 +758,14 @@ declare class InputHandler<TData extends Row = Row> {
|
|
|
648
758
|
* Handle cell double click event (start editing)
|
|
649
759
|
*/
|
|
650
760
|
handleCellDoubleClick(rowIndex: number, colIndex: number): void;
|
|
761
|
+
/**
|
|
762
|
+
* Handle cell mouse enter event (for hover highlighting)
|
|
763
|
+
*/
|
|
764
|
+
handleCellMouseEnter(rowIndex: number, colIndex: number): void;
|
|
765
|
+
/**
|
|
766
|
+
* Handle cell mouse leave event (for hover highlighting)
|
|
767
|
+
*/
|
|
768
|
+
handleCellMouseLeave(): void;
|
|
651
769
|
/**
|
|
652
770
|
* Handle fill handle mouse down event
|
|
653
771
|
*/
|
|
@@ -683,16 +801,222 @@ declare class InputHandler<TData extends Row = Row> {
|
|
|
683
801
|
row: number;
|
|
684
802
|
col: number;
|
|
685
803
|
} | null, filterPopupOpen: boolean): KeyboardResult;
|
|
686
|
-
/**
|
|
687
|
-
* Find column index at a given X coordinate
|
|
688
|
-
*/
|
|
689
|
-
private findColumnAtX;
|
|
690
804
|
/**
|
|
691
805
|
* Calculate auto-scroll deltas based on mouse position
|
|
692
806
|
*/
|
|
693
807
|
private calculateAutoScroll;
|
|
694
808
|
}
|
|
695
809
|
//#endregion
|
|
810
|
+
//#region ../core/src/highlight-manager.d.ts
|
|
811
|
+
interface HighlightManagerOptions {
|
|
812
|
+
getActiveCell: () => CellPosition | null;
|
|
813
|
+
getSelectionRange: () => CellRange | null;
|
|
814
|
+
getColumn: (colIndex: number) => ColumnDefinition | undefined;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Manages row/column/cell highlighting state and class computation.
|
|
818
|
+
* Emits SET_HOVER_POSITION instructions when hover position changes.
|
|
819
|
+
*/
|
|
820
|
+
declare class HighlightManager<TData = Record<string, unknown>> {
|
|
821
|
+
private options;
|
|
822
|
+
private highlightingOptions;
|
|
823
|
+
private hoverPosition;
|
|
824
|
+
private emitter;
|
|
825
|
+
onInstruction: (listener: InstructionListener) => () => void;
|
|
826
|
+
private emit;
|
|
827
|
+
private rowClassCache;
|
|
828
|
+
private columnClassCache;
|
|
829
|
+
private cellClassCache;
|
|
830
|
+
constructor(options: HighlightManagerOptions, highlightingOptions?: HighlightingOptions<TData>);
|
|
831
|
+
/**
|
|
832
|
+
* Check if highlighting is enabled (any callback defined).
|
|
833
|
+
* Hover tracking is automatically enabled when highlighting is enabled.
|
|
834
|
+
*/
|
|
835
|
+
isEnabled(): boolean;
|
|
836
|
+
/**
|
|
837
|
+
* Set the current hover position. Clears caches and emits instruction.
|
|
838
|
+
* Hover tracking is automatically enabled when any highlighting callback is defined.
|
|
839
|
+
*/
|
|
840
|
+
setHoverPosition(position: CellPosition | null): void;
|
|
841
|
+
/**
|
|
842
|
+
* Get the current hover position
|
|
843
|
+
*/
|
|
844
|
+
getHoverPosition(): CellPosition | null;
|
|
845
|
+
/**
|
|
846
|
+
* Called when selection changes. Clears all caches.
|
|
847
|
+
*/
|
|
848
|
+
onSelectionChange(): void;
|
|
849
|
+
/**
|
|
850
|
+
* Build context for row highlighting callback.
|
|
851
|
+
* Returns context with `rowIndex` set, `colIndex` is null.
|
|
852
|
+
* `isHovered` is true when the mouse is on any cell in this row.
|
|
853
|
+
*/
|
|
854
|
+
buildRowContext(rowIndex: number, rowData?: TData): HighlightContext<TData>;
|
|
855
|
+
/**
|
|
856
|
+
* Build context for column highlighting callback.
|
|
857
|
+
* Returns context with `colIndex` set, `rowIndex` is null.
|
|
858
|
+
* `isHovered` is true when the mouse is on any cell in this column.
|
|
859
|
+
*/
|
|
860
|
+
buildColumnContext(colIndex: number, column: ColumnDefinition): HighlightContext<TData>;
|
|
861
|
+
/**
|
|
862
|
+
* Build context for cell highlighting callback.
|
|
863
|
+
* Returns context with both `rowIndex` and `colIndex` set.
|
|
864
|
+
* `isHovered` is true only when the mouse is on this exact cell.
|
|
865
|
+
*/
|
|
866
|
+
buildCellContext(rowIndex: number, colIndex: number, column: ColumnDefinition, rowData?: TData): HighlightContext<TData>;
|
|
867
|
+
/**
|
|
868
|
+
* Compute row classes using cache and user callback
|
|
869
|
+
*/
|
|
870
|
+
computeRowClasses(rowIndex: number, rowData?: TData): string[];
|
|
871
|
+
/**
|
|
872
|
+
* Compute column classes using cache and user callback (or per-column override)
|
|
873
|
+
*/
|
|
874
|
+
computeColumnClasses(colIndex: number, column: ColumnDefinition): string[];
|
|
875
|
+
/**
|
|
876
|
+
* Compute cell classes using cache and user callback (or per-column override)
|
|
877
|
+
*/
|
|
878
|
+
computeCellClasses(rowIndex: number, colIndex: number, column: ColumnDefinition, rowData?: TData): string[];
|
|
879
|
+
/**
|
|
880
|
+
* Compute combined cell classes (column + cell classes flattened)
|
|
881
|
+
*/
|
|
882
|
+
computeCombinedCellClasses(rowIndex: number, colIndex: number, column: ColumnDefinition, rowData?: TData): string[];
|
|
883
|
+
/**
|
|
884
|
+
* Clear all caches
|
|
885
|
+
*/
|
|
886
|
+
clearAllCaches(): void;
|
|
887
|
+
/**
|
|
888
|
+
* Destroy the manager and release resources
|
|
889
|
+
*/
|
|
890
|
+
destroy(): void;
|
|
891
|
+
}
|
|
892
|
+
//#endregion
|
|
893
|
+
//#region ../core/src/sort-filter-manager.d.ts
|
|
894
|
+
interface SortFilterManagerOptions<TData> {
|
|
895
|
+
/** Get all columns */
|
|
896
|
+
getColumns: () => ColumnDefinition[];
|
|
897
|
+
/** Check if sorting is enabled globally */
|
|
898
|
+
isSortingEnabled: () => boolean;
|
|
899
|
+
/** Get cached rows for distinct value computation */
|
|
900
|
+
getCachedRows: () => Map<number, TData>;
|
|
901
|
+
/** Called when sort/filter changes to trigger data refresh */
|
|
902
|
+
onSortFilterChange: () => Promise<void>;
|
|
903
|
+
/** Called after data refresh to update UI */
|
|
904
|
+
onDataRefreshed: () => void;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Manages sorting and filtering state and operations.
|
|
908
|
+
*/
|
|
909
|
+
declare class SortFilterManager<TData = Record<string, unknown>> {
|
|
910
|
+
private options;
|
|
911
|
+
private emitter;
|
|
912
|
+
private sortModel;
|
|
913
|
+
private filterModel;
|
|
914
|
+
private openFilterColIndex;
|
|
915
|
+
onInstruction: (listener: InstructionListener) => () => void;
|
|
916
|
+
private emit;
|
|
917
|
+
constructor(options: SortFilterManagerOptions<TData>);
|
|
918
|
+
setSort(colId: string, direction: SortDirection | null, addToExisting?: boolean): Promise<void>;
|
|
919
|
+
getSortModel(): SortModel[];
|
|
920
|
+
setFilter(colId: string, filter: ColumnFilterModel | string | null): Promise<void>;
|
|
921
|
+
getFilterModel(): FilterModel;
|
|
922
|
+
/**
|
|
923
|
+
* Check if a column has an active filter
|
|
924
|
+
*/
|
|
925
|
+
hasActiveFilter(colId: string): boolean;
|
|
926
|
+
/**
|
|
927
|
+
* Check if a column is sortable
|
|
928
|
+
*/
|
|
929
|
+
isColumnSortable(colIndex: number): boolean;
|
|
930
|
+
/**
|
|
931
|
+
* Check if a column is filterable
|
|
932
|
+
*/
|
|
933
|
+
isColumnFilterable(colIndex: number): boolean;
|
|
934
|
+
/**
|
|
935
|
+
* Get distinct values for a column (for filter dropdowns)
|
|
936
|
+
* For array-type columns (like tags), each unique array combination is returned.
|
|
937
|
+
* Arrays are sorted internally for consistent comparison.
|
|
938
|
+
* Limited to maxValues to avoid performance issues with large datasets.
|
|
939
|
+
*/
|
|
940
|
+
getDistinctValuesForColumn(colId: string, maxValues?: number): CellValue[];
|
|
941
|
+
/**
|
|
942
|
+
* Open filter popup for a column (toggles if already open for same column)
|
|
943
|
+
*/
|
|
944
|
+
openFilterPopup(colIndex: number, anchorRect: {
|
|
945
|
+
top: number;
|
|
946
|
+
left: number;
|
|
947
|
+
width: number;
|
|
948
|
+
height: number;
|
|
949
|
+
}): void;
|
|
950
|
+
/**
|
|
951
|
+
* Close filter popup
|
|
952
|
+
*/
|
|
953
|
+
closeFilterPopup(): void;
|
|
954
|
+
/**
|
|
955
|
+
* Get sort info map for header rendering
|
|
956
|
+
*/
|
|
957
|
+
getSortInfoMap(): Map<string, {
|
|
958
|
+
direction: SortDirection;
|
|
959
|
+
index: number;
|
|
960
|
+
}>;
|
|
961
|
+
destroy(): void;
|
|
962
|
+
}
|
|
963
|
+
//#endregion
|
|
964
|
+
//#region ../core/src/row-mutation-manager.d.ts
|
|
965
|
+
interface RowMutationManagerOptions<TData> {
|
|
966
|
+
/** Get the cached rows map */
|
|
967
|
+
getCachedRows: () => Map<number, TData>;
|
|
968
|
+
/** Set the cached rows map (for bulk operations) */
|
|
969
|
+
setCachedRows: (rows: Map<number, TData>) => void;
|
|
970
|
+
/** Get total row count */
|
|
971
|
+
getTotalRows: () => number;
|
|
972
|
+
/** Set total row count */
|
|
973
|
+
setTotalRows: (count: number) => void;
|
|
974
|
+
/** Update a single slot after row change */
|
|
975
|
+
updateSlot: (rowIndex: number) => void;
|
|
976
|
+
/** Refresh all slots after bulk changes */
|
|
977
|
+
refreshAllSlots: () => void;
|
|
978
|
+
/** Emit content size change */
|
|
979
|
+
emitContentSize: () => void;
|
|
980
|
+
/** Clear selection if it references invalid rows */
|
|
981
|
+
clearSelectionIfInvalid: (maxValidRow: number) => void;
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Manages row CRUD operations and cache management.
|
|
985
|
+
*/
|
|
986
|
+
declare class RowMutationManager<TData extends Row = Row> {
|
|
987
|
+
private options;
|
|
988
|
+
private emitter;
|
|
989
|
+
onInstruction: (listener: InstructionListener) => () => void;
|
|
990
|
+
private emit;
|
|
991
|
+
constructor(options: RowMutationManagerOptions<TData>);
|
|
992
|
+
/**
|
|
993
|
+
* Get a row by index.
|
|
994
|
+
*/
|
|
995
|
+
getRow(index: number): TData | undefined;
|
|
996
|
+
/**
|
|
997
|
+
* Add rows to the grid at the specified index.
|
|
998
|
+
* If no index is provided, rows are added at the end.
|
|
999
|
+
*/
|
|
1000
|
+
addRows(rows: TData[], index?: number): void;
|
|
1001
|
+
/**
|
|
1002
|
+
* Update existing rows with partial data.
|
|
1003
|
+
*/
|
|
1004
|
+
updateRows(updates: Array<{
|
|
1005
|
+
index: number;
|
|
1006
|
+
data: Partial<TData>;
|
|
1007
|
+
}>): void;
|
|
1008
|
+
/**
|
|
1009
|
+
* Delete rows at the specified indices.
|
|
1010
|
+
*/
|
|
1011
|
+
deleteRows(indices: number[]): void;
|
|
1012
|
+
/**
|
|
1013
|
+
* Set a complete row at the specified index.
|
|
1014
|
+
* Use this for complete row replacement. For partial updates, use updateRows.
|
|
1015
|
+
*/
|
|
1016
|
+
setRow(index: number, data: TData): void;
|
|
1017
|
+
destroy(): void;
|
|
1018
|
+
}
|
|
1019
|
+
//#endregion
|
|
696
1020
|
//#region ../core/src/grid-core.d.ts
|
|
697
1021
|
declare class GridCore<TData extends Row = Row> {
|
|
698
1022
|
private columns;
|
|
@@ -709,29 +1033,25 @@ declare class GridCore<TData extends Row = Row> {
|
|
|
709
1033
|
private totalRows;
|
|
710
1034
|
private currentPageIndex;
|
|
711
1035
|
private pageSize;
|
|
712
|
-
private sortModel;
|
|
713
|
-
private filterModel;
|
|
714
|
-
private openFilterColIndex;
|
|
715
1036
|
readonly selection: SelectionManager;
|
|
716
1037
|
readonly fill: FillManager;
|
|
717
1038
|
readonly input: InputHandler<TData>;
|
|
1039
|
+
readonly highlight: HighlightManager<TData> | null;
|
|
1040
|
+
readonly sortFilter: SortFilterManager<TData>;
|
|
1041
|
+
readonly rowMutation: RowMutationManager<TData>;
|
|
718
1042
|
private readonly slotPool;
|
|
719
1043
|
private readonly editManager;
|
|
720
1044
|
private columnPositions;
|
|
721
|
-
private
|
|
722
|
-
|
|
1045
|
+
private emitter;
|
|
1046
|
+
onInstruction: (listener: InstructionListener) => () => void;
|
|
1047
|
+
onBatchInstruction: (listener: BatchInstructionListener) => () => void;
|
|
1048
|
+
private emit;
|
|
1049
|
+
private emitBatch;
|
|
723
1050
|
private naturalContentHeight;
|
|
724
1051
|
private virtualContentHeight;
|
|
725
1052
|
private scrollRatio;
|
|
1053
|
+
private isDestroyed;
|
|
726
1054
|
constructor(options: GridCoreOptions<TData>);
|
|
727
|
-
onInstruction(listener: InstructionListener): () => void;
|
|
728
|
-
/**
|
|
729
|
-
* Subscribe to batched instructions for efficient React state updates.
|
|
730
|
-
* Batch listeners receive arrays of instructions instead of individual ones.
|
|
731
|
-
*/
|
|
732
|
-
onBatchInstruction(listener: BatchInstructionListener): () => void;
|
|
733
|
-
private emit;
|
|
734
|
-
private emitBatch;
|
|
735
1055
|
/**
|
|
736
1056
|
* Initialize the grid and load initial data.
|
|
737
1057
|
*/
|
|
@@ -745,37 +1065,16 @@ declare class GridCore<TData extends Row = Row> {
|
|
|
745
1065
|
private fetchAllData;
|
|
746
1066
|
setSort(colId: string, direction: SortDirection | null, addToExisting?: boolean): Promise<void>;
|
|
747
1067
|
setFilter(colId: string, filter: ColumnFilterModel | string | null): Promise<void>;
|
|
748
|
-
/**
|
|
749
|
-
* Check if a column has an active filter
|
|
750
|
-
*/
|
|
751
1068
|
hasActiveFilter(colId: string): boolean;
|
|
752
|
-
/**
|
|
753
|
-
* Check if a column is sortable
|
|
754
|
-
*/
|
|
755
1069
|
isColumnSortable(colIndex: number): boolean;
|
|
756
|
-
/**
|
|
757
|
-
* Check if a column is filterable
|
|
758
|
-
*/
|
|
759
1070
|
isColumnFilterable(colIndex: number): boolean;
|
|
760
|
-
/**
|
|
761
|
-
* Get distinct values for a column (for filter dropdowns)
|
|
762
|
-
* For array-type columns (like tags), each unique array combination is returned.
|
|
763
|
-
* Arrays are sorted internally for consistent comparison.
|
|
764
|
-
* Limited to MAX_DISTINCT_VALUES to avoid performance issues with large datasets.
|
|
765
|
-
*/
|
|
766
1071
|
getDistinctValuesForColumn(colId: string, maxValues?: number): CellValue[];
|
|
767
|
-
/**
|
|
768
|
-
* Open filter popup for a column (toggles if already open for same column)
|
|
769
|
-
*/
|
|
770
1072
|
openFilterPopup(colIndex: number, anchorRect: {
|
|
771
1073
|
top: number;
|
|
772
1074
|
left: number;
|
|
773
1075
|
width: number;
|
|
774
1076
|
height: number;
|
|
775
1077
|
}): void;
|
|
776
|
-
/**
|
|
777
|
-
* Close filter popup
|
|
778
|
-
*/
|
|
779
1078
|
closeFilterPopup(): void;
|
|
780
1079
|
getSortModel(): SortModel[];
|
|
781
1080
|
getFilterModel(): FilterModel;
|
|
@@ -786,8 +1085,6 @@ declare class GridCore<TData extends Row = Row> {
|
|
|
786
1085
|
getEditState(): EditState | null;
|
|
787
1086
|
getCellValue(row: number, col: number): CellValue;
|
|
788
1087
|
setCellValue(row: number, col: number, value: CellValue): void;
|
|
789
|
-
private getFieldValue;
|
|
790
|
-
private setFieldValue;
|
|
791
1088
|
private computeColumnPositions;
|
|
792
1089
|
private emitContentSize;
|
|
793
1090
|
private emitHeaders;
|
|
@@ -844,6 +1141,31 @@ declare class GridCore<TData extends Row = Row> {
|
|
|
844
1141
|
* Useful after in-place data modifications like fill operations.
|
|
845
1142
|
*/
|
|
846
1143
|
refreshSlotData(): void;
|
|
1144
|
+
/**
|
|
1145
|
+
* Add rows to the grid at the specified index.
|
|
1146
|
+
* If no index is provided, rows are added at the end.
|
|
1147
|
+
*/
|
|
1148
|
+
addRows(rows: TData[], index?: number): void;
|
|
1149
|
+
/**
|
|
1150
|
+
* Update existing rows with partial data.
|
|
1151
|
+
*/
|
|
1152
|
+
updateRows(updates: Array<{
|
|
1153
|
+
index: number;
|
|
1154
|
+
data: Partial<TData>;
|
|
1155
|
+
}>): void;
|
|
1156
|
+
/**
|
|
1157
|
+
* Delete rows at the specified indices.
|
|
1158
|
+
*/
|
|
1159
|
+
deleteRows(indices: number[]): void;
|
|
1160
|
+
/**
|
|
1161
|
+
* Get a row by index.
|
|
1162
|
+
*/
|
|
1163
|
+
getRow(index: number): TData | undefined;
|
|
1164
|
+
/**
|
|
1165
|
+
* Set a complete row at the specified index.
|
|
1166
|
+
* Use this for complete row replacement. For partial updates, use updateRows.
|
|
1167
|
+
*/
|
|
1168
|
+
setRow(index: number, data: TData): void;
|
|
847
1169
|
/**
|
|
848
1170
|
* Update the data source and refresh.
|
|
849
1171
|
*/
|
|
@@ -852,6 +1174,22 @@ declare class GridCore<TData extends Row = Row> {
|
|
|
852
1174
|
* Update columns and recompute layout.
|
|
853
1175
|
*/
|
|
854
1176
|
setColumns(columns: ColumnDefinition[]): void;
|
|
1177
|
+
/**
|
|
1178
|
+
* Destroy the grid core and release all references.
|
|
1179
|
+
* Call this before discarding the GridCore to ensure proper cleanup.
|
|
1180
|
+
* This method is idempotent - safe to call multiple times.
|
|
1181
|
+
*/
|
|
1182
|
+
destroy(): void;
|
|
1183
|
+
}
|
|
1184
|
+
//#endregion
|
|
1185
|
+
//#region ../core/src/sorting/parallel-sort-manager.d.ts
|
|
1186
|
+
interface ParallelSortOptions {
|
|
1187
|
+
/** Maximum number of workers (default: navigator.hardwareConcurrency || 4) */
|
|
1188
|
+
maxWorkers?: number;
|
|
1189
|
+
/** Threshold for parallel sorting (default: 400000) */
|
|
1190
|
+
parallelThreshold?: number;
|
|
1191
|
+
/** Minimum chunk size (default: 50000) */
|
|
1192
|
+
minChunkSize?: number;
|
|
855
1193
|
}
|
|
856
1194
|
//#endregion
|
|
857
1195
|
//#region ../core/src/data-source/client-data-source.d.ts
|
|
@@ -860,6 +1198,8 @@ interface ClientDataSourceOptions<TData> {
|
|
|
860
1198
|
getFieldValue?: (row: TData, field: string) => CellValue;
|
|
861
1199
|
/** Use Web Worker for sorting large datasets (default: true) */
|
|
862
1200
|
useWorker?: boolean;
|
|
1201
|
+
/** Options for parallel sorting (only used when useWorker is true) */
|
|
1202
|
+
parallelSort?: ParallelSortOptions | false;
|
|
863
1203
|
}
|
|
864
1204
|
/**
|
|
865
1205
|
* Creates a client-side data source that holds all data in memory.
|
|
@@ -985,6 +1325,8 @@ interface GridProps<TData extends Row = Row> {
|
|
|
985
1325
|
initialHeight?: number;
|
|
986
1326
|
/** Optional ref to access GridCore API */
|
|
987
1327
|
gridRef?: React.MutableRefObject<GridRef<TData> | null>;
|
|
1328
|
+
/** Row/column/cell highlighting configuration */
|
|
1329
|
+
highlighting?: HighlightingOptions<TData>;
|
|
988
1330
|
}
|
|
989
1331
|
//#endregion
|
|
990
1332
|
//#region src/Grid.d.ts
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e,{useCallback as t,useEffect as n,useMemo as r,useReducer as i,useRef as a,useState as o}from"react";import{GridCore as s,GridCore as c,buildCellClasses as l,calculateScaledColumnPositions as u,createClientDataSource as d,createClientDataSource as f,createDataSourceFromArray as p,createDataSourceFromArray as m,createMutableClientDataSource as h,createServerDataSource as g,getTotalWidth as _,injectStyles as v,isCellActive as y,isCellEditing as b,isCellInFillPreview as x,isCellSelected as S}from"gp-grid-core";import{Fragment as C,jsx as w,jsxs as T}from"react/jsx-runtime";const E=[{value:`contains`,label:`Contains`},{value:`notContains`,label:`Does not contain`},{value:`equals`,label:`Equals`},{value:`notEquals`,label:`Does not equal`},{value:`startsWith`,label:`Starts with`},{value:`endsWith`,label:`Ends with`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Is not blank`}];function D({distinctValues:e,currentFilter:n,onApply:i,onClose:a}){let s=t(e=>Array.isArray(e)?e.join(`, `):String(e??``),[]),c=r(()=>{let t=e.filter(e=>e!=null&&e!==``&&!(Array.isArray(e)&&e.length===0)).map(e=>s(e));return Array.from(new Set(t)).sort((e,t)=>{let n=parseFloat(e),r=parseFloat(t);return!isNaN(n)&&!isNaN(r)?n-r:e.localeCompare(t,void 0,{numeric:!0,sensitivity:`base`})})},[e,s]),l=c.length>100,[u,d]=o(r(()=>{if(!n?.conditions[0])return l?`condition`:`values`;let e=n.conditions[0];return e.selectedValues&&e.selectedValues.size>0?`values`:`condition`},[n,l])),f=r(()=>n?.conditions[0]?n.conditions[0].selectedValues??new Set:new Set,[n]),p=r(()=>n?.conditions[0]?n.conditions[0].includeBlank??!0:!0,[n]),[m,h]=o(``),[g,_]=o(f),[v,y]=o(p),[b,x]=o(r(()=>{if(!n?.conditions.length)return[{operator:`contains`,value:``,nextOperator:`and`}];let e=n.conditions[0];if(e.selectedValues&&e.selectedValues.size>0)return[{operator:`contains`,value:``,nextOperator:`and`}];let t=n.combination??`and`;return n.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value??``,nextOperator:n.nextOperator??t}})},[n])),S=r(()=>{if(!m)return c;let e=m.toLowerCase();return c.filter(t=>t.toLowerCase().includes(e))},[c,m]),D=r(()=>e.some(e=>e==null||e===``),[e]),O=r(()=>S.every(e=>g.has(e))&&(!D||v),[S,g,D,v]),k=t(()=>{_(new Set(S)),D&&y(!0)},[S,D]),A=t(()=>{_(new Set),y(!1)},[]),j=t(e=>{_(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),M=t((e,t)=>{x(n=>{let r=[...n];return r[e]={...r[e],...t},r})},[]),N=t(()=>{x(e=>[...e,{operator:`contains`,value:``,nextOperator:`and`}])},[]),P=t(e=>{x(t=>t.filter((t,n)=>n!==e))},[]),F=t(()=>{if(u===`values`){if(c.every(e=>g.has(e))&&(!D||v)){i(null);return}i({conditions:[{type:`text`,operator:`equals`,selectedValues:g,includeBlank:v}],combination:`and`})}else{let e=b.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.value.trim()!==``);if(e.length===0){i(null);return}i({conditions:e.map(e=>({type:`text`,operator:e.operator,value:e.value,nextOperator:e.nextOperator})),combination:`and`})}},[u,c,g,v,D,b,i]),I=t(()=>{i(null)},[i]);return T(`div`,{className:`gp-grid-filter-content gp-grid-filter-text`,children:[!l&&T(`div`,{className:`gp-grid-filter-mode-toggle`,children:[w(`button`,{type:`button`,className:u===`values`?`active`:``,onClick:()=>d(`values`),children:`Values`}),w(`button`,{type:`button`,className:u===`condition`?`active`:``,onClick:()=>d(`condition`),children:`Condition`})]}),l&&u===`condition`&&T(`div`,{className:`gp-grid-filter-info`,children:[`Too many unique values (`,c.length,`). Use conditions to filter.`]}),u===`values`&&T(C,{children:[w(`input`,{className:`gp-grid-filter-search`,type:`text`,placeholder:`Search...`,value:m,onChange:e=>h(e.target.value),autoFocus:!0}),T(`div`,{className:`gp-grid-filter-actions`,children:[w(`button`,{type:`button`,onClick:k,disabled:O,children:`Select All`}),w(`button`,{type:`button`,onClick:A,children:`Deselect All`})]}),T(`div`,{className:`gp-grid-filter-list`,children:[D&&T(`label`,{className:`gp-grid-filter-option`,children:[w(`input`,{type:`checkbox`,checked:v,onChange:()=>y(!v)}),w(`span`,{className:`gp-grid-filter-blank`,children:`(Blanks)`})]}),S.map(e=>T(`label`,{className:`gp-grid-filter-option`,children:[w(`input`,{type:`checkbox`,checked:g.has(e),onChange:()=>j(e)}),w(`span`,{children:e})]},e))]})]}),u===`condition`&&T(C,{children:[b.map((e,t)=>T(`div`,{className:`gp-grid-filter-condition`,children:[t>0&&T(`div`,{className:`gp-grid-filter-combination`,children:[w(`button`,{type:`button`,className:b[t-1]?.nextOperator===`and`?`active`:``,onClick:()=>M(t-1,{nextOperator:`and`}),children:`AND`}),w(`button`,{type:`button`,className:b[t-1]?.nextOperator===`or`?`active`:``,onClick:()=>M(t-1,{nextOperator:`or`}),children:`OR`})]}),T(`div`,{className:`gp-grid-filter-row`,children:[w(`select`,{value:e.operator,onChange:e=>M(t,{operator:e.target.value}),autoFocus:t===0,children:E.map(e=>w(`option`,{value:e.value,children:e.label},e.value))}),e.operator!==`blank`&&e.operator!==`notBlank`&&w(`input`,{type:`text`,value:e.value,onChange:e=>M(t,{value:e.target.value}),placeholder:`Value`,className:`gp-grid-filter-text-input`}),b.length>1&&w(`button`,{type:`button`,className:`gp-grid-filter-remove`,onClick:()=>P(t),children:`×`})]})]},t)),w(`button`,{type:`button`,className:`gp-grid-filter-add`,onClick:N,children:`+ Add condition`})]}),T(`div`,{className:`gp-grid-filter-buttons`,children:[w(`button`,{type:`button`,className:`gp-grid-filter-btn-clear`,onClick:I,children:`Clear`}),w(`button`,{type:`button`,className:`gp-grid-filter-btn-apply`,onClick:F,children:`Apply`})]})]})}const O=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`>=`,label:`≥`},{value:`<=`,label:`≤`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}];function k({currentFilter:e,onApply:n,onClose:i}){let[a,s]=o(r(()=>{if(!e?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let t=e.combination??`and`;return e.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value==null?``:String(n.value),valueTo:n.valueTo==null?``:String(n.valueTo),nextOperator:n.nextOperator??t}})},[e])),c=t((e,t)=>{s(n=>{let r=[...n];return r[e]={...r[e],...t},r})},[]),l=t(()=>{s(e=>[...e,{operator:`=`,value:``,valueTo:``,nextOperator:`and`}])},[]),u=t(e=>{s(t=>t.filter((t,n)=>n!==e))},[]),d=t(()=>{let e=a.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){n(null);return}n({conditions:e.map(e=>({type:`number`,operator:e.operator,value:e.value?parseFloat(e.value):void 0,valueTo:e.valueTo?parseFloat(e.valueTo):void 0,nextOperator:e.nextOperator})),combination:`and`})},[a,n]),f=t(()=>{n(null)},[n]);return T(`div`,{className:`gp-grid-filter-content gp-grid-filter-number`,children:[a.map((e,t)=>T(`div`,{className:`gp-grid-filter-condition`,children:[t>0&&T(`div`,{className:`gp-grid-filter-combination`,children:[w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`and`?`active`:``,onClick:()=>c(t-1,{nextOperator:`and`}),children:`AND`}),w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`or`?`active`:``,onClick:()=>c(t-1,{nextOperator:`or`}),children:`OR`})]}),T(`div`,{className:`gp-grid-filter-row`,children:[w(`select`,{value:e.operator,onChange:e=>c(t,{operator:e.target.value}),children:O.map(e=>w(`option`,{value:e.value,children:e.label},e.value))}),e.operator!==`blank`&&e.operator!==`notBlank`&&w(`input`,{type:`number`,value:e.value,onChange:e=>c(t,{value:e.target.value}),placeholder:`Value`}),e.operator===`between`&&T(C,{children:[w(`span`,{className:`gp-grid-filter-to`,children:`to`}),w(`input`,{type:`number`,value:e.valueTo,onChange:e=>c(t,{valueTo:e.target.value}),placeholder:`Value`})]}),a.length>1&&w(`button`,{type:`button`,className:`gp-grid-filter-remove`,onClick:()=>u(t),children:`×`})]})]},t)),w(`button`,{type:`button`,className:`gp-grid-filter-add`,onClick:l,children:`+ Add condition`}),T(`div`,{className:`gp-grid-filter-buttons`,children:[w(`button`,{type:`button`,className:`gp-grid-filter-btn-clear`,onClick:f,children:`Clear`}),w(`button`,{type:`button`,className:`gp-grid-filter-btn-apply`,onClick:d,children:`Apply`})]})]})}const A=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}];function j(e){if(!e)return``;let t=typeof e==`string`?new Date(e):e;return isNaN(t.getTime())?``:t.toISOString().split(`T`)[0]}function M({currentFilter:e,onApply:n,onClose:i}){let[a,s]=o(r(()=>{if(!e?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let t=e.combination??`and`;return e.conditions.map(e=>{let n=e;return{operator:n.operator,value:j(n.value),valueTo:j(n.valueTo),nextOperator:n.nextOperator??t}})},[e])),c=t((e,t)=>{s(n=>{let r=[...n];return r[e]={...r[e],...t},r})},[]),l=t(()=>{s(e=>[...e,{operator:`=`,value:``,valueTo:``,nextOperator:`and`}])},[]),u=t(e=>{s(t=>t.filter((t,n)=>n!==e))},[]),d=t(()=>{let e=a.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){n(null);return}n({conditions:e.map(e=>({type:`date`,operator:e.operator,value:e.value||void 0,valueTo:e.valueTo||void 0,nextOperator:e.nextOperator})),combination:`and`})},[a,n]),f=t(()=>{n(null)},[n]);return T(`div`,{className:`gp-grid-filter-content gp-grid-filter-date`,children:[a.map((e,t)=>T(`div`,{className:`gp-grid-filter-condition`,children:[t>0&&T(`div`,{className:`gp-grid-filter-combination`,children:[w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`and`?`active`:``,onClick:()=>c(t-1,{nextOperator:`and`}),children:`AND`}),w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`or`?`active`:``,onClick:()=>c(t-1,{nextOperator:`or`}),children:`OR`})]}),T(`div`,{className:`gp-grid-filter-row`,children:[w(`select`,{value:e.operator,onChange:e=>c(t,{operator:e.target.value}),children:A.map(e=>w(`option`,{value:e.value,children:e.label},e.value))}),e.operator!==`blank`&&e.operator!==`notBlank`&&w(`input`,{type:`date`,value:e.value,onChange:e=>c(t,{value:e.target.value})}),e.operator===`between`&&T(C,{children:[w(`span`,{className:`gp-grid-filter-to`,children:`to`}),w(`input`,{type:`date`,value:e.valueTo,onChange:e=>c(t,{valueTo:e.target.value})})]}),a.length>1&&w(`button`,{type:`button`,className:`gp-grid-filter-remove`,onClick:()=>u(t),children:`×`})]})]},t)),w(`button`,{type:`button`,className:`gp-grid-filter-add`,onClick:l,children:`+ Add condition`}),T(`div`,{className:`gp-grid-filter-buttons`,children:[w(`button`,{type:`button`,className:`gp-grid-filter-btn-clear`,onClick:f,children:`Clear`}),w(`button`,{type:`button`,className:`gp-grid-filter-btn-apply`,onClick:d,children:`Apply`})]})]})}function N({column:e,colIndex:r,anchorRect:i,distinctValues:o,currentFilter:s,onApply:c,onClose:l}){let u=a(null);n(()=>{let e=e=>{let t=e.target;t.closest(`.gp-grid-filter-icon`)||u.current&&!u.current.contains(t)&&l()},t=e=>{e.key===`Escape`&&l()};return requestAnimationFrame(()=>{document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t)}),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[l]);let d=t(t=>{c(e.colId??e.field,t),l()},[e,c,l]),f={position:`fixed`,top:i.top+i.height+4,left:i.left,minWidth:Math.max(200,i.width),zIndex:1e4},p=e.cellDataType,m=p===`text`||p===`object`,h=p===`number`,g=p===`date`||p===`dateString`||p===`dateTime`||p===`dateTimeString`;return T(`div`,{ref:u,className:`gp-grid-filter-popup`,style:f,children:[T(`div`,{className:`gp-grid-filter-header`,children:[`Filter: `,e.headerName??e.field]}),m&&w(D,{distinctValues:o,currentFilter:s,onApply:d,onClose:l}),h&&w(k,{currentFilter:s,onApply:d,onClose:l}),g&&w(M,{currentFilter:s,onApply:d,onClose:l}),!m&&!h&&!g&&w(D,{distinctValues:o,currentFilter:s,onApply:d,onClose:l})]})}function P(e){return{slots:new Map,activeCell:null,selectionRange:null,editingCell:null,contentWidth:0,contentHeight:e?.initialHeight??0,viewportWidth:e?.initialWidth??0,headers:new Map,filterPopup:null,isLoading:!1,error:null,totalRows:0,visibleRowRange:null}}function F(e,t,n){switch(e.type){case`CREATE_SLOT`:return t.set(e.slotId,{slotId:e.slotId,rowIndex:-1,rowData:{},translateY:0}),null;case`DESTROY_SLOT`:return t.delete(e.slotId),null;case`ASSIGN_SLOT`:{let n=t.get(e.slotId);return n&&t.set(e.slotId,{...n,rowIndex:e.rowIndex,rowData:e.rowData}),null}case`MOVE_SLOT`:{let n=t.get(e.slotId);return n&&t.set(e.slotId,{...n,translateY:e.translateY}),null}case`SET_ACTIVE_CELL`:return{activeCell:e.position};case`SET_SELECTION_RANGE`:return{selectionRange:e.range};case`UPDATE_VISIBLE_RANGE`:return{visibleRowRange:{start:e.start,end:e.end}};case`START_EDIT`:return{editingCell:{row:e.row,col:e.col,initialValue:e.initialValue}};case`STOP_EDIT`:return{editingCell:null};case`SET_CONTENT_SIZE`:return{contentWidth:e.width,contentHeight:e.height,viewportWidth:e.viewportWidth};case`UPDATE_HEADER`:return n.set(e.colIndex,{column:e.column,sortDirection:e.sortDirection,sortIndex:e.sortIndex,sortable:e.sortable,filterable:e.filterable,hasFilter:e.hasFilter}),null;case`OPEN_FILTER_POPUP`:return{filterPopup:{isOpen:!0,colIndex:e.colIndex,column:e.column,anchorRect:e.anchorRect,distinctValues:e.distinctValues,currentFilter:e.currentFilter}};case`CLOSE_FILTER_POPUP`:return{filterPopup:null};case`DATA_LOADING`:return{isLoading:!0,error:null};case`DATA_LOADED`:return{isLoading:!1,totalRows:e.totalRows};case`DATA_ERROR`:return{isLoading:!1,error:e.error};case`ROWS_ADDED`:case`ROWS_REMOVED`:return{totalRows:e.totalRows};case`ROWS_UPDATED`:case`TRANSACTION_PROCESSED`:return null;default:return null}}function I(e,t){if(t.type===`RESET`)return P();let{instructions:n}=t;if(n.length===0)return e;let r=new Map(e.slots),i=new Map(e.headers),a={};for(let e of n){let t=F(e,r,i);t&&(a={...a,...t})}return{...e,...a,slots:r,headers:i}}function L(e,t){for(let n of e.values())if(n.rowIndex===t)return n;return null}function R(e,t,n,r,i,a){let o=L(a,n),s=(o?o.translateY:i+n*r)-t.scrollTop,c=s+r,l=i,u=t.clientHeight;if(s<l)t.scrollTop=e.getScrollTopForRow(n);else if(c>u){let a=t.clientHeight-i,o=Math.floor(a/r),s=Math.max(0,n-o+1);t.scrollTop=e.getScrollTopForRow(s)}}function z(e,r,i,s){let{activeCell:c,selectionRange:l,editingCell:u,filterPopupOpen:d,rowHeight:f,headerHeight:p,columnPositions:m,slots:h}=s,g=a(null),[_,v]=o({isDragging:!1,dragType:null,fillSourceRange:null,fillTarget:null});n(()=>{let t=e.current;t?.input&&t.input.updateDeps({getHeaderHeight:()=>p,getRowHeight:()=>f,getColumnPositions:()=>m,getColumnCount:()=>i.length})},[e,p,f,m,i.length]);let y=t((e,t)=>{g.current&&clearInterval(g.current),g.current=setInterval(()=>{let n=r.current;n&&(n.scrollTop+=t,n.scrollLeft+=e)},16)},[r]),b=t(()=>{g.current&&=(clearInterval(g.current),null)},[]),x=t(()=>{let e=r.current;if(!e)return null;let t=e.getBoundingClientRect();return{top:t.top,left:t.left,width:t.width,height:t.height,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft}},[r]),S=e=>({clientX:e.clientX,clientY:e.clientY,button:e.button,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey}),C=t(()=>{let t=t=>{let n=e.current,r=x();if(!n?.input||!r)return;let i=n.input.handleDragMove(S(t),r);i&&(i.autoScroll?y(i.autoScroll.dx,i.autoScroll.dy):b(),v(n.input.getDragState()))},n=()=>{let r=e.current;r?.input&&(r.input.handleDragEnd(),v(r.input.getDragState())),b(),document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,n)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,n)},[e,x,y,b]),w=t((t,n,i)=>{let a=e.current;if(!a?.input)return;let o=a.input.handleCellMouseDown(t,n,S(i));o.focusContainer&&r.current?.focus(),o.startDrag===`selection`&&(a.input.startSelectionDrag(),v(a.input.getDragState()),C())},[e,r,C]),T=t((t,n)=>{let r=e.current;r?.input&&r.input.handleCellDoubleClick(t,n)},[e]),E=t(t=>{let n=e.current;if(!n?.input)return;let r=n.input.handleFillHandleMouseDown(c,l,S(t));r.preventDefault&&t.preventDefault(),r.stopPropagation&&t.stopPropagation(),r.startDrag===`fill`&&(v(n.input.getDragState()),C())},[e,c,l,C]),D=t((t,n)=>{let r=e.current;if(!r?.input)return;let a=i[t];if(!a)return;let o=a.colId??a.field;r.input.handleHeaderClick(o,n.shiftKey)},[e,i]),O=t(t=>{let n=e.current,i=r.current;if(!n?.input)return;let a=n.input.handleKeyDown({key:t.key,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,metaKey:t.metaKey},c,u,d);a.preventDefault&&t.preventDefault(),a.scrollToCell&&i&&R(n,i,a.scrollToCell.row,f,p,h)},[e,r,c,u,d,f,p,h]),k=t((t,n)=>{let i=e.current,a=r.current;if(!i?.input||!a)return;let o=i.input.handleWheel(t.deltaY,t.deltaX,n);o&&(t.preventDefault(),a.scrollTop+=o.dy,a.scrollLeft+=o.dx)},[e,r]);return n(()=>()=>{b()},[b]),{handleCellMouseDown:w,handleCellDoubleClick:T,handleFillHandleMouseDown:E,handleHeaderClick:D,handleKeyDown:O,handleWheel:k,dragState:_}}function B(e,t){let n=t.split(`.`),r=e;for(let e of n){if(typeof r!=`object`||!r)return null;r=r[e]}return r??null}function V(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,isActive:a,isSelected:o,isEditing:s,cellRenderers:c,globalCellRenderer:l}=e,u=B(n,t.field),d={value:u,rowData:n,column:t,rowIndex:r,colIndex:i,isActive:a,isSelected:o,isEditing:s};if(t.cellRenderer&&typeof t.cellRenderer==`string`){let e=c[t.cellRenderer];if(e)return e(d)}return l?l(d):u==null?``:String(u)}function H(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,initialValue:a,coreRef:o,editRenderers:s,globalEditRenderer:c}=e,l=o.current;if(!l)return null;let u={value:B(n,t.field),rowData:n,column:t,rowIndex:r,colIndex:i,isActive:!0,isSelected:!0,isEditing:!0,initialValue:a,onValueChange:e=>l.updateEditValue(e),onCommit:()=>l.commitEdit(),onCancel:()=>l.cancelEdit()};if(t.editRenderer&&typeof t.editRenderer==`string`){let e=s[t.editRenderer];if(e)return e(u)}return c?c(u):w(`input`,{className:`gp-grid-edit-input`,type:`text`,defaultValue:a==null?``:String(a),autoFocus:!0,onFocus:e=>e.target.select(),onChange:e=>l.updateEditValue(e.target.value),onKeyDown:e=>{e.stopPropagation(),e.key===`Enter`?l.commitEdit():e.key===`Escape`?l.cancelEdit():e.key===`Tab`&&(e.preventDefault(),l.commitEdit(),l.selection.moveFocus(e.shiftKey?`left`:`right`,!1))},onBlur:()=>l.commitEdit()})}function U(e){let{column:t,colIndex:n,sortDirection:r,sortIndex:i,sortable:a,filterable:o,hasFilter:s,coreRef:c,containerRef:l,headerRenderers:u,globalHeaderRenderer:d}=e,f=c.current,p={column:t,colIndex:n,sortDirection:r,sortIndex:i,sortable:a,filterable:o,hasFilter:s,onSort:(e,n)=>{f&&a&&f.setSort(t.colId??t.field,e,n)},onFilterClick:()=>{if(f&&o){let e=l.current?.querySelector(`[data-col-index="${n}"]`);if(e){let t=e.getBoundingClientRect();f.openFilterPopup(n,{top:t.top,left:t.left,width:t.width,height:t.height})}}}};if(t.headerRenderer&&typeof t.headerRenderer==`string`){let e=u[t.headerRenderer];if(e)return e(p)}return d?d(p):T(C,{children:[w(`span`,{className:`gp-grid-header-text`,children:t.headerName??t.field}),T(`span`,{className:`gp-grid-header-icons`,children:[a&&T(`span`,{className:`gp-grid-sort-arrows`,children:[T(`span`,{className:`gp-grid-sort-arrows-stack`,children:[w(`svg`,{className:`gp-grid-sort-arrow-up${r===`asc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`,children:w(`path`,{d:`M4 0L8 6H0L4 0Z`,fill:`currentColor`})}),w(`svg`,{className:`gp-grid-sort-arrow-down${r===`desc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`,children:w(`path`,{d:`M4 6L0 0H8L4 6Z`,fill:`currentColor`})})]}),i!==void 0&&i>0&&w(`span`,{className:`gp-grid-sort-index`,children:i})]}),o&&w(`span`,{className:`gp-grid-filter-icon${s?` active`:``}`,onMouseDown:e=>{e.stopPropagation(),e.preventDefault(),p.onFilterClick()},onClick:e=>{e.stopPropagation()},children:w(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`currentColor`,children:w(`path`,{d:`M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z`})})})]})]})}function W(e){v();let{columns:o,dataSource:s,rowData:d,rowHeight:p,headerHeight:h=p,overscan:g=3,sortingEnabled:C=!0,darkMode:E=!1,wheelDampening:D=.1,cellRenderers:O={},editRenderers:k={},headerRenderers:A={},cellRenderer:j,editRenderer:M,headerRenderer:F,initialWidth:L,initialHeight:R}=e,B=a(null),W=a(null),[G,ee]=i(I,{initialWidth:L,initialHeight:R},P),K=h,q=r(()=>s||(d?m(d):f([])),[s,d]),{positions:J,widths:Y}=r(()=>u(o,G.viewportWidth),[o,G.viewportWidth]),X=_(J),{handleCellMouseDown:te,handleCellDoubleClick:ne,handleFillHandleMouseDown:re,handleHeaderClick:ie,handleKeyDown:ae,handleWheel:oe,dragState:Z}=z(W,B,o,{activeCell:G.activeCell,selectionRange:G.selectionRange,editingCell:G.editingCell,filterPopupOpen:G.filterPopup?.isOpen??!1,rowHeight:p,headerHeight:K,columnPositions:J,slots:G.slots});n(()=>{let e=new c({columns:o,dataSource:q,rowHeight:p,headerHeight:K,overscan:g,sortingEnabled:C});W.current=e;let t=e.onBatchInstruction(e=>{ee({type:`BATCH_INSTRUCTIONS`,instructions:e})});return e.initialize(),()=>{t(),W.current=null}},[o,q,p,K,g,C]),n(()=>{let e=q;if(e.subscribe)return e.subscribe(()=>{W.current?.refresh()})},[q]);let Q=t(()=>{let e=B.current,t=W.current;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)},[]);n(()=>{let e=B.current,t=W.current;if(!e||!t)return;if(typeof ResizeObserver>`u`){Q();return}let n=new ResizeObserver(()=>{t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)});return n.observe(e),Q(),()=>n.disconnect()},[Q]);let se=t((e,t)=>{let n=W.current;n&&n.setFilter(e,t)},[]),ce=t(()=>{let e=W.current;e&&e.closeFilterPopup()},[]),le=r(()=>Array.from(G.slots.values()),[G.slots]),$=r(()=>{let{activeCell:e,selectionRange:t,slots:n}=G;if(!e&&!t)return null;let r,i,a,s;if(t)r=Math.max(t.startRow,t.endRow),i=Math.max(t.startCol,t.endCol),a=Math.min(t.startCol,t.endCol),s=Math.max(t.startCol,t.endCol);else if(e)r=e.row,i=e.col,a=i,s=i;else return null;for(let e=a;e<=s;e++){let t=o[e];if(!t||t.editable!==!0)return null}let c=null;for(let e of n.values())if(e.rowIndex===r){c=e.translateY;break}if(c===null)return null;let l=J[i]??0,u=Y[i]??0;return{top:c+p-5,left:l+u-20}},[G.activeCell,G.selectionRange,G.slots,p,J,Y,o]);return T(`div`,{ref:B,className:`gp-grid-container${E?` gp-grid-container--dark`:``}`,style:{width:`100%`,height:`100%`,overflow:`auto`,position:`relative`},onScroll:Q,onWheel:e=>oe(e,D),onKeyDown:ae,tabIndex:0,children:[T(`div`,{style:{width:Math.max(G.contentWidth,X),height:Math.max(G.contentHeight,K),position:`relative`,minWidth:`100%`},children:[w(`div`,{className:`gp-grid-header`,style:{position:`sticky`,top:0,left:0,height:h,width:Math.max(G.contentWidth,X),minWidth:`100%`},children:o.map((e,t)=>{let n=G.headers.get(t);return w(`div`,{className:`gp-grid-header-cell`,"data-col-index":t,style:{position:`absolute`,left:`${J[t]}px`,top:0,width:`${Y[t]}px`,height:`${h}px`,background:`transparent`},onClick:e=>ie(t,e),children:U({column:e,colIndex:t,sortDirection:n?.sortDirection,sortIndex:n?.sortIndex,sortable:n?.sortable??!0,filterable:n?.filterable??!0,hasFilter:n?.hasFilter??!1,coreRef:W,containerRef:B,headerRenderers:A,globalHeaderRenderer:F})},e.colId??e.field)})}),le.map(e=>e.rowIndex<0?null:w(`div`,{className:`gp-grid-row ${e.rowIndex%2==0?`gp-grid-row--even`:``}`,style:{position:`absolute`,top:0,left:0,transform:`translateY(${e.translateY}px)`,width:`${Math.max(G.contentWidth,X)}px`,height:`${p}px`},children:o.map((t,n)=>{let r=b(e.rowIndex,n,G.editingCell),i=y(e.rowIndex,n,G.activeCell),a=S(e.rowIndex,n,G.selectionRange);return w(`div`,{className:l(i,a,r,x(e.rowIndex,n,Z.dragType===`fill`,Z.fillSourceRange,Z.fillTarget)),style:{position:`absolute`,left:`${J[n]}px`,top:0,width:`${Y[n]}px`,height:`${p}px`},onMouseDown:t=>te(e.rowIndex,n,t),onDoubleClick:()=>ne(e.rowIndex,n),children:r&&G.editingCell?H({column:t,rowData:e.rowData,rowIndex:e.rowIndex,colIndex:n,initialValue:G.editingCell.initialValue,coreRef:W,editRenderers:k,globalEditRenderer:M}):V({column:t,rowData:e.rowData,rowIndex:e.rowIndex,colIndex:n,isActive:i,isSelected:a,isEditing:r,cellRenderers:O,globalCellRenderer:j})},`${e.slotId}-${n}`)})},e.slotId)),$&&!G.editingCell&&w(`div`,{className:`gp-grid-fill-handle`,style:{position:`absolute`,top:$.top,left:$.left,zIndex:200},onMouseDown:re}),G.isLoading&&T(`div`,{className:`gp-grid-loading`,children:[w(`div`,{className:`gp-grid-loading-spinner`}),`Loading...`]}),G.error&&T(`div`,{className:`gp-grid-error`,children:[`Error: `,G.error]}),!G.isLoading&&!G.error&&G.totalRows===0&&w(`div`,{className:`gp-grid-empty`,children:`No data to display`})]}),G.filterPopup?.isOpen&&G.filterPopup.column&&G.filterPopup.anchorRect&&w(N,{column:G.filterPopup.column,colIndex:G.filterPopup.colIndex,anchorRect:G.filterPopup.anchorRect,distinctValues:G.filterPopup.distinctValues,currentFilter:G.filterPopup.currentFilter,onApply:se,onClose:ce})]})}export{W as Grid,s as GridCore,d as createClientDataSource,p as createDataSourceFromArray,h as createMutableClientDataSource,g as createServerDataSource};
|
|
1
|
+
import e,{useCallback as t,useEffect as n,useMemo as r,useReducer as i,useRef as a,useState as o}from"react";import{GridCore as s,GridCore as c,buildCellClasses as l,calculateScaledColumnPositions as u,createClientDataSource as d,createClientDataSource as f,createDataSourceFromArray as p,createDataSourceFromArray as m,createMutableClientDataSource as h,createServerDataSource as g,getTotalWidth as _,injectStyles as v,isCellActive as y,isCellEditing as b,isCellInFillPreview as x,isCellSelected as S}from"gp-grid-core";import{Fragment as C,jsx as w,jsxs as T}from"react/jsx-runtime";const E=[{value:`contains`,label:`Contains`},{value:`notContains`,label:`Does not contain`},{value:`equals`,label:`Equals`},{value:`notEquals`,label:`Does not equal`},{value:`startsWith`,label:`Starts with`},{value:`endsWith`,label:`Ends with`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Is not blank`}];function D({distinctValues:e,currentFilter:n,onApply:i,onClose:a}){let s=t(e=>Array.isArray(e)?e.join(`, `):String(e??``),[]),c=r(()=>{let t=e.filter(e=>e!=null&&e!==``&&!(Array.isArray(e)&&e.length===0)).map(e=>s(e));return Array.from(new Set(t)).sort((e,t)=>{let n=parseFloat(e),r=parseFloat(t);return!isNaN(n)&&!isNaN(r)?n-r:e.localeCompare(t,void 0,{numeric:!0,sensitivity:`base`})})},[e,s]),l=c.length>100,[u,d]=o(r(()=>{if(!n?.conditions[0])return l?`condition`:`values`;let e=n.conditions[0];return e.selectedValues&&e.selectedValues.size>0?`values`:`condition`},[n,l])),f=r(()=>n?.conditions[0]?n.conditions[0].selectedValues??new Set:new Set,[n]),p=r(()=>n?.conditions[0]?n.conditions[0].includeBlank??!0:!0,[n]),[m,h]=o(``),[g,_]=o(f),[v,y]=o(p),[b,x]=o(r(()=>{if(!n?.conditions.length)return[{operator:`contains`,value:``,nextOperator:`and`}];let e=n.conditions[0];if(e.selectedValues&&e.selectedValues.size>0)return[{operator:`contains`,value:``,nextOperator:`and`}];let t=n.combination??`and`;return n.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value??``,nextOperator:n.nextOperator??t}})},[n])),S=r(()=>{if(!m)return c;let e=m.toLowerCase();return c.filter(t=>t.toLowerCase().includes(e))},[c,m]),D=r(()=>e.some(e=>e==null||e===``),[e]),O=r(()=>S.every(e=>g.has(e))&&(!D||v),[S,g,D,v]),k=t(()=>{_(new Set(S)),D&&y(!0)},[S,D]),A=t(()=>{_(new Set),y(!1)},[]),j=t(e=>{_(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),M=t((e,t)=>{x(n=>{let r=[...n];return r[e]={...r[e],...t},r})},[]),N=t(()=>{x(e=>[...e,{operator:`contains`,value:``,nextOperator:`and`}])},[]),P=t(e=>{x(t=>t.filter((t,n)=>n!==e))},[]),F=t(()=>{if(u===`values`){if(c.every(e=>g.has(e))&&(!D||v)){i(null);return}i({conditions:[{type:`text`,operator:`equals`,selectedValues:g,includeBlank:v}],combination:`and`})}else{let e=b.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.value.trim()!==``);if(e.length===0){i(null);return}i({conditions:e.map(e=>({type:`text`,operator:e.operator,value:e.value,nextOperator:e.nextOperator})),combination:`and`})}},[u,c,g,v,D,b,i]),I=t(()=>{i(null)},[i]);return T(`div`,{className:`gp-grid-filter-content gp-grid-filter-text`,children:[!l&&T(`div`,{className:`gp-grid-filter-mode-toggle`,children:[w(`button`,{type:`button`,className:u===`values`?`active`:``,onClick:()=>d(`values`),children:`Values`}),w(`button`,{type:`button`,className:u===`condition`?`active`:``,onClick:()=>d(`condition`),children:`Condition`})]}),l&&u===`condition`&&T(`div`,{className:`gp-grid-filter-info`,children:[`Too many unique values (`,c.length,`). Use conditions to filter.`]}),u===`values`&&T(C,{children:[w(`input`,{className:`gp-grid-filter-search`,type:`text`,placeholder:`Search...`,value:m,onChange:e=>h(e.target.value),autoFocus:!0}),T(`div`,{className:`gp-grid-filter-actions`,children:[w(`button`,{type:`button`,onClick:k,disabled:O,children:`Select All`}),w(`button`,{type:`button`,onClick:A,children:`Deselect All`})]}),T(`div`,{className:`gp-grid-filter-list`,children:[D&&T(`label`,{className:`gp-grid-filter-option`,children:[w(`input`,{type:`checkbox`,checked:v,onChange:()=>y(!v)}),w(`span`,{className:`gp-grid-filter-blank`,children:`(Blanks)`})]}),S.map(e=>T(`label`,{className:`gp-grid-filter-option`,children:[w(`input`,{type:`checkbox`,checked:g.has(e),onChange:()=>j(e)}),w(`span`,{children:e})]},e))]})]}),u===`condition`&&T(C,{children:[b.map((e,t)=>T(`div`,{className:`gp-grid-filter-condition`,children:[t>0&&T(`div`,{className:`gp-grid-filter-combination`,children:[w(`button`,{type:`button`,className:b[t-1]?.nextOperator===`and`?`active`:``,onClick:()=>M(t-1,{nextOperator:`and`}),children:`AND`}),w(`button`,{type:`button`,className:b[t-1]?.nextOperator===`or`?`active`:``,onClick:()=>M(t-1,{nextOperator:`or`}),children:`OR`})]}),T(`div`,{className:`gp-grid-filter-row`,children:[w(`select`,{value:e.operator,onChange:e=>M(t,{operator:e.target.value}),autoFocus:t===0,children:E.map(e=>w(`option`,{value:e.value,children:e.label},e.value))}),e.operator!==`blank`&&e.operator!==`notBlank`&&w(`input`,{type:`text`,value:e.value,onChange:e=>M(t,{value:e.target.value}),placeholder:`Value`,className:`gp-grid-filter-text-input`}),b.length>1&&w(`button`,{type:`button`,className:`gp-grid-filter-remove`,onClick:()=>P(t),children:`×`})]})]},t)),w(`button`,{type:`button`,className:`gp-grid-filter-add`,onClick:N,children:`+ Add condition`})]}),T(`div`,{className:`gp-grid-filter-buttons`,children:[w(`button`,{type:`button`,className:`gp-grid-filter-btn-clear`,onClick:I,children:`Clear`}),w(`button`,{type:`button`,className:`gp-grid-filter-btn-apply`,onClick:F,children:`Apply`})]})]})}const O=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`>=`,label:`≥`},{value:`<=`,label:`≤`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}];function k({currentFilter:e,onApply:n,onClose:i}){let[a,s]=o(r(()=>{if(!e?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let t=e.combination??`and`;return e.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value==null?``:String(n.value),valueTo:n.valueTo==null?``:String(n.valueTo),nextOperator:n.nextOperator??t}})},[e])),c=t((e,t)=>{s(n=>{let r=[...n];return r[e]={...r[e],...t},r})},[]),l=t(()=>{s(e=>[...e,{operator:`=`,value:``,valueTo:``,nextOperator:`and`}])},[]),u=t(e=>{s(t=>t.filter((t,n)=>n!==e))},[]),d=t(()=>{let e=a.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){n(null);return}n({conditions:e.map(e=>({type:`number`,operator:e.operator,value:e.value?parseFloat(e.value):void 0,valueTo:e.valueTo?parseFloat(e.valueTo):void 0,nextOperator:e.nextOperator})),combination:`and`})},[a,n]),f=t(()=>{n(null)},[n]);return T(`div`,{className:`gp-grid-filter-content gp-grid-filter-number`,children:[a.map((e,t)=>T(`div`,{className:`gp-grid-filter-condition`,children:[t>0&&T(`div`,{className:`gp-grid-filter-combination`,children:[w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`and`?`active`:``,onClick:()=>c(t-1,{nextOperator:`and`}),children:`AND`}),w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`or`?`active`:``,onClick:()=>c(t-1,{nextOperator:`or`}),children:`OR`})]}),T(`div`,{className:`gp-grid-filter-row`,children:[w(`select`,{value:e.operator,onChange:e=>c(t,{operator:e.target.value}),children:O.map(e=>w(`option`,{value:e.value,children:e.label},e.value))}),e.operator!==`blank`&&e.operator!==`notBlank`&&w(`input`,{type:`number`,value:e.value,onChange:e=>c(t,{value:e.target.value}),placeholder:`Value`}),e.operator===`between`&&T(C,{children:[w(`span`,{className:`gp-grid-filter-to`,children:`to`}),w(`input`,{type:`number`,value:e.valueTo,onChange:e=>c(t,{valueTo:e.target.value}),placeholder:`Value`})]}),a.length>1&&w(`button`,{type:`button`,className:`gp-grid-filter-remove`,onClick:()=>u(t),children:`×`})]})]},t)),w(`button`,{type:`button`,className:`gp-grid-filter-add`,onClick:l,children:`+ Add condition`}),T(`div`,{className:`gp-grid-filter-buttons`,children:[w(`button`,{type:`button`,className:`gp-grid-filter-btn-clear`,onClick:f,children:`Clear`}),w(`button`,{type:`button`,className:`gp-grid-filter-btn-apply`,onClick:d,children:`Apply`})]})]})}const A=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}];function j(e){if(!e)return``;let t=typeof e==`string`?new Date(e):e;return isNaN(t.getTime())?``:t.toISOString().split(`T`)[0]}function M({currentFilter:e,onApply:n,onClose:i}){let[a,s]=o(r(()=>{if(!e?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let t=e.combination??`and`;return e.conditions.map(e=>{let n=e;return{operator:n.operator,value:j(n.value),valueTo:j(n.valueTo),nextOperator:n.nextOperator??t}})},[e])),c=t((e,t)=>{s(n=>{let r=[...n];return r[e]={...r[e],...t},r})},[]),l=t(()=>{s(e=>[...e,{operator:`=`,value:``,valueTo:``,nextOperator:`and`}])},[]),u=t(e=>{s(t=>t.filter((t,n)=>n!==e))},[]),d=t(()=>{let e=a.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){n(null);return}n({conditions:e.map(e=>({type:`date`,operator:e.operator,value:e.value||void 0,valueTo:e.valueTo||void 0,nextOperator:e.nextOperator})),combination:`and`})},[a,n]),f=t(()=>{n(null)},[n]);return T(`div`,{className:`gp-grid-filter-content gp-grid-filter-date`,children:[a.map((e,t)=>T(`div`,{className:`gp-grid-filter-condition`,children:[t>0&&T(`div`,{className:`gp-grid-filter-combination`,children:[w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`and`?`active`:``,onClick:()=>c(t-1,{nextOperator:`and`}),children:`AND`}),w(`button`,{type:`button`,className:a[t-1]?.nextOperator===`or`?`active`:``,onClick:()=>c(t-1,{nextOperator:`or`}),children:`OR`})]}),T(`div`,{className:`gp-grid-filter-row`,children:[w(`select`,{value:e.operator,onChange:e=>c(t,{operator:e.target.value}),children:A.map(e=>w(`option`,{value:e.value,children:e.label},e.value))}),e.operator!==`blank`&&e.operator!==`notBlank`&&w(`input`,{type:`date`,value:e.value,onChange:e=>c(t,{value:e.target.value})}),e.operator===`between`&&T(C,{children:[w(`span`,{className:`gp-grid-filter-to`,children:`to`}),w(`input`,{type:`date`,value:e.valueTo,onChange:e=>c(t,{valueTo:e.target.value})})]}),a.length>1&&w(`button`,{type:`button`,className:`gp-grid-filter-remove`,onClick:()=>u(t),children:`×`})]})]},t)),w(`button`,{type:`button`,className:`gp-grid-filter-add`,onClick:l,children:`+ Add condition`}),T(`div`,{className:`gp-grid-filter-buttons`,children:[w(`button`,{type:`button`,className:`gp-grid-filter-btn-clear`,onClick:f,children:`Clear`}),w(`button`,{type:`button`,className:`gp-grid-filter-btn-apply`,onClick:d,children:`Apply`})]})]})}function N({column:e,colIndex:r,anchorRect:i,distinctValues:o,currentFilter:s,onApply:c,onClose:l}){let u=a(null);n(()=>{let e=e=>{let t=e.target;t.closest(`.gp-grid-filter-icon`)||u.current&&!u.current.contains(t)&&l()},t=e=>{e.key===`Escape`&&l()};return requestAnimationFrame(()=>{document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t)}),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[l]);let d=t(t=>{c(e.colId??e.field,t),l()},[e,c,l]),f={position:`fixed`,top:i.top+i.height+4,left:i.left,minWidth:Math.max(200,i.width),zIndex:1e4},p=e.cellDataType,m=p===`text`||p===`object`,h=p===`number`,g=p===`date`||p===`dateString`||p===`dateTime`||p===`dateTimeString`;return T(`div`,{ref:u,className:`gp-grid-filter-popup`,style:f,children:[T(`div`,{className:`gp-grid-filter-header`,children:[`Filter: `,e.headerName??e.field]}),m&&w(D,{distinctValues:o,currentFilter:s,onApply:d,onClose:l}),h&&w(k,{currentFilter:s,onApply:d,onClose:l}),g&&w(M,{currentFilter:s,onApply:d,onClose:l}),!m&&!h&&!g&&w(D,{distinctValues:o,currentFilter:s,onApply:d,onClose:l})]})}function P(e){return{slots:new Map,activeCell:null,selectionRange:null,editingCell:null,contentWidth:0,contentHeight:e?.initialHeight??0,viewportWidth:e?.initialWidth??0,headers:new Map,filterPopup:null,isLoading:!1,error:null,totalRows:0,visibleRowRange:null,hoverPosition:null}}function F(e,t,n){switch(e.type){case`CREATE_SLOT`:return t.set(e.slotId,{slotId:e.slotId,rowIndex:-1,rowData:{},translateY:0}),null;case`DESTROY_SLOT`:return t.delete(e.slotId),null;case`ASSIGN_SLOT`:{let n=t.get(e.slotId);return n&&t.set(e.slotId,{...n,rowIndex:e.rowIndex,rowData:e.rowData}),null}case`MOVE_SLOT`:{let n=t.get(e.slotId);return n&&t.set(e.slotId,{...n,translateY:e.translateY}),null}case`SET_ACTIVE_CELL`:return{activeCell:e.position};case`SET_SELECTION_RANGE`:return{selectionRange:e.range};case`UPDATE_VISIBLE_RANGE`:return{visibleRowRange:{start:e.start,end:e.end}};case`SET_HOVER_POSITION`:return{hoverPosition:e.position};case`START_EDIT`:return{editingCell:{row:e.row,col:e.col,initialValue:e.initialValue}};case`STOP_EDIT`:return{editingCell:null};case`SET_CONTENT_SIZE`:return{contentWidth:e.width,contentHeight:e.height,viewportWidth:e.viewportWidth};case`UPDATE_HEADER`:return n.set(e.colIndex,{column:e.column,sortDirection:e.sortDirection,sortIndex:e.sortIndex,sortable:e.sortable,filterable:e.filterable,hasFilter:e.hasFilter}),null;case`OPEN_FILTER_POPUP`:return{filterPopup:{isOpen:!0,colIndex:e.colIndex,column:e.column,anchorRect:e.anchorRect,distinctValues:e.distinctValues,currentFilter:e.currentFilter}};case`CLOSE_FILTER_POPUP`:return{filterPopup:null};case`DATA_LOADING`:return{isLoading:!0,error:null};case`DATA_LOADED`:return{isLoading:!1,totalRows:e.totalRows};case`DATA_ERROR`:return{isLoading:!1,error:e.error};case`ROWS_ADDED`:case`ROWS_REMOVED`:return{totalRows:e.totalRows};case`ROWS_UPDATED`:case`TRANSACTION_PROCESSED`:return null;default:return null}}function I(e,t){if(t.type===`RESET`)return P();let{instructions:n}=t;if(n.length===0)return e;let r=new Map(e.slots),i=new Map(e.headers),a={};for(let e of n){let t=F(e,r,i);t&&(a={...a,...t})}return{...e,...a,slots:r,headers:i}}function L(e,t){for(let n of e.values())if(n.rowIndex===t)return n;return null}function ee(e,t,n,r,i,a){let o=L(a,n),s=(o?o.translateY:i+n*r)-t.scrollTop,c=s+r,l=i,u=t.clientHeight;if(s<l)t.scrollTop=e.getScrollTopForRow(n);else if(c>u){let a=t.clientHeight-i,o=Math.floor(a/r),s=Math.max(0,n-o+1);t.scrollTop=e.getScrollTopForRow(s)}}function te(e,r,i,s){let{activeCell:c,selectionRange:l,editingCell:u,filterPopupOpen:d,rowHeight:f,headerHeight:p,columnPositions:m,visibleColumnsWithIndices:h,slots:g}=s,_=a(null),[v,y]=o({isDragging:!1,dragType:null,fillSourceRange:null,fillTarget:null});n(()=>{let t=e.current;t?.input&&t.input.updateDeps({getHeaderHeight:()=>p,getRowHeight:()=>f,getColumnPositions:()=>m,getColumnCount:()=>h.length,getOriginalColumnIndex:e=>{let t=h[e];return t?t.originalIndex:e}})},[e,p,f,m,h]);let b=t((e,t)=>{_.current&&clearInterval(_.current),_.current=setInterval(()=>{let n=r.current;n&&(n.scrollTop+=t,n.scrollLeft+=e)},16)},[r]),x=t(()=>{_.current&&=(clearInterval(_.current),null)},[]),S=t(()=>{let e=r.current;if(!e)return null;let t=e.getBoundingClientRect();return{top:t.top,left:t.left,width:t.width,height:t.height,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft}},[r]),C=e=>({clientX:e.clientX,clientY:e.clientY,button:e.button,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey}),w=t(()=>{let t=t=>{let n=e.current,r=S();if(!n?.input||!r)return;let i=n.input.handleDragMove(C(t),r);i&&(i.autoScroll?b(i.autoScroll.dx,i.autoScroll.dy):x(),y(n.input.getDragState()))},n=()=>{let r=e.current;r?.input&&(r.input.handleDragEnd(),y(r.input.getDragState())),x(),document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,n)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,n)},[e,S,b,x]),T=t((t,n,i)=>{let a=e.current;if(!a?.input)return;let o=a.input.handleCellMouseDown(t,n,C(i));o.focusContainer&&r.current?.focus(),o.startDrag===`selection`&&(a.input.startSelectionDrag(),y(a.input.getDragState()),w())},[e,r,w]),E=t((t,n)=>{let r=e.current;r?.input&&r.input.handleCellDoubleClick(t,n)},[e]),D=t(t=>{let n=e.current;if(!n?.input)return;let r=n.input.handleFillHandleMouseDown(c,l,C(t));r.preventDefault&&t.preventDefault(),r.stopPropagation&&t.stopPropagation(),r.startDrag===`fill`&&(y(n.input.getDragState()),w())},[e,c,l,w]),O=t((t,n)=>{let r=e.current;if(!r?.input)return;let a=i[t];if(!a)return;let o=a.colId??a.field;r.input.handleHeaderClick(o,n.shiftKey)},[e,i]),k=t(t=>{let n=e.current,i=r.current;if(!n?.input)return;let a=n.input.handleKeyDown({key:t.key,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,metaKey:t.metaKey},c,u,d);a.preventDefault&&t.preventDefault(),a.scrollToCell&&i&&ee(n,i,a.scrollToCell.row,f,p,g)},[e,r,c,u,d,f,p,g]),A=t((t,n)=>{let i=e.current,a=r.current;if(!i?.input||!a)return;let o=i.input.handleWheel(t.deltaY,t.deltaX,n);o&&(t.preventDefault(),a.scrollTop+=o.dy,a.scrollLeft+=o.dx)},[e,r]);return n(()=>()=>{x()},[x]),{handleCellMouseDown:T,handleCellDoubleClick:E,handleFillHandleMouseDown:D,handleHeaderClick:O,handleKeyDown:k,handleWheel:A,dragState:v}}function R(e,t){let n=t.split(`.`),r=e;for(let e of n){if(typeof r!=`object`||!r)return null;r=r[e]}return r??null}function ne(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,isActive:a,isSelected:o,isEditing:s,cellRenderers:c,globalCellRenderer:l}=e,u=R(n,t.field),d={value:u,rowData:n,column:t,rowIndex:r,colIndex:i,isActive:a,isSelected:o,isEditing:s};if(t.cellRenderer&&typeof t.cellRenderer==`string`){let e=c[t.cellRenderer];if(e)return e(d)}return l?l(d):u==null?``:String(u)}function re(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,initialValue:a,coreRef:o,editRenderers:s,globalEditRenderer:c}=e,l=o.current;if(!l)return null;let u={value:R(n,t.field),rowData:n,column:t,rowIndex:r,colIndex:i,isActive:!0,isSelected:!0,isEditing:!0,initialValue:a,onValueChange:e=>l.updateEditValue(e),onCommit:()=>l.commitEdit(),onCancel:()=>l.cancelEdit()};if(t.editRenderer&&typeof t.editRenderer==`string`){let e=s[t.editRenderer];if(e)return e(u)}return c?c(u):w(`input`,{className:`gp-grid-edit-input`,type:`text`,defaultValue:a==null?``:String(a),autoFocus:!0,onFocus:e=>e.target.select(),onChange:e=>l.updateEditValue(e.target.value),onKeyDown:e=>{e.stopPropagation(),e.key===`Enter`?l.commitEdit():e.key===`Escape`?l.cancelEdit():e.key===`Tab`&&(e.preventDefault(),l.commitEdit(),l.selection.moveFocus(e.shiftKey?`left`:`right`,!1))},onBlur:()=>l.commitEdit()})}function ie(e){let{column:t,colIndex:n,sortDirection:r,sortIndex:i,sortable:a,filterable:o,hasFilter:s,coreRef:c,containerRef:l,headerRenderers:u,globalHeaderRenderer:d}=e,f=c.current,p={column:t,colIndex:n,sortDirection:r,sortIndex:i,sortable:a,filterable:o,hasFilter:s,onSort:(e,n)=>{f&&a&&f.setSort(t.colId??t.field,e,n)},onFilterClick:()=>{if(f&&o){let e=l.current?.querySelector(`[data-col-index="${n}"]`);if(e){let t=e.getBoundingClientRect();f.openFilterPopup(n,{top:t.top,left:t.left,width:t.width,height:t.height})}}}};if(t.headerRenderer&&typeof t.headerRenderer==`string`){let e=u[t.headerRenderer];if(e)return e(p)}return d?d(p):T(C,{children:[w(`span`,{className:`gp-grid-header-text`,children:t.headerName??t.field}),T(`span`,{className:`gp-grid-header-icons`,children:[a&&T(`span`,{className:`gp-grid-sort-arrows`,children:[T(`span`,{className:`gp-grid-sort-arrows-stack`,children:[w(`svg`,{className:`gp-grid-sort-arrow-up${r===`asc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`,children:w(`path`,{d:`M4 0L8 6H0L4 0Z`,fill:`currentColor`})}),w(`svg`,{className:`gp-grid-sort-arrow-down${r===`desc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`,children:w(`path`,{d:`M4 6L0 0H8L4 6Z`,fill:`currentColor`})})]}),i!==void 0&&i>0&&w(`span`,{className:`gp-grid-sort-index`,children:i})]}),o&&w(`span`,{className:`gp-grid-filter-icon${s?` active`:``}`,onMouseDown:e=>{e.stopPropagation(),e.preventDefault(),p.onFilterClick()},onClick:e=>{e.stopPropagation()},children:w(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`currentColor`,children:w(`path`,{d:`M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z`})})})]})]})}function z(e){v();let{columns:o,dataSource:s,rowData:d,rowHeight:p,headerHeight:h=p,overscan:g=3,sortingEnabled:C=!0,darkMode:E=!1,wheelDampening:D=.1,cellRenderers:O={},editRenderers:k={},headerRenderers:A={},cellRenderer:j,editRenderer:M,headerRenderer:F,initialWidth:L,initialHeight:ee,gridRef:R,highlighting:z}=e,B=a(null),V=a(null),H=a(null),[U,W]=i(I,{initialWidth:L,initialHeight:ee},P),G=h,{dataSource:K,ownsDataSource:ae}=r(()=>s?{dataSource:s,ownsDataSource:!1}:d?{dataSource:m(d),ownsDataSource:!0}:{dataSource:f([]),ownsDataSource:!0},[s,d]);n(()=>{let e=H.current;e&&e!==K&&W({type:`RESET`}),H.current=K},[K]);let q=r(()=>o.map((e,t)=>({column:e,originalIndex:t})).filter(({column:e})=>!e.hidden),[o]),{positions:J,widths:Y}=r(()=>u(q.map(e=>e.column),U.viewportWidth),[q,U.viewportWidth]),X=_(J),{handleCellMouseDown:oe,handleCellDoubleClick:se,handleFillHandleMouseDown:ce,handleHeaderClick:le,handleKeyDown:ue,handleWheel:de,dragState:Z}=te(V,B,o,{activeCell:U.activeCell,selectionRange:U.selectionRange,editingCell:U.editingCell,filterPopupOpen:U.filterPopup?.isOpen??!1,rowHeight:p,headerHeight:G,columnPositions:J,visibleColumnsWithIndices:q,slots:U.slots});n(()=>{let e=new c({columns:o,dataSource:K,rowHeight:p,headerHeight:G,overscan:g,sortingEnabled:C,highlighting:z});V.current=e,R&&(R.current={core:e});let t=e.onBatchInstruction(e=>{W({type:`BATCH_INSTRUCTIONS`,instructions:e})});return e.initialize(),()=>{t(),e.destroy(),ae&&K.destroy?.(),V.current=null,R&&(R.current=null)}},[o,K,ae,p,G,g,C,R,z]),n(()=>{let e=K;if(e.subscribe)return e.subscribe(()=>{V.current?.refresh()})},[K]);let Q=t(()=>{let e=B.current,t=V.current;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)},[]);n(()=>{let e=B.current,t=V.current;if(!e||!t)return;if(typeof ResizeObserver>`u`){Q();return}let n=new ResizeObserver(()=>{t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)});return n.observe(e),Q(),()=>n.disconnect()},[Q]);let fe=t((e,t)=>{let n=V.current;n&&n.setFilter(e,t)},[]),pe=t(()=>{let e=V.current;e&&e.closeFilterPopup()},[]),me=t((e,t)=>{V.current?.input.handleCellMouseEnter(e,t)},[]),he=t(()=>{V.current?.input.handleCellMouseLeave()},[]),ge=r(()=>Array.from(U.slots.values()),[U.slots]),$=r(()=>{let{activeCell:e,selectionRange:t,slots:n}=U;if(!e&&!t)return null;let r,i,a,s;if(t)r=Math.max(t.startRow,t.endRow),i=Math.max(t.startCol,t.endCol),a=Math.min(t.startCol,t.endCol),s=Math.max(t.startCol,t.endCol);else if(e)r=e.row,i=e.col,a=i,s=i;else return null;for(let e=a;e<=s;e++){let t=o[e];if(!(!t||t.hidden)&&t.editable!==!0)return null}let c=q.findIndex(e=>e.originalIndex===i);if(c===-1)return null;let l=null;for(let e of n.values())if(e.rowIndex===r){l=e.translateY;break}if(l===null)return null;let u=J[c]??0,d=Y[c]??0;return{top:l+p-5,left:u+d-20}},[U.activeCell,U.selectionRange,U.slots,p,J,Y,o,q]);return T(`div`,{ref:B,className:`gp-grid-container${E?` gp-grid-container--dark`:``}`,style:{width:`100%`,height:`100%`,overflow:`auto`,position:`relative`},onScroll:Q,onWheel:e=>de(e,D),onKeyDown:ue,tabIndex:0,children:[T(`div`,{style:{width:Math.max(U.contentWidth,X),height:Math.max(U.contentHeight,G),position:`relative`,minWidth:`100%`},children:[w(`div`,{className:`gp-grid-header`,style:{position:`sticky`,top:0,left:0,height:h,width:Math.max(U.contentWidth,X),minWidth:`100%`},children:q.map(({column:e,originalIndex:t},n)=>{let r=U.headers.get(t);return w(`div`,{className:`gp-grid-header-cell`,"data-col-index":t,style:{position:`absolute`,left:`${J[n]}px`,top:0,width:`${Y[n]}px`,height:`${h}px`,background:`transparent`},onClick:e=>le(t,e),children:ie({column:e,colIndex:t,sortDirection:r?.sortDirection,sortIndex:r?.sortIndex,sortable:r?.sortable??!0,filterable:r?.filterable??!0,hasFilter:r?.hasFilter??!1,coreRef:V,containerRef:B,headerRenderers:A,globalHeaderRenderer:F})},e.colId??e.field)})}),ge.map(e=>e.rowIndex<0?null:w(`div`,{className:[`gp-grid-row`,...V.current?.highlight?.computeRowClasses(e.rowIndex,e.rowData)??[]].filter(Boolean).join(` `),style:{position:`absolute`,top:0,left:0,transform:`translateY(${e.translateY}px)`,width:`${Math.max(U.contentWidth,X)}px`,height:`${p}px`},children:q.map(({column:t,originalIndex:n},r)=>{let i=b(e.rowIndex,n,U.editingCell),a=y(e.rowIndex,n,U.activeCell),o=S(e.rowIndex,n,U.selectionRange);return w(`div`,{className:[l(a,o,i,x(e.rowIndex,n,Z.dragType===`fill`,Z.fillSourceRange,Z.fillTarget)),...V.current?.highlight?.computeCombinedCellClasses(e.rowIndex,n,t,e.rowData)??[]].filter(Boolean).join(` `),style:{position:`absolute`,left:`${J[r]}px`,top:0,width:`${Y[r]}px`,height:`${p}px`},onMouseDown:t=>oe(e.rowIndex,n,t),onDoubleClick:()=>se(e.rowIndex,n),onMouseEnter:()=>me(e.rowIndex,n),onMouseLeave:he,children:i&&U.editingCell?re({column:t,rowData:e.rowData,rowIndex:e.rowIndex,colIndex:n,initialValue:U.editingCell.initialValue,coreRef:V,editRenderers:k,globalEditRenderer:M}):ne({column:t,rowData:e.rowData,rowIndex:e.rowIndex,colIndex:n,isActive:a,isSelected:o,isEditing:i,cellRenderers:O,globalCellRenderer:j})},`${e.slotId}-${n}`)})},e.slotId)),$&&!U.editingCell&&w(`div`,{className:`gp-grid-fill-handle`,style:{position:`absolute`,top:$.top,left:$.left,zIndex:200},onMouseDown:ce}),U.isLoading&&T(`div`,{className:`gp-grid-loading`,children:[w(`div`,{className:`gp-grid-loading-spinner`}),`Loading...`]}),U.error&&T(`div`,{className:`gp-grid-error`,children:[`Error: `,U.error]}),!U.isLoading&&!U.error&&U.totalRows===0&&w(`div`,{className:`gp-grid-empty`,children:`No data to display`})]}),U.filterPopup?.isOpen&&U.filterPopup.column&&U.filterPopup.anchorRect&&w(N,{column:U.filterPopup.column,colIndex:U.filterPopup.colIndex,anchorRect:U.filterPopup.anchorRect,distinctValues:U.filterPopup.distinctValues,currentFilter:U.filterPopup.currentFilter,onApply:fe,onClose:pe})]})}export{z as Grid,s as GridCore,d as createClientDataSource,p as createDataSourceFromArray,h as createMutableClientDataSource,g as createServerDataSource};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gp-grid-react",
|
|
3
3
|
"description": "A high-performance React data grid component with virtual scrolling, cell selection, sorting, filtering, and Excel-like editing",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"link-workspace-packages": false
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"gp-grid-core": "0.
|
|
48
|
+
"gp-grid-core": "0.7.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"react": "^19.0.0",
|