@gp-grid/angular 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { input, output, computed, TemplateRef, ChangeDetectionStrategy, Component, ViewChild, signal, effect, HostListener, inject, PLATFORM_ID, InjectionToken, Injectable } from '@angular/core';
3
3
  import { NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
4
- import { getFieldValue, isCellSelected, isCellActive, formatCellValue, isCellInFillPreview, buildCellClasses, isCellEditing, calculateFilterPopupPosition, calculateScaledColumnPositions, getTotalWidth, calculateFillHandlePosition, DataSourceOwner, AutoScrollDriver, PendingRowDragController, InputEventAdapter, applyBatchInstructions, scrollCellIntoView, GridCore, createMutableClientDataSource } from '@gp-grid/core';
4
+ import { getFieldValue, isCellSelected, isCellActive, formatCellValue, isCellInFillPreview, buildCellClasses, isCellEditing, calculateFilterPopupPosition, bindPeekSelectAll, calculateScaledColumnPositions, getTotalWidth, calculateFillHandlePosition, DataSourceOwner, AutoScrollDriver, PendingRowDragController, InputEventAdapter, applyBatchInstructions, scrollCellIntoView, GridCore, createMutableClientDataSource } from '@gp-grid/core';
5
5
  export { GridCore, createClientDataSource, createDataSourceFromArray, createMutableClientDataSource, createServerDataSource } from '@gp-grid/core';
6
6
 
7
- const TEMPLATE$1 = `
7
+ const TEMPLATE$2 = `
8
8
  <div
9
9
  class="gp-grid-header"
10
10
  [class.gp-grid-header--loading]="isLoading()"
@@ -153,7 +153,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
153
153
  standalone: true,
154
154
  imports: [NgTemplateOutlet],
155
155
  changeDetection: ChangeDetectionStrategy.OnPush,
156
- template: TEMPLATE$1,
156
+ template: TEMPLATE$2,
157
157
  }]
158
158
  }], propDecorators: { headerHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerHeight", required: true }] }], scrollLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollLeft", required: true }] }], contentWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentWidth", required: true }] }], totalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalWidth", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: true }] }], visibleColumnsWithIndices: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleColumnsWithIndices", required: true }] }], columnPositions: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnPositions", required: true }] }], columnWidths: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnWidths", required: true }] }], headers: [{ type: i0.Input, args: [{ isSignal: true, alias: "headers", required: true }] }], sortingEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingEnabled", required: false }] }], headerRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerRenderers", required: false }] }], globalHeaderRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalHeaderRenderer", required: false }] }], headerPointerDown: [{ type: i0.Output, args: ["headerPointerDown"] }], filterPointerDown: [{ type: i0.Output, args: ["filterPointerDown"] }], resizePointerDown: [{ type: i0.Output, args: ["resizePointerDown"] }], headerSort: [{ type: i0.Output, args: ["headerSort"] }], headerFilterOpen: [{ type: i0.Output, args: ["headerFilterOpen"] }] } });
159
159
 
@@ -183,8 +183,8 @@ const GRID_BODY_TEMPLATE = `<div
183
183
  <div
184
184
  [class]="cellClass(slot.rowIndex, entry.originalIndex, entry.column, slot.rowData)"
185
185
  style="position: absolute; top: 0;"
186
- [attr.data-row-index]="slot.rowIndex"
187
- [attr.data-col-index]="entry.originalIndex"
186
+ [attr.data-cell-row]="slot.rowIndex"
187
+ [attr.data-cell-col]="entry.originalIndex"
188
188
  [style.left.px]="columnPositions()[i]"
189
189
  [style.width.px]="columnWidths()[i]"
190
190
  [style.height.px]="rowHeight()"
@@ -428,7 +428,7 @@ class GridBodyComponent {
428
428
  }
429
429
  }
430
430
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GridBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
431
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: GridBodyComponent, isStandalone: true, selector: "gp-grid-body", inputs: { rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: true, transformFunction: null }, totalHeaderHeight: { classPropertyName: "totalHeaderHeight", publicName: "totalHeaderHeight", isSignal: true, isRequired: true, transformFunction: null }, contentWidth: { classPropertyName: "contentWidth", publicName: "contentWidth", isSignal: true, isRequired: true, transformFunction: null }, contentHeight: { classPropertyName: "contentHeight", publicName: "contentHeight", isSignal: true, isRequired: true, transformFunction: null }, rowsWrapperOffset: { classPropertyName: "rowsWrapperOffset", publicName: "rowsWrapperOffset", isSignal: true, isRequired: true, transformFunction: null }, slotsArray: { classPropertyName: "slotsArray", publicName: "slotsArray", isSignal: true, isRequired: true, transformFunction: null }, visibleColumnWithIndices: { classPropertyName: "visibleColumnWithIndices", publicName: "visibleColumnWithIndices", isSignal: true, isRequired: true, transformFunction: null }, totalWidth: { classPropertyName: "totalWidth", publicName: "totalWidth", isSignal: true, isRequired: true, transformFunction: null }, columnPositions: { classPropertyName: "columnPositions", publicName: "columnPositions", isSignal: true, isRequired: true, transformFunction: null }, columnWidths: { classPropertyName: "columnWidths", publicName: "columnWidths", isSignal: true, isRequired: true, transformFunction: null }, totalRows: { classPropertyName: "totalRows", publicName: "totalRows", isSignal: true, isRequired: true, transformFunction: null }, activeCell: { classPropertyName: "activeCell", publicName: "activeCell", isSignal: true, isRequired: false, transformFunction: null }, selectionRange: { classPropertyName: "selectionRange", publicName: "selectionRange", isSignal: true, isRequired: false, transformFunction: null }, editingCell: { classPropertyName: "editingCell", publicName: "editingCell", isSignal: true, isRequired: false, transformFunction: null }, cellRenderers: { classPropertyName: "cellRenderers", publicName: "cellRenderers", isSignal: true, isRequired: false, transformFunction: null }, globalCellRenderer: { classPropertyName: "globalCellRenderer", publicName: "globalCellRenderer", isSignal: true, isRequired: false, transformFunction: null }, editRenderers: { classPropertyName: "editRenderers", publicName: "editRenderers", isSignal: true, isRequired: false, transformFunction: null }, globalEditRenderer: { classPropertyName: "globalEditRenderer", publicName: "globalEditRenderer", isSignal: true, isRequired: false, transformFunction: null }, hoverPosition: { classPropertyName: "hoverPosition", publicName: "hoverPosition", isSignal: true, isRequired: false, transformFunction: null }, computeRowClasses: { classPropertyName: "computeRowClasses", publicName: "computeRowClasses", isSignal: true, isRequired: false, transformFunction: null }, computeCellClasses: { classPropertyName: "computeCellClasses", publicName: "computeCellClasses", isSignal: true, isRequired: false, transformFunction: null }, fillHandlePosition: { classPropertyName: "fillHandlePosition", publicName: "fillHandlePosition", isSignal: true, isRequired: false, transformFunction: null }, dragState: { classPropertyName: "dragState", publicName: "dragState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrolled: "scrolled", cellPointerDown: "cellPointerDown", cellPointerEnter: "cellPointerEnter", cellPointerLeave: "cellPointerLeave", cellDoubleClick: "cellDoubleClick", editValueChange: "editValueChange", editCommit: "editCommit", editCancel: "editCancel", fillHandlePointerDown: "fillHandlePointerDown" }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], ngImport: i0, template: "<div\n #scrollContainer\n style=\"height: 100%; overflow: auto; position: relative;\"\n (scroll)=\"onScroll()\">\n <div\n style=\"position: relative; min-width: 100%\"\n [style.width.px]=\"innerWidth()\"\n [style.height.px]=\"sizerHeight()\">\n <div\n class=\"gp-grid-rows-wrapper\"\n [style.width.px]=\"innerWidth()\"\n [style.transform]=\"wrapperTransform()\">\n @for (slot of slotsArray(); track slot.slotId) {\n @if (slot.rowIndex >= 0) {\n <div\n [class]=\"rowClass(slot.rowIndex, slot.rowData)\"\n style=\"position: absolute; top: 0; left: 0\"\n [style.transform]=\"'translateY(' + slot.translateY + 'px)'\"\n [style.width.px]=\"innerWidth()\"\n [style.height.px]=\"rowHeight()\"\n >\n @for (entry of visibleColumnWithIndices(); track entry.originalIndex; let i = $index) {\n @let editing = isEditing(slot.rowIndex, entry.originalIndex);\n <div\n [class]=\"cellClass(slot.rowIndex, entry.originalIndex, entry.column, slot.rowData)\"\n style=\"position: absolute; top: 0;\"\n [attr.data-row-index]=\"slot.rowIndex\"\n [attr.data-col-index]=\"entry.originalIndex\"\n [style.left.px]=\"columnPositions()[i]\"\n [style.width.px]=\"columnWidths()[i]\"\n [style.height.px]=\"rowHeight()\"\n (pointerdown)=\"cellPointerDown.emit({ rowIndex: slot.rowIndex, colIndex: entry.originalIndex, event: $event })\"\n (mouseenter)=\"cellPointerEnter.emit({ rowIndex: slot.rowIndex, colIndex: entry.originalIndex })\"\n (mouseleave)=\"cellPointerLeave.emit()\"\n (dblclick)=\"cellDoubleClick.emit({ rowIndex: slot.rowIndex, colIndex: entry.originalIndex })\"\n >\n @if (editing) {\n @let etpl = editTemplate(entry.column);\n @if (etpl) {\n <ng-container\n [ngTemplateOutlet]=\"etpl\"\n [ngTemplateOutletContext]=\"{ $implicit: editParams(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }\">\n </ng-container>\n } @else {\n <input\n class=\"gp-grid-edit-input\"\n type=\"text\"\n [value]=\"editInitialValue()\"\n autofocus\n (focus)=\"onEditFocus($event)\"\n (input)=\"editValueChange.emit(asInput($event).value)\"\n (keydown)=\"onEditKeyDown($event)\"\n (blur)=\"editCommit.emit()\" />\n }\n } @else {\n @let tpl = cellTemplate(entry.column);\n @if (tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: cellParams(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }\">\n </ng-container>\n } @else {\n {{ cellDisplay(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }}\n }\n }\n </div>\n }\n </div>\n }\n }\n @if (fillHandlePosition(); as fhp) {\n @if (editingCell() === null) {\n <div\n class=\"gp-grid-fill-handle\"\n [style.top.px]=\"fhp.top\"\n [style.left.px]=\"fhp.left\"\n (pointerdown)=\"fillHandlePointerDown.emit({ event: $event })\">\n </div>\n }\n }\n @if (rowDropIndicator(); as rd) {\n <div\n class=\"gp-grid-row-drop-indicator\"\n [style.transform]=\"'translateY(' + rd.dropIndicatorY + 'px)'\"\n [style.width.px]=\"rowDropIndicatorWidth()\"></div>\n }\n </div>\n </div>\n @if (totalRows() === 0) {\n <div class=\"gp-grid-empty\">No data to display</div>\n }\n </div>\n", isInline: true, styles: [":host{display:flex;flex:1;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
431
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: GridBodyComponent, isStandalone: true, selector: "gp-grid-body", inputs: { rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: true, transformFunction: null }, totalHeaderHeight: { classPropertyName: "totalHeaderHeight", publicName: "totalHeaderHeight", isSignal: true, isRequired: true, transformFunction: null }, contentWidth: { classPropertyName: "contentWidth", publicName: "contentWidth", isSignal: true, isRequired: true, transformFunction: null }, contentHeight: { classPropertyName: "contentHeight", publicName: "contentHeight", isSignal: true, isRequired: true, transformFunction: null }, rowsWrapperOffset: { classPropertyName: "rowsWrapperOffset", publicName: "rowsWrapperOffset", isSignal: true, isRequired: true, transformFunction: null }, slotsArray: { classPropertyName: "slotsArray", publicName: "slotsArray", isSignal: true, isRequired: true, transformFunction: null }, visibleColumnWithIndices: { classPropertyName: "visibleColumnWithIndices", publicName: "visibleColumnWithIndices", isSignal: true, isRequired: true, transformFunction: null }, totalWidth: { classPropertyName: "totalWidth", publicName: "totalWidth", isSignal: true, isRequired: true, transformFunction: null }, columnPositions: { classPropertyName: "columnPositions", publicName: "columnPositions", isSignal: true, isRequired: true, transformFunction: null }, columnWidths: { classPropertyName: "columnWidths", publicName: "columnWidths", isSignal: true, isRequired: true, transformFunction: null }, totalRows: { classPropertyName: "totalRows", publicName: "totalRows", isSignal: true, isRequired: true, transformFunction: null }, activeCell: { classPropertyName: "activeCell", publicName: "activeCell", isSignal: true, isRequired: false, transformFunction: null }, selectionRange: { classPropertyName: "selectionRange", publicName: "selectionRange", isSignal: true, isRequired: false, transformFunction: null }, editingCell: { classPropertyName: "editingCell", publicName: "editingCell", isSignal: true, isRequired: false, transformFunction: null }, cellRenderers: { classPropertyName: "cellRenderers", publicName: "cellRenderers", isSignal: true, isRequired: false, transformFunction: null }, globalCellRenderer: { classPropertyName: "globalCellRenderer", publicName: "globalCellRenderer", isSignal: true, isRequired: false, transformFunction: null }, editRenderers: { classPropertyName: "editRenderers", publicName: "editRenderers", isSignal: true, isRequired: false, transformFunction: null }, globalEditRenderer: { classPropertyName: "globalEditRenderer", publicName: "globalEditRenderer", isSignal: true, isRequired: false, transformFunction: null }, hoverPosition: { classPropertyName: "hoverPosition", publicName: "hoverPosition", isSignal: true, isRequired: false, transformFunction: null }, computeRowClasses: { classPropertyName: "computeRowClasses", publicName: "computeRowClasses", isSignal: true, isRequired: false, transformFunction: null }, computeCellClasses: { classPropertyName: "computeCellClasses", publicName: "computeCellClasses", isSignal: true, isRequired: false, transformFunction: null }, fillHandlePosition: { classPropertyName: "fillHandlePosition", publicName: "fillHandlePosition", isSignal: true, isRequired: false, transformFunction: null }, dragState: { classPropertyName: "dragState", publicName: "dragState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrolled: "scrolled", cellPointerDown: "cellPointerDown", cellPointerEnter: "cellPointerEnter", cellPointerLeave: "cellPointerLeave", cellDoubleClick: "cellDoubleClick", editValueChange: "editValueChange", editCommit: "editCommit", editCancel: "editCancel", fillHandlePointerDown: "fillHandlePointerDown" }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true }], ngImport: i0, template: "<div\n #scrollContainer\n style=\"height: 100%; overflow: auto; position: relative;\"\n (scroll)=\"onScroll()\">\n <div\n style=\"position: relative; min-width: 100%\"\n [style.width.px]=\"innerWidth()\"\n [style.height.px]=\"sizerHeight()\">\n <div\n class=\"gp-grid-rows-wrapper\"\n [style.width.px]=\"innerWidth()\"\n [style.transform]=\"wrapperTransform()\">\n @for (slot of slotsArray(); track slot.slotId) {\n @if (slot.rowIndex >= 0) {\n <div\n [class]=\"rowClass(slot.rowIndex, slot.rowData)\"\n style=\"position: absolute; top: 0; left: 0\"\n [style.transform]=\"'translateY(' + slot.translateY + 'px)'\"\n [style.width.px]=\"innerWidth()\"\n [style.height.px]=\"rowHeight()\"\n >\n @for (entry of visibleColumnWithIndices(); track entry.originalIndex; let i = $index) {\n @let editing = isEditing(slot.rowIndex, entry.originalIndex);\n <div\n [class]=\"cellClass(slot.rowIndex, entry.originalIndex, entry.column, slot.rowData)\"\n style=\"position: absolute; top: 0;\"\n [attr.data-cell-row]=\"slot.rowIndex\"\n [attr.data-cell-col]=\"entry.originalIndex\"\n [style.left.px]=\"columnPositions()[i]\"\n [style.width.px]=\"columnWidths()[i]\"\n [style.height.px]=\"rowHeight()\"\n (pointerdown)=\"cellPointerDown.emit({ rowIndex: slot.rowIndex, colIndex: entry.originalIndex, event: $event })\"\n (mouseenter)=\"cellPointerEnter.emit({ rowIndex: slot.rowIndex, colIndex: entry.originalIndex })\"\n (mouseleave)=\"cellPointerLeave.emit()\"\n (dblclick)=\"cellDoubleClick.emit({ rowIndex: slot.rowIndex, colIndex: entry.originalIndex })\"\n >\n @if (editing) {\n @let etpl = editTemplate(entry.column);\n @if (etpl) {\n <ng-container\n [ngTemplateOutlet]=\"etpl\"\n [ngTemplateOutletContext]=\"{ $implicit: editParams(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }\">\n </ng-container>\n } @else {\n <input\n class=\"gp-grid-edit-input\"\n type=\"text\"\n [value]=\"editInitialValue()\"\n autofocus\n (focus)=\"onEditFocus($event)\"\n (input)=\"editValueChange.emit(asInput($event).value)\"\n (keydown)=\"onEditKeyDown($event)\"\n (blur)=\"editCommit.emit()\" />\n }\n } @else {\n @let tpl = cellTemplate(entry.column);\n @if (tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: cellParams(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }\">\n </ng-container>\n } @else {\n {{ cellDisplay(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }}\n }\n }\n </div>\n }\n </div>\n }\n }\n @if (fillHandlePosition(); as fhp) {\n @if (editingCell() === null) {\n <div\n class=\"gp-grid-fill-handle\"\n [style.top.px]=\"fhp.top\"\n [style.left.px]=\"fhp.left\"\n (pointerdown)=\"fillHandlePointerDown.emit({ event: $event })\">\n </div>\n }\n }\n @if (rowDropIndicator(); as rd) {\n <div\n class=\"gp-grid-row-drop-indicator\"\n [style.transform]=\"'translateY(' + rd.dropIndicatorY + 'px)'\"\n [style.width.px]=\"rowDropIndicatorWidth()\"></div>\n }\n </div>\n </div>\n @if (totalRows() === 0) {\n <div class=\"gp-grid-empty\">No data to display</div>\n }\n </div>\n", isInline: true, styles: [":host{display:flex;flex:1;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
432
432
  }
433
433
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GridBodyComponent, decorators: [{
434
434
  type: Component,
@@ -823,18 +823,31 @@ class FilterPopupComponent {
823
823
  this.anchorEl();
824
824
  this.currentFilter();
825
825
  this.initFromCurrentFilter();
826
- requestAnimationFrame(() => this.updatePosition());
826
+ // Update synchronously so the new column's anchor lands before paint,
827
+ // not one frame later (which would briefly show the popup at the
828
+ // previously-open column's position).
829
+ this.updatePosition();
827
830
  });
828
831
  }
829
832
  ngAfterViewInit() {
833
+ // Run once the popup element exists; the constructor effect may have run
834
+ // before the view was ready and bailed.
835
+ this.updatePosition();
830
836
  requestAnimationFrame(() => {
831
837
  document.addEventListener('pointerdown', this.onDocumentPointerDown, true);
832
838
  });
833
- window.addEventListener('resize', this.onWindowResize);
839
+ // Scroll events don't bubble, so listen in the capture phase on window to
840
+ // catch scrolls from the grid body, the page, and any wrapping scroll
841
+ // container in the host app.
842
+ window.addEventListener('scroll', this.onWindowScrollOrResize, { passive: true, capture: true });
843
+ window.addEventListener('resize', this.onWindowScrollOrResize);
834
844
  }
835
845
  ngOnDestroy() {
836
846
  document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);
837
- window.removeEventListener('resize', this.onWindowResize);
847
+ window.removeEventListener('scroll', this.onWindowScrollOrResize, { capture: true });
848
+ window.removeEventListener('resize', this.onWindowScrollOrResize);
849
+ if (this.repositionRafId !== null)
850
+ cancelAnimationFrame(this.repositionRafId);
838
851
  }
839
852
  onEscape() {
840
853
  this.close.emit();
@@ -947,8 +960,14 @@ class FilterPopupComponent {
947
960
  return;
948
961
  this.close.emit();
949
962
  };
950
- onWindowResize = () => {
951
- this.updatePosition();
963
+ repositionRafId = null;
964
+ onWindowScrollOrResize = () => {
965
+ if (this.repositionRafId !== null)
966
+ return;
967
+ this.repositionRafId = requestAnimationFrame(() => {
968
+ this.repositionRafId = null;
969
+ this.updatePosition();
970
+ });
952
971
  };
953
972
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: FilterPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
954
973
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: FilterPopupComponent, isStandalone: true, selector: "gp-grid-filter-popup", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, colIndex: { classPropertyName: "colIndex", publicName: "colIndex", isSignal: true, isRequired: true, transformFunction: null }, anchorEl: { classPropertyName: "anchorEl", publicName: "anchorEl", isSignal: true, isRequired: true, transformFunction: null }, distinctValues: { classPropertyName: "distinctValues", publicName: "distinctValues", isSignal: true, isRequired: true, transformFunction: null }, currentFilter: { classPropertyName: "currentFilter", publicName: "currentFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { apply: "apply", close: "close" }, host: { listeners: { "keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "popupEl", first: true, predicate: ["popupEl"], descendants: true }], ngImport: i0, template: "\n<div\n #popupEl\n class=\"gp-grid-filter-popup\"\n [style.position]=\"'fixed'\"\n [style.zIndex]=\"10000\"\n [style.top.px]=\"popupTop()\"\n [style.left.px]=\"popupLeft()\"\n [style.minWidth.px]=\"popupMinWidth()\"\n [style.visibility]=\"positioned() ? 'visible' : 'hidden'\"\n (keydown.escape)=\"close.emit()\"\n (click)=\"$event.stopPropagation()\">\n\n <div class=\"gp-grid-filter-header\">\n Filter: {{ column().headerName ?? column().field }}\n </div>\n\n <div [class]=\"'gp-grid-filter-content ' + (isNumberColumn() ? 'gp-grid-filter-number' : 'gp-grid-filter-text')\">\n @if (isNumberColumn()) {\n @for (cond of numberConditions; track $index; let i = $index) {\n <div class=\"gp-grid-filter-condition\">\n @if (i > 0) {\n <div class=\"gp-grid-filter-combination\">\n <button\n type=\"button\"\n [class.active]=\"numberConditions[i - 1]?.nextOperator === 'and'\"\n (click)=\"setNumberNextOp(i - 1, 'and')\">\n AND\n </button>\n <button\n type=\"button\"\n [class.active]=\"numberConditions[i - 1]?.nextOperator === 'or'\"\n (click)=\"setNumberNextOp(i - 1, 'or')\">\n OR\n </button>\n </div>\n }\n <div class=\"gp-grid-filter-row\">\n <select\n [value]=\"cond.operator\"\n (change)=\"onNumberOperatorChange(i, $any($event.target).value)\">\n @for (op of numberOperators; track op.value) {\n <option [value]=\"op.value\">{{ op.label }}</option>\n }\n </select>\n @if (!isValueLessNumberOp(cond.operator)) {\n <input\n type=\"number\"\n [value]=\"cond.value\"\n (input)=\"cond.value = $any($event.target).value\"\n placeholder=\"Value\" />\n @if (cond.operator === 'between') {\n <span class=\"gp-grid-filter-to\">to</span>\n <input\n type=\"number\"\n [value]=\"cond.valueTo\"\n (input)=\"cond.valueTo = $any($event.target).value\"\n placeholder=\"Value\" />\n }\n }\n @if (numberConditions.length > 1) {\n <button\n type=\"button\"\n class=\"gp-grid-filter-remove\"\n (click)=\"removeNumberCondition(i)\">\u00D7</button>\n }\n </div>\n </div>\n }\n <button type=\"button\" class=\"gp-grid-filter-add\" (click)=\"addNumberCondition()\">\n + Add condition\n </button>\n } @else {\n @if (showValuesMode()) {\n <div class=\"gp-grid-filter-mode-toggle\">\n <button\n type=\"button\"\n [class.active]=\"filterMode === 'values'\"\n (click)=\"filterMode = 'values'\">\n Values\n </button>\n <button\n type=\"button\"\n [class.active]=\"filterMode === 'condition'\"\n (click)=\"filterMode = 'condition'\">\n Condition\n </button>\n </div>\n }\n\n @if (filterMode === 'values' && showValuesMode()) {\n <input\n class=\"gp-grid-filter-search\"\n type=\"text\"\n [value]=\"searchText\"\n (input)=\"searchText = $any($event.target).value\"\n placeholder=\"Search...\" />\n <div class=\"gp-grid-filter-actions\">\n <button type=\"button\" (click)=\"selectAll()\">Select All</button>\n <button type=\"button\" (click)=\"deselectAll()\">Deselect All</button>\n </div>\n <div class=\"gp-grid-filter-list\">\n <label class=\"gp-grid-filter-option\">\n <input\n type=\"checkbox\"\n [checked]=\"includeBlanks\"\n (change)=\"includeBlanks = $any($event.target).checked\" />\n <span class=\"gp-grid-filter-blank\">(Blanks)</span>\n </label>\n @for (entry of filteredUniqueEntries(); track entry.key) {\n <label class=\"gp-grid-filter-option\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedValues.has(entry.key)\"\n (change)=\"toggleValue(entry.key, $any($event.target).checked)\" />\n <span>{{ entry.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (filterMode === 'condition') {\n @for (cond of textConditions; track $index; let i = $index) {\n <div class=\"gp-grid-filter-condition\">\n @if (i > 0) {\n <div class=\"gp-grid-filter-combination\">\n <button\n type=\"button\"\n [class.active]=\"textConditions[i - 1]?.nextOperator === 'and'\"\n (click)=\"setTextNextOp(i - 1, 'and')\">\n AND\n </button>\n <button\n type=\"button\"\n [class.active]=\"textConditions[i - 1]?.nextOperator === 'or'\"\n (click)=\"setTextNextOp(i - 1, 'or')\">\n OR\n </button>\n </div>\n }\n <div class=\"gp-grid-filter-row\">\n <select\n [value]=\"cond.operator\"\n (change)=\"onTextOperatorChange(i, $any($event.target).value)\">\n @for (op of textOperators; track op.value) {\n <option [value]=\"op.value\">{{ op.label }}</option>\n }\n </select>\n @if (!isValueLessTextOp(cond.operator)) {\n <input\n class=\"gp-grid-filter-text-input\"\n type=\"text\"\n [value]=\"cond.value\"\n (input)=\"cond.value = $any($event.target).value\"\n placeholder=\"Value\" />\n }\n @if (textConditions.length > 1) {\n <button\n type=\"button\"\n class=\"gp-grid-filter-remove\"\n (click)=\"removeTextCondition(i)\">\u00D7</button>\n }\n </div>\n </div>\n }\n <button type=\"button\" class=\"gp-grid-filter-add\" (click)=\"addTextCondition()\">\n + Add condition\n </button>\n }\n }\n\n <div class=\"gp-grid-filter-buttons\">\n <button type=\"button\" class=\"gp-grid-filter-btn-clear\" (click)=\"handleClear()\">\n Clear\n </button>\n <button type=\"button\" class=\"gp-grid-filter-btn-apply\" (click)=\"handleApply()\">\n Apply\n </button>\n </div>\n </div>\n</div>\n", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
@@ -975,7 +994,7 @@ const setField = (arr, index, key, value) => {
975
994
  item[key] = value;
976
995
  };
977
996
 
978
- const TEMPLATE = `
997
+ const TEMPLATE$1 = `
979
998
  @if (filterPopup(); as fp) {
980
999
  <gp-grid-filter-popup
981
1000
  [column]="fp.column"
@@ -1088,10 +1107,163 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
1088
1107
  standalone: true,
1089
1108
  imports: [FilterPopupComponent],
1090
1109
  changeDetection: ChangeDetectionStrategy.OnPush,
1091
- template: TEMPLATE,
1110
+ template: TEMPLATE$1,
1092
1111
  }]
1093
1112
  }], propDecorators: { filterPopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPopup", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], headerHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerHeight", required: true }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: true }] }], dragState: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragState", required: true }] }], visibleColumnWithIndices: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleColumnWithIndices", required: true }] }], columnPositions: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnPositions", required: true }] }], scrollLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollLeft", required: true }] }], effectiveColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "effectiveColumns", required: true }] }], totalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalWidth", required: true }] }], filterApply: [{ type: i0.Output, args: ["filterApply"] }], filterClose: [{ type: i0.Output, args: ["filterClose"] }] } });
1094
1113
 
1114
+ const TEMPLATE = `
1115
+ <div
1116
+ #overlayEl
1117
+ class="gp-grid-cell-peek"
1118
+ [style.position]="'fixed'"
1119
+ [style.top.px]="top()"
1120
+ [style.left.px]="left()"
1121
+ [style.width.px]="width()"
1122
+ [style.visibility]="positioned() ? 'visible' : 'hidden'">
1123
+ @if (template(); as tpl) {
1124
+ <ng-container
1125
+ [ngTemplateOutlet]="tpl"
1126
+ [ngTemplateOutletContext]="{ $implicit: rendererParams() }">
1127
+ </ng-container>
1128
+ } @else {
1129
+ {{ fallbackText() }}
1130
+ }
1131
+ </div>
1132
+ `;
1133
+ class CellPeekComponent {
1134
+ overlayEl;
1135
+ peekCell = input.required(...(ngDevMode ? [{ debugName: "peekCell" }] : /* istanbul ignore next */ []));
1136
+ column = input.required(...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
1137
+ rowData = input.required(...(ngDevMode ? [{ debugName: "rowData" }] : /* istanbul ignore next */ []));
1138
+ containerEl = input.required(...(ngDevMode ? [{ debugName: "containerEl" }] : /* istanbul ignore next */ []));
1139
+ cellRenderers = input({}, ...(ngDevMode ? [{ debugName: "cellRenderers" }] : /* istanbul ignore next */ []));
1140
+ globalCellRenderer = input(null, ...(ngDevMode ? [{ debugName: "globalCellRenderer" }] : /* istanbul ignore next */ []));
1141
+ close = output();
1142
+ top = signal(0, ...(ngDevMode ? [{ debugName: "top" }] : /* istanbul ignore next */ []));
1143
+ left = signal(0, ...(ngDevMode ? [{ debugName: "left" }] : /* istanbul ignore next */ []));
1144
+ width = signal(0, ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
1145
+ positioned = signal(false, ...(ngDevMode ? [{ debugName: "positioned" }] : /* istanbul ignore next */ []));
1146
+ template = computed(() => {
1147
+ const renderer = this.column().cellRenderer;
1148
+ if (renderer instanceof TemplateRef)
1149
+ return renderer;
1150
+ if (typeof renderer === 'string') {
1151
+ const registered = this.cellRenderers()[renderer];
1152
+ if (registered)
1153
+ return registered;
1154
+ }
1155
+ return this.globalCellRenderer();
1156
+ }, ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
1157
+ rendererParams = computed(() => {
1158
+ const col = this.column();
1159
+ const data = this.rowData();
1160
+ const rawValue = getFieldValue(data, col.field);
1161
+ const displayValue = col.valueFormatter ? col.valueFormatter(rawValue) : rawValue;
1162
+ return {
1163
+ value: displayValue,
1164
+ rowData: data,
1165
+ column: col,
1166
+ rowIndex: this.peekCell().row,
1167
+ colIndex: this.peekCell().col,
1168
+ isActive: true,
1169
+ isSelected: false,
1170
+ isEditing: false,
1171
+ };
1172
+ }, ...(ngDevMode ? [{ debugName: "rendererParams" }] : /* istanbul ignore next */ []));
1173
+ fallbackText = computed(() => {
1174
+ const col = this.column();
1175
+ const renderer = col.cellRenderer;
1176
+ const value = getFieldValue(this.rowData(), col.field);
1177
+ if (typeof renderer === 'function') {
1178
+ const result = renderer(this.rendererParams());
1179
+ return result === null || result === undefined ? '' : String(result);
1180
+ }
1181
+ return formatCellValue(value, col.valueFormatter);
1182
+ }, ...(ngDevMode ? [{ debugName: "fallbackText" }] : /* istanbul ignore next */ []));
1183
+ rafId = null;
1184
+ pointerRafId = null;
1185
+ unbindSelectAll = null;
1186
+ constructor() {
1187
+ effect(() => {
1188
+ this.peekCell();
1189
+ this.updatePosition();
1190
+ });
1191
+ }
1192
+ ngAfterViewInit() {
1193
+ this.updatePosition();
1194
+ window.addEventListener('scroll', this.onWindowScrollOrResize, { passive: true, capture: true });
1195
+ window.addEventListener('resize', this.onWindowScrollOrResize);
1196
+ if (this.overlayEl?.nativeElement) {
1197
+ this.unbindSelectAll = bindPeekSelectAll(this.overlayEl.nativeElement);
1198
+ }
1199
+ this.pointerRafId = requestAnimationFrame(() => {
1200
+ document.addEventListener('pointerdown', this.onDocumentPointerDown);
1201
+ });
1202
+ }
1203
+ ngOnDestroy() {
1204
+ window.removeEventListener('scroll', this.onWindowScrollOrResize, { capture: true });
1205
+ window.removeEventListener('resize', this.onWindowScrollOrResize);
1206
+ document.removeEventListener('pointerdown', this.onDocumentPointerDown);
1207
+ this.unbindSelectAll?.();
1208
+ if (this.rafId !== null)
1209
+ cancelAnimationFrame(this.rafId);
1210
+ if (this.pointerRafId !== null)
1211
+ cancelAnimationFrame(this.pointerRafId);
1212
+ }
1213
+ onEscape() {
1214
+ this.close.emit();
1215
+ }
1216
+ updatePosition() {
1217
+ const container = this.containerEl();
1218
+ const overlay = this.overlayEl?.nativeElement;
1219
+ if (!container || !overlay)
1220
+ return;
1221
+ const peek = this.peekCell();
1222
+ const cellEl = container.querySelector(`[data-cell-row="${peek.row}"][data-cell-col="${peek.col}"]`);
1223
+ if (!cellEl) {
1224
+ this.close.emit();
1225
+ return;
1226
+ }
1227
+ const rect = cellEl.getBoundingClientRect();
1228
+ this.top.set(rect.top);
1229
+ this.left.set(rect.left);
1230
+ this.width.set(rect.width);
1231
+ this.positioned.set(true);
1232
+ }
1233
+ onWindowScrollOrResize = () => {
1234
+ if (this.rafId !== null)
1235
+ return;
1236
+ this.rafId = requestAnimationFrame(() => {
1237
+ this.rafId = null;
1238
+ this.updatePosition();
1239
+ });
1240
+ };
1241
+ onDocumentPointerDown = (event) => {
1242
+ const target = event.target;
1243
+ if (this.overlayEl?.nativeElement?.contains(target))
1244
+ return;
1245
+ this.close.emit();
1246
+ };
1247
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CellPeekComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1248
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: CellPeekComponent, isStandalone: true, selector: "gp-grid-cell-peek", inputs: { peekCell: { classPropertyName: "peekCell", publicName: "peekCell", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: true, transformFunction: null }, containerEl: { classPropertyName: "containerEl", publicName: "containerEl", isSignal: true, isRequired: true, transformFunction: null }, cellRenderers: { classPropertyName: "cellRenderers", publicName: "cellRenderers", isSignal: true, isRequired: false, transformFunction: null }, globalCellRenderer: { classPropertyName: "globalCellRenderer", publicName: "globalCellRenderer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, host: { listeners: { "keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "overlayEl", first: true, predicate: ["overlayEl"], descendants: true }], ngImport: i0, template: "\n <div\n #overlayEl\n class=\"gp-grid-cell-peek\"\n [style.position]=\"'fixed'\"\n [style.top.px]=\"top()\"\n [style.left.px]=\"left()\"\n [style.width.px]=\"width()\"\n [style.visibility]=\"positioned() ? 'visible' : 'hidden'\">\n @if (template(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: rendererParams() }\">\n </ng-container>\n } @else {\n {{ fallbackText() }}\n }\n </div>\n", isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1249
+ }
1250
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: CellPeekComponent, decorators: [{
1251
+ type: Component,
1252
+ args: [{
1253
+ selector: 'gp-grid-cell-peek',
1254
+ standalone: true,
1255
+ imports: [NgTemplateOutlet],
1256
+ changeDetection: ChangeDetectionStrategy.OnPush,
1257
+ template: TEMPLATE,
1258
+ }]
1259
+ }], ctorParameters: () => [], propDecorators: { overlayEl: [{
1260
+ type: ViewChild,
1261
+ args: ['overlayEl', { static: false }]
1262
+ }], peekCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "peekCell", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], rowData: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowData", required: true }] }], containerEl: [{ type: i0.Input, args: [{ isSignal: true, alias: "containerEl", required: true }] }], cellRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderers", required: false }] }], globalCellRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalCellRenderer", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], onEscape: [{
1263
+ type: HostListener,
1264
+ args: ['keydown.escape']
1265
+ }] } });
1266
+
1095
1267
  const GP_GRID_TEMPLATE = `
1096
1268
  <div #container
1097
1269
  [class]="'gp-grid-container' + (darkMode() ? ' gp-grid-container--dark' : '')"
@@ -1168,6 +1340,17 @@ const GP_GRID_TEMPLATE = `
1168
1340
  (filterApply)="onFilterApply($event)"
1169
1341
  (filterClose)="onFilterClose()"
1170
1342
  />
1343
+ @if (peekContext(); as ctx) {
1344
+ <gp-grid-cell-peek
1345
+ [peekCell]="ctx.peek"
1346
+ [column]="ctx.column"
1347
+ [rowData]="ctx.rowData"
1348
+ [containerEl]="container"
1349
+ [cellRenderers]="cellRenderers()"
1350
+ [globalCellRenderer]="cellRenderer()"
1351
+ (close)="onPeekClose()"
1352
+ />
1353
+ }
1171
1354
  </div>
1172
1355
  `;
1173
1356
 
@@ -1202,6 +1385,7 @@ class GpGridViewModel {
1202
1385
  selectionRange = signal(null, ...(ngDevMode ? [{ debugName: "selectionRange" }] : /* istanbul ignore next */ []));
1203
1386
  editingCell = signal(null, ...(ngDevMode ? [{ debugName: "editingCell" }] : /* istanbul ignore next */ []));
1204
1387
  hoverPosition = signal(null, ...(ngDevMode ? [{ debugName: "hoverPosition" }] : /* istanbul ignore next */ []));
1388
+ peekCell = signal(null, ...(ngDevMode ? [{ debugName: "peekCell" }] : /* istanbul ignore next */ []));
1205
1389
  columnsOverride = signal(null, ...(ngDevMode ? [{ debugName: "columnsOverride" }] : /* istanbul ignore next */ []));
1206
1390
  dragState = signal(INITIAL_DRAG_STATE, ...(ngDevMode ? [{ debugName: "dragState" }] : /* istanbul ignore next */ []));
1207
1391
  contentWidth = signal(0, ...(ngDevMode ? [{ debugName: "contentWidth" }] : /* istanbul ignore next */ []));
@@ -1250,6 +1434,7 @@ class GpGridViewModel {
1250
1434
  setSelectionRange: (v) => this.selectionRange.set(v),
1251
1435
  setEditingCell: (v) => this.editingCell.set(v),
1252
1436
  setHoverPosition: (v) => this.hoverPosition.set(v),
1437
+ setPeekCell: (v) => this.peekCell.set(v),
1253
1438
  setColumnsOverride: (v) => this.columnsOverride.set(v),
1254
1439
  onFilterPopupChange: (v) => this.materializeFilterPopup(v),
1255
1440
  };
@@ -1531,8 +1716,23 @@ class GpGridComponent {
1531
1716
  return this.bindings.coreRef?.highlight?.computeCombinedCellClasses(rowIndex, colIndex, column, rowData) ?? [];
1532
1717
  };
1533
1718
  onCellDoubleClick(evt) {
1534
- this.bindings.coreRef?.startEdit(evt.rowIndex, evt.colIndex);
1719
+ this.bindings.coreRef?.input.handleCellDoubleClick(evt.rowIndex, evt.colIndex);
1720
+ }
1721
+ onPeekClose() {
1722
+ this.bindings.coreRef?.stopPeek();
1535
1723
  }
1724
+ peekContext = computed(() => {
1725
+ const peek = this.vm.peekCell();
1726
+ if (peek === null)
1727
+ return null;
1728
+ const column = this.vm.effectiveColumns()[peek.col];
1729
+ if (!column)
1730
+ return null;
1731
+ const slot = [...this.vm.slots().values()].find((s) => s.rowIndex === peek.row);
1732
+ if (!slot)
1733
+ return null;
1734
+ return { peek, column, rowData: slot.rowData };
1735
+ }, ...(ngDevMode ? [{ debugName: "peekContext" }] : /* istanbul ignore next */ []));
1536
1736
  onEditValueChange(value) {
1537
1737
  this.bindings.coreRef?.updateEditValue(value);
1538
1738
  }
@@ -1593,11 +1793,11 @@ class GpGridComponent {
1593
1793
  this.bindings.pendingRowDrag.releaseLocks();
1594
1794
  };
1595
1795
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GpGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1596
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.7", type: GpGridComponent, isStandalone: true, selector: "gp-grid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, getRowId: { classPropertyName: "getRowId", publicName: "getRowId", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, headerHeight: { classPropertyName: "headerHeight", publicName: "headerHeight", isSignal: true, isRequired: false, transformFunction: null }, darkMode: { classPropertyName: "darkMode", publicName: "darkMode", isSignal: true, isRequired: false, transformFunction: null }, cellRenderers: { classPropertyName: "cellRenderers", publicName: "cellRenderers", isSignal: true, isRequired: false, transformFunction: null }, headerRenderers: { classPropertyName: "headerRenderers", publicName: "headerRenderers", isSignal: true, isRequired: false, transformFunction: null }, editRenderers: { classPropertyName: "editRenderers", publicName: "editRenderers", isSignal: true, isRequired: false, transformFunction: null }, cellRenderer: { classPropertyName: "cellRenderer", publicName: "cellRenderer", isSignal: true, isRequired: false, transformFunction: null }, headerRenderer: { classPropertyName: "headerRenderer", publicName: "headerRenderer", isSignal: true, isRequired: false, transformFunction: null }, editRenderer: { classPropertyName: "editRenderer", publicName: "editRenderer", isSignal: true, isRequired: false, transformFunction: null }, highlighting: { classPropertyName: "highlighting", publicName: "highlighting", isSignal: true, isRequired: false, transformFunction: null }, rowDragEntireRow: { classPropertyName: "rowDragEntireRow", publicName: "rowDragEntireRow", isSignal: true, isRequired: false, transformFunction: null }, overscan: { classPropertyName: "overscan", publicName: "overscan", isSignal: true, isRequired: false, transformFunction: null }, rowLoading: { classPropertyName: "rowLoading", publicName: "rowLoading", isSignal: true, isRequired: false, transformFunction: null }, sortingEnabled: { classPropertyName: "sortingEnabled", publicName: "sortingEnabled", isSignal: true, isRequired: false, transformFunction: null }, wheelDampening: { classPropertyName: "wheelDampening", publicName: "wheelDampening", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onRowDragEnd: "onRowDragEnd", onCellValueChanged: "onCellValueChanged", onColumnResized: "onColumnResized", onColumnMoved: "onColumnMoved" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "body", first: true, predicate: GridBodyComponent, descendants: true }], ngImport: i0, template: "\n <div #container\n [class]=\"'gp-grid-container' + (darkMode() ? ' gp-grid-container--dark' : '')\"\n style=\"width: 100%; height: 100%; display: flex; flex-direction: column; position: relative; outline: none;\"\n tabindex=\"0\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (wheel)=\"onWheel($event)\"\n >\n <gp-grid-header\n [headerHeight]=\"headerHeight()\"\n [scrollLeft]=\"vm.scrollLeft()\"\n [contentWidth]=\"vm.contentWidth()\"\n [totalWidth]=\"vm.totalWidth()\"\n [isLoading]=\"vm.isLoading()\"\n [visibleColumnsWithIndices]=\"vm.visibleColumnWithIndices()\"\n [columnPositions]=\"vm.columnPositions()\"\n [columnWidths]=\"vm.columnWidths()\"\n [headers]=\"vm.headerState()\"\n [sortingEnabled]=\"sortingEnabled()\"\n [headerRenderers]=\"headerRenderers()\"\n [globalHeaderRenderer]=\"headerRenderer()\"\n (headerPointerDown)=\"onHeaderPointerDown($event)\"\n (filterPointerDown)=\"onFilterPointerDown($event)\"\n (resizePointerDown)=\"onResizePointerDown($event)\"\n (headerSort)=\"onHeaderSort($event)\"\n />\n <gp-grid-body\n [rowHeight]=\"rowHeight()\"\n [totalHeaderHeight]=\"headerHeight()\"\n [contentWidth]=\"vm.contentWidth()\"\n [contentHeight]=\"vm.contentHeight()\"\n [totalWidth]=\"vm.totalWidth()\"\n [rowsWrapperOffset]=\"vm.rowsWrapperOffset()\"\n [slotsArray]=\"vm.slotsArray()\"\n [visibleColumnWithIndices]=\"vm.visibleColumnWithIndices()\"\n [columnPositions]=\"vm.columnPositions()\"\n [columnWidths]=\"vm.columnWidths()\"\n [totalRows]=\"vm.totalRows()\"\n [activeCell]=\"vm.activeCell()\"\n [selectionRange]=\"vm.selectionRange()\"\n [editingCell]=\"vm.editingCell()\"\n [cellRenderers]=\"cellRenderers()\"\n [globalCellRenderer]=\"cellRenderer()\"\n [editRenderers]=\"editRenderers()\"\n [globalEditRenderer]=\"editRenderer()\"\n [hoverPosition]=\"vm.hoverPosition()\"\n [computeRowClasses]=\"computeRowClassesFn\"\n [computeCellClasses]=\"computeCellClassesFn\"\n [fillHandlePosition]=\"vm.fillHandlePosition()\"\n [dragState]=\"vm.dragState()\"\n (scrolled)=\"onBodyScroll($event)\"\n (cellPointerDown)=\"onCellPointerDown($event)\"\n (cellPointerEnter)=\"onCellPointerEnter($event)\"\n (cellPointerLeave)=\"onCellPointerLeave()\"\n (cellDoubleClick)=\"onCellDoubleClick($event)\"\n (editValueChange)=\"onEditValueChange($event)\"\n (editCommit)=\"onEditCommit()\"\n (editCancel)=\"onEditCancel()\"\n (fillHandlePointerDown)=\"onFillHandlePointerDown($event)\"\n />\n <gp-grid-overlays\n [filterPopup]=\"vm.filterPopup()\"\n [isLoading]=\"vm.isLoading()\"\n [errorMessage]=\"vm.errorMessage()\"\n [headerHeight]=\"headerHeight()\"\n [rowHeight]=\"rowHeight()\"\n [dragState]=\"vm.dragState()\"\n [visibleColumnWithIndices]=\"vm.visibleColumnWithIndices()\"\n [columnPositions]=\"vm.columnPositions()\"\n [scrollLeft]=\"vm.scrollLeft()\"\n [effectiveColumns]=\"vm.effectiveColumns()\"\n [totalWidth]=\"vm.totalWidth()\"\n (filterApply)=\"onFilterApply($event)\"\n (filterClose)=\"onFilterClose()\"\n />\n </div>\n ", isInline: true, styles: [":host{display:block;height:100%;min-height:0}\n"], dependencies: [{ kind: "component", type: GridHeaderComponent, selector: "gp-grid-header", inputs: ["headerHeight", "scrollLeft", "contentWidth", "totalWidth", "isLoading", "visibleColumnsWithIndices", "columnPositions", "columnWidths", "headers", "sortingEnabled", "headerRenderers", "globalHeaderRenderer"], outputs: ["headerPointerDown", "filterPointerDown", "resizePointerDown", "headerSort", "headerFilterOpen"] }, { kind: "component", type: GridBodyComponent, selector: "gp-grid-body", inputs: ["rowHeight", "totalHeaderHeight", "contentWidth", "contentHeight", "rowsWrapperOffset", "slotsArray", "visibleColumnWithIndices", "totalWidth", "columnPositions", "columnWidths", "totalRows", "activeCell", "selectionRange", "editingCell", "cellRenderers", "globalCellRenderer", "editRenderers", "globalEditRenderer", "hoverPosition", "computeRowClasses", "computeCellClasses", "fillHandlePosition", "dragState"], outputs: ["scrolled", "cellPointerDown", "cellPointerEnter", "cellPointerLeave", "cellDoubleClick", "editValueChange", "editCommit", "editCancel", "fillHandlePointerDown"] }, { kind: "component", type: GridOverlaysComponent, selector: "gp-grid-overlays", inputs: ["filterPopup", "isLoading", "errorMessage", "headerHeight", "rowHeight", "dragState", "visibleColumnWithIndices", "columnPositions", "scrollLeft", "effectiveColumns", "totalWidth"], outputs: ["filterApply", "filterClose"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1796
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: GpGridComponent, isStandalone: true, selector: "gp-grid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, getRowId: { classPropertyName: "getRowId", publicName: "getRowId", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, headerHeight: { classPropertyName: "headerHeight", publicName: "headerHeight", isSignal: true, isRequired: false, transformFunction: null }, darkMode: { classPropertyName: "darkMode", publicName: "darkMode", isSignal: true, isRequired: false, transformFunction: null }, cellRenderers: { classPropertyName: "cellRenderers", publicName: "cellRenderers", isSignal: true, isRequired: false, transformFunction: null }, headerRenderers: { classPropertyName: "headerRenderers", publicName: "headerRenderers", isSignal: true, isRequired: false, transformFunction: null }, editRenderers: { classPropertyName: "editRenderers", publicName: "editRenderers", isSignal: true, isRequired: false, transformFunction: null }, cellRenderer: { classPropertyName: "cellRenderer", publicName: "cellRenderer", isSignal: true, isRequired: false, transformFunction: null }, headerRenderer: { classPropertyName: "headerRenderer", publicName: "headerRenderer", isSignal: true, isRequired: false, transformFunction: null }, editRenderer: { classPropertyName: "editRenderer", publicName: "editRenderer", isSignal: true, isRequired: false, transformFunction: null }, highlighting: { classPropertyName: "highlighting", publicName: "highlighting", isSignal: true, isRequired: false, transformFunction: null }, rowDragEntireRow: { classPropertyName: "rowDragEntireRow", publicName: "rowDragEntireRow", isSignal: true, isRequired: false, transformFunction: null }, overscan: { classPropertyName: "overscan", publicName: "overscan", isSignal: true, isRequired: false, transformFunction: null }, rowLoading: { classPropertyName: "rowLoading", publicName: "rowLoading", isSignal: true, isRequired: false, transformFunction: null }, sortingEnabled: { classPropertyName: "sortingEnabled", publicName: "sortingEnabled", isSignal: true, isRequired: false, transformFunction: null }, wheelDampening: { classPropertyName: "wheelDampening", publicName: "wheelDampening", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onRowDragEnd: "onRowDragEnd", onCellValueChanged: "onCellValueChanged", onColumnResized: "onColumnResized", onColumnMoved: "onColumnMoved" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "body", first: true, predicate: GridBodyComponent, descendants: true }], ngImport: i0, template: "\n <div #container\n [class]=\"'gp-grid-container' + (darkMode() ? ' gp-grid-container--dark' : '')\"\n style=\"width: 100%; height: 100%; display: flex; flex-direction: column; position: relative; outline: none;\"\n tabindex=\"0\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (wheel)=\"onWheel($event)\"\n >\n <gp-grid-header\n [headerHeight]=\"headerHeight()\"\n [scrollLeft]=\"vm.scrollLeft()\"\n [contentWidth]=\"vm.contentWidth()\"\n [totalWidth]=\"vm.totalWidth()\"\n [isLoading]=\"vm.isLoading()\"\n [visibleColumnsWithIndices]=\"vm.visibleColumnWithIndices()\"\n [columnPositions]=\"vm.columnPositions()\"\n [columnWidths]=\"vm.columnWidths()\"\n [headers]=\"vm.headerState()\"\n [sortingEnabled]=\"sortingEnabled()\"\n [headerRenderers]=\"headerRenderers()\"\n [globalHeaderRenderer]=\"headerRenderer()\"\n (headerPointerDown)=\"onHeaderPointerDown($event)\"\n (filterPointerDown)=\"onFilterPointerDown($event)\"\n (resizePointerDown)=\"onResizePointerDown($event)\"\n (headerSort)=\"onHeaderSort($event)\"\n />\n <gp-grid-body\n [rowHeight]=\"rowHeight()\"\n [totalHeaderHeight]=\"headerHeight()\"\n [contentWidth]=\"vm.contentWidth()\"\n [contentHeight]=\"vm.contentHeight()\"\n [totalWidth]=\"vm.totalWidth()\"\n [rowsWrapperOffset]=\"vm.rowsWrapperOffset()\"\n [slotsArray]=\"vm.slotsArray()\"\n [visibleColumnWithIndices]=\"vm.visibleColumnWithIndices()\"\n [columnPositions]=\"vm.columnPositions()\"\n [columnWidths]=\"vm.columnWidths()\"\n [totalRows]=\"vm.totalRows()\"\n [activeCell]=\"vm.activeCell()\"\n [selectionRange]=\"vm.selectionRange()\"\n [editingCell]=\"vm.editingCell()\"\n [cellRenderers]=\"cellRenderers()\"\n [globalCellRenderer]=\"cellRenderer()\"\n [editRenderers]=\"editRenderers()\"\n [globalEditRenderer]=\"editRenderer()\"\n [hoverPosition]=\"vm.hoverPosition()\"\n [computeRowClasses]=\"computeRowClassesFn\"\n [computeCellClasses]=\"computeCellClassesFn\"\n [fillHandlePosition]=\"vm.fillHandlePosition()\"\n [dragState]=\"vm.dragState()\"\n (scrolled)=\"onBodyScroll($event)\"\n (cellPointerDown)=\"onCellPointerDown($event)\"\n (cellPointerEnter)=\"onCellPointerEnter($event)\"\n (cellPointerLeave)=\"onCellPointerLeave()\"\n (cellDoubleClick)=\"onCellDoubleClick($event)\"\n (editValueChange)=\"onEditValueChange($event)\"\n (editCommit)=\"onEditCommit()\"\n (editCancel)=\"onEditCancel()\"\n (fillHandlePointerDown)=\"onFillHandlePointerDown($event)\"\n />\n <gp-grid-overlays\n [filterPopup]=\"vm.filterPopup()\"\n [isLoading]=\"vm.isLoading()\"\n [errorMessage]=\"vm.errorMessage()\"\n [headerHeight]=\"headerHeight()\"\n [rowHeight]=\"rowHeight()\"\n [dragState]=\"vm.dragState()\"\n [visibleColumnWithIndices]=\"vm.visibleColumnWithIndices()\"\n [columnPositions]=\"vm.columnPositions()\"\n [scrollLeft]=\"vm.scrollLeft()\"\n [effectiveColumns]=\"vm.effectiveColumns()\"\n [totalWidth]=\"vm.totalWidth()\"\n (filterApply)=\"onFilterApply($event)\"\n (filterClose)=\"onFilterClose()\"\n />\n @if (peekContext(); as ctx) {\n <gp-grid-cell-peek\n [peekCell]=\"ctx.peek\"\n [column]=\"ctx.column\"\n [rowData]=\"ctx.rowData\"\n [containerEl]=\"container\"\n [cellRenderers]=\"cellRenderers()\"\n [globalCellRenderer]=\"cellRenderer()\"\n (close)=\"onPeekClose()\"\n />\n }\n </div>\n ", isInline: true, styles: [":host{display:block;height:100%;min-height:0}\n"], dependencies: [{ kind: "component", type: GridHeaderComponent, selector: "gp-grid-header", inputs: ["headerHeight", "scrollLeft", "contentWidth", "totalWidth", "isLoading", "visibleColumnsWithIndices", "columnPositions", "columnWidths", "headers", "sortingEnabled", "headerRenderers", "globalHeaderRenderer"], outputs: ["headerPointerDown", "filterPointerDown", "resizePointerDown", "headerSort", "headerFilterOpen"] }, { kind: "component", type: GridBodyComponent, selector: "gp-grid-body", inputs: ["rowHeight", "totalHeaderHeight", "contentWidth", "contentHeight", "rowsWrapperOffset", "slotsArray", "visibleColumnWithIndices", "totalWidth", "columnPositions", "columnWidths", "totalRows", "activeCell", "selectionRange", "editingCell", "cellRenderers", "globalCellRenderer", "editRenderers", "globalEditRenderer", "hoverPosition", "computeRowClasses", "computeCellClasses", "fillHandlePosition", "dragState"], outputs: ["scrolled", "cellPointerDown", "cellPointerEnter", "cellPointerLeave", "cellDoubleClick", "editValueChange", "editCommit", "editCancel", "fillHandlePointerDown"] }, { kind: "component", type: GridOverlaysComponent, selector: "gp-grid-overlays", inputs: ["filterPopup", "isLoading", "errorMessage", "headerHeight", "rowHeight", "dragState", "visibleColumnWithIndices", "columnPositions", "scrollLeft", "effectiveColumns", "totalWidth"], outputs: ["filterApply", "filterClose"] }, { kind: "component", type: CellPeekComponent, selector: "gp-grid-cell-peek", inputs: ["peekCell", "column", "rowData", "containerEl", "cellRenderers", "globalCellRenderer"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1597
1797
  }
1598
1798
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GpGridComponent, decorators: [{
1599
1799
  type: Component,
1600
- args: [{ selector: 'gp-grid', standalone: true, imports: [GridHeaderComponent, GridBodyComponent, GridOverlaysComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: GP_GRID_TEMPLATE, styles: [":host{display:block;height:100%;min-height:0}\n"] }]
1800
+ args: [{ selector: 'gp-grid', standalone: true, imports: [GridHeaderComponent, GridBodyComponent, GridOverlaysComponent, CellPeekComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: GP_GRID_TEMPLATE, styles: [":host{display:block;height:100%;min-height:0}\n"] }]
1601
1801
  }], ctorParameters: () => [], propDecorators: { container: [{
1602
1802
  type: ViewChild,
1603
1803
  args: ['container', { static: true }]
@@ -1742,5 +1942,5 @@ const provideGridData = (options) => [
1742
1942
  * Generated bundle index. Do not edit.
1743
1943
  */
1744
1944
 
1745
- export { FilterPopupComponent, GRID_DATA_OPTIONS, GpGridComponent, GridBodyComponent, GridDataService, GridHeaderComponent, GridOverlaysComponent, createGridData, injectGridData, provideGridData };
1945
+ export { CellPeekComponent, FilterPopupComponent, GRID_DATA_OPTIONS, GpGridComponent, GridBodyComponent, GridDataService, GridHeaderComponent, GridOverlaysComponent, createGridData, injectGridData, provideGridData };
1746
1946
  //# sourceMappingURL=gp-grid-angular.mjs.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gp-grid/angular",
3
3
  "description": "A high-performance Angular data grid component with virtual scrolling, cell selection, sorting, filtering, and Excel-like editing",
4
- "version": "0.16.0",
4
+ "version": "0.17.0",
5
5
  "license": "Apache-2.0",
6
6
  "module": "fesm2022/gp-grid-angular.mjs",
7
7
  "typings": "types/gp-grid-angular.d.ts",
@@ -51,7 +51,7 @@
51
51
  "@angular/core": ">=18.0.0"
52
52
  },
53
53
  "dependencies": {
54
- "@gp-grid/core": "0.16.0",
54
+ "@gp-grid/core": "0.17.0",
55
55
  "tslib": "^2.8.1"
56
56
  },
57
57
  "sideEffects": false,
@@ -1,8 +1,8 @@
1
- import * as _angular_core from '@angular/core';
2
- import { TemplateRef, ElementRef, AfterViewInit, OnDestroy, Signal, OnInit, InjectionToken, Provider } from '@angular/core';
3
1
  import * as _gp_grid_core from '@gp-grid/core';
4
2
  import { HeaderRendererParams, SortDirection, VisibleColumnInfo, HeaderData, ColumnDefinition, SlotData, CellPosition, CellRange, CellValue, CellRendererParams, EditRendererParams, FillHandlePosition, DragState, ColumnFilterModel, BatchChangeSetters, DataSource, RowId, HighlightingOptions, RowLoadingOptions, CellValueChangedEvent, ParallelSortOptions, MutableDataSource } from '@gp-grid/core';
5
3
  export { CellDataType, CellPosition, CellRange, CellRendererParams, CellValue, CellValueChangedEvent, ColumnDefinition, ColumnFilterModel, DataSource, DataSourceLoadMode, DataSourceRange, DataSourceRequest, DataSourceResponse, EditRendererParams, FilterCondition, FilterModel, GridCore, GridInstruction, HeaderRendererParams, HighlightContext, HighlightingOptions, MutableDataSource, RowCacheEviction, RowCacheOptions, RowId, RowLoadingMode, RowLoadingOptions, SortDirection, SortModel, createClientDataSource, createDataSourceFromArray, createMutableClientDataSource, createServerDataSource } from '@gp-grid/core';
4
+ import * as _angular_core from '@angular/core';
5
+ import { TemplateRef, ElementRef, AfterViewInit, OnDestroy, Signal, OnInit, InjectionToken, Provider } from '@angular/core';
6
6
 
7
7
  type HeaderRendererTemplate = TemplateRef<{
8
8
  $implicit: HeaderRendererParams;
@@ -219,7 +219,8 @@ declare class FilterPopupComponent implements AfterViewInit, OnDestroy {
219
219
  private initFromCurrentFilter;
220
220
  private updatePosition;
221
221
  private onDocumentPointerDown;
222
- private onWindowResize;
222
+ private repositionRafId;
223
+ private onWindowScrollOrResize;
223
224
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FilterPopupComponent, never>;
224
225
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<FilterPopupComponent, "gp-grid-filter-popup", never, { "column": { "alias": "column"; "required": true; "isSignal": true; }; "colIndex": { "alias": "colIndex"; "required": true; "isSignal": true; }; "anchorEl": { "alias": "anchorEl"; "required": true; "isSignal": true; }; "distinctValues": { "alias": "distinctValues"; "required": true; "isSignal": true; }; "currentFilter": { "alias": "currentFilter"; "required": false; "isSignal": true; }; }, { "apply": "apply"; "close": "close"; }, never, never, true, never>;
225
226
  }
@@ -259,6 +260,36 @@ declare class GridOverlaysComponent {
259
260
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<GridOverlaysComponent, "gp-grid-overlays", never, { "filterPopup": { "alias": "filterPopup"; "required": false; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "headerHeight": { "alias": "headerHeight"; "required": true; "isSignal": true; }; "rowHeight": { "alias": "rowHeight"; "required": true; "isSignal": true; }; "dragState": { "alias": "dragState"; "required": true; "isSignal": true; }; "visibleColumnWithIndices": { "alias": "visibleColumnWithIndices"; "required": true; "isSignal": true; }; "columnPositions": { "alias": "columnPositions"; "required": true; "isSignal": true; }; "scrollLeft": { "alias": "scrollLeft"; "required": true; "isSignal": true; }; "effectiveColumns": { "alias": "effectiveColumns"; "required": true; "isSignal": true; }; "totalWidth": { "alias": "totalWidth"; "required": true; "isSignal": true; }; }, { "filterApply": "filterApply"; "filterClose": "filterClose"; }, never, never, true, never>;
260
261
  }
261
262
 
263
+ declare class CellPeekComponent implements AfterViewInit, OnDestroy {
264
+ overlayEl: ElementRef<HTMLDivElement>;
265
+ peekCell: _angular_core.InputSignal<CellPosition>;
266
+ column: _angular_core.InputSignal<ColumnDefinition>;
267
+ rowData: _angular_core.InputSignal<unknown>;
268
+ containerEl: _angular_core.InputSignal<HTMLElement>;
269
+ cellRenderers: _angular_core.InputSignal<Record<string, CellRendererTemplate>>;
270
+ globalCellRenderer: _angular_core.InputSignal<CellRendererTemplate>;
271
+ close: _angular_core.OutputEmitterRef<void>;
272
+ protected top: _angular_core.WritableSignal<number>;
273
+ protected left: _angular_core.WritableSignal<number>;
274
+ protected width: _angular_core.WritableSignal<number>;
275
+ protected positioned: _angular_core.WritableSignal<boolean>;
276
+ protected template: _angular_core.Signal<CellRendererTemplate>;
277
+ protected rendererParams: _angular_core.Signal<CellRendererParams<unknown>>;
278
+ protected fallbackText: _angular_core.Signal<string>;
279
+ private rafId;
280
+ private pointerRafId;
281
+ private unbindSelectAll;
282
+ constructor();
283
+ ngAfterViewInit(): void;
284
+ ngOnDestroy(): void;
285
+ onEscape(): void;
286
+ private updatePosition;
287
+ private onWindowScrollOrResize;
288
+ private onDocumentPointerDown;
289
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<CellPeekComponent, never>;
290
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<CellPeekComponent, "gp-grid-cell-peek", never, { "peekCell": { "alias": "peekCell"; "required": true; "isSignal": true; }; "column": { "alias": "column"; "required": true; "isSignal": true; }; "rowData": { "alias": "rowData"; "required": true; "isSignal": true; }; "containerEl": { "alias": "containerEl"; "required": true; "isSignal": true; }; "cellRenderers": { "alias": "cellRenderers"; "required": false; "isSignal": true; }; "globalCellRenderer": { "alias": "globalCellRenderer"; "required": false; "isSignal": true; }; }, { "close": "close"; }, never, never, true, never>;
291
+ }
292
+
262
293
  /**
263
294
  * Column definition extended for Angular — allows `cellRenderer`,
264
295
  * `editRenderer`, and `headerRenderer` to be passed directly as
@@ -304,6 +335,7 @@ declare class GpGridViewModel {
304
335
  readonly selectionRange: _angular_core.WritableSignal<CellRange>;
305
336
  readonly editingCell: _angular_core.WritableSignal<EditingCellState>;
306
337
  readonly hoverPosition: _angular_core.WritableSignal<CellPosition>;
338
+ readonly peekCell: _angular_core.WritableSignal<CellPosition>;
307
339
  readonly columnsOverride: _angular_core.WritableSignal<ColumnDefinition[]>;
308
340
  readonly dragState: _angular_core.WritableSignal<DragState>;
309
341
  readonly contentWidth: _angular_core.WritableSignal<number>;
@@ -377,6 +409,12 @@ declare class GpGridComponent implements OnInit, AfterViewInit, OnDestroy {
377
409
  protected computeRowClassesFn: (rowIndex: number, rowData: unknown) => string[];
378
410
  protected computeCellClassesFn: (rowIndex: number, colIndex: number, column: ColumnDefinition, rowData: unknown) => string[];
379
411
  protected onCellDoubleClick(evt: CellDoubleClickEvent): void;
412
+ protected onPeekClose(): void;
413
+ protected peekContext: _angular_core.Signal<{
414
+ peek: _gp_grid_core.CellPosition;
415
+ column: ColumnDefinition;
416
+ rowData: unknown;
417
+ }>;
380
418
  protected onEditValueChange(value: string): void;
381
419
  protected onEditCommit(): void;
382
420
  protected onEditCancel(): void;
@@ -520,5 +558,5 @@ declare const injectGridData: <TData>() => GridDataService<TData>;
520
558
  */
521
559
  declare const provideGridData: <TData>(options: GridDataOptions<TData>) => Provider[];
522
560
 
523
- export { FilterPopupComponent, GRID_DATA_OPTIONS, GpGridComponent, GridBodyComponent, GridDataService, GridHeaderComponent, GridOverlaysComponent, createGridData, injectGridData, provideGridData };
561
+ export { CellPeekComponent, FilterPopupComponent, GRID_DATA_OPTIONS, GpGridComponent, GridBodyComponent, GridDataService, GridHeaderComponent, GridOverlaysComponent, createGridData, injectGridData, provideGridData };
524
562
  export type { ActiveFilterPopup, AngularColumnDefinition, CellClassFn, CellDoubleClickEvent, CellPointerDownEvent, CellPointerEnterEvent, CellRendererTemplate, CreateGridDataOptions, EditRendererTemplate, EditingCellState, FillHandlePointerDownEvent, FilterPointerDownEvent, GridDataApi, GridDataOptions, HeaderPointerDownEvent, HeaderRendererTemplate, HeaderSortEvent, ResizePointerDownEvent, RowClassFn };