gp-grid-vue 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -61,6 +61,81 @@ interface FillHandleState {
61
61
  targetCol: number;
62
62
  }
63
63
  //#endregion
64
+ //#region ../core/src/types/highlighting.d.ts
65
+ /**
66
+ * Minimal column info for highlighting context.
67
+ * Uses structural typing to avoid circular dependency with columns.ts.
68
+ */
69
+ interface HighlightColumnInfo {
70
+ field: string;
71
+ colId?: string;
72
+ }
73
+ /**
74
+ * Unified context for row, column, and cell highlighting.
75
+ *
76
+ * - Row context: `rowIndex` is set, `colIndex` is null
77
+ * - Column context: `colIndex` is set, `rowIndex` is null
78
+ * - Cell context: both `rowIndex` and `colIndex` are set
79
+ */
80
+ interface HighlightContext<TData = Record<string, unknown>> {
81
+ /** Row index. Null for column-only context. */
82
+ rowIndex: number | null;
83
+ /** Column index. Null for row-only context. */
84
+ colIndex: number | null;
85
+ /** Column definition. Present for column and cell contexts. */
86
+ column?: HighlightColumnInfo;
87
+ /** Row data. Present for row and cell contexts. */
88
+ rowData?: TData;
89
+ /** Currently hovered cell position, null if not hovering */
90
+ hoverPosition: CellPosition | null;
91
+ /** Currently active (focused) cell position */
92
+ activeCell: CellPosition | null;
93
+ /** Current selection range */
94
+ selectionRange: CellRange | null;
95
+ /** Whether this row/column/cell is hovered (respects hoverScope) */
96
+ isHovered: boolean;
97
+ /** Whether this row/column contains or is the active cell */
98
+ isActive: boolean;
99
+ /** Whether this row/column/cell overlaps or is in the selection range */
100
+ isSelected: boolean;
101
+ }
102
+ /**
103
+ * Grid-level highlighting options.
104
+ * Hover tracking is automatically enabled when any highlighting callback is defined.
105
+ * Each callback type has its own natural interpretation of `isHovered`:
106
+ * - computeRowClasses: isHovered = mouse is on any cell in this row
107
+ * - computeColumnClasses: isHovered = mouse is on any cell in this column
108
+ * - computeCellClasses: isHovered = mouse is on this exact cell
109
+ *
110
+ * For a crosshair effect, implement both computeRowClasses and computeColumnClasses.
111
+ */
112
+ interface HighlightingOptions<TData = Record<string, unknown>> {
113
+ /**
114
+ * Row-level class callback.
115
+ * Classes returned are applied to the row container element.
116
+ * Context has `rowIndex` set, `colIndex` is null.
117
+ * `isHovered` is true when the mouse is on any cell in this row.
118
+ * @returns Array of CSS class names
119
+ */
120
+ computeRowClasses?: (context: HighlightContext<TData>) => string[];
121
+ /**
122
+ * Column-level class callback.
123
+ * Classes returned are applied to all cells in that column (not header).
124
+ * Context has `colIndex` set, `rowIndex` is null.
125
+ * `isHovered` is true when the mouse is on any cell in this column.
126
+ * @returns Array of CSS class names
127
+ */
128
+ computeColumnClasses?: (context: HighlightContext<TData>) => string[];
129
+ /**
130
+ * Cell-level class callback.
131
+ * Classes returned are applied to individual cells for fine-grained control.
132
+ * Context has both `rowIndex` and `colIndex` set.
133
+ * `isHovered` is true only when the mouse is on this exact cell.
134
+ * @returns Array of CSS class names
135
+ */
136
+ computeCellClasses?: (context: HighlightContext<TData>) => string[];
137
+ }
138
+ //#endregion
64
139
  //#region ../core/src/types/columns.d.ts
65
140
  /** Column definition */
66
141
  interface ColumnDefinition {
@@ -74,10 +149,26 @@ interface ColumnDefinition {
74
149
  sortable?: boolean;
75
150
  /** Whether column is filterable. Default: true */
76
151
  filterable?: boolean;
152
+ /** Whether column is hidden. Hidden columns are not rendered but still exist in the definition. Default: false */
153
+ hidden?: boolean;
77
154
  /** Renderer key for adapter lookup, or inline renderer function */
78
155
  cellRenderer?: string;
79
156
  editRenderer?: string;
80
157
  headerRenderer?: string;
158
+ /**
159
+ * Per-column override for column-level highlighting.
160
+ * If defined, overrides grid-level computeColumnClasses for this column.
161
+ * Context has `colIndex` set, `rowIndex` is null.
162
+ * @returns Array of CSS class names to apply to all cells in this column
163
+ */
164
+ computeColumnClasses?: (context: HighlightContext) => string[];
165
+ /**
166
+ * Per-column override for cell-level highlighting.
167
+ * If defined, overrides grid-level computeCellClasses for cells in this column.
168
+ * Context has both `rowIndex` and `colIndex` set.
169
+ * @returns Array of CSS class names to apply to individual cells
170
+ */
171
+ computeCellClasses?: (context: HighlightContext) => string[];
81
172
  }
82
173
  //#endregion
83
174
  //#region ../core/src/types/filters.d.ts
@@ -189,6 +280,11 @@ interface SetActiveCellInstruction {
189
280
  type: "SET_ACTIVE_CELL";
190
281
  position: CellPosition | null;
191
282
  }
283
+ /** Set hover position instruction (for highlighting) */
284
+ interface SetHoverPositionInstruction {
285
+ type: "SET_HOVER_POSITION";
286
+ position: CellPosition | null;
287
+ }
192
288
  /** Set selection range instruction */
193
289
  interface SetSelectionRangeInstruction {
194
290
  type: "SET_SELECTION_RANGE";
@@ -298,19 +394,20 @@ interface DataErrorInstruction {
298
394
  /** Rows added instruction */
299
395
  interface RowsAddedInstruction {
300
396
  type: "ROWS_ADDED";
397
+ indices: number[];
301
398
  count: number;
302
399
  totalRows: number;
303
400
  }
304
401
  /** Rows removed instruction */
305
402
  interface RowsRemovedInstruction {
306
403
  type: "ROWS_REMOVED";
307
- count: number;
404
+ indices: number[];
308
405
  totalRows: number;
309
406
  }
310
407
  /** Rows updated instruction */
311
408
  interface RowsUpdatedInstruction {
312
409
  type: "ROWS_UPDATED";
313
- count: number;
410
+ indices: number[];
314
411
  }
315
412
  /** Transaction processed instruction */
316
413
  interface TransactionProcessedInstruction {
@@ -323,6 +420,7 @@ interface TransactionProcessedInstruction {
323
420
  type GridInstruction = /** Slot lifecycle */
324
421
  CreateSlotInstruction | DestroySlotInstruction | AssignSlotInstruction | MoveSlotInstruction
325
422
  /** Selection */ | SetActiveCellInstruction | SetSelectionRangeInstruction | UpdateVisibleRangeInstruction
423
+ /** Highlighting */ | SetHoverPositionInstruction
326
424
  /** Editing */ | StartEditInstruction | StopEditInstruction | CommitEditInstruction
327
425
  /** Layout */ | SetContentSizeInstruction | UpdateHeaderInstruction
328
426
  /** Filter popup */ | OpenFilterPopupInstruction | CloseFilterPopupInstruction
@@ -331,8 +429,6 @@ CreateSlotInstruction | DestroySlotInstruction | AssignSlotInstruction | MoveSlo
331
429
  /** Transactions */ | RowsAddedInstruction | RowsRemovedInstruction | RowsUpdatedInstruction | TransactionProcessedInstruction;
332
430
  /** Instruction listener: Single instruction Listener that receives a single instruction, used by frameworks to update their state */
333
431
  type InstructionListener = (instruction: GridInstruction) => void;
334
- /** Batch instruction listener: Batch instruction Listener that receives an array of instructions, used by frameworks to update their state */
335
- type BatchInstructionListener = (instructions: GridInstruction[]) => void;
336
432
  //#endregion
337
433
  //#region ../core/src/types/renderers.d.ts
338
434
  /** Cell renderer params */
@@ -406,6 +502,8 @@ interface GridCoreOptions<TData = Row> {
406
502
  transactionDebounceMs?: number;
407
503
  /** Function to extract unique ID from row. Required for mutations. */
408
504
  getRowId?: (row: TData) => RowId;
505
+ /** Row/column/cell highlighting configuration */
506
+ highlighting?: HighlightingOptions<TData>;
409
507
  }
410
508
  //#endregion
411
509
  //#region ../core/src/types/input.d.ts
@@ -486,10 +584,16 @@ interface InputHandlerDeps {
486
584
  getHeaderHeight: () => number;
487
585
  /** Get row height */
488
586
  getRowHeight: () => number;
489
- /** Get column positions array */
587
+ /** Get column positions array (indexed by visible column) */
490
588
  getColumnPositions: () => number[];
491
- /** Get column count */
589
+ /** Get visible column count */
492
590
  getColumnCount: () => number;
591
+ /**
592
+ * Convert visible column index to original column index.
593
+ * Used when columns can be hidden. Returns the original index for selection tracking.
594
+ * If not provided, visible index is used directly (no hidden columns).
595
+ */
596
+ getOriginalColumnIndex?: (visibleIndex: number) => number;
493
597
  }
494
598
  /** Current drag state for UI rendering */
495
599
  interface DragState {
@@ -506,6 +610,63 @@ interface DragState {
506
610
  } | null;
507
611
  }
508
612
  //#endregion
613
+ //#region ../core/src/utils/positioning.d.ts
614
+ /**
615
+ * Calculate cumulative column positions (prefix sums)
616
+ * Returns an array where positions[i] is the left position of column i
617
+ * positions[columns.length] is the total width
618
+ */
619
+ declare const calculateColumnPositions: (columns: ColumnDefinition[]) => number[];
620
+ /**
621
+ * Get total width from column positions
622
+ */
623
+ declare const getTotalWidth: (columnPositions: number[]) => number;
624
+ /**
625
+ * Find column index at a given X coordinate
626
+ */
627
+ declare const findColumnAtX: (x: number, columnPositions: number[]) => number;
628
+ //#endregion
629
+ //#region ../core/src/utils/classNames.d.ts
630
+ /**
631
+ * Check if a cell is within the selection range
632
+ */
633
+ declare const isCellSelected: (row: number, col: number, selectionRange: CellRange | null) => boolean;
634
+ /**
635
+ * Check if a cell is the active cell
636
+ */
637
+ declare const isCellActive: (row: number, col: number, activeCell: CellPosition | null) => boolean;
638
+ /**
639
+ * Check if a row is within the visible range (not in overscan)
640
+ */
641
+ declare const isRowVisible: (row: number, visibleRowRange: {
642
+ start: number;
643
+ end: number;
644
+ } | null) => boolean;
645
+ /**
646
+ * Check if a cell is being edited
647
+ */
648
+ declare const isCellEditing: (row: number, col: number, editingCell: {
649
+ row: number;
650
+ col: number;
651
+ } | null) => boolean;
652
+ /**
653
+ * Check if a cell is in the fill preview range (vertical-only fill)
654
+ */
655
+ declare const isCellInFillPreview: (row: number, col: number, isDraggingFill: boolean, fillSourceRange: CellRange | null, fillTarget: {
656
+ row: number;
657
+ col: number;
658
+ } | null) => boolean;
659
+ /**
660
+ * Build cell CSS classes based on state
661
+ */
662
+ declare const buildCellClasses: (isActive: boolean, isSelected: boolean, isEditing: boolean, inFillPreview: boolean) => string;
663
+ //#endregion
664
+ //#region ../core/src/utils/event-emitter.d.ts
665
+ /**
666
+ * Batch instruction listener for efficient state updates
667
+ */
668
+ type BatchInstructionListener = (instructions: GridInstruction[]) => void;
669
+ //#endregion
509
670
  //#region ../core/src/selection.d.ts
510
671
  type Direction = "up" | "down" | "left" | "right";
511
672
  interface SelectionManagerOptions {
@@ -521,10 +682,10 @@ interface SelectionManagerOptions {
521
682
  declare class SelectionManager {
522
683
  private state;
523
684
  private options;
524
- private listeners;
525
- constructor(options: SelectionManagerOptions);
526
- onInstruction(listener: InstructionListener): () => void;
685
+ private emitter;
686
+ onInstruction: (listener: InstructionListener) => () => void;
527
687
  private emit;
688
+ constructor(options: SelectionManagerOptions);
528
689
  getState(): SelectionState;
529
690
  getActiveCell(): CellPosition | null;
530
691
  getSelectionRange(): CellRange | null;
@@ -589,10 +750,10 @@ interface FillManagerOptions {
589
750
  declare class FillManager {
590
751
  private state;
591
752
  private options;
592
- private listeners;
593
- constructor(options: FillManagerOptions);
594
- onInstruction(listener: InstructionListener): () => void;
753
+ private emitter;
754
+ onInstruction: (listener: InstructionListener) => () => void;
595
755
  private emit;
756
+ constructor(options: FillManagerOptions);
596
757
  getState(): FillHandleState | null;
597
758
  isActive(): boolean;
598
759
  /**
@@ -649,6 +810,14 @@ declare class InputHandler<TData extends Row = Row> {
649
810
  * Handle cell double click event (start editing)
650
811
  */
651
812
  handleCellDoubleClick(rowIndex: number, colIndex: number): void;
813
+ /**
814
+ * Handle cell mouse enter event (for hover highlighting)
815
+ */
816
+ handleCellMouseEnter(rowIndex: number, colIndex: number): void;
817
+ /**
818
+ * Handle cell mouse leave event (for hover highlighting)
819
+ */
820
+ handleCellMouseLeave(): void;
652
821
  /**
653
822
  * Handle fill handle mouse down event
654
823
  */
@@ -684,16 +853,222 @@ declare class InputHandler<TData extends Row = Row> {
684
853
  row: number;
685
854
  col: number;
686
855
  } | null, filterPopupOpen: boolean): KeyboardResult;
687
- /**
688
- * Find column index at a given X coordinate
689
- */
690
- private findColumnAtX;
691
856
  /**
692
857
  * Calculate auto-scroll deltas based on mouse position
693
858
  */
694
859
  private calculateAutoScroll;
695
860
  }
696
861
  //#endregion
862
+ //#region ../core/src/highlight-manager.d.ts
863
+ interface HighlightManagerOptions {
864
+ getActiveCell: () => CellPosition | null;
865
+ getSelectionRange: () => CellRange | null;
866
+ getColumn: (colIndex: number) => ColumnDefinition | undefined;
867
+ }
868
+ /**
869
+ * Manages row/column/cell highlighting state and class computation.
870
+ * Emits SET_HOVER_POSITION instructions when hover position changes.
871
+ */
872
+ declare class HighlightManager<TData = Record<string, unknown>> {
873
+ private options;
874
+ private highlightingOptions;
875
+ private hoverPosition;
876
+ private emitter;
877
+ onInstruction: (listener: InstructionListener) => () => void;
878
+ private emit;
879
+ private rowClassCache;
880
+ private columnClassCache;
881
+ private cellClassCache;
882
+ constructor(options: HighlightManagerOptions, highlightingOptions?: HighlightingOptions<TData>);
883
+ /**
884
+ * Check if highlighting is enabled (any callback defined).
885
+ * Hover tracking is automatically enabled when highlighting is enabled.
886
+ */
887
+ isEnabled(): boolean;
888
+ /**
889
+ * Set the current hover position. Clears caches and emits instruction.
890
+ * Hover tracking is automatically enabled when any highlighting callback is defined.
891
+ */
892
+ setHoverPosition(position: CellPosition | null): void;
893
+ /**
894
+ * Get the current hover position
895
+ */
896
+ getHoverPosition(): CellPosition | null;
897
+ /**
898
+ * Called when selection changes. Clears all caches.
899
+ */
900
+ onSelectionChange(): void;
901
+ /**
902
+ * Build context for row highlighting callback.
903
+ * Returns context with `rowIndex` set, `colIndex` is null.
904
+ * `isHovered` is true when the mouse is on any cell in this row.
905
+ */
906
+ buildRowContext(rowIndex: number, rowData?: TData): HighlightContext<TData>;
907
+ /**
908
+ * Build context for column highlighting callback.
909
+ * Returns context with `colIndex` set, `rowIndex` is null.
910
+ * `isHovered` is true when the mouse is on any cell in this column.
911
+ */
912
+ buildColumnContext(colIndex: number, column: ColumnDefinition): HighlightContext<TData>;
913
+ /**
914
+ * Build context for cell highlighting callback.
915
+ * Returns context with both `rowIndex` and `colIndex` set.
916
+ * `isHovered` is true only when the mouse is on this exact cell.
917
+ */
918
+ buildCellContext(rowIndex: number, colIndex: number, column: ColumnDefinition, rowData?: TData): HighlightContext<TData>;
919
+ /**
920
+ * Compute row classes using cache and user callback
921
+ */
922
+ computeRowClasses(rowIndex: number, rowData?: TData): string[];
923
+ /**
924
+ * Compute column classes using cache and user callback (or per-column override)
925
+ */
926
+ computeColumnClasses(colIndex: number, column: ColumnDefinition): string[];
927
+ /**
928
+ * Compute cell classes using cache and user callback (or per-column override)
929
+ */
930
+ computeCellClasses(rowIndex: number, colIndex: number, column: ColumnDefinition, rowData?: TData): string[];
931
+ /**
932
+ * Compute combined cell classes (column + cell classes flattened)
933
+ */
934
+ computeCombinedCellClasses(rowIndex: number, colIndex: number, column: ColumnDefinition, rowData?: TData): string[];
935
+ /**
936
+ * Clear all caches
937
+ */
938
+ clearAllCaches(): void;
939
+ /**
940
+ * Destroy the manager and release resources
941
+ */
942
+ destroy(): void;
943
+ }
944
+ //#endregion
945
+ //#region ../core/src/sort-filter-manager.d.ts
946
+ interface SortFilterManagerOptions<TData> {
947
+ /** Get all columns */
948
+ getColumns: () => ColumnDefinition[];
949
+ /** Check if sorting is enabled globally */
950
+ isSortingEnabled: () => boolean;
951
+ /** Get cached rows for distinct value computation */
952
+ getCachedRows: () => Map<number, TData>;
953
+ /** Called when sort/filter changes to trigger data refresh */
954
+ onSortFilterChange: () => Promise<void>;
955
+ /** Called after data refresh to update UI */
956
+ onDataRefreshed: () => void;
957
+ }
958
+ /**
959
+ * Manages sorting and filtering state and operations.
960
+ */
961
+ declare class SortFilterManager<TData = Record<string, unknown>> {
962
+ private options;
963
+ private emitter;
964
+ private sortModel;
965
+ private filterModel;
966
+ private openFilterColIndex;
967
+ onInstruction: (listener: InstructionListener) => () => void;
968
+ private emit;
969
+ constructor(options: SortFilterManagerOptions<TData>);
970
+ setSort(colId: string, direction: SortDirection | null, addToExisting?: boolean): Promise<void>;
971
+ getSortModel(): SortModel[];
972
+ setFilter(colId: string, filter: ColumnFilterModel | string | null): Promise<void>;
973
+ getFilterModel(): FilterModel;
974
+ /**
975
+ * Check if a column has an active filter
976
+ */
977
+ hasActiveFilter(colId: string): boolean;
978
+ /**
979
+ * Check if a column is sortable
980
+ */
981
+ isColumnSortable(colIndex: number): boolean;
982
+ /**
983
+ * Check if a column is filterable
984
+ */
985
+ isColumnFilterable(colIndex: number): boolean;
986
+ /**
987
+ * Get distinct values for a column (for filter dropdowns)
988
+ * For array-type columns (like tags), each unique array combination is returned.
989
+ * Arrays are sorted internally for consistent comparison.
990
+ * Limited to maxValues to avoid performance issues with large datasets.
991
+ */
992
+ getDistinctValuesForColumn(colId: string, maxValues?: number): CellValue[];
993
+ /**
994
+ * Open filter popup for a column (toggles if already open for same column)
995
+ */
996
+ openFilterPopup(colIndex: number, anchorRect: {
997
+ top: number;
998
+ left: number;
999
+ width: number;
1000
+ height: number;
1001
+ }): void;
1002
+ /**
1003
+ * Close filter popup
1004
+ */
1005
+ closeFilterPopup(): void;
1006
+ /**
1007
+ * Get sort info map for header rendering
1008
+ */
1009
+ getSortInfoMap(): Map<string, {
1010
+ direction: SortDirection;
1011
+ index: number;
1012
+ }>;
1013
+ destroy(): void;
1014
+ }
1015
+ //#endregion
1016
+ //#region ../core/src/row-mutation-manager.d.ts
1017
+ interface RowMutationManagerOptions<TData> {
1018
+ /** Get the cached rows map */
1019
+ getCachedRows: () => Map<number, TData>;
1020
+ /** Set the cached rows map (for bulk operations) */
1021
+ setCachedRows: (rows: Map<number, TData>) => void;
1022
+ /** Get total row count */
1023
+ getTotalRows: () => number;
1024
+ /** Set total row count */
1025
+ setTotalRows: (count: number) => void;
1026
+ /** Update a single slot after row change */
1027
+ updateSlot: (rowIndex: number) => void;
1028
+ /** Refresh all slots after bulk changes */
1029
+ refreshAllSlots: () => void;
1030
+ /** Emit content size change */
1031
+ emitContentSize: () => void;
1032
+ /** Clear selection if it references invalid rows */
1033
+ clearSelectionIfInvalid: (maxValidRow: number) => void;
1034
+ }
1035
+ /**
1036
+ * Manages row CRUD operations and cache management.
1037
+ */
1038
+ declare class RowMutationManager<TData extends Row = Row> {
1039
+ private options;
1040
+ private emitter;
1041
+ onInstruction: (listener: InstructionListener) => () => void;
1042
+ private emit;
1043
+ constructor(options: RowMutationManagerOptions<TData>);
1044
+ /**
1045
+ * Get a row by index.
1046
+ */
1047
+ getRow(index: number): TData | undefined;
1048
+ /**
1049
+ * Add rows to the grid at the specified index.
1050
+ * If no index is provided, rows are added at the end.
1051
+ */
1052
+ addRows(rows: TData[], index?: number): void;
1053
+ /**
1054
+ * Update existing rows with partial data.
1055
+ */
1056
+ updateRows(updates: Array<{
1057
+ index: number;
1058
+ data: Partial<TData>;
1059
+ }>): void;
1060
+ /**
1061
+ * Delete rows at the specified indices.
1062
+ */
1063
+ deleteRows(indices: number[]): void;
1064
+ /**
1065
+ * Set a complete row at the specified index.
1066
+ * Use this for complete row replacement. For partial updates, use updateRows.
1067
+ */
1068
+ setRow(index: number, data: TData): void;
1069
+ destroy(): void;
1070
+ }
1071
+ //#endregion
697
1072
  //#region ../core/src/grid-core.d.ts
698
1073
  declare class GridCore<TData extends Row = Row> {
699
1074
  private columns;
@@ -710,30 +1085,25 @@ declare class GridCore<TData extends Row = Row> {
710
1085
  private totalRows;
711
1086
  private currentPageIndex;
712
1087
  private pageSize;
713
- private sortModel;
714
- private filterModel;
715
- private openFilterColIndex;
716
1088
  readonly selection: SelectionManager;
717
1089
  readonly fill: FillManager;
718
1090
  readonly input: InputHandler<TData>;
1091
+ readonly highlight: HighlightManager<TData> | null;
1092
+ readonly sortFilter: SortFilterManager<TData>;
1093
+ readonly rowMutation: RowMutationManager<TData>;
719
1094
  private readonly slotPool;
720
1095
  private readonly editManager;
721
1096
  private columnPositions;
722
- private listeners;
723
- private batchListeners;
1097
+ private emitter;
1098
+ onInstruction: (listener: InstructionListener) => () => void;
1099
+ onBatchInstruction: (listener: BatchInstructionListener) => () => void;
1100
+ private emit;
1101
+ private emitBatch;
724
1102
  private naturalContentHeight;
725
1103
  private virtualContentHeight;
726
1104
  private scrollRatio;
727
1105
  private isDestroyed;
728
1106
  constructor(options: GridCoreOptions<TData>);
729
- onInstruction(listener: InstructionListener): () => void;
730
- /**
731
- * Subscribe to batched instructions for efficient React state updates.
732
- * Batch listeners receive arrays of instructions instead of individual ones.
733
- */
734
- onBatchInstruction(listener: BatchInstructionListener): () => void;
735
- private emit;
736
- private emitBatch;
737
1107
  /**
738
1108
  * Initialize the grid and load initial data.
739
1109
  */
@@ -747,37 +1117,16 @@ declare class GridCore<TData extends Row = Row> {
747
1117
  private fetchAllData;
748
1118
  setSort(colId: string, direction: SortDirection | null, addToExisting?: boolean): Promise<void>;
749
1119
  setFilter(colId: string, filter: ColumnFilterModel | string | null): Promise<void>;
750
- /**
751
- * Check if a column has an active filter
752
- */
753
1120
  hasActiveFilter(colId: string): boolean;
754
- /**
755
- * Check if a column is sortable
756
- */
757
1121
  isColumnSortable(colIndex: number): boolean;
758
- /**
759
- * Check if a column is filterable
760
- */
761
1122
  isColumnFilterable(colIndex: number): boolean;
762
- /**
763
- * Get distinct values for a column (for filter dropdowns)
764
- * For array-type columns (like tags), each unique array combination is returned.
765
- * Arrays are sorted internally for consistent comparison.
766
- * Limited to MAX_DISTINCT_VALUES to avoid performance issues with large datasets.
767
- */
768
1123
  getDistinctValuesForColumn(colId: string, maxValues?: number): CellValue[];
769
- /**
770
- * Open filter popup for a column (toggles if already open for same column)
771
- */
772
1124
  openFilterPopup(colIndex: number, anchorRect: {
773
1125
  top: number;
774
1126
  left: number;
775
1127
  width: number;
776
1128
  height: number;
777
1129
  }): void;
778
- /**
779
- * Close filter popup
780
- */
781
1130
  closeFilterPopup(): void;
782
1131
  getSortModel(): SortModel[];
783
1132
  getFilterModel(): FilterModel;
@@ -788,8 +1137,6 @@ declare class GridCore<TData extends Row = Row> {
788
1137
  getEditState(): EditState | null;
789
1138
  getCellValue(row: number, col: number): CellValue;
790
1139
  setCellValue(row: number, col: number, value: CellValue): void;
791
- private getFieldValue;
792
- private setFieldValue;
793
1140
  private computeColumnPositions;
794
1141
  private emitContentSize;
795
1142
  private emitHeaders;
@@ -846,6 +1193,31 @@ declare class GridCore<TData extends Row = Row> {
846
1193
  * Useful after in-place data modifications like fill operations.
847
1194
  */
848
1195
  refreshSlotData(): void;
1196
+ /**
1197
+ * Add rows to the grid at the specified index.
1198
+ * If no index is provided, rows are added at the end.
1199
+ */
1200
+ addRows(rows: TData[], index?: number): void;
1201
+ /**
1202
+ * Update existing rows with partial data.
1203
+ */
1204
+ updateRows(updates: Array<{
1205
+ index: number;
1206
+ data: Partial<TData>;
1207
+ }>): void;
1208
+ /**
1209
+ * Delete rows at the specified indices.
1210
+ */
1211
+ deleteRows(indices: number[]): void;
1212
+ /**
1213
+ * Get a row by index.
1214
+ */
1215
+ getRow(index: number): TData | undefined;
1216
+ /**
1217
+ * Set a complete row at the specified index.
1218
+ * Use this for complete row replacement. For partial updates, use updateRows.
1219
+ */
1220
+ setRow(index: number, data: TData): void;
849
1221
  /**
850
1222
  * Update the data source and refresh.
851
1223
  */
@@ -967,67 +1339,11 @@ declare const gridStyles: string;
967
1339
  */
968
1340
  declare function injectStyles(): void;
969
1341
  //#endregion
970
- //#region ../core/src/utils/positioning.d.ts
971
- /**
972
- * Calculate cumulative column positions (prefix sums)
973
- * Returns an array where positions[i] is the left position of column i
974
- * positions[columns.length] is the total width
975
- */
976
- declare function calculateColumnPositions(columns: ColumnDefinition[]): number[];
977
- /**
978
- * Get total width from column positions
979
- */
980
- declare function getTotalWidth(columnPositions: number[]): number;
981
- /**
982
- * Find column index at a given X coordinate
983
- */
984
- declare function findColumnAtX(x: number, columnPositions: number[]): number;
985
- //#endregion
986
- //#region ../core/src/utils/classNames.d.ts
987
- /**
988
- * Check if a cell is within the selection range
989
- */
990
- declare function isCellSelected(row: number, col: number, selectionRange: CellRange | null): boolean;
991
- /**
992
- * Check if a cell is the active cell
993
- */
994
- declare function isCellActive(row: number, col: number, activeCell: CellPosition | null): boolean;
995
- /**
996
- * Check if a row is within the visible range (not in overscan)
997
- */
998
- declare function isRowVisible(row: number, visibleRowRange: {
999
- start: number;
1000
- end: number;
1001
- } | null): boolean;
1002
- /**
1003
- * Check if a cell is being edited
1004
- */
1005
- declare function isCellEditing(row: number, col: number, editingCell: {
1006
- row: number;
1007
- col: number;
1008
- } | null): boolean;
1009
- /**
1010
- * Check if a cell is in the fill preview range (vertical-only fill)
1011
- */
1012
- declare function isCellInFillPreview(row: number, col: number, isDraggingFill: boolean, fillSourceRange: {
1013
- startRow: number;
1014
- startCol: number;
1015
- endRow: number;
1016
- endCol: number;
1017
- } | null, fillTarget: {
1018
- row: number;
1019
- col: number;
1020
- } | null): boolean;
1021
- /**
1022
- * Build cell CSS classes based on state
1023
- */
1024
- declare function buildCellClasses(isActive: boolean, isSelected: boolean, isEditing: boolean, inFillPreview: boolean): string;
1025
- //#endregion
1026
1342
  //#region ../core/src/types/ui-state.d.ts
1027
- interface SlotData {
1343
+ interface SlotData<TData = Row> {
1028
1344
  slotId: string;
1029
1345
  rowIndex: number;
1030
- rowData: Row;
1346
+ rowData: TData;
1031
1347
  translateY: number;
1032
1348
  }
1033
1349
  interface HeaderData {
@@ -1051,8 +1367,8 @@ interface FilterPopupState {
1051
1367
  distinctValues: CellValue[];
1052
1368
  currentFilter?: ColumnFilterModel;
1053
1369
  }
1054
- interface GridState {
1055
- slots: Map<string, SlotData>;
1370
+ interface GridState<TData = Row> {
1371
+ slots: Map<string, SlotData<TData>>;
1056
1372
  activeCell: CellPosition | null;
1057
1373
  selectionRange: CellRange | null;
1058
1374
  editingCell: {
@@ -1074,6 +1390,8 @@ interface GridState {
1074
1390
  start: number;
1075
1391
  end: number;
1076
1392
  } | null;
1393
+ /** Currently hovered cell position (for highlighting) */
1394
+ hoverPosition: CellPosition | null;
1077
1395
  }
1078
1396
  //#endregion
1079
1397
  //#region src/types.d.ts
@@ -1128,6 +1446,8 @@ type __VLS_Props = {
1128
1446
  initialWidth?: number;
1129
1447
  /** Initial viewport height for SSR (pixels). ResizeObserver takes over on client. */
1130
1448
  initialHeight?: number;
1449
+ /** Row/column/cell highlighting configuration */
1450
+ highlighting?: HighlightingOptions<Row>;
1131
1451
  };
1132
1452
  declare const __VLS_export: vue0.DefineComponent<__VLS_Props, {
1133
1453
  core: vue0.ShallowRef<GridCore<unknown> | null, GridCore<unknown> | null>;
@@ -1153,6 +1473,7 @@ interface UseGpGridOptions<TData extends Row = Row> {
1153
1473
  sortingEnabled?: boolean;
1154
1474
  darkMode?: boolean;
1155
1475
  wheelDampening?: number;
1476
+ highlighting?: HighlightingOptions<TData>;
1156
1477
  cellRenderers?: Record<string, VueCellRenderer<TData>>;
1157
1478
  editRenderers?: Record<string, VueEditRenderer<TData>>;
1158
1479
  headerRenderers?: Record<string, VueHeaderRenderer>;
@@ -1182,6 +1503,8 @@ interface UseGpGridResult<TData extends Row = Row> {
1182
1503
  handleWheel: (e: WheelEvent, wheelDampening: number) => void;
1183
1504
  handleFilterApply: (colId: string, filter: ColumnFilterModel | null) => void;
1184
1505
  handleFilterPopupClose: () => void;
1506
+ handleCellMouseEnter: (rowIndex: number, colIndex: number) => void;
1507
+ handleCellMouseLeave: () => void;
1185
1508
  dragState: Ref<{
1186
1509
  isDragging: boolean;
1187
1510
  dragType: "selection" | "fill" | null;
@@ -1209,6 +1532,10 @@ interface UseGpGridResult<TData extends Row = Row> {
1209
1532
  declare function useGpGrid<TData extends Row = Row>(options: UseGpGridOptions<TData>): UseGpGridResult<TData>;
1210
1533
  //#endregion
1211
1534
  //#region src/composables/useInputHandler.d.ts
1535
+ interface VisibleColumnInfo$1 {
1536
+ column: ColumnDefinition;
1537
+ originalIndex: number;
1538
+ }
1212
1539
  interface UseInputHandlerOptions {
1213
1540
  activeCell: ComputedRef<CellPosition | null>;
1214
1541
  selectionRange: ComputedRef<CellRange | null>;
@@ -1220,6 +1547,8 @@ interface UseInputHandlerOptions {
1220
1547
  rowHeight: number;
1221
1548
  headerHeight: number;
1222
1549
  columnPositions: ComputedRef<number[]>;
1550
+ /** Visible columns with their original indices (for hidden column support) */
1551
+ visibleColumnsWithIndices: ComputedRef<VisibleColumnInfo$1[]>;
1223
1552
  slots: ComputedRef<Map<string, SlotData>>;
1224
1553
  }
1225
1554
  interface UseInputHandlerResult {
@@ -1246,11 +1575,16 @@ declare function useAutoScroll(containerRef: Ref<HTMLDivElement | null>): {
1246
1575
  };
1247
1576
  //#endregion
1248
1577
  //#region src/composables/useFillHandle.d.ts
1578
+ interface VisibleColumnInfo {
1579
+ column: ColumnDefinition;
1580
+ originalIndex: number;
1581
+ }
1249
1582
  interface UseFillHandleOptions {
1250
1583
  activeCell: ComputedRef<CellPosition | null>;
1251
1584
  selectionRange: ComputedRef<CellRange | null>;
1252
1585
  slots: ComputedRef<Map<string, SlotData>>;
1253
1586
  columns: ComputedRef<ColumnDefinition[]>;
1587
+ visibleColumnsWithIndices: ComputedRef<VisibleColumnInfo[]>;
1254
1588
  columnPositions: ComputedRef<number[]>;
1255
1589
  columnWidths: ComputedRef<number[]>;
1256
1590
  rowHeight: number;
@@ -1313,9 +1647,9 @@ declare function useGridState(args?: InitialStateArgs): {
1313
1647
  slots: Map<string, {
1314
1648
  slotId: string;
1315
1649
  rowIndex: number;
1316
- rowData: Row;
1650
+ rowData: unknown;
1317
1651
  translateY: number;
1318
- }> & Omit<Map<string, SlotData>, keyof Map<any, any>>;
1652
+ }> & Omit<Map<string, SlotData<unknown>>, keyof Map<any, any>>;
1319
1653
  activeCell: {
1320
1654
  row: number;
1321
1655
  col: number;
@@ -1344,9 +1678,12 @@ declare function useGridState(args?: InitialStateArgs): {
1344
1678
  editable?: boolean | undefined;
1345
1679
  sortable?: boolean | undefined;
1346
1680
  filterable?: boolean | undefined;
1681
+ hidden?: boolean | undefined;
1347
1682
  cellRenderer?: string | undefined;
1348
1683
  editRenderer?: string | undefined;
1349
1684
  headerRenderer?: string | undefined;
1685
+ computeColumnClasses?: ((context: HighlightContext) => string[]) | undefined;
1686
+ computeCellClasses?: ((context: HighlightContext) => string[]) | undefined;
1350
1687
  };
1351
1688
  sortDirection?: SortDirection | undefined;
1352
1689
  sortIndex?: number | undefined;
@@ -1366,9 +1703,12 @@ declare function useGridState(args?: InitialStateArgs): {
1366
1703
  editable?: boolean | undefined;
1367
1704
  sortable?: boolean | undefined;
1368
1705
  filterable?: boolean | undefined;
1706
+ hidden?: boolean | undefined;
1369
1707
  cellRenderer?: string | undefined;
1370
1708
  editRenderer?: string | undefined;
1371
1709
  headerRenderer?: string | undefined;
1710
+ computeColumnClasses?: ((context: HighlightContext) => string[]) | undefined;
1711
+ computeCellClasses?: ((context: HighlightContext) => string[]) | undefined;
1372
1712
  } | null;
1373
1713
  anchorRect: {
1374
1714
  top: number;
@@ -1408,6 +1748,10 @@ declare function useGridState(args?: InitialStateArgs): {
1408
1748
  start: number;
1409
1749
  end: number;
1410
1750
  } | null;
1751
+ hoverPosition: {
1752
+ row: number;
1753
+ col: number;
1754
+ } | null;
1411
1755
  };
1412
1756
  applyInstructions: (instructions: GridInstruction[]) => void;
1413
1757
  reset: () => void;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{Fragment as e,computed as t,createBlock as n,createCommentVNode as r,createElementBlock as i,createElementVNode as a,createTextVNode as o,createVNode as s,defineComponent as c,h as l,normalizeClass as u,normalizeStyle as d,onMounted as f,onUnmounted as p,openBlock as m,reactive as h,ref as g,renderList as _,resolveDynamicComponent as v,shallowRef as y,toDisplayString as b,unref as x,vModelText as S,watch as C,withDirectives as w}from"vue";import{GridCore as T,GridCore as E,buildCellClasses as D,buildCellClasses as ee,calculateColumnPositions as O,calculateScaledColumnPositions as k,createClientDataSource as A,createClientDataSource as j,createDataSourceFromArray as M,createDataSourceFromArray as N,createMutableClientDataSource as P,createServerDataSource as F,findColumnAtX as I,getTotalWidth as L,getTotalWidth as R,gridStyles as te,injectStyles as ne,injectStyles as re,isCellActive as ie,isCellActive as z,isCellEditing as B,isCellEditing as V,isCellInFillPreview as ae,isCellInFillPreview as oe,isCellSelected as H,isCellSelected as U,isRowVisible as se}from"gp-grid-core";function W(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 G(e,t){switch(e.type){case`CREATE_SLOT`:t.slots.set(e.slotId,{slotId:e.slotId,rowIndex:-1,rowData:{},translateY:0});break;case`DESTROY_SLOT`:t.slots.delete(e.slotId);break;case`ASSIGN_SLOT`:{let n=t.slots.get(e.slotId);n&&t.slots.set(e.slotId,{...n,rowIndex:e.rowIndex,rowData:e.rowData});break}case`MOVE_SLOT`:{let n=t.slots.get(e.slotId);n&&t.slots.set(e.slotId,{...n,translateY:e.translateY});break}case`SET_ACTIVE_CELL`:t.activeCell=e.position;break;case`SET_SELECTION_RANGE`:t.selectionRange=e.range;break;case`UPDATE_VISIBLE_RANGE`:t.visibleRowRange={start:e.start,end:e.end};break;case`START_EDIT`:t.editingCell={row:e.row,col:e.col,initialValue:e.initialValue};break;case`STOP_EDIT`:t.editingCell=null;break;case`SET_CONTENT_SIZE`:t.contentWidth=e.width,t.contentHeight=e.height,t.viewportWidth=e.viewportWidth;break;case`UPDATE_HEADER`:t.headers.set(e.colIndex,{column:e.column,sortDirection:e.sortDirection,sortIndex:e.sortIndex,sortable:e.sortable,filterable:e.filterable,hasFilter:e.hasFilter});break;case`OPEN_FILTER_POPUP`:t.filterPopup={isOpen:!0,colIndex:e.colIndex,column:e.column,anchorRect:e.anchorRect,distinctValues:e.distinctValues,currentFilter:e.currentFilter};break;case`CLOSE_FILTER_POPUP`:t.filterPopup=null;break;case`DATA_LOADING`:t.isLoading=!0,t.error=null;break;case`DATA_LOADED`:t.isLoading=!1,t.totalRows=e.totalRows;break;case`DATA_ERROR`:t.isLoading=!1,t.error=e.error;break;case`ROWS_ADDED`:case`ROWS_REMOVED`:t.totalRows=e.totalRows;break;case`ROWS_UPDATED`:case`TRANSACTION_PROCESSED`:break}}function K(e){let t=h(W(e));function n(e){for(let n of e)G(n,t)}function r(){let e=W();t.slots=e.slots,t.activeCell=e.activeCell,t.selectionRange=e.selectionRange,t.editingCell=e.editingCell,t.contentWidth=e.contentWidth,t.contentHeight=e.contentHeight,t.viewportWidth=e.viewportWidth,t.headers=e.headers,t.filterPopup=e.filterPopup,t.isLoading=e.isLoading,t.error=e.error,t.totalRows=e.totalRows,t.visibleRowRange=e.visibleRowRange}return{state:t,applyInstructions:n,reset:r}}function q(e){let t=g(null);function n(n,r){t.value&&clearInterval(t.value),t.value=setInterval(()=>{let t=e.value;t&&(t.scrollTop+=r,t.scrollLeft+=n)},16)}function r(){t.value&&=(clearInterval(t.value),null)}return p(()=>{r()}),{startAutoScroll:n,stopAutoScroll:r}}function ce(e,t){for(let n of e.values())if(n.rowIndex===t)return n;return null}function le(e,t,n,r,i,a){let o=ce(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 J(e,t,n,r){let{activeCell:i,selectionRange:a,editingCell:o,filterPopupOpen:s,rowHeight:c,headerHeight:l,columnPositions:u,slots:d}=r,{startAutoScroll:f,stopAutoScroll:m}=q(t),h=g({isDragging:!1,dragType:null,fillSourceRange:null,fillTarget:null});C([()=>l,()=>c,u,()=>n.value.length],()=>{let t=e.value;t?.input&&t.input.updateDeps({getHeaderHeight:()=>l,getRowHeight:()=>c,getColumnPositions:()=>u.value,getColumnCount:()=>n.value.length})},{immediate:!0});function _(){let e=t.value;if(!e)return null;let n=e.getBoundingClientRect();return{top:n.top,left:n.left,width:n.width,height:n.height,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft}}function v(e){return{clientX:e.clientX,clientY:e.clientY,button:e.button,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey}}function y(){let t=t=>{let n=e.value,r=_();if(!n?.input||!r)return;let i=n.input.handleDragMove(v(t),r);i&&(i.autoScroll?f(i.autoScroll.dx,i.autoScroll.dy):m(),h.value=n.input.getDragState())},n=()=>{let r=e.value;r?.input&&(r.input.handleDragEnd(),h.value=r.input.getDragState()),m(),document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,n)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,n)}function b(n,r,i){let a=e.value;if(!a?.input)return;let o=a.input.handleCellMouseDown(n,r,v(i));o.focusContainer&&t.value?.focus(),o.startDrag===`selection`&&(a.input.startSelectionDrag(),h.value=a.input.getDragState(),y())}function x(t,n){let r=e.value;r?.input&&r.input.handleCellDoubleClick(t,n)}function S(t){let n=e.value;if(!n?.input)return;let r=n.input.handleFillHandleMouseDown(i.value,a.value,v(t));r.preventDefault&&t.preventDefault(),r.stopPropagation&&t.stopPropagation(),r.startDrag===`fill`&&(h.value=n.input.getDragState(),y())}function w(t,r){let i=e.value;if(!i?.input)return;let a=n.value[t];if(!a)return;let o=a.colId??a.field;i.input.handleHeaderClick(o,r.shiftKey)}function T(n){let r=e.value,a=t.value;if(!r?.input)return;let u=r.input.handleKeyDown({key:n.key,shiftKey:n.shiftKey,ctrlKey:n.ctrlKey,metaKey:n.metaKey},i.value,o.value,s.value);u.preventDefault&&n.preventDefault(),u.scrollToCell&&a&&le(r,a,u.scrollToCell.row,c,l,d.value)}function E(n,r){let i=e.value,a=t.value;if(!i?.input||!a)return;let o=i.input.handleWheel(n.deltaY,n.deltaX,r);o&&(n.preventDefault(),a.scrollTop+=o.dy,a.scrollLeft+=o.dx)}return p(()=>{m()}),{handleCellMouseDown:b,handleCellDoubleClick:x,handleFillHandleMouseDown:S,handleHeaderClick:w,handleKeyDown:T,handleWheel:E,dragState:h}}function Y(e){let{activeCell:n,selectionRange:r,slots:i,columns:a,columnPositions:o,columnWidths:s,rowHeight:c}=e;return{fillHandlePosition:t(()=>{let e=n.value,t=r.value,l=i.value;if(!e&&!t)return null;let u,d,f,p;if(t)u=Math.max(t.startRow,t.endRow),d=Math.max(t.startCol,t.endCol),f=Math.min(t.startCol,t.endCol),p=Math.max(t.startCol,t.endCol);else if(e)u=e.row,d=e.col,f=d,p=d;else return null;let m=a.value;for(let e=f;e<=p;e++){let t=m[e];if(!t||t.editable!==!0)return null}let h=null;for(let e of l.values())if(e.rowIndex===u){h=e.translateY;break}if(h===null)return null;let g=o.value[d]??0,_=s.value[d]??0;return{top:h+c-5,left:g+_-20}})}}function X(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function Z(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 ue(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,isActive:a,isSelected:s,isEditing:c,cellRenderers:l,globalCellRenderer:u}=e,d=Z(n,t.field),f={value:d,rowData:n,column:t,rowIndex:r,colIndex:i,isActive:a,isSelected:s,isEditing:c};if(t.cellRenderer&&typeof t.cellRenderer==`string`){let e=l[t.cellRenderer];if(e)return X(e(f))}return u?X(u(f)):o(d==null?``:String(d))}function Q(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function de(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,initialValue:a,core:s,editRenderers:c,globalEditRenderer:u}=e;if(!s)return o(``);let d={value:Z(n,t.field),rowData:n,column:t,rowIndex:r,colIndex:i,isActive:!0,isSelected:!0,isEditing:!0,initialValue:a,onValueChange:e=>s.updateEditValue(e),onCommit:()=>s.commitEdit(),onCancel:()=>s.cancelEdit()};if(t.editRenderer&&typeof t.editRenderer==`string`){let e=c[t.editRenderer];if(e)return Q(e(d))}return u?Q(u(d)):l(`input`,{class:`gp-grid-edit-input`,type:`text`,value:a==null?``:String(a),autofocus:!0,onFocus:e=>e.target.select(),onInput:e=>s.updateEditValue(e.target.value),onKeydown:e=>{e.stopPropagation(),e.key===`Enter`?s.commitEdit():e.key===`Escape`?s.cancelEdit():e.key===`Tab`&&(e.preventDefault(),s.commitEdit(),s.selection.moveFocus(e.shiftKey?`left`:`right`,!1))},onBlur:()=>s.commitEdit()})}function fe(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function pe(t){let{column:n,colIndex:r,sortDirection:i,sortIndex:a,sortable:o,filterable:s,hasFilter:c,core:u,container:d,headerRenderers:f,globalHeaderRenderer:p}=t,m={column:n,colIndex:r,sortDirection:i,sortIndex:a,sortable:o,filterable:s,hasFilter:c,onSort:(e,t)=>{u&&o&&u.setSort(n.colId??n.field,e,t)},onFilterClick:()=>{if(u&&s){let e=d?.querySelector(`[data-col-index="${r}"]`);if(e){let t=e.getBoundingClientRect();u.openFilterPopup(r,{top:t.top,left:t.left,width:t.width,height:t.height})}}}};if(n.headerRenderer&&typeof n.headerRenderer==`string`){let e=f[n.headerRenderer];if(e)return fe(e(m))}if(p)return fe(p(m));let h=[l(`span`,{class:`gp-grid-header-text`},n.headerName??n.field)],g=[];if(o){let e=[l(`span`,{class:`gp-grid-sort-arrows-stack`},[l(`svg`,{class:`gp-grid-sort-arrow-up${i===`asc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`},[l(`path`,{d:`M4 0L8 6H0L4 0Z`,fill:`currentColor`})]),l(`svg`,{class:`gp-grid-sort-arrow-down${i===`desc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`},[l(`path`,{d:`M4 6L0 0H8L4 6Z`,fill:`currentColor`})])])];a!==void 0&&a>0&&e.push(l(`span`,{class:`gp-grid-sort-index`},String(a))),g.push(l(`span`,{class:`gp-grid-sort-arrows`},e))}return s&&g.push(l(`span`,{class:`gp-grid-filter-icon${c?` active`:``}`,onMousedown:e=>{e.stopPropagation(),e.preventDefault(),m.onFilterClick()},onClick:e=>{e.stopPropagation()}},[l(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`currentColor`},[l(`path`,{d:`M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z`})])])),g.length>0&&h.push(l(`span`,{class:`gp-grid-header-icons`},g)),l(e,h)}function me(e,t){let{onClose:n,ignoreSelector:r=`.gp-grid-filter-icon`}=t,i=null,a=null;f(()=>{i=t=>{let i=t.target;r&&i.closest(r)||e.value&&!e.value.contains(i)&&n()},a=e=>{e.key===`Escape`&&n()},requestAnimationFrame(()=>{i&&document.addEventListener(`mousedown`,i),a&&document.addEventListener(`keydown`,a)})}),p(()=>{i&&document.removeEventListener(`mousedown`,i),a&&document.removeEventListener(`keydown`,a)})}function $(e,t=`and`){let n=g([...e]);return{conditions:n,combination:g(t),updateCondition:(e,t)=>{let r=[...n.value];r[e]={...r[e],...t},n.value=r},addCondition:e=>{n.value=[...n.value,{operator:e,value:``,valueTo:``,nextOperator:`and`}]},removeCondition:e=>{n.value=n.value.filter((t,n)=>n!==e)}}}const he={class:`gp-grid-filter-content gp-grid-filter-text`},ge={key:0,class:`gp-grid-filter-mode-toggle`},_e={key:1,class:`gp-grid-filter-info`},ve={class:`gp-grid-filter-actions`},ye=[`disabled`],be={class:`gp-grid-filter-list`},xe={key:0,class:`gp-grid-filter-option`},Se=[`checked`],Ce=[`checked`,`onChange`],we={key:0,class:`gp-grid-filter-combination`},Te=[`onClick`],Ee=[`onClick`],De={class:`gp-grid-filter-row`},Oe=[`value`,`autofocus`,`onChange`],ke=[`value`],Ae=[`value`,`onInput`],je=[`onClick`];var Me=c({__name:`TextFilterContent`,props:{distinctValues:{},currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{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`}],c=n,l=o;function d(e){return Array.isArray(e)?e.join(`, `):String(e??``)}let f=t(()=>{let e=c.distinctValues.filter(e=>e!=null&&e!==``&&!(Array.isArray(e)&&e.length===0)).map(e=>d(e));return Array.from(new Set(e)).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`})})}),p=t(()=>f.value.length>100),h=g(t(()=>{if(!c.currentFilter?.conditions[0])return p.value?`condition`:`values`;let e=c.currentFilter.conditions[0];return e.selectedValues&&e.selectedValues.size>0?`values`:`condition`}).value),v=t(()=>c.currentFilter?.conditions[0]?c.currentFilter.conditions[0].selectedValues??new Set:new Set),y=t(()=>c.currentFilter?.conditions[0]?c.currentFilter.conditions[0].includeBlank??!0:!0),C=g(``),T=g(new Set(v.value)),E=g(y.value),{conditions:D,combination:ee,updateCondition:O,addCondition:k,removeCondition:A}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`contains`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.conditions[0];if(e.selectedValues&&e.selectedValues.size>0)return[{operator:`contains`,value:``,valueTo:``,nextOperator:`and`}];let t=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value??``,valueTo:``,nextOperator:n.nextOperator??t}})}).value,c.currentFilter?.combination??`and`),j=t(()=>{if(!C.value)return f.value;let e=C.value.toLowerCase();return f.value.filter(t=>t.toLowerCase().includes(e))}),M=t(()=>c.distinctValues.some(e=>e==null||e===``)),N=t(()=>j.value.every(e=>T.value.has(e))&&(!M.value||E.value));function P(){T.value=new Set(j.value),M.value&&(E.value=!0)}function F(){T.value=new Set,E.value=!1}function I(e){let t=new Set(T.value);t.has(e)?t.delete(e):t.add(e),T.value=t}function L(){if(h.value===`values`){if(f.value.every(e=>T.value.has(e))&&(!M.value||E.value)){l(`apply`,null);return}l(`apply`,{conditions:[{type:`text`,operator:`equals`,selectedValues:T.value,includeBlank:E.value}],combination:`and`})}else{let e=D.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.value.trim()!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`text`,operator:e.operator,value:e.value,nextOperator:e.nextOperator})),combination:`and`})}}function R(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,he,[r(` Mode toggle - only show if not too many values `),p.value?r(`v-if`,!0):(m(),i(`div`,ge,[a(`button`,{type:`button`,class:u({active:h.value===`values`}),onClick:n[0]||=e=>h.value=`values`},` Values `,2),a(`button`,{type:`button`,class:u({active:h.value===`condition`}),onClick:n[1]||=e=>h.value=`condition`},` Condition `,2)])),r(` Too many values message `),p.value&&h.value===`condition`?(m(),i(`div`,_e,` Too many unique values (`+b(f.value.length)+`). Use conditions to filter. `,1)):r(`v-if`,!0),r(` VALUES MODE `),h.value===`values`?(m(),i(e,{key:2},[r(` Search input `),w(a(`input`,{"onUpdate:modelValue":n[2]||=e=>C.value=e,class:`gp-grid-filter-search`,type:`text`,placeholder:`Search...`,autofocus:``},null,512),[[S,C.value]]),r(` Select all / Deselect all `),a(`div`,ve,[a(`button`,{type:`button`,disabled:N.value,onClick:P},` Select All `,8,ye),a(`button`,{type:`button`,onClick:F},` Deselect All `)]),r(` Checkbox list `),a(`div`,be,[r(` Blanks option `),M.value?(m(),i(`label`,xe,[a(`input`,{type:`checkbox`,checked:E.value,onChange:n[3]||=e=>E.value=!E.value},null,40,Se),n[5]||=a(`span`,{class:`gp-grid-filter-blank`},`(Blanks)`,-1)])):r(`v-if`,!0),r(` Values `),(m(!0),i(e,null,_(j.value,e=>(m(),i(`label`,{key:e,class:`gp-grid-filter-option`},[a(`input`,{type:`checkbox`,checked:T.value.has(e),onChange:t=>I(e)},null,40,Ce),a(`span`,null,b(e),1)]))),128))])],64)):r(`v-if`,!0),r(` CONDITION MODE `),h.value===`condition`?(m(),i(e,{key:3},[(m(!0),i(e,null,_(x(D),(t,n)=>(m(),i(`div`,{key:n,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),n>0?(m(),i(`div`,we,[a(`button`,{type:`button`,class:u({active:x(D)[n-1]?.nextOperator===`and`}),onClick:e=>x(O)(n-1,{nextOperator:`and`})},` AND `,10,Te),a(`button`,{type:`button`,class:u({active:x(D)[n-1]?.nextOperator===`or`}),onClick:e=>x(O)(n-1,{nextOperator:`or`})},` OR `,10,Ee)])):r(`v-if`,!0),a(`div`,De,[r(` Operator select `),a(`select`,{value:t.operator,autofocus:n===0,onChange:e=>x(O)(n,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,ke)),64))],40,Oe),r(` Text input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`text`,value:t.value,placeholder:`Value`,class:`gp-grid-filter-text-input`,onInput:e=>x(O)(n,{value:e.target.value})},null,40,Ae)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(D).length>1?(m(),i(`button`,{key:1,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(A)(n)},` × `,8,je)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[4]||=e=>x(k)(`contains`)},` + Add condition `)],64)):r(`v-if`,!0),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:R},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:L},` Apply `)])]))}});const Ne={class:`gp-grid-filter-content gp-grid-filter-number`},Pe={key:0,class:`gp-grid-filter-combination`},Fe=[`onClick`],Ie=[`onClick`],Le={class:`gp-grid-filter-row`},Re=[`value`,`onChange`],ze=[`value`],Be=[`value`,`onInput`],Ve=[`value`,`onInput`],He=[`onClick`];var Ue=c({__name:`NumberFilterContent`,props:{currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{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`}],c=n,l=o,{conditions:d,combination:f,updateCondition:p,addCondition:h,removeCondition:g}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(t=>{let n=t;return{operator:n.operator,value:n.value==null?``:String(n.value),valueTo:n.valueTo==null?``:String(n.valueTo),nextOperator:n.nextOperator??e}})}).value,c.currentFilter?.combination??`and`);function v(){let e=d.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{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`})}function y(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,Ne,[(m(!0),i(e,null,_(x(d),(t,o)=>(m(),i(`div`,{key:o,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),o>0?(m(),i(`div`,Pe,[a(`button`,{type:`button`,class:u({active:x(d)[o-1]?.nextOperator===`and`}),onClick:e=>x(p)(o-1,{nextOperator:`and`})},` AND `,10,Fe),a(`button`,{type:`button`,class:u({active:x(d)[o-1]?.nextOperator===`or`}),onClick:e=>x(p)(o-1,{nextOperator:`or`})},` OR `,10,Ie)])):r(`v-if`,!0),a(`div`,Le,[r(` Operator select `),a(`select`,{value:t.operator,onChange:e=>x(p)(o,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,ze)),64))],40,Re),r(` Number input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`number`,value:t.value,placeholder:`Value`,onInput:e=>x(p)(o,{value:e.target.value})},null,40,Be)):r(`v-if`,!0),r(` Second number input for "between" `),t.operator===`between`?(m(),i(e,{key:1},[n[1]||=a(`span`,{class:`gp-grid-filter-to`},`to`,-1),a(`input`,{type:`number`,value:t.valueTo,placeholder:`Value`,onInput:e=>x(p)(o,{valueTo:e.target.value})},null,40,Ve)],64)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(d).length>1?(m(),i(`button`,{key:2,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(g)(o)},` × `,8,He)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[0]||=e=>x(h)(`=`)},` + Add condition `),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:y},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:v},` Apply `)])]))}});const We={class:`gp-grid-filter-content gp-grid-filter-date`},Ge={key:0,class:`gp-grid-filter-combination`},Ke=[`onClick`],qe=[`onClick`],Je={class:`gp-grid-filter-row`},Ye=[`value`,`onChange`],Xe=[`value`],Ze=[`value`,`onInput`],Qe=[`value`,`onInput`],$e=[`onClick`];var et=c({__name:`DateFilterContent`,props:{currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}],c=n,l=o;function d(e){if(!e)return``;let t=typeof e==`string`?new Date(e):e;return isNaN(t.getTime())?``:t.toISOString().split(`T`)[0]}let{conditions:f,combination:p,updateCondition:h,addCondition:g,removeCondition:v}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(t=>{let n=t;return{operator:n.operator,value:d(n.value),valueTo:d(n.valueTo),nextOperator:n.nextOperator??e}})}).value,c.currentFilter?.combination??`and`);function y(){let e=f.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`date`,operator:e.operator,value:e.value||void 0,valueTo:e.valueTo||void 0,nextOperator:e.nextOperator})),combination:`and`})}function S(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,We,[(m(!0),i(e,null,_(x(f),(t,o)=>(m(),i(`div`,{key:o,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),o>0?(m(),i(`div`,Ge,[a(`button`,{type:`button`,class:u({active:x(f)[o-1]?.nextOperator===`and`}),onClick:e=>x(h)(o-1,{nextOperator:`and`})},` AND `,10,Ke),a(`button`,{type:`button`,class:u({active:x(f)[o-1]?.nextOperator===`or`}),onClick:e=>x(h)(o-1,{nextOperator:`or`})},` OR `,10,qe)])):r(`v-if`,!0),a(`div`,Je,[r(` Operator select `),a(`select`,{value:t.operator,onChange:e=>x(h)(o,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,Xe)),64))],40,Ye),r(` Date input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`date`,value:t.value,onInput:e=>x(h)(o,{value:e.target.value})},null,40,Ze)):r(`v-if`,!0),r(` Second date input for "between" `),t.operator===`between`?(m(),i(e,{key:1},[n[1]||=a(`span`,{class:`gp-grid-filter-to`},`to`,-1),a(`input`,{type:`date`,value:t.valueTo,onInput:e=>x(h)(o,{valueTo:e.target.value})},null,40,Qe)],64)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(f).length>1?(m(),i(`button`,{key:2,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(v)(o)},` × `,8,$e)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[0]||=e=>x(g)(`=`)},` + Add condition `),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:S},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:y},` Apply `)])]))}});const tt={class:`gp-grid-filter-header`};var nt=c({__name:`FilterPopup`,props:{column:{},colIndex:{},anchorRect:{},distinctValues:{},currentFilter:{}},emits:[`apply`,`close`],setup(o,{emit:c}){let l=o,u=c,f=g(null);me(f,{onClose:()=>u(`close`),ignoreSelector:`.gp-grid-filter-icon`});let p=t(()=>l.column.colId??l.column.field);function h(e){u(`apply`,p.value,e),u(`close`)}function _(){u(`close`)}let v=t(()=>l.column.cellDataType);t(()=>v.value===`text`||v.value===`object`);let y=t(()=>v.value===`number`),x=t(()=>v.value===`date`||v.value===`dateString`||v.value===`dateTime`||v.value===`dateTimeString`),S=t(()=>({position:`fixed`,top:`${l.anchorRect.top+l.anchorRect.height+4}px`,left:`${l.anchorRect.left}px`,minWidth:`${Math.max(200,l.anchorRect.width)}px`,zIndex:1e4}));return(t,c)=>(m(),i(`div`,{ref_key:`popupRef`,ref:f,class:`gp-grid-filter-popup`,style:d(S.value)},[a(`div`,tt,` Filter: `+b(o.column.headerName??o.column.field),1),r(` Number filter `),y.value?(m(),n(Ue,{key:0,"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`current-filter`])):x.value?(m(),i(e,{key:1},[r(` Date filter `),s(et,{"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`current-filter`])],2112)):(m(),i(e,{key:2},[r(` Text filter (default) `),s(Me,{"distinct-values":o.distinctValues,"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`distinct-values`,`current-filter`])],2112))],4))}});const rt=[`data-col-index`,`onClick`],it=[`onMousedown`,`onDblclick`],at={key:1,class:`gp-grid-loading`},ot={key:2,class:`gp-grid-error`},st={key:3,class:`gp-grid-empty`};var ct=c({__name:`GpGrid`,props:{columns:{},dataSource:{},rowData:{},rowHeight:{},headerHeight:{},overscan:{default:3},sortingEnabled:{type:Boolean,default:!0},darkMode:{type:Boolean,default:!1},wheelDampening:{default:.1},cellRenderers:{default:()=>({})},editRenderers:{default:()=>({})},headerRenderers:{default:()=>({})},cellRenderer:{},editRenderer:{},headerRenderer:{},initialWidth:{},initialHeight:{}},setup(s,{expose:c}){re();let l=s,h=g(null),S=y(null),w=y(null),T=y(null),{state:D,applyInstructions:O,reset:A}=K({initialWidth:l.initialWidth,initialHeight:l.initialHeight}),M=t(()=>l.headerHeight??l.rowHeight),P=t(()=>k(l.columns,D.viewportWidth)),F=t(()=>P.value.positions),I=t(()=>P.value.widths),L=t(()=>R(F.value)),te=t(()=>Array.from(D.slots.values())),{handleCellMouseDown:ne,handleCellDoubleClick:ie,handleFillHandleMouseDown:B,handleHeaderClick:ae,handleKeyDown:H,handleWheel:se,dragState:W}=J(S,h,t(()=>l.columns),{activeCell:t(()=>D.activeCell),selectionRange:t(()=>D.selectionRange),editingCell:t(()=>D.editingCell),filterPopupOpen:t(()=>D.filterPopup?.isOpen??!1),rowHeight:l.rowHeight,headerHeight:M.value,columnPositions:F,slots:t(()=>D.slots)}),{fillHandlePosition:G}=Y({activeCell:t(()=>D.activeCell),selectionRange:t(()=>D.selectionRange),slots:t(()=>D.slots),columns:t(()=>l.columns),columnPositions:F,columnWidths:I,rowHeight:l.rowHeight});function q(){let e=h.value,t=S.value;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)}function ce(e,t){let n=S.value;n&&n.setFilter(e,t)}function le(){let e=S.value;e&&e.closeFilterPopup()}function X(e,t){let n=V(e,t,D.editingCell);return ee(z(e,t,D.activeCell),U(e,t,D.selectionRange),n,oe(e,t,W.value.dragType===`fill`,W.value.fillSourceRange,W.value.fillTarget))}function Z(){return l.dataSource??(l.rowData?N(l.rowData):j([]))}function Q(e){T.value&&=(T.value(),null),S.value&&S.value.destroy();let t=new E({columns:l.columns,dataSource:e,rowHeight:l.rowHeight,headerHeight:M.value,overscan:l.overscan,sortingEnabled:l.sortingEnabled});S.value=t,T.value=t.onBatchInstruction(e=>{O(e)}),t.initialize();let n=h.value;n&&t.setViewport(n.scrollTop,n.scrollLeft,n.clientWidth,n.clientHeight)}return f(()=>{let e=Z();w.value=e,Q(e);let t=h.value;if(t&&typeof ResizeObserver<`u`){let e=new ResizeObserver(()=>{S.value?.setViewport(t.scrollTop,t.scrollLeft,t.clientWidth,t.clientHeight)});e.observe(t),p(()=>{e.disconnect()})}p(()=>{T.value&&=(T.value(),null),S.value&&=(S.value.destroy(),null),w.value&&=(w.value.destroy?.(),null)})}),C([()=>l.dataSource,()=>l.rowData],()=>{let e=Z(),t=w.value;t&&t!==e?(t.destroy?.(),A(),w.value=e,Q(e)):t||(w.value=e)}),C(()=>l.dataSource,e=>{if(e){let t=e;if(t.subscribe){let e=t.subscribe(()=>{S.value?.refresh()});p(()=>e())}}},{immediate:!0}),c({core:S}),(t,c)=>(m(),i(`div`,{ref_key:`containerRef`,ref:h,class:u([`gp-grid-container`,{"gp-grid-container--dark":s.darkMode}]),style:{width:`100%`,height:`100%`,overflow:`auto`,position:`relative`},tabindex:`0`,onScroll:q,onWheel:c[1]||=e=>x(se)(e,s.wheelDampening),onKeydown:c[2]||=(...e)=>x(H)&&x(H)(...e)},[r(` Content sizer `),a(`div`,{style:d({width:`${Math.max(x(D).contentWidth,L.value)}px`,height:`${Math.max(x(D).contentHeight,M.value)}px`,position:`relative`,minWidth:`100%`})},[r(` Headers `),a(`div`,{class:`gp-grid-header`,style:d({position:`sticky`,top:0,left:0,height:`${M.value}px`,width:`${Math.max(x(D).contentWidth,L.value)}px`,minWidth:`100%`})},[(m(!0),i(e,null,_(s.columns,(e,t)=>(m(),i(`div`,{key:e.colId??e.field,class:`gp-grid-header-cell`,"data-col-index":t,style:d({position:`absolute`,left:`${F.value[t]}px`,top:0,width:`${I.value[t]}px`,height:`${M.value}px`,background:`transparent`}),onClick:e=>x(ae)(t,e)},[(m(),n(v(x(pe)({column:e,colIndex:t,sortDirection:x(D).headers.get(t)?.sortDirection,sortIndex:x(D).headers.get(t)?.sortIndex,sortable:x(D).headers.get(t)?.sortable??!0,filterable:x(D).headers.get(t)?.filterable??!0,hasFilter:x(D).headers.get(t)?.hasFilter??!1,core:S.value,container:h.value,headerRenderers:s.headerRenderers??{},globalHeaderRenderer:s.headerRenderer}))))],12,rt))),128))],4),r(` Row slots `),(m(!0),i(e,null,_(te.value.filter(e=>e.rowIndex>=0),t=>(m(),i(`div`,{key:t.slotId,class:u([`gp-grid-row`,{"gp-grid-row--even":t.rowIndex%2==0}]),style:d({position:`absolute`,top:0,left:0,transform:`translateY(${t.translateY}px)`,width:`${Math.max(x(D).contentWidth,L.value)}px`,height:`${s.rowHeight}px`})},[(m(!0),i(e,null,_(s.columns,(a,o)=>(m(),i(`div`,{key:`${t.slotId}-${o}`,class:u(X(t.rowIndex,o)),style:d({position:`absolute`,left:`${F.value[o]}px`,top:0,width:`${I.value[o]}px`,height:`${s.rowHeight}px`}),onMousedown:e=>x(ne)(t.rowIndex,o,e),onDblclick:()=>x(ie)(t.rowIndex,o)},[r(` Edit mode `),x(V)(t.rowIndex,o,x(D).editingCell)&&x(D).editingCell?(m(),n(v(x(de)({column:a,rowData:t.rowData,rowIndex:t.rowIndex,colIndex:o,initialValue:x(D).editingCell.initialValue,core:S.value,editRenderers:s.editRenderers??{},globalEditRenderer:s.editRenderer})),{key:0})):(m(),i(e,{key:1},[r(` View mode `),(m(),n(v(x(ue)({column:a,rowData:t.rowData,rowIndex:t.rowIndex,colIndex:o,isActive:x(z)(t.rowIndex,o,x(D).activeCell),isSelected:x(U)(t.rowIndex,o,x(D).selectionRange),isEditing:!1,cellRenderers:s.cellRenderers??{},globalCellRenderer:s.cellRenderer}))))],64))],46,it))),128))],6))),128)),r(` Fill handle `),x(G)&&!x(D).editingCell?(m(),i(`div`,{key:0,class:`gp-grid-fill-handle`,style:d({position:`absolute`,top:`${x(G).top}px`,left:`${x(G).left}px`,zIndex:200}),onMousedown:c[0]||=(...e)=>x(B)&&x(B)(...e)},null,36)):r(`v-if`,!0),r(` Loading indicator `),x(D).isLoading?(m(),i(`div`,at,[...c[3]||=[a(`div`,{class:`gp-grid-loading-spinner`},null,-1),o(` Loading... `,-1)]])):r(`v-if`,!0),r(` Error message `),x(D).error?(m(),i(`div`,ot,` Error: `+b(x(D).error),1)):r(`v-if`,!0),r(` Empty state `),!x(D).isLoading&&!x(D).error&&x(D).totalRows===0?(m(),i(`div`,st,` No data to display `)):r(`v-if`,!0)],4),r(` Filter Popup `),x(D).filterPopup?.isOpen&&x(D).filterPopup.column&&x(D).filterPopup.anchorRect?(m(),n(nt,{key:0,column:x(D).filterPopup.column,"col-index":x(D).filterPopup.colIndex,"anchor-rect":x(D).filterPopup.anchorRect,"distinct-values":x(D).filterPopup.distinctValues,"current-filter":x(D).filterPopup.currentFilter,onApply:ce,onClose:le},null,8,[`column`,`col-index`,`anchor-rect`,`distinct-values`,`current-filter`])):r(`v-if`,!0)],34))}});function lt(e){re();let n=g(null),r=g(null),{state:i,applyInstructions:a}=K(),o=t(()=>e.headerHeight??e.rowHeight),s=t(()=>k(e.columns,i.viewportWidth)),c=t(()=>s.value.positions),l=t(()=>s.value.widths),u=t(()=>R(c.value)),d=t(()=>Array.from(i.slots.values())),{handleCellMouseDown:m,handleCellDoubleClick:h,handleFillHandleMouseDown:_,handleHeaderClick:v,handleKeyDown:y,handleWheel:b,dragState:x}=J(r,n,t(()=>e.columns),{activeCell:t(()=>i.activeCell),selectionRange:t(()=>i.selectionRange),editingCell:t(()=>i.editingCell),filterPopupOpen:t(()=>i.filterPopup?.isOpen??!1),rowHeight:e.rowHeight,headerHeight:o.value,columnPositions:c,slots:t(()=>i.slots)}),S=()=>{let e=n.value,t=r.value;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)},w=(e,t)=>{let n=r.value;n&&n.setFilter(e,t)},T=()=>{let e=r.value;e&&e.closeFilterPopup()};f(()=>{let t=e.dataSource??(e.rowData?N(e.rowData):j([])),i=new E({columns:e.columns,dataSource:t,rowHeight:e.rowHeight,headerHeight:o.value,overscan:e.overscan??3,sortingEnabled:e.sortingEnabled??!0});r.value=i;let s=i.onBatchInstruction(e=>{a(e)});i.initialize();let c=n.value;if(c){i.setViewport(c.scrollTop,c.scrollLeft,c.clientWidth,c.clientHeight);let e=new ResizeObserver(()=>{i.setViewport(c.scrollTop,c.scrollLeft,c.clientWidth,c.clientHeight)});e.observe(c),p(()=>{e.disconnect(),s(),r.value=null})}}),C(()=>e.dataSource,e=>{if(e){let t=e;if(t.subscribe){let e=t.subscribe(()=>{r.value?.refresh()});p(()=>e())}}},{immediate:!0});let{fillHandlePosition:D}=Y({activeCell:t(()=>i.activeCell),selectionRange:t(()=>i.selectionRange),slots:t(()=>i.slots),columns:t(()=>e.columns),columnPositions:c,columnWidths:l,rowHeight:e.rowHeight});return{containerRef:n,coreRef:r,state:i,slotsArray:d,totalHeaderHeight:o,columnPositions:c,columnWidths:l,totalWidth:u,fillHandlePosition:D,handleScroll:S,handleCellMouseDown:m,handleCellDoubleClick:h,handleFillHandleMouseDown:_,handleHeaderClick:v,handleKeyDown:y,handleWheel:b,handleFilterApply:w,handleFilterPopupClose:T,dragState:x,isCellSelected:U,isCellActive:z,isCellEditing:V,isCellInFillPreview:oe,buildCellClasses:ee}}export{ct as GpGrid,ct as default,T as GridCore,D as buildCellClasses,O as calculateColumnPositions,A as createClientDataSource,M as createDataSourceFromArray,W as createInitialState,P as createMutableClientDataSource,F as createServerDataSource,I as findColumnAtX,Z as getCellValue,L as getTotalWidth,te as gridStyles,ne as injectStyles,ie as isCellActive,B as isCellEditing,ae as isCellInFillPreview,H as isCellSelected,se as isRowVisible,ue as renderCell,de as renderEditCell,pe as renderHeader,q as useAutoScroll,Y as useFillHandle,$ as useFilterConditions,me as useFilterPopup,lt as useGpGrid,K as useGridState,J as useInputHandler};
1
+ import{Fragment as e,computed as t,createBlock as n,createCommentVNode as r,createElementBlock as i,createElementVNode as a,createTextVNode as o,createVNode as s,defineComponent as c,h as l,normalizeClass as u,normalizeStyle as d,onMounted as f,onUnmounted as p,openBlock as m,reactive as h,ref as g,renderList as _,resolveDynamicComponent as v,shallowRef as y,toDisplayString as b,unref as x,vModelText as S,watch as C,withDirectives as w}from"vue";import{GridCore as T,GridCore as E,buildCellClasses as D,buildCellClasses as ee,calculateColumnPositions as O,calculateScaledColumnPositions as k,createClientDataSource as A,createClientDataSource as j,createDataSourceFromArray as M,createDataSourceFromArray as N,createMutableClientDataSource as P,createServerDataSource as F,findColumnAtX as I,getTotalWidth as L,getTotalWidth as R,gridStyles as z,injectStyles as te,injectStyles as ne,isCellActive as re,isCellActive as B,isCellEditing as ie,isCellEditing as V,isCellInFillPreview as H,isCellInFillPreview as ae,isCellSelected as oe,isCellSelected as U,isRowVisible as W}from"gp-grid-core";function G(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 K(e,t){switch(e.type){case`CREATE_SLOT`:t.slots.set(e.slotId,{slotId:e.slotId,rowIndex:-1,rowData:{},translateY:0});break;case`DESTROY_SLOT`:t.slots.delete(e.slotId);break;case`ASSIGN_SLOT`:{let n=t.slots.get(e.slotId);n&&t.slots.set(e.slotId,{...n,rowIndex:e.rowIndex,rowData:e.rowData});break}case`MOVE_SLOT`:{let n=t.slots.get(e.slotId);n&&t.slots.set(e.slotId,{...n,translateY:e.translateY});break}case`SET_ACTIVE_CELL`:t.activeCell=e.position;break;case`SET_SELECTION_RANGE`:t.selectionRange=e.range;break;case`UPDATE_VISIBLE_RANGE`:t.visibleRowRange={start:e.start,end:e.end};break;case`SET_HOVER_POSITION`:t.hoverPosition=e.position;break;case`START_EDIT`:t.editingCell={row:e.row,col:e.col,initialValue:e.initialValue};break;case`STOP_EDIT`:t.editingCell=null;break;case`SET_CONTENT_SIZE`:t.contentWidth=e.width,t.contentHeight=e.height,t.viewportWidth=e.viewportWidth;break;case`UPDATE_HEADER`:t.headers.set(e.colIndex,{column:e.column,sortDirection:e.sortDirection,sortIndex:e.sortIndex,sortable:e.sortable,filterable:e.filterable,hasFilter:e.hasFilter});break;case`OPEN_FILTER_POPUP`:t.filterPopup={isOpen:!0,colIndex:e.colIndex,column:e.column,anchorRect:e.anchorRect,distinctValues:e.distinctValues,currentFilter:e.currentFilter};break;case`CLOSE_FILTER_POPUP`:t.filterPopup=null;break;case`DATA_LOADING`:t.isLoading=!0,t.error=null;break;case`DATA_LOADED`:t.isLoading=!1,t.totalRows=e.totalRows;break;case`DATA_ERROR`:t.isLoading=!1,t.error=e.error;break;case`ROWS_ADDED`:case`ROWS_REMOVED`:t.totalRows=e.totalRows;break;case`ROWS_UPDATED`:case`TRANSACTION_PROCESSED`:break}}function q(e){let t=h(G(e));function n(e){for(let n of e)K(n,t)}function r(){let e=G();t.slots=e.slots,t.activeCell=e.activeCell,t.selectionRange=e.selectionRange,t.editingCell=e.editingCell,t.contentWidth=e.contentWidth,t.contentHeight=e.contentHeight,t.viewportWidth=e.viewportWidth,t.headers=e.headers,t.filterPopup=e.filterPopup,t.isLoading=e.isLoading,t.error=e.error,t.totalRows=e.totalRows,t.visibleRowRange=e.visibleRowRange,t.hoverPosition=e.hoverPosition}return{state:t,applyInstructions:n,reset:r}}function J(e){let t=g(null);function n(n,r){t.value&&clearInterval(t.value),t.value=setInterval(()=>{let t=e.value;t&&(t.scrollTop+=r,t.scrollLeft+=n)},16)}function r(){t.value&&=(clearInterval(t.value),null)}return p(()=>{r()}),{startAutoScroll:n,stopAutoScroll:r}}function se(e,t){for(let n of e.values())if(n.rowIndex===t)return n;return null}function ce(e,t,n,r,i,a){let o=se(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 Y(e,t,n,r){let{activeCell:i,selectionRange:a,editingCell:o,filterPopupOpen:s,rowHeight:c,headerHeight:l,columnPositions:u,visibleColumnsWithIndices:d,slots:f}=r,{startAutoScroll:m,stopAutoScroll:h}=J(t),_=g({isDragging:!1,dragType:null,fillSourceRange:null,fillTarget:null});C([()=>l,()=>c,u,d],()=>{let t=e.value;if(t?.input){let e=d.value;t.input.updateDeps({getHeaderHeight:()=>l,getRowHeight:()=>c,getColumnPositions:()=>u.value,getColumnCount:()=>e.length,getOriginalColumnIndex:t=>{let n=e[t];return n?n.originalIndex:t}})}},{immediate:!0});function v(){let e=t.value;if(!e)return null;let n=e.getBoundingClientRect();return{top:n.top,left:n.left,width:n.width,height:n.height,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft}}function y(e){return{clientX:e.clientX,clientY:e.clientY,button:e.button,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey}}function b(){let t=t=>{let n=e.value,r=v();if(!n?.input||!r)return;let i=n.input.handleDragMove(y(t),r);i&&(i.autoScroll?m(i.autoScroll.dx,i.autoScroll.dy):h(),_.value=n.input.getDragState())},n=()=>{let r=e.value;r?.input&&(r.input.handleDragEnd(),_.value=r.input.getDragState()),h(),document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,n)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,n)}function x(n,r,i){let a=e.value;if(!a?.input)return;let o=a.input.handleCellMouseDown(n,r,y(i));o.focusContainer&&t.value?.focus(),o.startDrag===`selection`&&(a.input.startSelectionDrag(),_.value=a.input.getDragState(),b())}function S(t,n){let r=e.value;r?.input&&r.input.handleCellDoubleClick(t,n)}function w(t){let n=e.value;if(!n?.input)return;let r=n.input.handleFillHandleMouseDown(i.value,a.value,y(t));r.preventDefault&&t.preventDefault(),r.stopPropagation&&t.stopPropagation(),r.startDrag===`fill`&&(_.value=n.input.getDragState(),b())}function T(t,r){let i=e.value;if(!i?.input)return;let a=n.value[t];if(!a)return;let o=a.colId??a.field;i.input.handleHeaderClick(o,r.shiftKey)}function E(n){let r=e.value,a=t.value;if(!r?.input)return;let u=r.input.handleKeyDown({key:n.key,shiftKey:n.shiftKey,ctrlKey:n.ctrlKey,metaKey:n.metaKey},i.value,o.value,s.value);u.preventDefault&&n.preventDefault(),u.scrollToCell&&a&&ce(r,a,u.scrollToCell.row,c,l,f.value)}function D(n,r){let i=e.value,a=t.value;if(!i?.input||!a)return;let o=i.input.handleWheel(n.deltaY,n.deltaX,r);o&&(n.preventDefault(),a.scrollTop+=o.dy,a.scrollLeft+=o.dx)}return p(()=>{h()}),{handleCellMouseDown:x,handleCellDoubleClick:S,handleFillHandleMouseDown:w,handleHeaderClick:T,handleKeyDown:E,handleWheel:D,dragState:_}}function X(e){let{activeCell:n,selectionRange:r,slots:i,columns:a,visibleColumnsWithIndices:o,columnPositions:s,columnWidths:c,rowHeight:l}=e;return{fillHandlePosition:t(()=>{let e=n.value,t=r.value,u=i.value;if(!e&&!t)return null;let d,f,p,m;if(t)d=Math.max(t.startRow,t.endRow),f=Math.max(t.startCol,t.endCol),p=Math.min(t.startCol,t.endCol),m=Math.max(t.startCol,t.endCol);else if(e)d=e.row,f=e.col,p=f,m=f;else return null;let h=a.value;for(let e=p;e<=m;e++){let t=h[e];if(!(!t||t.hidden)&&t.editable!==!0)return null}let g=o.value.findIndex(e=>e.originalIndex===f);if(g===-1)return null;let _=null;for(let e of u.values())if(e.rowIndex===d){_=e.translateY;break}if(_===null)return null;let v=s.value[g]??0,y=c.value[g]??0;return{top:_+l-5,left:v+y-20}})}}function Z(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function Q(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 le(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,isActive:a,isSelected:s,isEditing:c,cellRenderers:l,globalCellRenderer:u}=e,d=Q(n,t.field),f={value:d,rowData:n,column:t,rowIndex:r,colIndex:i,isActive:a,isSelected:s,isEditing:c};if(t.cellRenderer&&typeof t.cellRenderer==`string`){let e=l[t.cellRenderer];if(e)return Z(e(f))}return u?Z(u(f)):o(d==null?``:String(d))}function ue(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function de(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,initialValue:a,core:s,editRenderers:c,globalEditRenderer:u}=e;if(!s)return o(``);let d={value:Q(n,t.field),rowData:n,column:t,rowIndex:r,colIndex:i,isActive:!0,isSelected:!0,isEditing:!0,initialValue:a,onValueChange:e=>s.updateEditValue(e),onCommit:()=>s.commitEdit(),onCancel:()=>s.cancelEdit()};if(t.editRenderer&&typeof t.editRenderer==`string`){let e=c[t.editRenderer];if(e)return ue(e(d))}return u?ue(u(d)):l(`input`,{class:`gp-grid-edit-input`,type:`text`,value:a==null?``:String(a),autofocus:!0,onFocus:e=>e.target.select(),onInput:e=>s.updateEditValue(e.target.value),onKeydown:e=>{e.stopPropagation(),e.key===`Enter`?s.commitEdit():e.key===`Escape`?s.cancelEdit():e.key===`Tab`&&(e.preventDefault(),s.commitEdit(),s.selection.moveFocus(e.shiftKey?`left`:`right`,!1))},onBlur:()=>s.commitEdit()})}function fe(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function pe(t){let{column:n,colIndex:r,sortDirection:i,sortIndex:a,sortable:o,filterable:s,hasFilter:c,core:u,container:d,headerRenderers:f,globalHeaderRenderer:p}=t,m={column:n,colIndex:r,sortDirection:i,sortIndex:a,sortable:o,filterable:s,hasFilter:c,onSort:(e,t)=>{u&&o&&u.setSort(n.colId??n.field,e,t)},onFilterClick:()=>{if(u&&s){let e=d?.querySelector(`[data-col-index="${r}"]`);if(e){let t=e.getBoundingClientRect();u.openFilterPopup(r,{top:t.top,left:t.left,width:t.width,height:t.height})}}}};if(n.headerRenderer&&typeof n.headerRenderer==`string`){let e=f[n.headerRenderer];if(e)return fe(e(m))}if(p)return fe(p(m));let h=[l(`span`,{class:`gp-grid-header-text`},n.headerName??n.field)],g=[];if(o){let e=[l(`span`,{class:`gp-grid-sort-arrows-stack`},[l(`svg`,{class:`gp-grid-sort-arrow-up${i===`asc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`},[l(`path`,{d:`M4 0L8 6H0L4 0Z`,fill:`currentColor`})]),l(`svg`,{class:`gp-grid-sort-arrow-down${i===`desc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`},[l(`path`,{d:`M4 6L0 0H8L4 6Z`,fill:`currentColor`})])])];a!==void 0&&a>0&&e.push(l(`span`,{class:`gp-grid-sort-index`},String(a))),g.push(l(`span`,{class:`gp-grid-sort-arrows`},e))}return s&&g.push(l(`span`,{class:`gp-grid-filter-icon${c?` active`:``}`,onMousedown:e=>{e.stopPropagation(),e.preventDefault(),m.onFilterClick()},onClick:e=>{e.stopPropagation()}},[l(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`currentColor`},[l(`path`,{d:`M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z`})])])),g.length>0&&h.push(l(`span`,{class:`gp-grid-header-icons`},g)),l(e,h)}function me(e,t){let{onClose:n,ignoreSelector:r=`.gp-grid-filter-icon`}=t,i=null,a=null;f(()=>{i=t=>{let i=t.target;r&&i.closest(r)||e.value&&!e.value.contains(i)&&n()},a=e=>{e.key===`Escape`&&n()},requestAnimationFrame(()=>{i&&document.addEventListener(`mousedown`,i),a&&document.addEventListener(`keydown`,a)})}),p(()=>{i&&document.removeEventListener(`mousedown`,i),a&&document.removeEventListener(`keydown`,a)})}function $(e,t=`and`){let n=g([...e]);return{conditions:n,combination:g(t),updateCondition:(e,t)=>{let r=[...n.value];r[e]={...r[e],...t},n.value=r},addCondition:e=>{n.value=[...n.value,{operator:e,value:``,valueTo:``,nextOperator:`and`}]},removeCondition:e=>{n.value=n.value.filter((t,n)=>n!==e)}}}const he={class:`gp-grid-filter-content gp-grid-filter-text`},ge={key:0,class:`gp-grid-filter-mode-toggle`},_e={key:1,class:`gp-grid-filter-info`},ve={class:`gp-grid-filter-actions`},ye=[`disabled`],be={class:`gp-grid-filter-list`},xe={key:0,class:`gp-grid-filter-option`},Se=[`checked`],Ce=[`checked`,`onChange`],we={key:0,class:`gp-grid-filter-combination`},Te=[`onClick`],Ee=[`onClick`],De={class:`gp-grid-filter-row`},Oe=[`value`,`autofocus`,`onChange`],ke=[`value`],Ae=[`value`,`onInput`],je=[`onClick`];var Me=c({__name:`TextFilterContent`,props:{distinctValues:{},currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{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`}],c=n,l=o;function d(e){return Array.isArray(e)?e.join(`, `):String(e??``)}let f=t(()=>{let e=c.distinctValues.filter(e=>e!=null&&e!==``&&!(Array.isArray(e)&&e.length===0)).map(e=>d(e));return Array.from(new Set(e)).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`})})}),p=t(()=>f.value.length>100),h=g(t(()=>{if(!c.currentFilter?.conditions[0])return p.value?`condition`:`values`;let e=c.currentFilter.conditions[0];return e.selectedValues&&e.selectedValues.size>0?`values`:`condition`}).value),v=t(()=>c.currentFilter?.conditions[0]?c.currentFilter.conditions[0].selectedValues??new Set:new Set),y=t(()=>c.currentFilter?.conditions[0]?c.currentFilter.conditions[0].includeBlank??!0:!0),C=g(``),T=g(new Set(v.value)),E=g(y.value),{conditions:D,combination:ee,updateCondition:O,addCondition:k,removeCondition:A}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`contains`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.conditions[0];if(e.selectedValues&&e.selectedValues.size>0)return[{operator:`contains`,value:``,valueTo:``,nextOperator:`and`}];let t=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value??``,valueTo:``,nextOperator:n.nextOperator??t}})}).value,c.currentFilter?.combination??`and`),j=t(()=>{if(!C.value)return f.value;let e=C.value.toLowerCase();return f.value.filter(t=>t.toLowerCase().includes(e))}),M=t(()=>c.distinctValues.some(e=>e==null||e===``)),N=t(()=>j.value.every(e=>T.value.has(e))&&(!M.value||E.value));function P(){T.value=new Set(j.value),M.value&&(E.value=!0)}function F(){T.value=new Set,E.value=!1}function I(e){let t=new Set(T.value);t.has(e)?t.delete(e):t.add(e),T.value=t}function L(){if(h.value===`values`){if(f.value.every(e=>T.value.has(e))&&(!M.value||E.value)){l(`apply`,null);return}l(`apply`,{conditions:[{type:`text`,operator:`equals`,selectedValues:T.value,includeBlank:E.value}],combination:`and`})}else{let e=D.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.value.trim()!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`text`,operator:e.operator,value:e.value,nextOperator:e.nextOperator})),combination:`and`})}}function R(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,he,[r(` Mode toggle - only show if not too many values `),p.value?r(`v-if`,!0):(m(),i(`div`,ge,[a(`button`,{type:`button`,class:u({active:h.value===`values`}),onClick:n[0]||=e=>h.value=`values`},` Values `,2),a(`button`,{type:`button`,class:u({active:h.value===`condition`}),onClick:n[1]||=e=>h.value=`condition`},` Condition `,2)])),r(` Too many values message `),p.value&&h.value===`condition`?(m(),i(`div`,_e,` Too many unique values (`+b(f.value.length)+`). Use conditions to filter. `,1)):r(`v-if`,!0),r(` VALUES MODE `),h.value===`values`?(m(),i(e,{key:2},[r(` Search input `),w(a(`input`,{"onUpdate:modelValue":n[2]||=e=>C.value=e,class:`gp-grid-filter-search`,type:`text`,placeholder:`Search...`,autofocus:``},null,512),[[S,C.value]]),r(` Select all / Deselect all `),a(`div`,ve,[a(`button`,{type:`button`,disabled:N.value,onClick:P},` Select All `,8,ye),a(`button`,{type:`button`,onClick:F},` Deselect All `)]),r(` Checkbox list `),a(`div`,be,[r(` Blanks option `),M.value?(m(),i(`label`,xe,[a(`input`,{type:`checkbox`,checked:E.value,onChange:n[3]||=e=>E.value=!E.value},null,40,Se),n[5]||=a(`span`,{class:`gp-grid-filter-blank`},`(Blanks)`,-1)])):r(`v-if`,!0),r(` Values `),(m(!0),i(e,null,_(j.value,e=>(m(),i(`label`,{key:e,class:`gp-grid-filter-option`},[a(`input`,{type:`checkbox`,checked:T.value.has(e),onChange:t=>I(e)},null,40,Ce),a(`span`,null,b(e),1)]))),128))])],64)):r(`v-if`,!0),r(` CONDITION MODE `),h.value===`condition`?(m(),i(e,{key:3},[(m(!0),i(e,null,_(x(D),(t,n)=>(m(),i(`div`,{key:n,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),n>0?(m(),i(`div`,we,[a(`button`,{type:`button`,class:u({active:x(D)[n-1]?.nextOperator===`and`}),onClick:e=>x(O)(n-1,{nextOperator:`and`})},` AND `,10,Te),a(`button`,{type:`button`,class:u({active:x(D)[n-1]?.nextOperator===`or`}),onClick:e=>x(O)(n-1,{nextOperator:`or`})},` OR `,10,Ee)])):r(`v-if`,!0),a(`div`,De,[r(` Operator select `),a(`select`,{value:t.operator,autofocus:n===0,onChange:e=>x(O)(n,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,ke)),64))],40,Oe),r(` Text input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`text`,value:t.value,placeholder:`Value`,class:`gp-grid-filter-text-input`,onInput:e=>x(O)(n,{value:e.target.value})},null,40,Ae)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(D).length>1?(m(),i(`button`,{key:1,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(A)(n)},` × `,8,je)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[4]||=e=>x(k)(`contains`)},` + Add condition `)],64)):r(`v-if`,!0),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:R},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:L},` Apply `)])]))}});const Ne={class:`gp-grid-filter-content gp-grid-filter-number`},Pe={key:0,class:`gp-grid-filter-combination`},Fe=[`onClick`],Ie=[`onClick`],Le={class:`gp-grid-filter-row`},Re=[`value`,`onChange`],ze=[`value`],Be=[`value`,`onInput`],Ve=[`value`,`onInput`],He=[`onClick`];var Ue=c({__name:`NumberFilterContent`,props:{currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{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`}],c=n,l=o,{conditions:d,combination:f,updateCondition:p,addCondition:h,removeCondition:g}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(t=>{let n=t;return{operator:n.operator,value:n.value==null?``:String(n.value),valueTo:n.valueTo==null?``:String(n.valueTo),nextOperator:n.nextOperator??e}})}).value,c.currentFilter?.combination??`and`);function v(){let e=d.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{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`})}function y(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,Ne,[(m(!0),i(e,null,_(x(d),(t,o)=>(m(),i(`div`,{key:o,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),o>0?(m(),i(`div`,Pe,[a(`button`,{type:`button`,class:u({active:x(d)[o-1]?.nextOperator===`and`}),onClick:e=>x(p)(o-1,{nextOperator:`and`})},` AND `,10,Fe),a(`button`,{type:`button`,class:u({active:x(d)[o-1]?.nextOperator===`or`}),onClick:e=>x(p)(o-1,{nextOperator:`or`})},` OR `,10,Ie)])):r(`v-if`,!0),a(`div`,Le,[r(` Operator select `),a(`select`,{value:t.operator,onChange:e=>x(p)(o,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,ze)),64))],40,Re),r(` Number input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`number`,value:t.value,placeholder:`Value`,onInput:e=>x(p)(o,{value:e.target.value})},null,40,Be)):r(`v-if`,!0),r(` Second number input for "between" `),t.operator===`between`?(m(),i(e,{key:1},[n[1]||=a(`span`,{class:`gp-grid-filter-to`},`to`,-1),a(`input`,{type:`number`,value:t.valueTo,placeholder:`Value`,onInput:e=>x(p)(o,{valueTo:e.target.value})},null,40,Ve)],64)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(d).length>1?(m(),i(`button`,{key:2,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(g)(o)},` × `,8,He)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[0]||=e=>x(h)(`=`)},` + Add condition `),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:y},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:v},` Apply `)])]))}});const We={class:`gp-grid-filter-content gp-grid-filter-date`},Ge={key:0,class:`gp-grid-filter-combination`},Ke=[`onClick`],qe=[`onClick`],Je={class:`gp-grid-filter-row`},Ye=[`value`,`onChange`],Xe=[`value`],Ze=[`value`,`onInput`],Qe=[`value`,`onInput`],$e=[`onClick`];var et=c({__name:`DateFilterContent`,props:{currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}],c=n,l=o;function d(e){if(!e)return``;let t=typeof e==`string`?new Date(e):e;return isNaN(t.getTime())?``:t.toISOString().split(`T`)[0]}let{conditions:f,combination:p,updateCondition:h,addCondition:g,removeCondition:v}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(t=>{let n=t;return{operator:n.operator,value:d(n.value),valueTo:d(n.valueTo),nextOperator:n.nextOperator??e}})}).value,c.currentFilter?.combination??`and`);function y(){let e=f.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`date`,operator:e.operator,value:e.value||void 0,valueTo:e.valueTo||void 0,nextOperator:e.nextOperator})),combination:`and`})}function S(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,We,[(m(!0),i(e,null,_(x(f),(t,o)=>(m(),i(`div`,{key:o,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),o>0?(m(),i(`div`,Ge,[a(`button`,{type:`button`,class:u({active:x(f)[o-1]?.nextOperator===`and`}),onClick:e=>x(h)(o-1,{nextOperator:`and`})},` AND `,10,Ke),a(`button`,{type:`button`,class:u({active:x(f)[o-1]?.nextOperator===`or`}),onClick:e=>x(h)(o-1,{nextOperator:`or`})},` OR `,10,qe)])):r(`v-if`,!0),a(`div`,Je,[r(` Operator select `),a(`select`,{value:t.operator,onChange:e=>x(h)(o,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,Xe)),64))],40,Ye),r(` Date input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`date`,value:t.value,onInput:e=>x(h)(o,{value:e.target.value})},null,40,Ze)):r(`v-if`,!0),r(` Second date input for "between" `),t.operator===`between`?(m(),i(e,{key:1},[n[1]||=a(`span`,{class:`gp-grid-filter-to`},`to`,-1),a(`input`,{type:`date`,value:t.valueTo,onInput:e=>x(h)(o,{valueTo:e.target.value})},null,40,Qe)],64)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(f).length>1?(m(),i(`button`,{key:2,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(v)(o)},` × `,8,$e)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[0]||=e=>x(g)(`=`)},` + Add condition `),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:S},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:y},` Apply `)])]))}});const tt={class:`gp-grid-filter-header`};var nt=c({__name:`FilterPopup`,props:{column:{},colIndex:{},anchorRect:{},distinctValues:{},currentFilter:{}},emits:[`apply`,`close`],setup(o,{emit:c}){let l=o,u=c,f=g(null);me(f,{onClose:()=>u(`close`),ignoreSelector:`.gp-grid-filter-icon`});let p=t(()=>l.column.colId??l.column.field);function h(e){u(`apply`,p.value,e),u(`close`)}function _(){u(`close`)}let v=t(()=>l.column.cellDataType);t(()=>v.value===`text`||v.value===`object`);let y=t(()=>v.value===`number`),x=t(()=>v.value===`date`||v.value===`dateString`||v.value===`dateTime`||v.value===`dateTimeString`),S=t(()=>({position:`fixed`,top:`${l.anchorRect.top+l.anchorRect.height+4}px`,left:`${l.anchorRect.left}px`,minWidth:`${Math.max(200,l.anchorRect.width)}px`,zIndex:1e4}));return(t,c)=>(m(),i(`div`,{ref_key:`popupRef`,ref:f,class:`gp-grid-filter-popup`,style:d(S.value)},[a(`div`,tt,` Filter: `+b(o.column.headerName??o.column.field),1),r(` Number filter `),y.value?(m(),n(Ue,{key:0,"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`current-filter`])):x.value?(m(),i(e,{key:1},[r(` Date filter `),s(et,{"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`current-filter`])],2112)):(m(),i(e,{key:2},[r(` Text filter (default) `),s(Me,{"distinct-values":o.distinctValues,"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`distinct-values`,`current-filter`])],2112))],4))}});const rt=[`data-col-index`,`onClick`],it=[`onMousedown`,`onDblclick`,`onMouseenter`],at={key:1,class:`gp-grid-loading`},ot={key:2,class:`gp-grid-error`},st={key:3,class:`gp-grid-empty`};var ct=c({__name:`GpGrid`,props:{columns:{},dataSource:{},rowData:{},rowHeight:{},headerHeight:{},overscan:{default:3},sortingEnabled:{type:Boolean,default:!0},darkMode:{type:Boolean,default:!1},wheelDampening:{default:.1},cellRenderers:{default:()=>({})},editRenderers:{default:()=>({})},headerRenderers:{default:()=>({})},cellRenderer:{},editRenderer:{},headerRenderer:{},initialWidth:{},initialHeight:{},highlighting:{}},setup(s,{expose:c}){ne();let l=s,h=g(null),S=y(null),w=y(null),T=y(null),{state:D,applyInstructions:O,reset:A}=q({initialWidth:l.initialWidth,initialHeight:l.initialHeight}),M=t(()=>l.headerHeight??l.rowHeight),P=t(()=>l.columns.map((e,t)=>({column:e,originalIndex:t})).filter(({column:e})=>!e.hidden)),F=t(()=>k(P.value.map(e=>e.column),D.viewportWidth)),I=t(()=>F.value.positions),L=t(()=>F.value.widths),z=t(()=>R(I.value)),te=t(()=>Array.from(D.slots.values())),{handleCellMouseDown:re,handleCellDoubleClick:ie,handleFillHandleMouseDown:H,handleHeaderClick:oe,handleKeyDown:W,handleWheel:G,dragState:K}=Y(S,h,t(()=>l.columns),{activeCell:t(()=>D.activeCell),selectionRange:t(()=>D.selectionRange),editingCell:t(()=>D.editingCell),filterPopupOpen:t(()=>D.filterPopup?.isOpen??!1),rowHeight:l.rowHeight,headerHeight:M.value,columnPositions:I,visibleColumnsWithIndices:P,slots:t(()=>D.slots)}),{fillHandlePosition:J}=X({activeCell:t(()=>D.activeCell),selectionRange:t(()=>D.selectionRange),slots:t(()=>D.slots),columns:t(()=>l.columns),visibleColumnsWithIndices:P,columnPositions:I,columnWidths:L,rowHeight:l.rowHeight});function se(){let e=h.value,t=S.value;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)}function ce(e,t){let n=S.value;n&&n.setFilter(e,t)}function Z(){let e=S.value;e&&e.closeFilterPopup()}function Q(e,t){S.value?.input.handleCellMouseEnter(e,t)}function ue(){S.value?.input.handleCellMouseLeave()}function fe(e){return[`gp-grid-row`,...S.value?.highlight?.computeRowClasses(e.rowIndex,e.rowData)??[]].filter(Boolean).join(` `)}function me(e,t,n,r,i){let a=V(e,t,D.editingCell);return[ee(B(e,t,D.activeCell),U(e,t,D.selectionRange),a,ae(e,t,K.value.dragType===`fill`,K.value.fillSourceRange,K.value.fillTarget)),...S.value?.highlight?.computeCombinedCellClasses(e,t,n,r)??[]].filter(Boolean).join(` `)}function $(){return l.dataSource??(l.rowData?N(l.rowData):j([]))}function he(e){T.value&&=(T.value(),null),S.value&&S.value.destroy();let t=new E({columns:l.columns,dataSource:e,rowHeight:l.rowHeight,headerHeight:M.value,overscan:l.overscan,sortingEnabled:l.sortingEnabled,highlighting:l.highlighting});S.value=t,T.value=t.onBatchInstruction(e=>{O(e)}),t.initialize();let n=h.value;n&&t.setViewport(n.scrollTop,n.scrollLeft,n.clientWidth,n.clientHeight)}return f(()=>{let e=$();w.value=e,he(e);let t=h.value;if(t&&typeof ResizeObserver<`u`){let e=new ResizeObserver(()=>{S.value?.setViewport(t.scrollTop,t.scrollLeft,t.clientWidth,t.clientHeight)});e.observe(t),p(()=>{e.disconnect()})}p(()=>{T.value&&=(T.value(),null),S.value&&=(S.value.destroy(),null),w.value&&=(w.value.destroy?.(),null)})}),C([()=>l.dataSource,()=>l.rowData],()=>{let e=$(),t=w.value;t&&t!==e?(t.destroy?.(),A(),w.value=e,he(e)):t||(w.value=e)}),C(()=>l.dataSource,e=>{if(e){let t=e;if(t.subscribe){let e=t.subscribe(()=>{S.value?.refresh()});p(()=>e())}}},{immediate:!0}),c({core:S}),(t,c)=>(m(),i(`div`,{ref_key:`containerRef`,ref:h,class:u([`gp-grid-container`,{"gp-grid-container--dark":s.darkMode}]),style:{width:`100%`,height:`100%`,overflow:`auto`,position:`relative`},tabindex:`0`,onScroll:se,onWheel:c[1]||=e=>x(G)(e,s.wheelDampening),onKeydown:c[2]||=(...e)=>x(W)&&x(W)(...e)},[r(` Content sizer `),a(`div`,{style:d({width:`${Math.max(x(D).contentWidth,z.value)}px`,height:`${Math.max(x(D).contentHeight,M.value)}px`,position:`relative`,minWidth:`100%`})},[r(` Headers `),a(`div`,{class:`gp-grid-header`,style:d({position:`sticky`,top:0,left:0,height:`${M.value}px`,width:`${Math.max(x(D).contentWidth,z.value)}px`,minWidth:`100%`})},[(m(!0),i(e,null,_(P.value,({column:e,originalIndex:t},r)=>(m(),i(`div`,{key:e.colId??e.field,class:`gp-grid-header-cell`,"data-col-index":t,style:d({position:`absolute`,left:`${I.value[r]}px`,top:0,width:`${L.value[r]}px`,height:`${M.value}px`,background:`transparent`}),onClick:e=>x(oe)(t,e)},[(m(),n(v(x(pe)({column:e,colIndex:t,sortDirection:x(D).headers.get(t)?.sortDirection,sortIndex:x(D).headers.get(t)?.sortIndex,sortable:x(D).headers.get(t)?.sortable??!0,filterable:x(D).headers.get(t)?.filterable??!0,hasFilter:x(D).headers.get(t)?.hasFilter??!1,core:S.value,container:h.value,headerRenderers:s.headerRenderers??{},globalHeaderRenderer:s.headerRenderer}))))],12,rt))),128))],4),r(` Row slots `),(m(!0),i(e,null,_(te.value.filter(e=>e.rowIndex>=0),t=>(m(),i(`div`,{key:t.slotId,class:u(fe(t)),style:d({position:`absolute`,top:0,left:0,transform:`translateY(${t.translateY}px)`,width:`${Math.max(x(D).contentWidth,z.value)}px`,height:`${s.rowHeight}px`})},[(m(!0),i(e,null,_(P.value,({column:a,originalIndex:o},c)=>(m(),i(`div`,{key:`${t.slotId}-${o}`,class:u(me(t.rowIndex,o,a,t.rowData,x(D).hoverPosition)),style:d({position:`absolute`,left:`${I.value[c]}px`,top:0,width:`${L.value[c]}px`,height:`${s.rowHeight}px`}),onMousedown:e=>x(re)(t.rowIndex,o,e),onDblclick:()=>x(ie)(t.rowIndex,o),onMouseenter:()=>Q(t.rowIndex,o),onMouseleave:ue},[r(` Edit mode `),x(V)(t.rowIndex,o,x(D).editingCell)&&x(D).editingCell?(m(),n(v(x(de)({column:a,rowData:t.rowData,rowIndex:t.rowIndex,colIndex:o,initialValue:x(D).editingCell.initialValue,core:S.value,editRenderers:s.editRenderers??{},globalEditRenderer:s.editRenderer})),{key:0})):(m(),i(e,{key:1},[r(` View mode `),(m(),n(v(x(le)({column:a,rowData:t.rowData,rowIndex:t.rowIndex,colIndex:o,isActive:x(B)(t.rowIndex,o,x(D).activeCell),isSelected:x(U)(t.rowIndex,o,x(D).selectionRange),isEditing:!1,cellRenderers:s.cellRenderers??{},globalCellRenderer:s.cellRenderer}))))],64))],46,it))),128))],6))),128)),r(` Fill handle `),x(J)&&!x(D).editingCell?(m(),i(`div`,{key:0,class:`gp-grid-fill-handle`,style:d({position:`absolute`,top:`${x(J).top}px`,left:`${x(J).left}px`,zIndex:200}),onMousedown:c[0]||=(...e)=>x(H)&&x(H)(...e)},null,36)):r(`v-if`,!0),r(` Loading indicator `),x(D).isLoading?(m(),i(`div`,at,[...c[3]||=[a(`div`,{class:`gp-grid-loading-spinner`},null,-1),o(` Loading... `,-1)]])):r(`v-if`,!0),r(` Error message `),x(D).error?(m(),i(`div`,ot,` Error: `+b(x(D).error),1)):r(`v-if`,!0),r(` Empty state `),!x(D).isLoading&&!x(D).error&&x(D).totalRows===0?(m(),i(`div`,st,` No data to display `)):r(`v-if`,!0)],4),r(` Filter Popup `),x(D).filterPopup?.isOpen&&x(D).filterPopup.column&&x(D).filterPopup.anchorRect?(m(),n(nt,{key:0,column:x(D).filterPopup.column,"col-index":x(D).filterPopup.colIndex,"anchor-rect":x(D).filterPopup.anchorRect,"distinct-values":x(D).filterPopup.distinctValues,"current-filter":x(D).filterPopup.currentFilter,onApply:ce,onClose:Z},null,8,[`column`,`col-index`,`anchor-rect`,`distinct-values`,`current-filter`])):r(`v-if`,!0)],34))}});function lt(e){ne();let n=g(null),r=g(null),{state:i,applyInstructions:a}=q(),o=t(()=>e.headerHeight??e.rowHeight),s=t(()=>e.columns.map((e,t)=>({column:e,originalIndex:t})).filter(({column:e})=>!e.hidden)),c=t(()=>k(s.value.map(e=>e.column),i.viewportWidth)),l=t(()=>c.value.positions),u=t(()=>c.value.widths),d=t(()=>R(l.value)),m=t(()=>Array.from(i.slots.values())),{handleCellMouseDown:h,handleCellDoubleClick:_,handleFillHandleMouseDown:v,handleHeaderClick:y,handleKeyDown:b,handleWheel:x,dragState:S}=Y(r,n,t(()=>e.columns),{activeCell:t(()=>i.activeCell),selectionRange:t(()=>i.selectionRange),editingCell:t(()=>i.editingCell),filterPopupOpen:t(()=>i.filterPopup?.isOpen??!1),rowHeight:e.rowHeight,headerHeight:o.value,columnPositions:l,visibleColumnsWithIndices:s,slots:t(()=>i.slots)}),w=()=>{let e=n.value,t=r.value;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)},T=(e,t)=>{let n=r.value;n&&n.setFilter(e,t)},D=()=>{let e=r.value;e&&e.closeFilterPopup()},O=(e,t)=>{r.value?.input.handleCellMouseEnter(e,t)},A=()=>{r.value?.input.handleCellMouseLeave()};f(()=>{let t=e.dataSource??(e.rowData?N(e.rowData):j([])),i=new E({columns:e.columns,dataSource:t,rowHeight:e.rowHeight,headerHeight:o.value,overscan:e.overscan??3,sortingEnabled:e.sortingEnabled??!0,highlighting:e.highlighting});r.value=i;let s=i.onBatchInstruction(e=>{a(e)});i.initialize();let c=n.value;if(c){i.setViewport(c.scrollTop,c.scrollLeft,c.clientWidth,c.clientHeight);let e=new ResizeObserver(()=>{i.setViewport(c.scrollTop,c.scrollLeft,c.clientWidth,c.clientHeight)});e.observe(c),p(()=>{e.disconnect(),s(),r.value=null})}}),C(()=>e.dataSource,e=>{if(e){let t=e;if(t.subscribe){let e=t.subscribe(()=>{r.value?.refresh()});p(()=>e())}}},{immediate:!0});let{fillHandlePosition:M}=X({activeCell:t(()=>i.activeCell),selectionRange:t(()=>i.selectionRange),slots:t(()=>i.slots),columns:t(()=>e.columns),visibleColumnsWithIndices:s,columnPositions:l,columnWidths:u,rowHeight:e.rowHeight});return{containerRef:n,coreRef:r,state:i,slotsArray:m,totalHeaderHeight:o,columnPositions:l,columnWidths:u,totalWidth:d,fillHandlePosition:M,handleScroll:w,handleCellMouseDown:h,handleCellDoubleClick:_,handleFillHandleMouseDown:v,handleHeaderClick:y,handleKeyDown:b,handleWheel:x,handleFilterApply:T,handleFilterPopupClose:D,handleCellMouseEnter:O,handleCellMouseLeave:A,dragState:S,isCellSelected:U,isCellActive:B,isCellEditing:V,isCellInFillPreview:ae,buildCellClasses:ee}}export{ct as GpGrid,ct as default,T as GridCore,D as buildCellClasses,O as calculateColumnPositions,A as createClientDataSource,M as createDataSourceFromArray,G as createInitialState,P as createMutableClientDataSource,F as createServerDataSource,I as findColumnAtX,Q as getCellValue,L as getTotalWidth,z as gridStyles,te as injectStyles,re as isCellActive,ie as isCellEditing,H as isCellInFillPreview,oe as isCellSelected,W as isRowVisible,le as renderCell,de as renderEditCell,pe as renderHeader,J as useAutoScroll,X as useFillHandle,$ as useFilterConditions,me as useFilterPopup,lt as useGpGrid,q as useGridState,Y as useInputHandler};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gp-grid-vue",
3
3
  "description": "A high-performance Vue 3 data grid component with virtual scrolling, cell selection, sorting, filtering, and Excel-like editing",
4
- "version": "0.6.0",
4
+ "version": "0.7.1",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -43,7 +43,7 @@
43
43
  "nuxt3"
44
44
  ],
45
45
  "dependencies": {
46
- "gp-grid-core": "0.6.0"
46
+ "gp-grid-core": "0.7.1"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "vue": "^3.4.0"