@gp-grid/angular 0.17.0 → 0.19.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,7 +1,7 @@
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, bindPeekSelectAll, 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, PendingCellTapController, TouchScrollController, InputEventAdapter, applyBatchInstructions, scrollCellIntoView, GridCore, createMutableClientDataSource } from '@gp-grid/core';
5
5
  export { GridCore, createClientDataSource, createDataSourceFromArray, createMutableClientDataSource, createServerDataSource } from '@gp-grid/core';
6
6
 
7
7
  const TEMPLATE$2 = `
@@ -1470,6 +1470,8 @@ class GpGridBindings {
1470
1470
  dataSourceOwner = new DataSourceOwner();
1471
1471
  autoScroll;
1472
1472
  pendingRowDrag;
1473
+ pendingCellTap;
1474
+ touchScroll;
1473
1475
  input;
1474
1476
  coreRef = null;
1475
1477
  unsubscribe = null;
@@ -1483,16 +1485,28 @@ class GpGridBindings {
1483
1485
  isBrowser: this.deps.isBrowser,
1484
1486
  onDragConfirmed: (state) => this.deps.vm.dragState.set(state),
1485
1487
  });
1488
+ this.pendingCellTap = new PendingCellTapController({
1489
+ getCore: () => this.coreRef,
1490
+ isBrowser: this.deps.isBrowser,
1491
+ onTapConfirmed: () => this.deps.getContainer()?.focus(),
1492
+ });
1493
+ this.touchScroll = new TouchScrollController({
1494
+ getCore: () => this.coreRef,
1495
+ getScrollEl: this.deps.getBody,
1496
+ isBrowser: this.deps.isBrowser,
1497
+ });
1486
1498
  this.input = new InputEventAdapter({
1487
1499
  getCore: () => this.coreRef,
1488
1500
  getBodyEl: this.deps.getBody,
1489
1501
  autoScroll: this.autoScroll,
1490
1502
  pendingRowDrag: this.pendingRowDrag,
1503
+ pendingCellTap: this.pendingCellTap,
1491
1504
  onDragStateChange: (state) => this.deps.vm.dragState.set(state),
1492
1505
  });
1493
1506
  }
1494
1507
  attach(core) {
1495
1508
  this.coreRef = core;
1509
+ this.touchScroll.syncCore();
1496
1510
  this.unsubscribe = core.onBatchInstruction((instructions) => {
1497
1511
  const vm = this.deps.vm;
1498
1512
  const maps = applyBatchInstructions(instructions, vm.slots(), vm.headerState(), vm.batchSetters);
@@ -1517,11 +1531,16 @@ class GpGridBindings {
1517
1531
  });
1518
1532
  this.resizeObserver.observe(container);
1519
1533
  this.coreRef?.setViewport(0, 0, container.clientWidth, bodyEl.clientHeight);
1534
+ // Synthetic touch scrolling: takes over touch gestures only when scroll
1535
+ // virtualization compresses the DOM scroll space; inert otherwise.
1536
+ this.touchScroll.attach();
1520
1537
  }
1521
1538
  destroy() {
1522
1539
  this.autoScroll.stop();
1523
1540
  this.pendingRowDrag.cancel();
1524
1541
  this.pendingRowDrag.releaseLocks();
1542
+ this.pendingCellTap.cancel();
1543
+ this.touchScroll.detach();
1525
1544
  this.unsubscribe?.();
1526
1545
  this.resizeObserver?.disconnect();
1527
1546
  this.coreRef?.destroy();
@@ -1553,16 +1572,22 @@ class GpGridBindings {
1553
1572
  const top = this.deps.vm.pendingScrollTop();
1554
1573
  const body = this.deps.getBody();
1555
1574
  if (top !== null && body) {
1575
+ this.touchScroll.stop();
1556
1576
  body.scrollTop = top;
1557
1577
  this.deps.vm.pendingScrollTop.set(null);
1558
1578
  }
1559
1579
  }
1560
- scrollToRow(row) {
1580
+ scrollToCell(cell) {
1561
1581
  const core = this.coreRef;
1562
1582
  const body = this.deps.getBody();
1563
1583
  if (core === null || body === null)
1564
1584
  return;
1565
- scrollCellIntoView(core, body, row, this.deps.getRowHeight(), this.deps.vm.slots(), this.deps.vm.rowsWrapperOffset());
1585
+ scrollCellIntoView(core, body, cell.row, this.deps.getRowHeight(), this.deps.vm.slots(), this.deps.vm.rowsWrapperOffset(), {
1586
+ colIndex: cell.col,
1587
+ visibleColumns: this.deps.vm.visibleColumnWithIndices(),
1588
+ columnPositions: this.deps.vm.columnPositions(),
1589
+ columnWidths: this.deps.vm.columnWidths(),
1590
+ });
1566
1591
  }
1567
1592
  }
1568
1593
 
@@ -1576,6 +1601,7 @@ const buildGridCore = (inputs, emitters) => {
1576
1601
  rowHeight: inputs.rowHeight,
1577
1602
  headerHeight: inputs.headerHeight,
1578
1603
  overscan: inputs.overscan,
1604
+ maxFlingVelocity: inputs.maxFlingVelocity,
1579
1605
  rowLoading: inputs.rowLoading,
1580
1606
  sortingEnabled: inputs.sortingEnabled,
1581
1607
  highlighting: inputs.highlighting,
@@ -1608,6 +1634,8 @@ class GpGridComponent {
1608
1634
  highlighting = input(null, ...(ngDevMode ? [{ debugName: "highlighting" }] : /* istanbul ignore next */ []));
1609
1635
  rowDragEntireRow = input(false, ...(ngDevMode ? [{ debugName: "rowDragEntireRow" }] : /* istanbul ignore next */ []));
1610
1636
  overscan = input(3, ...(ngDevMode ? [{ debugName: "overscan" }] : /* istanbul ignore next */ []));
1637
+ /** Max accumulated touch-fling velocity (logical px/ms) when scroll virtualization is active. Pair higher values with overscan 10-12. */
1638
+ maxFlingVelocity = input(undefined, ...(ngDevMode ? [{ debugName: "maxFlingVelocity" }] : /* istanbul ignore next */ []));
1611
1639
  rowLoading = input(null, ...(ngDevMode ? [{ debugName: "rowLoading" }] : /* istanbul ignore next */ []));
1612
1640
  sortingEnabled = input(true, ...(ngDevMode ? [{ debugName: "sortingEnabled" }] : /* istanbul ignore next */ []));
1613
1641
  wheelDampening = input(0.1, ...(ngDevMode ? [{ debugName: "wheelDampening" }] : /* istanbul ignore next */ []));
@@ -1641,6 +1669,7 @@ class GpGridComponent {
1641
1669
  rowHeight: this.rowHeight(),
1642
1670
  headerHeight: this.headerHeight(),
1643
1671
  overscan: this.overscan(),
1672
+ maxFlingVelocity: this.maxFlingVelocity(),
1644
1673
  rowLoading: this.rowLoading() ?? undefined,
1645
1674
  sortingEnabled: this.sortingEnabled(),
1646
1675
  highlighting: (this.highlighting() ?? undefined),
@@ -1762,7 +1791,7 @@ class GpGridComponent {
1762
1791
  if (result.preventDefault)
1763
1792
  event.preventDefault();
1764
1793
  if (result.scrollToCell)
1765
- this.bindings.scrollToRow(result.scrollToCell.row);
1794
+ this.bindings.scrollToCell(result.scrollToCell);
1766
1795
  }
1767
1796
  onPaste(event) {
1768
1797
  const editing = this.vm.editingCell();
@@ -1793,7 +1822,7 @@ class GpGridComponent {
1793
1822
  this.bindings.pendingRowDrag.releaseLocks();
1794
1823
  };
1795
1824
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GpGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
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 });
1825
+ 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 }, maxFlingVelocity: { classPropertyName: "maxFlingVelocity", publicName: "maxFlingVelocity", 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 });
1797
1826
  }
1798
1827
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GpGridComponent, decorators: [{
1799
1828
  type: Component,
@@ -1804,7 +1833,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
1804
1833
  }], body: [{
1805
1834
  type: ViewChild,
1806
1835
  args: [GridBodyComponent]
1807
- }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }], getRowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "getRowId", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], headerHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerHeight", required: false }] }], darkMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "darkMode", required: false }] }], cellRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderers", required: false }] }], headerRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerRenderers", required: false }] }], editRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRenderers", required: false }] }], cellRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderer", required: false }] }], headerRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerRenderer", required: false }] }], editRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRenderer", required: false }] }], highlighting: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlighting", required: false }] }], rowDragEntireRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDragEntireRow", required: false }] }], overscan: [{ type: i0.Input, args: [{ isSignal: true, alias: "overscan", required: false }] }], rowLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLoading", required: false }] }], sortingEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingEnabled", required: false }] }], wheelDampening: [{ type: i0.Input, args: [{ isSignal: true, alias: "wheelDampening", required: false }] }], onRowDragEnd: [{ type: i0.Output, args: ["onRowDragEnd"] }], onCellValueChanged: [{ type: i0.Output, args: ["onCellValueChanged"] }], onColumnResized: [{ type: i0.Output, args: ["onColumnResized"] }], onColumnMoved: [{ type: i0.Output, args: ["onColumnMoved"] }] } });
1836
+ }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }], getRowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "getRowId", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], headerHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerHeight", required: false }] }], darkMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "darkMode", required: false }] }], cellRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderers", required: false }] }], headerRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerRenderers", required: false }] }], editRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRenderers", required: false }] }], cellRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderer", required: false }] }], headerRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerRenderer", required: false }] }], editRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRenderer", required: false }] }], highlighting: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlighting", required: false }] }], rowDragEntireRow: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDragEntireRow", required: false }] }], overscan: [{ type: i0.Input, args: [{ isSignal: true, alias: "overscan", required: false }] }], maxFlingVelocity: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFlingVelocity", required: false }] }], rowLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLoading", required: false }] }], sortingEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortingEnabled", required: false }] }], wheelDampening: [{ type: i0.Input, args: [{ isSignal: true, alias: "wheelDampening", required: false }] }], onRowDragEnd: [{ type: i0.Output, args: ["onRowDragEnd"] }], onCellValueChanged: [{ type: i0.Output, args: ["onCellValueChanged"] }], onColumnResized: [{ type: i0.Output, args: ["onColumnResized"] }], onColumnMoved: [{ type: i0.Output, args: ["onColumnMoved"] }] } });
1808
1837
 
1809
1838
  /**
1810
1839
  * Angular helper for efficient grid data mutations.
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.17.0",
4
+ "version": "0.19.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.17.0",
54
+ "@gp-grid/core": "0.19.0",
55
55
  "tslib": "^2.8.1"
56
56
  },
57
57
  "sideEffects": false,
@@ -377,6 +377,8 @@ declare class GpGridComponent implements OnInit, AfterViewInit, OnDestroy {
377
377
  highlighting: _angular_core.InputSignal<HighlightingOptions<Record<string, unknown>>>;
378
378
  rowDragEntireRow: _angular_core.InputSignal<boolean>;
379
379
  overscan: _angular_core.InputSignal<number>;
380
+ /** Max accumulated touch-fling velocity (logical px/ms) when scroll virtualization is active. Pair higher values with overscan 10-12. */
381
+ maxFlingVelocity: _angular_core.InputSignal<number>;
380
382
  rowLoading: _angular_core.InputSignal<RowLoadingOptions>;
381
383
  sortingEnabled: _angular_core.InputSignal<boolean>;
382
384
  wheelDampening: _angular_core.InputSignal<number>;
@@ -431,7 +433,7 @@ declare class GpGridComponent implements OnInit, AfterViewInit, OnDestroy {
431
433
  private onDocumentPointerMove;
432
434
  private onDocumentPointerUp;
433
435
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GpGridComponent, never>;
434
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<GpGridComponent, "gp-grid", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "getRowId": { "alias": "getRowId"; "required": false; "isSignal": true; }; "rowHeight": { "alias": "rowHeight"; "required": false; "isSignal": true; }; "headerHeight": { "alias": "headerHeight"; "required": false; "isSignal": true; }; "darkMode": { "alias": "darkMode"; "required": false; "isSignal": true; }; "cellRenderers": { "alias": "cellRenderers"; "required": false; "isSignal": true; }; "headerRenderers": { "alias": "headerRenderers"; "required": false; "isSignal": true; }; "editRenderers": { "alias": "editRenderers"; "required": false; "isSignal": true; }; "cellRenderer": { "alias": "cellRenderer"; "required": false; "isSignal": true; }; "headerRenderer": { "alias": "headerRenderer"; "required": false; "isSignal": true; }; "editRenderer": { "alias": "editRenderer"; "required": false; "isSignal": true; }; "highlighting": { "alias": "highlighting"; "required": false; "isSignal": true; }; "rowDragEntireRow": { "alias": "rowDragEntireRow"; "required": false; "isSignal": true; }; "overscan": { "alias": "overscan"; "required": false; "isSignal": true; }; "rowLoading": { "alias": "rowLoading"; "required": false; "isSignal": true; }; "sortingEnabled": { "alias": "sortingEnabled"; "required": false; "isSignal": true; }; "wheelDampening": { "alias": "wheelDampening"; "required": false; "isSignal": true; }; }, { "onRowDragEnd": "onRowDragEnd"; "onCellValueChanged": "onCellValueChanged"; "onColumnResized": "onColumnResized"; "onColumnMoved": "onColumnMoved"; }, never, never, true, never>;
436
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GpGridComponent, "gp-grid", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "getRowId": { "alias": "getRowId"; "required": false; "isSignal": true; }; "rowHeight": { "alias": "rowHeight"; "required": false; "isSignal": true; }; "headerHeight": { "alias": "headerHeight"; "required": false; "isSignal": true; }; "darkMode": { "alias": "darkMode"; "required": false; "isSignal": true; }; "cellRenderers": { "alias": "cellRenderers"; "required": false; "isSignal": true; }; "headerRenderers": { "alias": "headerRenderers"; "required": false; "isSignal": true; }; "editRenderers": { "alias": "editRenderers"; "required": false; "isSignal": true; }; "cellRenderer": { "alias": "cellRenderer"; "required": false; "isSignal": true; }; "headerRenderer": { "alias": "headerRenderer"; "required": false; "isSignal": true; }; "editRenderer": { "alias": "editRenderer"; "required": false; "isSignal": true; }; "highlighting": { "alias": "highlighting"; "required": false; "isSignal": true; }; "rowDragEntireRow": { "alias": "rowDragEntireRow"; "required": false; "isSignal": true; }; "overscan": { "alias": "overscan"; "required": false; "isSignal": true; }; "maxFlingVelocity": { "alias": "maxFlingVelocity"; "required": false; "isSignal": true; }; "rowLoading": { "alias": "rowLoading"; "required": false; "isSignal": true; }; "sortingEnabled": { "alias": "sortingEnabled"; "required": false; "isSignal": true; }; "wheelDampening": { "alias": "wheelDampening"; "required": false; "isSignal": true; }; }, { "onRowDragEnd": "onRowDragEnd"; "onCellValueChanged": "onCellValueChanged"; "onColumnResized": "onColumnResized"; "onColumnMoved": "onColumnMoved"; }, never, never, true, never>;
435
437
  }
436
438
 
437
439
  interface CreateGridDataOptions<TData> {