gp-grid-core 0.1.5 → 0.2.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/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- //#region src/types.d.ts
1
+ //#region src/types/basic.d.ts
2
2
  /** Cell data type primitive types */
3
3
  type CellDataType = "text" | "number" | "boolean" | "date" | "dateString" | "dateTime" | "dateTimeString" | "object";
4
4
  /** Cell value type */
5
5
  type CellValue = string | number | boolean | Date | object | null;
6
6
  /** Row type */
7
7
  type Row = unknown;
8
+ /** Row ID type for transaction operations */
9
+ type RowId = string | number;
8
10
  /** Sort direction type */
9
11
  type SortDirection = "asc" | "desc";
10
12
  /** Sort model type */
@@ -12,24 +14,12 @@ type SortModel = {
12
14
  colId: string;
13
15
  direction: SortDirection;
14
16
  };
15
- /** Filter model type */
16
- type FilterModel = Record<string, string>;
17
- interface ColumnDefinition {
18
- field: string;
19
- colId?: string;
20
- cellDataType: CellDataType;
21
- width: number;
22
- headerName?: string;
23
- editable?: boolean;
24
- /** Renderer key for adapter lookup, or inline renderer function */
25
- cellRenderer?: string;
26
- editRenderer?: string;
27
- headerRenderer?: string;
28
- }
17
+ /** Cell position */
29
18
  interface CellPosition {
30
19
  row: number;
31
20
  col: number;
32
21
  }
22
+ /** Cell range */
33
23
  interface CellRange {
34
24
  startRow: number;
35
25
  startCol: number;
@@ -78,6 +68,78 @@ interface SlotState {
78
68
  /** Translate Y position of the slot, we use translateY to optimize the rendering of the slots (Relies on the GP) */
79
69
  translateY: number;
80
70
  }
71
+ //#endregion
72
+ //#region src/types/columns.d.ts
73
+ /** Column definition */
74
+ interface ColumnDefinition {
75
+ field: string;
76
+ colId?: string;
77
+ cellDataType: CellDataType;
78
+ width: number;
79
+ headerName?: string;
80
+ editable?: boolean;
81
+ /** Whether column is sortable. Default: true when sortingEnabled */
82
+ sortable?: boolean;
83
+ /** Whether column is filterable. Default: true */
84
+ filterable?: boolean;
85
+ /** Renderer key for adapter lookup, or inline renderer function */
86
+ cellRenderer?: string;
87
+ editRenderer?: string;
88
+ headerRenderer?: string;
89
+ }
90
+ //#endregion
91
+ //#region src/types/filters.d.ts
92
+ /** Text filter operators */
93
+ type TextFilterOperator = "contains" | "notContains" | "equals" | "notEquals" | "startsWith" | "endsWith" | "blank" | "notBlank";
94
+ /** Number filter operators (symbols for display) */
95
+ type NumberFilterOperator = "=" | "!=" | ">" | "<" | ">=" | "<=" | "between" | "blank" | "notBlank";
96
+ /** Date filter operators */
97
+ type DateFilterOperator = "=" | "!=" | ">" | "<" | "between" | "blank" | "notBlank";
98
+ /** Filter combination mode */
99
+ type FilterCombination = "and" | "or";
100
+ /** Text filter condition */
101
+ interface TextFilterCondition {
102
+ type: "text";
103
+ operator: TextFilterOperator;
104
+ value?: string;
105
+ /** Selected distinct values for checkbox-style filtering */
106
+ selectedValues?: Set<string>;
107
+ /** Include blank values */
108
+ includeBlank?: boolean;
109
+ /** Operator connecting this condition to the next. Defaults to ColumnFilterModel.combination */
110
+ nextOperator?: FilterCombination;
111
+ }
112
+ /** Number filter condition */
113
+ interface NumberFilterCondition {
114
+ type: "number";
115
+ operator: NumberFilterOperator;
116
+ value?: number;
117
+ /** Second value for "between" operator */
118
+ valueTo?: number;
119
+ /** Operator connecting this condition to the next. Defaults to ColumnFilterModel.combination */
120
+ nextOperator?: FilterCombination;
121
+ }
122
+ /** Date filter condition */
123
+ interface DateFilterCondition {
124
+ type: "date";
125
+ operator: DateFilterOperator;
126
+ value?: Date | string;
127
+ /** Second value for "between" operator */
128
+ valueTo?: Date | string;
129
+ /** Operator connecting this condition to the next. Defaults to ColumnFilterModel.combination */
130
+ nextOperator?: FilterCombination;
131
+ }
132
+ /** Union of filter condition types */
133
+ type FilterCondition = TextFilterCondition | NumberFilterCondition | DateFilterCondition;
134
+ /** Column filter model with multiple conditions */
135
+ interface ColumnFilterModel {
136
+ conditions: FilterCondition[];
137
+ combination: FilterCombination;
138
+ }
139
+ /** Filter model type - maps column ID to filter */
140
+ type FilterModel = Record<string, ColumnFilterModel>;
141
+ //#endregion
142
+ //#region src/types/data-source.d.ts
81
143
  /** Data source request */
82
144
  interface DataSourceRequest {
83
145
  /** Pagination */
@@ -99,10 +161,13 @@ interface DataSourceResponse<TData = Row> {
99
161
  /** Total rows */
100
162
  totalRows: number;
101
163
  }
164
+ /** Data source interface */
102
165
  interface DataSource<TData = Row> {
103
166
  fetch(request: DataSourceRequest): Promise<DataSourceResponse<TData>>;
104
167
  }
105
- /** Slot lifecycle instructions */
168
+ //#endregion
169
+ //#region src/types/instructions.d.ts
170
+ /** Create slot instruction */
106
171
  interface CreateSlotInstruction {
107
172
  type: "CREATE_SLOT";
108
173
  slotId: string;
@@ -125,7 +190,7 @@ interface MoveSlotInstruction {
125
190
  slotId: string;
126
191
  translateY: number;
127
192
  }
128
- /** Selection instructions */
193
+ /** Set active cell instruction */
129
194
  interface SetActiveCellInstruction {
130
195
  type: "SET_ACTIVE_CELL";
131
196
  position: CellPosition | null;
@@ -135,7 +200,13 @@ interface SetSelectionRangeInstruction {
135
200
  type: "SET_SELECTION_RANGE";
136
201
  range: CellRange | null;
137
202
  }
138
- /** Edit instructions */
203
+ /** Update visible range instruction - emitted when selection moves outside visible viewport */
204
+ interface UpdateVisibleRangeInstruction {
205
+ type: "UPDATE_VISIBLE_RANGE";
206
+ start: number;
207
+ end: number;
208
+ }
209
+ /** Start edit instruction */
139
210
  interface StartEditInstruction {
140
211
  type: "START_EDIT";
141
212
  row: number;
@@ -153,7 +224,7 @@ interface CommitEditInstruction {
153
224
  col: number;
154
225
  value: CellValue;
155
226
  }
156
- /** Layout instructions */
227
+ /** Set content size instruction */
157
228
  interface SetContentSizeInstruction {
158
229
  type: "SET_CONTENT_SIZE";
159
230
  width: number;
@@ -166,8 +237,32 @@ interface UpdateHeaderInstruction {
166
237
  column: ColumnDefinition;
167
238
  sortDirection?: SortDirection;
168
239
  sortIndex?: number;
240
+ /** Whether column is sortable */
241
+ sortable: boolean;
242
+ /** Whether column is filterable */
243
+ filterable: boolean;
244
+ /** Whether column has an active filter */
245
+ hasFilter: boolean;
246
+ }
247
+ /** Open filter popup instruction */
248
+ interface OpenFilterPopupInstruction {
249
+ type: "OPEN_FILTER_POPUP";
250
+ colIndex: number;
251
+ column: ColumnDefinition;
252
+ anchorRect: {
253
+ top: number;
254
+ left: number;
255
+ width: number;
256
+ height: number;
257
+ };
258
+ distinctValues: CellValue[];
259
+ currentFilter?: ColumnFilterModel;
260
+ }
261
+ /** Close filter popup instruction */
262
+ interface CloseFilterPopupInstruction {
263
+ type: "CLOSE_FILTER_POPUP";
169
264
  }
170
- /** Fill handle instructions */
265
+ /** Start fill instruction */
171
266
  interface StartFillInstruction {
172
267
  type: "START_FILL";
173
268
  sourceRange: CellRange;
@@ -205,27 +300,46 @@ interface DataErrorInstruction {
205
300
  type: "DATA_ERROR";
206
301
  error: string;
207
302
  }
303
+ /** Rows added instruction */
304
+ interface RowsAddedInstruction {
305
+ type: "ROWS_ADDED";
306
+ count: number;
307
+ totalRows: number;
308
+ }
309
+ /** Rows removed instruction */
310
+ interface RowsRemovedInstruction {
311
+ type: "ROWS_REMOVED";
312
+ count: number;
313
+ totalRows: number;
314
+ }
315
+ /** Rows updated instruction */
316
+ interface RowsUpdatedInstruction {
317
+ type: "ROWS_UPDATED";
318
+ count: number;
319
+ }
320
+ /** Transaction processed instruction */
321
+ interface TransactionProcessedInstruction {
322
+ type: "TRANSACTION_PROCESSED";
323
+ added: number;
324
+ removed: number;
325
+ updated: number;
326
+ }
208
327
  /** Union type of all instructions */
209
328
  type GridInstruction = /** Slot lifecycle */
210
329
  CreateSlotInstruction | DestroySlotInstruction | AssignSlotInstruction | MoveSlotInstruction
211
- /** Selection */ | SetActiveCellInstruction | SetSelectionRangeInstruction
330
+ /** Selection */ | SetActiveCellInstruction | SetSelectionRangeInstruction | UpdateVisibleRangeInstruction
212
331
  /** Editing */ | StartEditInstruction | StopEditInstruction | CommitEditInstruction
213
332
  /** Layout */ | SetContentSizeInstruction | UpdateHeaderInstruction
333
+ /** Filter popup */ | OpenFilterPopupInstruction | CloseFilterPopupInstruction
214
334
  /** Fill handle */ | StartFillInstruction | UpdateFillInstruction | CommitFillInstruction | CancelFillInstruction
215
- /** Data */ | DataLoadingInstruction | DataLoadedInstruction | DataErrorInstruction;
216
- /** Grid core options */
217
- interface GridCoreOptions<TData = Row> {
218
- /** Column definitions */
219
- columns: ColumnDefinition[];
220
- /** Data source */
221
- dataSource: DataSource<TData>;
222
- /** Row height */
223
- rowHeight: number;
224
- /** Header height: Default to row height */
225
- headerHeight?: number;
226
- /** Overscan: How many rows to render outside the viewport */
227
- overscan?: number;
228
- }
335
+ /** Data */ | DataLoadingInstruction | DataLoadedInstruction | DataErrorInstruction
336
+ /** Transactions */ | RowsAddedInstruction | RowsRemovedInstruction | RowsUpdatedInstruction | TransactionProcessedInstruction;
337
+ /** Instruction listener: Single instruction Listener that receives a single instruction, used by frameworks to update their state */
338
+ type InstructionListener = (instruction: GridInstruction) => void;
339
+ /** Batch instruction listener: Batch instruction Listener that receives an array of instructions, used by frameworks to update their state */
340
+ type BatchInstructionListener = (instructions: GridInstruction[]) => void;
341
+ //#endregion
342
+ //#region src/types/renderers.d.ts
229
343
  /** Cell renderer params */
230
344
  interface CellRendererParams {
231
345
  /** Cell value */
@@ -266,13 +380,136 @@ interface HeaderRendererParams {
266
380
  sortDirection?: SortDirection;
267
381
  /** Sort index */
268
382
  sortIndex?: number;
383
+ /** Whether column is sortable */
384
+ sortable: boolean;
385
+ /** Whether column is filterable */
386
+ filterable: boolean;
387
+ /** Whether column has an active filter */
388
+ hasFilter: boolean;
269
389
  /** On sort */
270
390
  onSort: (direction: SortDirection | null, addToExisting: boolean) => void;
391
+ /** On filter click */
392
+ onFilterClick: () => void;
393
+ }
394
+ //#endregion
395
+ //#region src/types/options.d.ts
396
+ /** Grid core options */
397
+ interface GridCoreOptions<TData = Row> {
398
+ /** Column definitions */
399
+ columns: ColumnDefinition[];
400
+ /** Data source */
401
+ dataSource: DataSource<TData>;
402
+ /** Row height */
403
+ rowHeight: number;
404
+ /** Header height: Default to row height */
405
+ headerHeight?: number;
406
+ /** Overscan: How many rows to render outside the viewport */
407
+ overscan?: number;
408
+ /** Enable/disable sorting globally. Default: true */
409
+ sortingEnabled?: boolean;
410
+ /** Debounce time for transactions in ms. Default 50. Set to 0 for sync. */
411
+ transactionDebounceMs?: number;
412
+ /** Function to extract unique ID from row. Required for mutations. */
413
+ getRowId?: (row: TData) => RowId;
414
+ }
415
+ //#endregion
416
+ //#region src/types/input.d.ts
417
+ /** Framework-agnostic pointer/mouse event data */
418
+ interface PointerEventData {
419
+ /** X coordinate relative to viewport */
420
+ clientX: number;
421
+ /** Y coordinate relative to viewport */
422
+ clientY: number;
423
+ /** Mouse button (0 = left, 1 = middle, 2 = right) */
424
+ button: number;
425
+ /** Whether Shift key is pressed */
426
+ shiftKey: boolean;
427
+ /** Whether Ctrl key is pressed */
428
+ ctrlKey: boolean;
429
+ /** Whether Meta/Command key is pressed */
430
+ metaKey: boolean;
431
+ }
432
+ /** Framework-agnostic keyboard event data */
433
+ interface KeyEventData {
434
+ /** Key value (e.g., 'Enter', 'ArrowUp', 'a') */
435
+ key: string;
436
+ /** Whether Shift key is pressed */
437
+ shiftKey: boolean;
438
+ /** Whether Ctrl key is pressed */
439
+ ctrlKey: boolean;
440
+ /** Whether Meta/Command key is pressed */
441
+ metaKey: boolean;
442
+ }
443
+ /** Container bounds and scroll position */
444
+ interface ContainerBounds {
445
+ /** Top position relative to viewport */
446
+ top: number;
447
+ /** Left position relative to viewport */
448
+ left: number;
449
+ /** Container width */
450
+ width: number;
451
+ /** Container height */
452
+ height: number;
453
+ /** Current scroll top position */
454
+ scrollTop: number;
455
+ /** Current scroll left position */
456
+ scrollLeft: number;
457
+ }
458
+ /** Result from mouse/pointer input handlers */
459
+ interface InputResult {
460
+ /** Whether to call preventDefault() on the event */
461
+ preventDefault: boolean;
462
+ /** Whether to call stopPropagation() on the event */
463
+ stopPropagation: boolean;
464
+ /** Whether framework should focus the container element */
465
+ focusContainer?: boolean;
466
+ /** Type of drag operation to start (framework manages global listeners) */
467
+ startDrag?: "selection" | "fill";
468
+ }
469
+ /** Result from keyboard input handler */
470
+ interface KeyboardResult {
471
+ /** Whether to call preventDefault() on the event */
472
+ preventDefault: boolean;
473
+ /** Cell to scroll into view (if navigation occurred) */
474
+ scrollToCell?: CellPosition;
475
+ }
476
+ /** Result from drag move handler */
477
+ interface DragMoveResult {
478
+ /** Target row index */
479
+ targetRow: number;
480
+ /** Target column index */
481
+ targetCol: number;
482
+ /** Auto-scroll deltas (null if no auto-scroll needed) */
483
+ autoScroll: {
484
+ dx: number;
485
+ dy: number;
486
+ } | null;
487
+ }
488
+ /** Options for InputHandler constructor */
489
+ interface InputHandlerDeps {
490
+ /** Get header height */
491
+ getHeaderHeight: () => number;
492
+ /** Get row height */
493
+ getRowHeight: () => number;
494
+ /** Get column positions array */
495
+ getColumnPositions: () => number[];
496
+ /** Get column count */
497
+ getColumnCount: () => number;
498
+ }
499
+ /** Current drag state for UI rendering */
500
+ interface DragState {
501
+ /** Whether any drag operation is active */
502
+ isDragging: boolean;
503
+ /** Type of active drag operation */
504
+ dragType: "selection" | "fill" | null;
505
+ /** Source range for fill operations */
506
+ fillSourceRange: CellRange | null;
507
+ /** Current fill target position */
508
+ fillTarget: {
509
+ row: number;
510
+ col: number;
511
+ } | null;
271
512
  }
272
- /** Instruction listener: Single instruction Listener that receives a single instruction, used by frameworks to update their state */
273
- type InstructionListener = (instruction: GridInstruction) => void;
274
- /** Batch instruction listener: Batch instruction Listener that receives an array of instructions, used by frameworks to update their state */
275
- type BatchInstructionListener = (instructions: GridInstruction[]) => void;
276
513
  //#endregion
277
514
  //#region src/selection.d.ts
278
515
  type Direction = "up" | "down" | "left" | "right";
@@ -380,19 +617,88 @@ declare class FillManager {
380
617
  */
381
618
  private calculateFilledCells;
382
619
  private getSourceColumnValues;
383
- private getSourceRowValues;
384
620
  private detectPattern;
385
621
  private applyPattern;
386
622
  }
387
623
  //#endregion
624
+ //#region src/input-handler.d.ts
625
+ declare class InputHandler<TData extends Row = Row> {
626
+ private core;
627
+ private deps;
628
+ private isDraggingSelection;
629
+ private isDraggingFill;
630
+ private fillSourceRange;
631
+ private fillTarget;
632
+ constructor(core: GridCore<TData>, deps: InputHandlerDeps);
633
+ /**
634
+ * Update dependencies (called when options change)
635
+ */
636
+ updateDeps(deps: Partial<InputHandlerDeps>): void;
637
+ /**
638
+ * Get current drag state for UI rendering
639
+ */
640
+ getDragState(): DragState;
641
+ /**
642
+ * Handle cell mouse down event
643
+ */
644
+ handleCellMouseDown(rowIndex: number, colIndex: number, event: PointerEventData): InputResult;
645
+ /**
646
+ * Handle cell double click event (start editing)
647
+ */
648
+ handleCellDoubleClick(rowIndex: number, colIndex: number): void;
649
+ /**
650
+ * Handle fill handle mouse down event
651
+ */
652
+ handleFillHandleMouseDown(activeCell: CellPosition | null, selectionRange: CellRange | null, _event: PointerEventData): InputResult;
653
+ /**
654
+ * Handle header click event (cycle sort direction)
655
+ */
656
+ handleHeaderClick(colId: string, addToExisting: boolean): void;
657
+ /**
658
+ * Start selection drag (called by framework after handleCellMouseDown returns startDrag: 'selection')
659
+ */
660
+ startSelectionDrag(): void;
661
+ /**
662
+ * Handle drag move event (selection or fill)
663
+ */
664
+ handleDragMove(event: PointerEventData, bounds: ContainerBounds): DragMoveResult | null;
665
+ /**
666
+ * Handle drag end event
667
+ */
668
+ handleDragEnd(): void;
669
+ /**
670
+ * Handle wheel event with dampening for large datasets
671
+ * Returns scroll deltas or null if no dampening needed
672
+ */
673
+ handleWheel(deltaY: number, deltaX: number, dampening: number): {
674
+ dy: number;
675
+ dx: number;
676
+ } | null;
677
+ /**
678
+ * Handle keyboard event
679
+ */
680
+ handleKeyDown(event: KeyEventData, activeCell: CellPosition | null, editingCell: {
681
+ row: number;
682
+ col: number;
683
+ } | null, filterPopupOpen: boolean): KeyboardResult;
684
+ /**
685
+ * Find column index at a given X coordinate
686
+ */
687
+ private findColumnAtX;
688
+ /**
689
+ * Calculate auto-scroll deltas based on mouse position
690
+ */
691
+ private calculateAutoScroll;
692
+ }
693
+ //#endregion
388
694
  //#region src/grid-core.d.ts
389
695
  declare class GridCore<TData extends Row = Row> {
390
- private static readonly MAX_SAFE_HEIGHT;
391
696
  private columns;
392
697
  private dataSource;
393
698
  private rowHeight;
394
699
  private headerHeight;
395
700
  private overscan;
701
+ private sortingEnabled;
396
702
  private scrollTop;
397
703
  private scrollLeft;
398
704
  private viewportWidth;
@@ -403,13 +709,18 @@ declare class GridCore<TData extends Row = Row> {
403
709
  private pageSize;
404
710
  private sortModel;
405
711
  private filterModel;
406
- private slotPool;
712
+ private openFilterColIndex;
407
713
  readonly selection: SelectionManager;
408
714
  readonly fill: FillManager;
409
- private editState;
715
+ readonly input: InputHandler<TData>;
716
+ private readonly slotPool;
717
+ private readonly editManager;
410
718
  private columnPositions;
411
719
  private listeners;
412
720
  private batchListeners;
721
+ private naturalContentHeight;
722
+ private virtualContentHeight;
723
+ private scrollRatio;
413
724
  constructor(options: GridCoreOptions<TData>);
414
725
  onInstruction(listener: InstructionListener): () => void;
415
726
  /**
@@ -425,50 +736,45 @@ declare class GridCore<TData extends Row = Row> {
425
736
  initialize(): Promise<void>;
426
737
  /**
427
738
  * Update viewport measurements and sync slots.
739
+ * When scroll virtualization is active, maps the DOM scroll position to the actual row position.
428
740
  */
429
741
  setViewport(scrollTop: number, scrollLeft: number, width: number, height: number): void;
742
+ private fetchData;
743
+ private fetchAllData;
744
+ setSort(colId: string, direction: SortDirection | null, addToExisting?: boolean): Promise<void>;
745
+ setFilter(colId: string, filter: ColumnFilterModel | string | null): Promise<void>;
430
746
  /**
431
- * Synchronize slots with current viewport position.
432
- * This implements the slot recycling strategy.
433
- */
434
- private syncSlots;
435
- private destroyAllSlots;
436
- /**
437
- * Get the virtual (unscaled) height of the entire grid content.
438
- */
439
- private getVirtualHeight;
440
- /**
441
- * Get the display height (capped) for the content sizer.
442
- * This is the height that will be used in CSS for the scrollable area.
747
+ * Check if a column has an active filter
443
748
  */
444
- private getDisplayHeight;
749
+ hasActiveFilter(colId: string): boolean;
445
750
  /**
446
- * Check if scaling is needed (virtual height exceeds safe limit).
751
+ * Check if a column is sortable
447
752
  */
448
- private needsScaling;
753
+ isColumnSortable(colIndex: number): boolean;
449
754
  /**
450
- * Get the scroll progress as a value from 0 to 1.
451
- * 0 = scrolled to top, 1 = scrolled to bottom.
755
+ * Check if a column is filterable
452
756
  */
453
- private getScrollProgress;
757
+ isColumnFilterable(colIndex: number): boolean;
454
758
  /**
455
- * Convert display scroll position to virtual scroll position.
456
- * Uses proportional mapping when content exceeds safe limits.
759
+ * Get distinct values for a column (for filter dropdowns)
760
+ * For array-type columns (like tags), each unique array combination is returned.
761
+ * Arrays are sorted internally for consistent comparison.
762
+ * Limited to MAX_DISTINCT_VALUES to avoid performance issues with large datasets.
457
763
  */
458
- private getVirtualScrollTop;
764
+ getDistinctValuesForColumn(colId: string, maxValues?: number): CellValue[];
459
765
  /**
460
- * Get the translateY for a row that keeps values within safe CSS limits.
461
- * Uses proportional positioning when content exceeds safe limits.
766
+ * Open filter popup for a column (toggles if already open for same column)
462
767
  */
463
- private getRowTranslateY;
464
- private fetchData;
465
- private fetchAllData;
466
- setSort(colId: string, direction: SortDirection | null, addToExisting?: boolean): Promise<void>;
467
- setFilter(colId: string, value: string): Promise<void>;
768
+ openFilterPopup(colIndex: number, anchorRect: {
769
+ top: number;
770
+ left: number;
771
+ width: number;
772
+ height: number;
773
+ }): void;
468
774
  /**
469
- * Force refresh all slot data (used after filtering/sorting when data changes)
775
+ * Close filter popup
470
776
  */
471
- private refreshAllSlots;
777
+ closeFilterPopup(): void;
472
778
  getSortModel(): SortModel[];
473
779
  getFilterModel(): FilterModel;
474
780
  startEdit(row: number, col: number): void;
@@ -490,38 +796,43 @@ declare class GridCore<TData extends Row = Row> {
490
796
  getHeaderHeight(): number;
491
797
  getTotalWidth(): number;
492
798
  getTotalHeight(): number;
493
- getRowData(rowIndex: number): TData | undefined;
494
- /**
495
- * Get the display Y position for a row (accounting for scaling).
496
- * Used by UI adapters for scroll-into-view functionality.
497
- */
498
- getDisplayYForRow(rowIndex: number): number;
499
799
  /**
500
- * Check if scaling is currently active.
800
+ * Check if scroll scaling is active (large datasets exceeding browser scroll limits).
801
+ * When scaling is active, scrollRatio < 1 and scroll positions are compressed.
501
802
  */
502
803
  isScalingActive(): boolean;
503
804
  /**
504
- * Convert a display Y position to a row index.
505
- * Used by UI adapters for mouse coordinate conversion during drag operations.
506
- * @param displayY The Y position in display coordinates (relative to content area, after header)
507
- * @param scrollTop The current scroll position
805
+ * Get the natural (uncapped) content height.
806
+ * Useful for debugging or displaying actual content size.
508
807
  */
509
- getRowIndexAtDisplayY(displayY: number, scrollTop: number): number;
808
+ getNaturalHeight(): number;
510
809
  /**
511
- * Calculate the scroll position needed to make a row visible.
512
- * For scaling mode: uses proportional mapping (rowIndex/totalRows scrollTop/maxScroll)
513
- * Used by UI adapters for scroll-into-view functionality.
810
+ * Get the scroll ratio used for scroll virtualization.
811
+ * Returns 1 when no virtualization is needed, < 1 when content exceeds browser limits.
514
812
  */
515
- getScrollTopForRow(rowIndex: number): number;
813
+ getScrollRatio(): number;
516
814
  /**
517
- * Get the currently visible row range (excluding overscan).
518
- * Returns { start, end } row indices that are fully visible in the viewport.
519
- * Used by UI adapters for scroll-into-view functionality.
815
+ * Get the visible row range (excluding overscan).
816
+ * Returns the first and last row indices that are actually visible in the viewport.
817
+ * Includes partially visible rows to avoid false positives when clicking on edge rows.
520
818
  */
521
819
  getVisibleRowRange(): {
522
820
  start: number;
523
821
  end: number;
524
822
  };
823
+ /**
824
+ * Get the scroll position needed to bring a row into view.
825
+ * Accounts for scroll scaling when active.
826
+ */
827
+ getScrollTopForRow(rowIndex: number): number;
828
+ /**
829
+ * Get the row index at a given viewport Y position.
830
+ * Accounts for scroll scaling when active.
831
+ * @param viewportY Y position in viewport (physical pixels below header, NOT including scroll)
832
+ * @param virtualScrollTop Current scroll position from container.scrollTop (virtual/scaled)
833
+ */
834
+ getRowIndexAtDisplayY(viewportY: number, virtualScrollTop: number): number;
835
+ getRowData(rowIndex: number): TData | undefined;
525
836
  /**
526
837
  * Refresh data from the data source.
527
838
  */
@@ -541,29 +852,535 @@ declare class GridCore<TData extends Row = Row> {
541
852
  setColumns(columns: ColumnDefinition[]): void;
542
853
  }
543
854
  //#endregion
544
- //#region src/data-source.d.ts
855
+ //#region src/slot-pool.d.ts
856
+ interface SlotPoolManagerOptions {
857
+ /** Get current row height */
858
+ getRowHeight: () => number;
859
+ /** Get current header height */
860
+ getHeaderHeight: () => number;
861
+ /** Get overscan count */
862
+ getOverscan: () => number;
863
+ /** Get current scroll top position (natural, not virtual) */
864
+ getScrollTop: () => number;
865
+ /** Get viewport height */
866
+ getViewportHeight: () => number;
867
+ /** Get total row count */
868
+ getTotalRows: () => number;
869
+ /** Get scroll ratio for virtualization (1 = no virtualization) */
870
+ getScrollRatio: () => number;
871
+ /** Get virtual content height */
872
+ getVirtualContentHeight: () => number;
873
+ /** Get row data by index */
874
+ getRowData: (rowIndex: number) => Row | undefined;
875
+ }
545
876
  /**
546
- * Creates a client-side data source that holds all data in memory.
547
- * Sorting and filtering are performed client-side.
548
- * For large datasets (10k+ rows), sorting is automatically offloaded to a Web Worker.
877
+ * Manages the slot pool for virtual scrolling.
878
+ * Handles slot creation, recycling, positioning, and destruction.
879
+ */
880
+ /** Batch instruction listener for efficient React state updates */
881
+ type BatchInstructionListener$1 = (instructions: GridInstruction[]) => void;
882
+ declare class SlotPoolManager {
883
+ private state;
884
+ private options;
885
+ private listeners;
886
+ private batchListeners;
887
+ constructor(options: SlotPoolManagerOptions);
888
+ onInstruction(listener: InstructionListener): () => void;
889
+ /**
890
+ * Subscribe to batched instructions for efficient state updates.
891
+ */
892
+ onBatchInstruction(listener: BatchInstructionListener$1): () => void;
893
+ private emit;
894
+ private emitBatch;
895
+ /**
896
+ * Get the slot ID for a given row index.
897
+ */
898
+ getSlotForRow(rowIndex: number): string | undefined;
899
+ /**
900
+ * Get all current slots.
901
+ */
902
+ getSlots(): Map<string, SlotState>;
903
+ /**
904
+ * Synchronize slots with current viewport position.
905
+ * This implements the slot recycling strategy.
906
+ */
907
+ syncSlots(): void;
908
+ /**
909
+ * Destroy all slots.
910
+ */
911
+ destroyAllSlots(): void;
912
+ /**
913
+ * Refresh all slot data without changing which rows are displayed.
914
+ * Used after filtering/sorting when data changes.
915
+ */
916
+ refreshAllSlots(): void;
917
+ /**
918
+ * Update a single slot's data.
919
+ */
920
+ updateSlot(rowIndex: number): void;
921
+ /**
922
+ * Calculate the translateY position for a row.
923
+ * Handles scroll virtualization for very large datasets.
924
+ */
925
+ private getRowTranslateY;
926
+ }
927
+ //#endregion
928
+ //#region src/edit-manager.d.ts
929
+ interface EditManagerOptions {
930
+ /** Get column definition by index */
931
+ getColumn: (colIndex: number) => ColumnDefinition | undefined;
932
+ /** Get cell value */
933
+ getCellValue: (row: number, col: number) => CellValue;
934
+ /** Set cell value */
935
+ setCellValue: (row: number, col: number, value: CellValue) => void;
936
+ /** Callback when edit is committed (to update slot display) */
937
+ onCommit?: (row: number, col: number, value: CellValue) => void;
938
+ }
939
+ /**
940
+ * Manages cell editing state and operations.
549
941
  */
550
- declare function createClientDataSource<TData extends Row = Row>(data: TData[], options?: {
942
+ declare class EditManager {
943
+ private editState;
944
+ private options;
945
+ private listeners;
946
+ constructor(options: EditManagerOptions);
947
+ onInstruction(listener: InstructionListener): () => void;
948
+ private emit;
949
+ /**
950
+ * Get the current edit state.
951
+ */
952
+ getState(): EditState | null;
953
+ /**
954
+ * Check if currently editing.
955
+ */
956
+ isEditing(): boolean;
957
+ /**
958
+ * Check if a specific cell is being edited.
959
+ */
960
+ isEditingCell(row: number, col: number): boolean;
961
+ /**
962
+ * Start editing a cell.
963
+ * Returns true if edit was started, false if cell is not editable.
964
+ */
965
+ startEdit(row: number, col: number): boolean;
966
+ /**
967
+ * Update the current edit value.
968
+ */
969
+ updateValue(value: CellValue): void;
970
+ /**
971
+ * Commit the current edit.
972
+ * Saves the value and closes the editor.
973
+ */
974
+ commit(): void;
975
+ /**
976
+ * Cancel the current edit.
977
+ * Discards changes and closes the editor.
978
+ */
979
+ cancel(): void;
980
+ }
981
+ //#endregion
982
+ //#region src/data-source/client-data-source.d.ts
983
+ interface ClientDataSourceOptions<TData> {
551
984
  /** Custom field accessor for nested properties */
552
985
  getFieldValue?: (row: TData, field: string) => CellValue;
553
986
  /** Use Web Worker for sorting large datasets (default: true) */
554
987
  useWorker?: boolean;
555
- }): DataSource<TData>;
988
+ }
989
+ /**
990
+ * Creates a client-side data source that holds all data in memory.
991
+ * Sorting and filtering are performed client-side.
992
+ * For large datasets, sorting is automatically offloaded to a Web Worker.
993
+ */
994
+ declare function createClientDataSource<TData extends Row = Row>(data: TData[], options?: ClientDataSourceOptions<TData>): DataSource<TData>;
995
+ /**
996
+ * Convenience function to create a data source from an array.
997
+ * This provides backwards compatibility with the old `rowData` prop.
998
+ */
999
+ declare function createDataSourceFromArray<TData extends Row = Row>(data: TData[]): DataSource<TData>;
1000
+ //#endregion
1001
+ //#region src/data-source/server-data-source.d.ts
556
1002
  type ServerFetchFunction<TData> = (request: DataSourceRequest) => Promise<DataSourceResponse<TData>>;
557
1003
  /**
558
1004
  * Creates a server-side data source that delegates all operations to the server.
559
1005
  * The fetch function receives sort/filter/pagination params to pass to the API.
560
1006
  */
561
1007
  declare function createServerDataSource<TData extends Row = Row>(fetchFn: ServerFetchFunction<TData>): DataSource<TData>;
1008
+ //#endregion
1009
+ //#region src/indexed-data-store/indexed-data-store.d.ts
1010
+ interface IndexedDataStoreOptions<TData> {
1011
+ /** Function to extract unique ID from row. Required for mutations. */
1012
+ getRowId: (row: TData) => RowId;
1013
+ /** Custom field accessor for nested properties */
1014
+ getFieldValue?: (row: TData, field: string) => CellValue;
1015
+ }
1016
+ /** Hash cache for a single row */
1017
+ interface RowSortCache {
1018
+ /** Map: sortModelHash -> computed hashes for that sort configuration */
1019
+ hashes: Map<string, number[]>;
1020
+ }
562
1021
  /**
563
- * Convenience function to create a data source from an array.
564
- * This provides backwards compatibility with the old `rowData` prop.
1022
+ * Efficient data structure for incremental operations on grid data.
1023
+ * Supports:
1024
+ * - O(1) lookup by row ID
1025
+ * - O(log n) binary insertion to maintain sort order
1026
+ * - Filter state caching with distinct values
1027
+ * - Hash caching for fast sorted comparisons
565
1028
  */
566
- declare function createDataSourceFromArray<TData extends Row = Row>(data: TData[]): DataSource<TData>;
1029
+ declare class IndexedDataStore<TData extends Row = Row> {
1030
+ private rows;
1031
+ private rowById;
1032
+ private sortedIndices;
1033
+ private sortModel;
1034
+ private sortModelHash;
1035
+ private filterModel;
1036
+ private filteredIndices;
1037
+ private distinctValues;
1038
+ private rowSortCache;
1039
+ private options;
1040
+ constructor(initialData: TData[] | undefined, options: IndexedDataStoreOptions<TData>);
1041
+ /**
1042
+ * Replace all data (used for initial load or full refresh).
1043
+ */
1044
+ setData(data: TData[]): void;
1045
+ /**
1046
+ * Query data with sorting, filtering, and pagination.
1047
+ * Compatible with DataSource.fetch() interface.
1048
+ */
1049
+ query(request: DataSourceRequest): DataSourceResponse<TData>;
1050
+ /**
1051
+ * Get row by ID.
1052
+ */
1053
+ getRowById(id: RowId): TData | undefined;
1054
+ /**
1055
+ * Get row by index.
1056
+ */
1057
+ getRowByIndex(index: number): TData | undefined;
1058
+ /**
1059
+ * Get total row count (unfiltered).
1060
+ */
1061
+ getTotalRowCount(): number;
1062
+ /**
1063
+ * Get visible row count (after filtering).
1064
+ */
1065
+ getVisibleRowCount(): number;
1066
+ /**
1067
+ * Get distinct values for a field (for filter UI).
1068
+ */
1069
+ getDistinctValues(field: string): CellValue[];
1070
+ /**
1071
+ * Add rows to the store.
1072
+ * Rows are inserted at their correct sorted position.
1073
+ */
1074
+ addRows(rows: TData[]): void;
1075
+ /**
1076
+ * Add a single row.
1077
+ */
1078
+ private addRow;
1079
+ /**
1080
+ * Remove rows by ID.
1081
+ */
1082
+ removeRows(ids: RowId[]): void;
1083
+ /**
1084
+ * Remove a single row by index.
1085
+ */
1086
+ private removeRowByIndex;
1087
+ /**
1088
+ * Update indices after a row removal.
1089
+ */
1090
+ private reindexAfterRemoval;
1091
+ /**
1092
+ * Update a cell value.
1093
+ */
1094
+ updateCell(id: RowId, field: string, value: CellValue): void;
1095
+ /**
1096
+ * Update multiple fields on a row.
1097
+ */
1098
+ updateRow(id: RowId, data: Partial<TData>): void;
1099
+ /**
1100
+ * Set the sort model. Triggers full re-sort if model changed.
1101
+ */
1102
+ setSortModel(model: SortModel[]): void;
1103
+ /**
1104
+ * Get current sort model.
1105
+ */
1106
+ getSortModel(): SortModel[];
1107
+ /**
1108
+ * Set the filter model.
1109
+ */
1110
+ setFilterModel(model: FilterModel): void;
1111
+ /**
1112
+ * Get current filter model.
1113
+ */
1114
+ getFilterModel(): FilterModel;
1115
+ /**
1116
+ * Rebuild sorted indices (full re-sort).
1117
+ */
1118
+ private rebuildSortedIndices;
1119
+ /**
1120
+ * Rebuild hash cache for all rows.
1121
+ */
1122
+ private rebuildHashCache;
1123
+ /**
1124
+ * Compute and cache sort hashes for a row.
1125
+ */
1126
+ private computeRowHashes;
1127
+ /**
1128
+ * Compare two rows using cached hashes.
1129
+ */
1130
+ private compareRows;
1131
+ /**
1132
+ * Binary search for insertion position in sortedIndices.
1133
+ */
1134
+ private binarySearchInsertPosition;
1135
+ /**
1136
+ * Rebuild filtered indices.
1137
+ */
1138
+ private rebuildFilteredIndices;
1139
+ /**
1140
+ * Check if a row passes the current filter.
1141
+ */
1142
+ private rowPassesFilter;
1143
+ /**
1144
+ * Get visible indices (filtered + sorted).
1145
+ */
1146
+ private getVisibleIndices;
1147
+ /**
1148
+ * Rebuild distinct values cache for all fields.
1149
+ */
1150
+ private rebuildDistinctValues;
1151
+ /**
1152
+ * Update distinct values when a row is added or removed.
1153
+ */
1154
+ private updateDistinctValuesForRow;
1155
+ /**
1156
+ * Update distinct value for a specific field when cell value changes.
1157
+ */
1158
+ private updateDistinctValueForField;
1159
+ }
1160
+ //#endregion
1161
+ //#region src/indexed-data-store/field-helpers.d.ts
1162
+ /**
1163
+ * Default field value accessor supporting dot notation.
1164
+ * @example
1165
+ * getFieldValue({ user: { name: "John" } }, "user.name") // "John"
1166
+ */
1167
+ declare function getFieldValue<TData extends Row>(row: TData, field: string): CellValue;
1168
+ /**
1169
+ * Set field value supporting dot notation.
1170
+ * Creates nested objects if they don't exist.
1171
+ * @example
1172
+ * const obj = { user: {} };
1173
+ * setFieldValue(obj, "user.name", "John");
1174
+ * // obj is now { user: { name: "John" } }
1175
+ */
1176
+ declare function setFieldValue<TData extends Row>(row: TData, field: string, value: CellValue): void;
1177
+ //#endregion
1178
+ //#region src/indexed-data-store/sorting.d.ts
1179
+ /**
1180
+ * Convert a string to a sortable number using first 10 characters.
1181
+ * Uses base-36 encoding (a-z = 0-25, 0-9 = 26-35).
1182
+ */
1183
+ declare function stringToSortableNumber(str: string): number;
1184
+ /**
1185
+ * Compare two cell values for sorting.
1186
+ * Handles null/undefined, arrays, numbers, dates, and strings.
1187
+ */
1188
+ declare function compareValues(a: CellValue, b: CellValue): number;
1189
+ /**
1190
+ * Compute a sortable hash for a cell value.
1191
+ * Used for fast comparisons in sorted indices.
1192
+ */
1193
+ declare function computeValueHash(value: CellValue): number;
1194
+ //#endregion
1195
+ //#region src/indexed-data-store/filtering.d.ts
1196
+ /**
1197
+ * Text filter condition type
1198
+ */
1199
+ interface TextCondition {
1200
+ type: "text";
1201
+ operator: string;
1202
+ value?: string;
1203
+ selectedValues?: Set<string>;
1204
+ includeBlank?: boolean;
1205
+ }
1206
+ /**
1207
+ * Number filter condition type
1208
+ */
1209
+ interface NumberCondition {
1210
+ type: "number";
1211
+ operator: string;
1212
+ value?: number;
1213
+ valueTo?: number;
1214
+ }
1215
+ /**
1216
+ * Date filter condition type
1217
+ */
1218
+ interface DateCondition {
1219
+ type: "date";
1220
+ operator: string;
1221
+ value?: Date | string;
1222
+ valueTo?: Date | string;
1223
+ }
1224
+ /**
1225
+ * Check if two dates are on the same day.
1226
+ */
1227
+ declare function isSameDay(a: Date, b: Date): boolean;
1228
+ /**
1229
+ * Evaluate a text filter condition against a cell value.
1230
+ */
1231
+ declare function evaluateTextCondition(cellValue: CellValue, condition: TextCondition): boolean;
1232
+ /**
1233
+ * Evaluate a number filter condition against a cell value.
1234
+ */
1235
+ declare function evaluateNumberCondition(cellValue: CellValue, condition: NumberCondition): boolean;
1236
+ /**
1237
+ * Evaluate a date filter condition against a cell value.
1238
+ */
1239
+ declare function evaluateDateCondition(cellValue: CellValue, condition: DateCondition): boolean;
1240
+ /**
1241
+ * Evaluate a column filter model against a cell value.
1242
+ * Uses left-to-right evaluation with per-condition operators.
1243
+ */
1244
+ declare function evaluateColumnFilter(cellValue: CellValue, filter: ColumnFilterModel): boolean;
1245
+ /**
1246
+ * Check if a row passes all filters in a filter model.
1247
+ */
1248
+ declare function rowPassesFilter<TData extends Row>(row: TData, filterModel: FilterModel, getFieldValue: (row: TData, field: string) => CellValue): boolean;
1249
+ //#endregion
1250
+ //#region src/transaction-manager.d.ts
1251
+ interface AddTransaction<TData> {
1252
+ type: "ADD";
1253
+ rows: TData[];
1254
+ }
1255
+ interface RemoveTransaction {
1256
+ type: "REMOVE";
1257
+ rowIds: RowId[];
1258
+ }
1259
+ interface UpdateCellTransaction {
1260
+ type: "UPDATE_CELL";
1261
+ rowId: RowId;
1262
+ field: string;
1263
+ value: CellValue;
1264
+ }
1265
+ interface UpdateRowTransaction<TData> {
1266
+ type: "UPDATE_ROW";
1267
+ rowId: RowId;
1268
+ data: Partial<TData>;
1269
+ }
1270
+ type Transaction<TData> = AddTransaction<TData> | RemoveTransaction | UpdateCellTransaction | UpdateRowTransaction<TData>;
1271
+ interface TransactionResult {
1272
+ added: number;
1273
+ removed: number;
1274
+ updated: number;
1275
+ }
1276
+ interface TransactionManagerOptions<TData extends Row> {
1277
+ /** Debounce time in milliseconds. Default 50. Set to 0 for sync. */
1278
+ debounceMs: number;
1279
+ /** The indexed data store to apply transactions to */
1280
+ store: IndexedDataStore<TData>;
1281
+ /** Callback when transactions are processed */
1282
+ onProcessed?: (result: TransactionResult) => void;
1283
+ }
1284
+ /**
1285
+ * Manages a queue of data mutations with debounced batch processing.
1286
+ * Supports ADD, REMOVE, UPDATE_CELL, and UPDATE_ROW operations.
1287
+ */
1288
+ declare class TransactionManager<TData extends Row = Row> {
1289
+ private queue;
1290
+ private debounceTimer;
1291
+ private pendingPromise;
1292
+ private options;
1293
+ constructor(options: TransactionManagerOptions<TData>);
1294
+ /**
1295
+ * Queue rows to be added.
1296
+ */
1297
+ add(rows: TData[]): void;
1298
+ /**
1299
+ * Queue rows to be removed by ID.
1300
+ */
1301
+ remove(rowIds: RowId[]): void;
1302
+ /**
1303
+ * Queue a cell update.
1304
+ */
1305
+ updateCell(rowId: RowId, field: string, value: CellValue): void;
1306
+ /**
1307
+ * Queue a row update (multiple fields).
1308
+ */
1309
+ updateRow(rowId: RowId, data: Partial<TData>): void;
1310
+ /**
1311
+ * Force immediate processing of queued transactions.
1312
+ * Returns a promise that resolves when processing is complete.
1313
+ */
1314
+ flush(): Promise<void>;
1315
+ /**
1316
+ * Check if there are pending transactions.
1317
+ */
1318
+ hasPending(): boolean;
1319
+ /**
1320
+ * Get count of pending transactions.
1321
+ */
1322
+ getPendingCount(): number;
1323
+ /**
1324
+ * Clear all pending transactions without processing.
1325
+ */
1326
+ clear(): void;
1327
+ /**
1328
+ * Schedule processing after throttle delay.
1329
+ * Uses throttle pattern: if a timer is already pending, new transactions
1330
+ * are added to the queue but don't reset the timer. This ensures updates
1331
+ * are processed even when they arrive faster than the throttle interval.
1332
+ */
1333
+ private scheduleProcessing;
1334
+ /**
1335
+ * Process all queued transactions.
1336
+ */
1337
+ private processQueue;
1338
+ }
1339
+ //#endregion
1340
+ //#region src/data-source/mutable-data-source.d.ts
1341
+ /** Callback for data change notifications */
1342
+ type DataChangeListener = (result: TransactionResult) => void;
1343
+ /**
1344
+ * Data source with mutation capabilities.
1345
+ * Extends DataSource with add, remove, and update operations.
1346
+ */
1347
+ interface MutableDataSource<TData = Row> extends DataSource<TData> {
1348
+ /** Add rows to the data source. Queued and processed after debounce. */
1349
+ addRows(rows: TData[]): void;
1350
+ /** Remove rows by ID. Queued and processed after debounce. */
1351
+ removeRows(ids: RowId[]): void;
1352
+ /** Update a cell value. Queued and processed after debounce. */
1353
+ updateCell(id: RowId, field: string, value: CellValue): void;
1354
+ /** Update multiple fields on a row. Queued and processed after debounce. */
1355
+ updateRow(id: RowId, data: Partial<TData>): void;
1356
+ /** Force immediate processing of queued transactions. */
1357
+ flushTransactions(): Promise<void>;
1358
+ /** Check if there are pending transactions. */
1359
+ hasPendingTransactions(): boolean;
1360
+ /** Get distinct values for a field (for filter UI). */
1361
+ getDistinctValues(field: string): CellValue[];
1362
+ /** Get a row by ID. */
1363
+ getRowById(id: RowId): TData | undefined;
1364
+ /** Get total row count. */
1365
+ getTotalRowCount(): number;
1366
+ /** Subscribe to data change notifications. Returns unsubscribe function. */
1367
+ subscribe(listener: DataChangeListener): () => void;
1368
+ }
1369
+ interface MutableClientDataSourceOptions<TData> {
1370
+ /** Function to extract unique ID from row. Required. */
1371
+ getRowId: (row: TData) => RowId;
1372
+ /** Custom field accessor for nested properties. */
1373
+ getFieldValue?: (row: TData, field: string) => CellValue;
1374
+ /** Debounce time for transactions in ms. Default 50. Set to 0 for sync. */
1375
+ debounceMs?: number;
1376
+ /** Callback when transactions are processed. */
1377
+ onTransactionProcessed?: (result: TransactionResult) => void;
1378
+ }
1379
+ /**
1380
+ * Creates a mutable client-side data source with transaction support.
1381
+ * Uses IndexedDataStore for efficient incremental operations.
1382
+ */
1383
+ declare function createMutableClientDataSource<TData extends Row = Row>(data: TData[], options: MutableClientDataSourceOptions<TData>): MutableDataSource<TData>;
567
1384
  //#endregion
568
1385
  //#region src/worker-manager.d.ts
569
1386
  /**
@@ -603,7 +1420,9 @@ declare class SortWorkerManager {
603
1420
  */
604
1421
  sortStringHashes(hashChunks: Float64Array[], direction: SortDirection, originalStrings: string[]): Promise<Uint32Array>;
605
1422
  /**
606
- * Resolve hash collisions by re-sorting collision groups using localeCompare.
1423
+ * Resolve hash collisions by re-sorting collision runs using localeCompare.
1424
+ * collisionRuns format: [start1, end1, start2, end2, ...] where each pair
1425
+ * defines a run of indices in the sorted array with identical hashes.
607
1426
  */
608
1427
  private resolveCollisions;
609
1428
  /**
@@ -630,5 +1449,144 @@ declare function getSharedSortWorker(): SortWorkerManager;
630
1449
  */
631
1450
  declare function terminateSharedSortWorker(): void;
632
1451
  //#endregion
633
- export { type AssignSlotInstruction, type BatchInstructionListener, type CancelFillInstruction, type CellDataType, type CellPosition, type CellRange, type CellRendererParams, type CellValue, type ColumnDefinition, type CommitEditInstruction, type CommitFillInstruction, type CreateSlotInstruction, type DataErrorInstruction, type DataLoadedInstruction, type DataLoadingInstruction, type DataSource, type DataSourceRequest, type DataSourceResponse, type DestroySlotInstruction, type Direction, type EditRendererParams, type EditState, type FillHandleState, FillManager, type FilterModel, GridCore, type GridCoreOptions, type GridInstruction, type HeaderRendererParams, type InstructionListener, type MoveSlotInstruction, type Row, SelectionManager, type SelectionState, type SetActiveCellInstruction, type SetContentSizeInstruction, type SetSelectionRangeInstruction, type SlotState, type SortDirection, type SortModel, SortWorkerManager, type StartEditInstruction, type StartFillInstruction, type StopEditInstruction, type UpdateFillInstruction, type UpdateHeaderInstruction, createClientDataSource, createDataSourceFromArray, createServerDataSource, getSharedSortWorker, terminateSharedSortWorker };
634
- //# sourceMappingURL=index.d.ts.map
1452
+ //#region src/styles/variables.d.ts
1453
+ declare const variablesStyles = "\n/* =============================================================================\n GP Grid - CSS Variables for Theming\n ============================================================================= */\n\n.gp-grid-container {\n /* Colors - Light Mode (default) */\n --gp-grid-bg: #ffffff;\n --gp-grid-bg-alt: #f8f9fa;\n --gp-grid-text: #212529;\n --gp-grid-text-secondary: #6c757d;\n --gp-grid-text-muted: #adb5bd;\n --gp-grid-border: #dee2e6;\n --gp-grid-border-light: #e9ecef;\n\n /* Header */\n --gp-grid-header-bg: #f1f3f5;\n --gp-grid-header-text: #212529;\n\n /* Selection */\n --gp-grid-primary: #228be6;\n --gp-grid-primary-light: #e7f5ff;\n --gp-grid-primary-border: #74c0fc;\n --gp-grid-hover: #f1f3f5;\n\n /* Filter */\n --gp-grid-filter-bg: #f8f9fa;\n --gp-grid-input-bg: #ffffff;\n --gp-grid-input-border: #ced4da;\n\n /* Error */\n --gp-grid-error-bg: #fff5f5;\n --gp-grid-error-text: #c92a2a;\n\n /* Loading */\n --gp-grid-loading-bg: rgba(255, 255, 255, 0.95);\n --gp-grid-loading-text: #495057;\n\n /* Scrollbar */\n --gp-grid-scrollbar-track: #f1f3f5;\n --gp-grid-scrollbar-thumb: #ced4da;\n --gp-grid-scrollbar-thumb-hover: #adb5bd;\n}\n\n/* Dark Mode */\n.gp-grid-container--dark {\n --gp-grid-bg: #1a1b1e;\n --gp-grid-bg-alt: #25262b;\n --gp-grid-text: #c1c2c5;\n --gp-grid-text-secondary: #909296;\n --gp-grid-text-muted: #5c5f66;\n --gp-grid-border: #373a40;\n --gp-grid-border-light: #2c2e33;\n\n /* Header */\n --gp-grid-header-bg: #25262b;\n --gp-grid-header-text: #c1c2c5;\n\n /* Selection */\n --gp-grid-primary: #339af0;\n --gp-grid-primary-light: #1c3d5a;\n --gp-grid-primary-border: #1c7ed6;\n --gp-grid-hover: #2c2e33;\n\n /* Filter */\n --gp-grid-filter-bg: #25262b;\n --gp-grid-input-bg: #1a1b1e;\n --gp-grid-input-border: #373a40;\n\n /* Error */\n --gp-grid-error-bg: #2c1a1a;\n --gp-grid-error-text: #ff6b6b;\n\n /* Loading */\n --gp-grid-loading-bg: rgba(26, 27, 30, 0.95);\n --gp-grid-loading-text: #c1c2c5;\n\n /* Scrollbar */\n --gp-grid-scrollbar-track: #25262b;\n --gp-grid-scrollbar-thumb: #373a40;\n --gp-grid-scrollbar-thumb-hover: #4a4d52;\n}\n";
1454
+ //#endregion
1455
+ //#region src/styles/container.d.ts
1456
+ declare const containerStyles = "\n/* =============================================================================\n GP Grid - Clean Flat Design\n ============================================================================= */\n\n/* Grid Container */\n.gp-grid-container {\n outline: none;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 13px;\n line-height: 1.5;\n color: var(--gp-grid-text);\n background-color: var(--gp-grid-bg);\n border: 1px solid var(--gp-grid-border);\n border-radius: 6px;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.gp-grid-container:focus {\n outline: none;\n border-color: var(--gp-grid-primary);\n}\n";
1457
+ //#endregion
1458
+ //#region src/styles/header.d.ts
1459
+ declare const headerStyles = "\n/* =============================================================================\n Header\n ============================================================================= */\n\n.gp-grid-header {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 100;\n background-color: var(--gp-grid-header-bg);\n border-bottom: 1px solid var(--gp-grid-border);\n}\n\n.gp-grid-container .gp-grid-header-cell {\n position: absolute;\n box-sizing: border-box;\n border-right: 1px solid var(--gp-grid-border);\n font-weight: 600;\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--gp-grid-header-text);\n cursor: pointer;\n user-select: none;\n display: flex;\n align-items: center;\n padding: 0 12px;\n background-color: transparent;\n transition: background-color 0.1s ease;\n}\n\n.gp-grid-container .gp-grid-header-cell:hover {\n background-color: var(--gp-grid-hover);\n}\n\n.gp-grid-container .gp-grid-header-cell:active {\n background-color: var(--gp-grid-border-light);\n}\n\n.gp-grid-container .gp-grid-header-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--gp-grid-header-text);\n}\n\n/* Header icons container */\n.gp-grid-header-icons {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: auto;\n}\n\n/* Stacked sort arrows */\n.gp-grid-sort-arrows {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 2px;\n margin-left: 6px;\n}\n\n.gp-grid-sort-arrows-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.gp-grid-sort-arrow-up,\n.gp-grid-sort-arrow-down {\n opacity: 0.35;\n transition: opacity 0.15s ease, color 0.15s ease;\n color: var(--gp-grid-text);\n}\n\n.gp-grid-sort-arrow-up.active,\n.gp-grid-sort-arrow-down.active {\n opacity: 1;\n color: var(--gp-grid-primary);\n}\n\n.gp-grid-sort-index {\n font-size: 9px;\n color: var(--gp-grid-primary);\n font-weight: 600;\n}\n\n/* Filter icon */\n.gp-grid-filter-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 4px;\n cursor: pointer;\n color: var(--gp-grid-text-secondary);\n transition: background-color 0.15s ease, color 0.15s ease;\n margin-left: 2px;\n}\n\n.gp-grid-filter-icon:hover {\n background-color: var(--gp-grid-hover);\n color: var(--gp-grid-primary);\n}\n\n.gp-grid-filter-icon.active {\n color: var(--gp-grid-primary);\n background-color: var(--gp-grid-primary-light);\n}\n";
1460
+ //#endregion
1461
+ //#region src/styles/cells.d.ts
1462
+ declare const cellStyles = "\n/* =============================================================================\n Data Cells\n ============================================================================= */\n\n.gp-grid-row {\n position: absolute;\n top: 0;\n left: 0;\n}\n\n.gp-grid-cell {\n position: absolute;\n top: 0;\n box-sizing: border-box;\n padding: 0 12px;\n display: flex;\n align-items: center;\n cursor: cell;\n color: var(--gp-grid-text);\n border-right: 1px solid var(--gp-grid-border-light);\n border-bottom: 1px solid var(--gp-grid-border-light);\n background-color: var(--gp-grid-bg);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: none;\n -webkit-user-select: none;\n}\n\n/* Alternating row colors */\n.gp-grid-row--even .gp-grid-cell {\n background-color: var(--gp-grid-bg-alt);\n}\n\n.gp-grid-cell:hover {\n background-color: var(--gp-grid-hover) !important;\n}\n\n/* Active cell (focused) */\n.gp-grid-cell--active {\n background-color: var(--gp-grid-primary-light) !important;\n border: 2px solid var(--gp-grid-primary) !important;\n outline: none;\n z-index: 5;\n padding: 0 11px;\n}\n\n/* Selected cells (range selection) */\n.gp-grid-cell--selected {\n background-color: var(--gp-grid-primary-light) !important;\n}\n\n/* Editing cell */\n.gp-grid-cell--editing {\n background-color: var(--gp-grid-bg) !important;\n border: 2px solid var(--gp-grid-primary) !important;\n padding: 0 !important;\n z-index: 10;\n}\n\n/* =============================================================================\n Fill Handle (drag to fill)\n ============================================================================= */\n\n.gp-grid-fill-handle {\n position: absolute;\n width: 8px;\n height: 8px;\n background-color: var(--gp-grid-primary);\n border: 2px solid var(--gp-grid-bg);\n cursor: crosshair;\n z-index: 100;\n pointer-events: auto;\n box-sizing: border-box;\n border-radius: 1px;\n}\n\n.gp-grid-fill-handle:hover {\n transform: scale(1.2);\n}\n\n/* Fill preview (cells being filled) */\n.gp-grid-cell--fill-preview {\n background-color: var(--gp-grid-primary-light) !important;\n border: 1px dashed var(--gp-grid-primary) !important;\n}\n\n/* =============================================================================\n Edit Input\n ============================================================================= */\n\n.gp-grid-edit-input {\n width: 100%;\n height: 100%;\n padding: 0 11px;\n font-family: inherit;\n font-size: inherit;\n color: var(--gp-grid-text);\n border: none;\n background-color: transparent;\n}\n\n.gp-grid-edit-input:focus {\n outline: none;\n}\n";
1463
+ //#endregion
1464
+ //#region src/styles/states.d.ts
1465
+ declare const statesStyles = "\n/* =============================================================================\n Loading & Error States\n ============================================================================= */\n\n.gp-grid-loading {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 12px 20px;\n background-color: var(--gp-grid-loading-bg);\n color: var(--gp-grid-loading-text);\n border-radius: 6px;\n border: 1px solid var(--gp-grid-border);\n font-weight: 500;\n font-size: 13px;\n z-index: 1000;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.gp-grid-loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--gp-grid-border);\n border-top-color: var(--gp-grid-primary);\n border-radius: 50%;\n animation: gp-grid-spin 0.7s linear infinite;\n}\n\n@keyframes gp-grid-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.gp-grid-error {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n padding: 12px 20px;\n background-color: var(--gp-grid-error-bg);\n color: var(--gp-grid-error-text);\n border-radius: 6px;\n border: 1px solid var(--gp-grid-error-text);\n font-weight: 500;\n font-size: 13px;\n z-index: 1000;\n max-width: 80%;\n text-align: center;\n}\n\n/* =============================================================================\n Empty State\n ============================================================================= */\n\n.gp-grid-empty {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: var(--gp-grid-text-muted);\n font-size: 14px;\n text-align: center;\n}\n";
1466
+ //#endregion
1467
+ //#region src/styles/scrollbar.d.ts
1468
+ declare const scrollbarStyles = "\n/* =============================================================================\n Scrollbar Styling\n ============================================================================= */\n\n.gp-grid-container::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.gp-grid-container::-webkit-scrollbar-track {\n background-color: var(--gp-grid-scrollbar-track);\n}\n\n.gp-grid-container::-webkit-scrollbar-thumb {\n background-color: var(--gp-grid-scrollbar-thumb);\n border-radius: 4px;\n}\n\n.gp-grid-container::-webkit-scrollbar-thumb:hover {\n background-color: var(--gp-grid-scrollbar-thumb-hover);\n}\n\n.gp-grid-container::-webkit-scrollbar-corner {\n background-color: var(--gp-grid-scrollbar-track);\n}\n";
1469
+ //#endregion
1470
+ //#region src/styles/filters.d.ts
1471
+ declare const filtersStyles = "\n/* =============================================================================\n Filter Popup\n ============================================================================= */\n\n.gp-grid-filter-popup {\n background-color: var(--gp-grid-bg);\n border: 1px solid var(--gp-grid-border);\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n max-height: 400px;\n display: flex;\n flex-direction: column;\n font-size: 13px;\n}\n\n.gp-grid-filter-header {\n padding: 10px 12px;\n font-weight: 600;\n border-bottom: 1px solid var(--gp-grid-border-light);\n color: var(--gp-grid-header-text);\n}\n\n.gp-grid-filter-content {\n padding: 10px 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n overflow: hidden;\n}\n\n/* Mode toggle (Values / Condition) */\n.gp-grid-filter-mode-toggle {\n display: flex;\n gap: 4px;\n background-color: var(--gp-grid-bg-alt);\n border-radius: 4px;\n padding: 2px;\n}\n\n.gp-grid-filter-mode-toggle button {\n flex: 1;\n padding: 6px 10px;\n font-size: 11px;\n font-family: inherit;\n border: none;\n border-radius: 3px;\n background-color: transparent;\n color: var(--gp-grid-text-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease;\n}\n\n.gp-grid-filter-mode-toggle button:hover {\n color: var(--gp-grid-text);\n}\n\n.gp-grid-filter-mode-toggle button.active {\n background-color: var(--gp-grid-bg);\n color: var(--gp-grid-text);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n/* Info message for too many values */\n.gp-grid-filter-info {\n font-size: 11px;\n color: var(--gp-grid-text-secondary);\n padding: 6px 8px;\n background-color: var(--gp-grid-bg-alt);\n border-radius: 4px;\n}\n\n/* Search input in filter */\n.gp-grid-filter-search {\n width: 100%;\n height: 30px;\n padding: 0 10px;\n font-family: inherit;\n font-size: 12px;\n border: 1px solid var(--gp-grid-input-border);\n border-radius: 4px;\n background-color: var(--gp-grid-input-bg);\n color: var(--gp-grid-text);\n box-sizing: border-box;\n}\n\n.gp-grid-filter-search:focus {\n outline: none;\n border-color: var(--gp-grid-primary);\n}\n\n/* Select All / Deselect All actions */\n.gp-grid-filter-actions {\n display: flex;\n gap: 8px;\n}\n\n.gp-grid-filter-actions button {\n flex: 1;\n padding: 4px 8px;\n font-size: 11px;\n font-family: inherit;\n border: 1px solid var(--gp-grid-input-border);\n border-radius: 3px;\n background-color: var(--gp-grid-bg);\n color: var(--gp-grid-text);\n cursor: pointer;\n}\n\n.gp-grid-filter-actions button:hover:not(:disabled) {\n background-color: var(--gp-grid-hover);\n}\n\n.gp-grid-filter-actions button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Checkbox list */\n.gp-grid-filter-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 4px;\n border: 1px solid var(--gp-grid-border-light);\n border-radius: 4px;\n padding: 6px;\n}\n\n.gp-grid-filter-option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 6px;\n border-radius: 3px;\n cursor: pointer;\n}\n\n.gp-grid-filter-option:hover {\n background-color: var(--gp-grid-hover);\n}\n\n.gp-grid-filter-option input[type=\"checkbox\"] {\n margin: 0;\n cursor: pointer;\n}\n\n.gp-grid-filter-option span {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.gp-grid-filter-blank {\n font-style: italic;\n color: var(--gp-grid-text-muted);\n}\n\n/* Filter condition row (for number/date filters) */\n.gp-grid-filter-condition {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.gp-grid-filter-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.gp-grid-filter-row select {\n height: 30px;\n padding: 0 6px;\n font-family: inherit;\n font-size: 12px;\n border: 1px solid var(--gp-grid-input-border);\n border-radius: 4px;\n background-color: var(--gp-grid-input-bg);\n color: var(--gp-grid-text);\n cursor: pointer;\n}\n\n.gp-grid-filter-row input[type=\"number\"],\n.gp-grid-filter-row input[type=\"date\"],\n.gp-grid-filter-row input[type=\"text\"],\n.gp-grid-filter-text-input {\n flex: 1;\n height: 30px;\n padding: 0 8px;\n font-family: inherit;\n font-size: 12px;\n border: 1px solid var(--gp-grid-input-border);\n border-radius: 4px;\n background-color: var(--gp-grid-input-bg);\n color: var(--gp-grid-text);\n min-width: 0;\n box-sizing: border-box;\n}\n\n.gp-grid-filter-row input:focus {\n outline: none;\n border-color: var(--gp-grid-primary);\n}\n\n.gp-grid-filter-to {\n font-size: 11px;\n color: var(--gp-grid-text-secondary);\n}\n\n.gp-grid-filter-remove {\n width: 24px;\n height: 24px;\n padding: 0;\n font-size: 16px;\n line-height: 1;\n border: none;\n border-radius: 3px;\n background-color: transparent;\n color: var(--gp-grid-text-muted);\n cursor: pointer;\n}\n\n.gp-grid-filter-remove:hover {\n background-color: var(--gp-grid-error-bg);\n color: var(--gp-grid-error-text);\n}\n\n/* AND/OR combination toggle */\n.gp-grid-filter-combination {\n display: flex;\n gap: 4px;\n margin-bottom: 4px;\n}\n\n.gp-grid-filter-combination button {\n flex: 1;\n padding: 4px 8px;\n font-size: 10px;\n font-family: inherit;\n border: 1px solid var(--gp-grid-input-border);\n border-radius: 3px;\n background-color: var(--gp-grid-bg);\n color: var(--gp-grid-text-secondary);\n cursor: pointer;\n}\n\n.gp-grid-filter-combination button.active {\n background-color: var(--gp-grid-primary);\n border-color: var(--gp-grid-primary);\n color: #fff;\n}\n\n/* Add condition button */\n.gp-grid-filter-add {\n width: 100%;\n padding: 6px;\n font-size: 11px;\n font-family: inherit;\n border: 1px dashed var(--gp-grid-border);\n border-radius: 4px;\n background-color: transparent;\n color: var(--gp-grid-text-secondary);\n cursor: pointer;\n}\n\n.gp-grid-filter-add:hover {\n background-color: var(--gp-grid-hover);\n border-color: var(--gp-grid-primary);\n color: var(--gp-grid-primary);\n}\n\n/* Apply / Clear buttons */\n.gp-grid-filter-buttons {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--gp-grid-border-light);\n}\n\n.gp-grid-filter-btn-clear,\n.gp-grid-filter-btn-apply {\n flex: 1;\n padding: 8px 12px;\n font-size: 12px;\n font-family: inherit;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.gp-grid-filter-btn-clear {\n border: 1px solid var(--gp-grid-input-border);\n background-color: var(--gp-grid-bg);\n color: var(--gp-grid-text);\n}\n\n.gp-grid-filter-btn-clear:hover {\n background-color: var(--gp-grid-hover);\n}\n\n.gp-grid-filter-btn-apply {\n border: 1px solid var(--gp-grid-primary);\n background-color: var(--gp-grid-primary);\n color: #fff;\n}\n\n.gp-grid-filter-btn-apply:hover {\n opacity: 0.9;\n}\n";
1472
+ //#endregion
1473
+ //#region src/styles/index.d.ts
1474
+ /**
1475
+ * Combined grid styles from all modules
1476
+ */
1477
+ declare const gridStyles: string;
1478
+ /**
1479
+ * Inject grid styles into the document head.
1480
+ * This is called automatically when the Grid component mounts.
1481
+ * Styles are only injected once, even if multiple Grid instances exist.
1482
+ */
1483
+ declare function injectStyles(): void;
1484
+ //#endregion
1485
+ //#region src/utils/positioning.d.ts
1486
+ /**
1487
+ * Calculate cumulative column positions (prefix sums)
1488
+ * Returns an array where positions[i] is the left position of column i
1489
+ * positions[columns.length] is the total width
1490
+ */
1491
+ declare function calculateColumnPositions(columns: ColumnDefinition[]): number[];
1492
+ /**
1493
+ * Get total width from column positions
1494
+ */
1495
+ declare function getTotalWidth(columnPositions: number[]): number;
1496
+ /**
1497
+ * Find column index at a given X coordinate
1498
+ */
1499
+ declare function findColumnAtX(x: number, columnPositions: number[]): number;
1500
+ //#endregion
1501
+ //#region src/utils/classNames.d.ts
1502
+ /**
1503
+ * Check if a cell is within the selection range
1504
+ */
1505
+ declare function isCellSelected(row: number, col: number, selectionRange: CellRange | null): boolean;
1506
+ /**
1507
+ * Check if a cell is the active cell
1508
+ */
1509
+ declare function isCellActive(row: number, col: number, activeCell: CellPosition | null): boolean;
1510
+ /**
1511
+ * Check if a row is within the visible range (not in overscan)
1512
+ */
1513
+ declare function isRowVisible(row: number, visibleRowRange: {
1514
+ start: number;
1515
+ end: number;
1516
+ } | null): boolean;
1517
+ /**
1518
+ * Check if a cell is being edited
1519
+ */
1520
+ declare function isCellEditing(row: number, col: number, editingCell: {
1521
+ row: number;
1522
+ col: number;
1523
+ } | null): boolean;
1524
+ /**
1525
+ * Check if a cell is in the fill preview range (vertical-only fill)
1526
+ */
1527
+ declare function isCellInFillPreview(row: number, col: number, isDraggingFill: boolean, fillSourceRange: {
1528
+ startRow: number;
1529
+ startCol: number;
1530
+ endRow: number;
1531
+ endCol: number;
1532
+ } | null, fillTarget: {
1533
+ row: number;
1534
+ col: number;
1535
+ } | null): boolean;
1536
+ /**
1537
+ * Build cell CSS classes based on state
1538
+ */
1539
+ declare function buildCellClasses(isActive: boolean, isSelected: boolean, isEditing: boolean, inFillPreview: boolean): string;
1540
+ //#endregion
1541
+ //#region src/types/ui-state.d.ts
1542
+ interface SlotData {
1543
+ slotId: string;
1544
+ rowIndex: number;
1545
+ rowData: Row;
1546
+ translateY: number;
1547
+ }
1548
+ interface HeaderData {
1549
+ column: ColumnDefinition;
1550
+ sortDirection?: SortDirection;
1551
+ sortIndex?: number;
1552
+ sortable: boolean;
1553
+ filterable: boolean;
1554
+ hasFilter: boolean;
1555
+ }
1556
+ interface FilterPopupState {
1557
+ isOpen: boolean;
1558
+ colIndex: number;
1559
+ column: ColumnDefinition | null;
1560
+ anchorRect: {
1561
+ top: number;
1562
+ left: number;
1563
+ width: number;
1564
+ height: number;
1565
+ } | null;
1566
+ distinctValues: CellValue[];
1567
+ currentFilter?: ColumnFilterModel;
1568
+ }
1569
+ interface GridState {
1570
+ slots: Map<string, SlotData>;
1571
+ activeCell: CellPosition | null;
1572
+ selectionRange: CellRange | null;
1573
+ editingCell: {
1574
+ row: number;
1575
+ col: number;
1576
+ initialValue: CellValue;
1577
+ } | null;
1578
+ contentWidth: number;
1579
+ contentHeight: number;
1580
+ headers: Map<number, HeaderData>;
1581
+ filterPopup: FilterPopupState | null;
1582
+ isLoading: boolean;
1583
+ error: string | null;
1584
+ totalRows: number;
1585
+ /** Visible row range (start inclusive, end inclusive). Used to prevent selection showing in overscan. */
1586
+ visibleRowRange: {
1587
+ start: number;
1588
+ end: number;
1589
+ } | null;
1590
+ }
1591
+ //#endregion
1592
+ export { type AssignSlotInstruction, type BatchInstructionListener, type CancelFillInstruction, type CellDataType, type CellPosition, type CellRange, type CellRendererParams, type CellValue, type CloseFilterPopupInstruction, type ColumnDefinition, type ColumnFilterModel, type CommitEditInstruction, type CommitFillInstruction, type ContainerBounds, type CreateSlotInstruction, type DataChangeListener, type DataErrorInstruction, type DataLoadedInstruction, type DataLoadingInstruction, type DataSource, type DataSourceRequest, type DataSourceResponse, type DateFilterCondition, type DateFilterOperator, type DestroySlotInstruction, type Direction, type DragMoveResult, type DragState, EditManager, type EditManagerOptions, type EditRendererParams, type EditState, type FillHandleState, FillManager, type FilterCombination, type FilterCondition, type FilterModel, type FilterPopupState, GridCore, type GridCoreOptions, type GridInstruction, type GridState, type HeaderData, type HeaderRendererParams, IndexedDataStore, type IndexedDataStoreOptions, InputHandler, type InputHandlerDeps, type InputResult, type InstructionListener, type KeyEventData, type KeyboardResult, type MoveSlotInstruction, type MutableClientDataSourceOptions, type MutableDataSource, type NumberFilterCondition, type NumberFilterOperator, type OpenFilterPopupInstruction, type PointerEventData, type Row, type RowId, type RowSortCache, type RowsAddedInstruction, type RowsRemovedInstruction, type RowsUpdatedInstruction, SelectionManager, type SelectionState, type SetActiveCellInstruction, type SetContentSizeInstruction, type SetSelectionRangeInstruction, type SlotData, type BatchInstructionListener$1 as SlotPoolBatchListener, SlotPoolManager, type SlotPoolManagerOptions, type SlotState, type SortDirection, type SortModel, SortWorkerManager, type StartEditInstruction, type StartFillInstruction, type StopEditInstruction, type TextFilterCondition, type TextFilterOperator, type Transaction, TransactionManager, type TransactionManagerOptions, type TransactionProcessedInstruction, type TransactionResult, type UpdateFillInstruction, type UpdateHeaderInstruction, buildCellClasses, calculateColumnPositions, cellStyles, compareValues, computeValueHash, containerStyles, createClientDataSource, createDataSourceFromArray, createMutableClientDataSource, createServerDataSource, evaluateColumnFilter, evaluateDateCondition, evaluateNumberCondition, evaluateTextCondition, filtersStyles, findColumnAtX, getFieldValue, getSharedSortWorker, getTotalWidth, gridStyles, headerStyles, injectStyles, isCellActive, isCellEditing, isCellInFillPreview, isCellSelected, isRowVisible, isSameDay, rowPassesFilter, scrollbarStyles, setFieldValue, statesStyles, stringToSortableNumber, terminateSharedSortWorker, variablesStyles };