@gp-grid/angular 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/styles.css CHANGED
@@ -391,12 +391,34 @@
391
391
  box-sizing: border-box;
392
392
  display: flex;
393
393
  overflow: hidden;
394
- text-overflow: ellipsis;
395
394
  white-space: nowrap;
396
395
  user-select: none;
397
396
  -webkit-user-select: none;
398
397
  }
399
398
 
399
+ /* Default cell content wrapper - the framework adapters wrap plain-text values
400
+ in this element so text-overflow can apply (it has no effect on the flex
401
+ container itself, which previously caused long text to hard-clip). */
402
+ .gp-grid-cell-content {
403
+ min-width: 0;
404
+ flex: 1 1 auto;
405
+ overflow: hidden;
406
+ text-overflow: ellipsis;
407
+ white-space: nowrap;
408
+ }
409
+
410
+ /* Wrapped cell content - ColumnDefinition.wrapText: true.
411
+ Text flows onto additional lines and is clipped to the fixed row height. */
412
+ .gp-grid-cell--wrap {
413
+ align-items: flex-start;
414
+ }
415
+
416
+ .gp-grid-cell--wrap .gp-grid-cell-content {
417
+ white-space: normal;
418
+ overflow-wrap: anywhere;
419
+ text-overflow: clip;
420
+ }
421
+
400
422
  /* Visual properties - :where() for zero specificity, so user highlight classes always win */
401
423
  :where(.gp-grid-cell) {
402
424
  align-items: center;
@@ -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, PendingCellTapController, TouchScrollController, InputEventAdapter, applyBatchInstructions, scrollCellIntoView, GridCore, createMutableClientDataSource } from '@gp-grid/core';
4
+ import { defaultGridLabels, getFieldValue, isCellSelected, isCellActive, formatCellValue, isCellInFillPreview, isCellEditing, buildCellClasses, labelsForSelectedValues, rawValuesForLabels, getTextOperatorOptions, getNumberOperatorOptions, formatLabel, groupDistinctValues, isBlankCellValue, calculateFilterPopupPosition, bindPeekSelectAll, calculateScaledColumnPositions, getTotalWidth, calculateFillHandlePosition, DataSourceOwner, AutoScrollDriver, PendingRowDragController, PendingCellTapController, TouchScrollController, InputEventAdapter, applyBatchInstructions, scrollCellIntoView, GridCore, resolveGridLabels, createMutableClientDataSource } from '@gp-grid/core';
5
5
  export { GridCore, createClientDataSource, createDataSourceFromArray, createMutableClientDataSource, createServerDataSource } from '@gp-grid/core';
6
6
 
7
7
  const TEMPLATE$2 = `
@@ -219,7 +219,7 @@ const GRID_BODY_TEMPLATE = `<div
219
219
  [ngTemplateOutletContext]="{ $implicit: cellParams(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }">
220
220
  </ng-container>
221
221
  } @else {
222
- {{ cellDisplay(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }}
222
+ <span class="gp-grid-cell-content">{{ cellDisplay(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }}</span>
223
223
  }
224
224
  }
225
225
  </div>
@@ -246,7 +246,7 @@ const GRID_BODY_TEMPLATE = `<div
246
246
  </div>
247
247
  </div>
248
248
  @if (totalRows() === 0) {
249
- <div class="gp-grid-empty">No data to display</div>
249
+ <div class="gp-grid-empty">{{ labels().emptyState }}</div>
250
250
  }
251
251
  </div>
252
252
  `;
@@ -276,6 +276,7 @@ class GridBodyComponent {
276
276
  computeCellClasses = input(null, ...(ngDevMode ? [{ debugName: "computeCellClasses" }] : /* istanbul ignore next */ []));
277
277
  fillHandlePosition = input(null, ...(ngDevMode ? [{ debugName: "fillHandlePosition" }] : /* istanbul ignore next */ []));
278
278
  dragState = input(null, ...(ngDevMode ? [{ debugName: "dragState" }] : /* istanbul ignore next */ []));
279
+ labels = input(defaultGridLabels, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
279
280
  scrolled = output();
280
281
  cellPointerDown = output();
281
282
  cellPointerEnter = output();
@@ -381,17 +382,22 @@ class GridBodyComponent {
381
382
  this.hoverPosition();
382
383
  const ds = this.dragState();
383
384
  const inFillPreview = isCellInFillPreview(rowIndex, colIndex, ds?.dragType === "fill", ds?.fillSourceRange ?? null, ds?.fillTarget ?? null);
384
- const base = buildCellClasses(isCellActive(rowIndex, colIndex, this.activeCell()), isCellSelected(rowIndex, colIndex, this.selectionRange()), isCellEditing(rowIndex, colIndex, editingCell), inFillPreview);
385
+ const editing = isCellEditing(rowIndex, colIndex, editingCell);
386
+ const base = buildCellClasses(isCellActive(rowIndex, colIndex, this.activeCell()), isCellSelected(rowIndex, colIndex, this.selectionRange()), editing, inFillPreview);
385
387
  const withHandle = column.rowDrag === true
386
388
  ? `${base} gp-grid-cell--row-drag-handle`
387
389
  : base;
390
+ // Wrap only affects the default text content, so skip it in edit mode.
391
+ const withWrap = column.wrapText === true && !editing
392
+ ? `${withHandle} gp-grid-cell--wrap`
393
+ : withHandle;
388
394
  const fn = this.computeCellClasses();
389
395
  if (fn === null)
390
- return withHandle;
396
+ return withWrap;
391
397
  const extra = fn(rowIndex, colIndex, column, rowData);
392
398
  if (extra.length === 0)
393
- return withHandle;
394
- return `${withHandle} ${extra.join(' ')}`;
399
+ return withWrap;
400
+ return `${withWrap} ${extra.join(' ')}`;
395
401
  }
396
402
  rowClass(rowIndex, rowData) {
397
403
  this.hoverPosition();
@@ -428,7 +434,7 @@ class GridBodyComponent {
428
434
  }
429
435
  }
430
436
  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-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 });
437
+ 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 }, labels: { classPropertyName: "labels", publicName: "labels", 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 <span class=\"gp-grid-cell-content\">{{ cellDisplay(slot.rowData, entry.column, slot.rowIndex, entry.originalIndex) }}</span>\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\">{{ labels().emptyState }}</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
438
  }
433
439
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GridBodyComponent, decorators: [{
434
440
  type: Component,
@@ -436,7 +442,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
436
442
  }], propDecorators: { scrollContainer: [{
437
443
  type: ViewChild,
438
444
  args: ["scrollContainer"]
439
- }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: true }] }], totalHeaderHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalHeaderHeight", required: true }] }], contentWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentWidth", required: true }] }], contentHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentHeight", required: true }] }], rowsWrapperOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsWrapperOffset", required: true }] }], slotsArray: [{ type: i0.Input, args: [{ isSignal: true, alias: "slotsArray", required: true }] }], visibleColumnWithIndices: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleColumnWithIndices", required: true }] }], totalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalWidth", required: true }] }], columnPositions: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnPositions", required: true }] }], columnWidths: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnWidths", required: true }] }], totalRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRows", required: true }] }], activeCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCell", required: false }] }], selectionRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionRange", required: false }] }], editingCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingCell", required: false }] }], cellRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderers", required: false }] }], globalCellRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalCellRenderer", required: false }] }], editRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRenderers", required: false }] }], globalEditRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalEditRenderer", required: false }] }], hoverPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverPosition", required: false }] }], computeRowClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "computeRowClasses", required: false }] }], computeCellClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "computeCellClasses", required: false }] }], fillHandlePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHandlePosition", required: false }] }], dragState: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragState", required: false }] }], scrolled: [{ type: i0.Output, args: ["scrolled"] }], cellPointerDown: [{ type: i0.Output, args: ["cellPointerDown"] }], cellPointerEnter: [{ type: i0.Output, args: ["cellPointerEnter"] }], cellPointerLeave: [{ type: i0.Output, args: ["cellPointerLeave"] }], cellDoubleClick: [{ type: i0.Output, args: ["cellDoubleClick"] }], editValueChange: [{ type: i0.Output, args: ["editValueChange"] }], editCommit: [{ type: i0.Output, args: ["editCommit"] }], editCancel: [{ type: i0.Output, args: ["editCancel"] }], fillHandlePointerDown: [{ type: i0.Output, args: ["fillHandlePointerDown"] }] } });
445
+ }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: true }] }], totalHeaderHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalHeaderHeight", required: true }] }], contentWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentWidth", required: true }] }], contentHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentHeight", required: true }] }], rowsWrapperOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsWrapperOffset", required: true }] }], slotsArray: [{ type: i0.Input, args: [{ isSignal: true, alias: "slotsArray", required: true }] }], visibleColumnWithIndices: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleColumnWithIndices", required: true }] }], totalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalWidth", required: true }] }], columnPositions: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnPositions", required: true }] }], columnWidths: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnWidths", required: true }] }], totalRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalRows", required: true }] }], activeCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeCell", required: false }] }], selectionRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionRange", required: false }] }], editingCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingCell", required: false }] }], cellRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellRenderers", required: false }] }], globalCellRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalCellRenderer", required: false }] }], editRenderers: [{ type: i0.Input, args: [{ isSignal: true, alias: "editRenderers", required: false }] }], globalEditRenderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalEditRenderer", required: false }] }], hoverPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverPosition", required: false }] }], computeRowClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "computeRowClasses", required: false }] }], computeCellClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "computeCellClasses", required: false }] }], fillHandlePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHandlePosition", required: false }] }], dragState: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragState", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], scrolled: [{ type: i0.Output, args: ["scrolled"] }], cellPointerDown: [{ type: i0.Output, args: ["cellPointerDown"] }], cellPointerEnter: [{ type: i0.Output, args: ["cellPointerEnter"] }], cellPointerLeave: [{ type: i0.Output, args: ["cellPointerLeave"] }], cellDoubleClick: [{ type: i0.Output, args: ["cellDoubleClick"] }], editValueChange: [{ type: i0.Output, args: ["editValueChange"] }], editCommit: [{ type: i0.Output, args: ["editCommit"] }], editCancel: [{ type: i0.Output, args: ["editCancel"] }], fillHandlePointerDown: [{ type: i0.Output, args: ["fillHandlePointerDown"] }] } });
440
446
 
441
447
  const FILTER_POPUP_TEMPLATE = `
442
448
  <div
@@ -452,7 +458,7 @@ const FILTER_POPUP_TEMPLATE = `
452
458
  (click)="$event.stopPropagation()">
453
459
 
454
460
  <div class="gp-grid-filter-header">
455
- Filter: {{ column().headerName ?? column().field }}
461
+ {{ filterTitle() }}
456
462
  </div>
457
463
 
458
464
  <div [class]="'gp-grid-filter-content ' + (isNumberColumn() ? 'gp-grid-filter-number' : 'gp-grid-filter-text')">
@@ -465,13 +471,13 @@ const FILTER_POPUP_TEMPLATE = `
465
471
  type="button"
466
472
  [class.active]="numberConditions[i - 1]?.nextOperator === 'and'"
467
473
  (click)="setNumberNextOp(i - 1, 'and')">
468
- AND
474
+ {{ labels().and }}
469
475
  </button>
470
476
  <button
471
477
  type="button"
472
478
  [class.active]="numberConditions[i - 1]?.nextOperator === 'or'"
473
479
  (click)="setNumberNextOp(i - 1, 'or')">
474
- OR
480
+ {{ labels().or }}
475
481
  </button>
476
482
  </div>
477
483
  }
@@ -479,7 +485,7 @@ const FILTER_POPUP_TEMPLATE = `
479
485
  <select
480
486
  [value]="cond.operator"
481
487
  (change)="onNumberOperatorChange(i, $any($event.target).value)">
482
- @for (op of numberOperators; track op.value) {
488
+ @for (op of numberOperators(); track op.value) {
483
489
  <option [value]="op.value">{{ op.label }}</option>
484
490
  }
485
491
  </select>
@@ -488,27 +494,27 @@ const FILTER_POPUP_TEMPLATE = `
488
494
  type="number"
489
495
  [value]="cond.value"
490
496
  (input)="cond.value = $any($event.target).value"
491
- placeholder="Value" />
497
+ [placeholder]="labels().valuePlaceholder" />
492
498
  @if (cond.operator === 'between') {
493
- <span class="gp-grid-filter-to">to</span>
499
+ <span class="gp-grid-filter-to">{{ labels().betweenSeparator }}</span>
494
500
  <input
495
501
  type="number"
496
502
  [value]="cond.valueTo"
497
503
  (input)="cond.valueTo = $any($event.target).value"
498
- placeholder="Value" />
504
+ [placeholder]="labels().valuePlaceholder" />
499
505
  }
500
506
  }
501
507
  @if (numberConditions.length > 1) {
502
508
  <button
503
509
  type="button"
504
510
  class="gp-grid-filter-remove"
505
- (click)="removeNumberCondition(i)">×</button>
511
+ (click)="removeNumberCondition(i)">{{ labels().removeCondition }}</button>
506
512
  }
507
513
  </div>
508
514
  </div>
509
515
  }
510
516
  <button type="button" class="gp-grid-filter-add" (click)="addNumberCondition()">
511
- + Add condition
517
+ {{ labels().addCondition }}
512
518
  </button>
513
519
  } @else {
514
520
  @if (showValuesMode()) {
@@ -517,13 +523,13 @@ const FILTER_POPUP_TEMPLATE = `
517
523
  type="button"
518
524
  [class.active]="filterMode === 'values'"
519
525
  (click)="filterMode = 'values'">
520
- Values
526
+ {{ labels().valuesMode }}
521
527
  </button>
522
528
  <button
523
529
  type="button"
524
530
  [class.active]="filterMode === 'condition'"
525
531
  (click)="filterMode = 'condition'">
526
- Condition
532
+ {{ labels().conditionMode }}
527
533
  </button>
528
534
  </div>
529
535
  }
@@ -534,25 +540,27 @@ const FILTER_POPUP_TEMPLATE = `
534
540
  type="text"
535
541
  [value]="searchText"
536
542
  (input)="searchText = $any($event.target).value"
537
- placeholder="Search..." />
543
+ [placeholder]="labels().searchPlaceholder" />
538
544
  <div class="gp-grid-filter-actions">
539
- <button type="button" (click)="selectAll()">Select All</button>
540
- <button type="button" (click)="deselectAll()">Deselect All</button>
545
+ <button type="button" (click)="selectAll()">{{ labels().selectAll }}</button>
546
+ <button type="button" (click)="deselectAll()">{{ labels().deselectAll }}</button>
541
547
  </div>
542
548
  <div class="gp-grid-filter-list">
543
- <label class="gp-grid-filter-option">
544
- <input
545
- type="checkbox"
546
- [checked]="includeBlanks"
547
- (change)="includeBlanks = $any($event.target).checked" />
548
- <span class="gp-grid-filter-blank">(Blanks)</span>
549
- </label>
550
- @for (entry of filteredUniqueEntries(); track entry.key) {
549
+ @if (hasBlanks()) {
551
550
  <label class="gp-grid-filter-option">
552
551
  <input
553
552
  type="checkbox"
554
- [checked]="selectedValues.has(entry.key)"
555
- (change)="toggleValue(entry.key, $any($event.target).checked)" />
553
+ [checked]="includeBlanks"
554
+ (change)="includeBlanks = $any($event.target).checked" />
555
+ <span class="gp-grid-filter-blank">{{ labels().blanks }}</span>
556
+ </label>
557
+ }
558
+ @for (entry of filteredUniqueEntries(); track entry.label) {
559
+ <label class="gp-grid-filter-option">
560
+ <input
561
+ type="checkbox"
562
+ [checked]="selectedLabels.has(entry.label)"
563
+ (change)="toggleValue(entry.label, $any($event.target).checked)" />
556
564
  <span>{{ entry.label }}</span>
557
565
  </label>
558
566
  }
@@ -568,13 +576,13 @@ const FILTER_POPUP_TEMPLATE = `
568
576
  type="button"
569
577
  [class.active]="textConditions[i - 1]?.nextOperator === 'and'"
570
578
  (click)="setTextNextOp(i - 1, 'and')">
571
- AND
579
+ {{ labels().and }}
572
580
  </button>
573
581
  <button
574
582
  type="button"
575
583
  [class.active]="textConditions[i - 1]?.nextOperator === 'or'"
576
584
  (click)="setTextNextOp(i - 1, 'or')">
577
- OR
585
+ {{ labels().or }}
578
586
  </button>
579
587
  </div>
580
588
  }
@@ -582,7 +590,7 @@ const FILTER_POPUP_TEMPLATE = `
582
590
  <select
583
591
  [value]="cond.operator"
584
592
  (change)="onTextOperatorChange(i, $any($event.target).value)">
585
- @for (op of textOperators; track op.value) {
593
+ @for (op of textOperators(); track op.value) {
586
594
  <option [value]="op.value">{{ op.label }}</option>
587
595
  }
588
596
  </select>
@@ -592,56 +600,35 @@ const FILTER_POPUP_TEMPLATE = `
592
600
  type="text"
593
601
  [value]="cond.value"
594
602
  (input)="cond.value = $any($event.target).value"
595
- placeholder="Value" />
603
+ [placeholder]="labels().valuePlaceholder" />
596
604
  }
597
605
  @if (textConditions.length > 1) {
598
606
  <button
599
607
  type="button"
600
608
  class="gp-grid-filter-remove"
601
- (click)="removeTextCondition(i)">×</button>
609
+ (click)="removeTextCondition(i)">{{ labels().removeCondition }}</button>
602
610
  }
603
611
  </div>
604
612
  </div>
605
613
  }
606
614
  <button type="button" class="gp-grid-filter-add" (click)="addTextCondition()">
607
- + Add condition
615
+ {{ labels().addCondition }}
608
616
  </button>
609
617
  }
610
618
  }
611
619
 
612
620
  <div class="gp-grid-filter-buttons">
613
621
  <button type="button" class="gp-grid-filter-btn-clear" (click)="handleClear()">
614
- Clear
622
+ {{ labels().clear }}
615
623
  </button>
616
624
  <button type="button" class="gp-grid-filter-btn-apply" (click)="handleApply()">
617
- Apply
625
+ {{ labels().apply }}
618
626
  </button>
619
627
  </div>
620
628
  </div>
621
629
  </div>
622
630
  `;
623
631
 
624
- const TEXT_OPERATORS = [
625
- { value: 'contains', label: 'Contains' },
626
- { value: 'notContains', label: 'Does not contain' },
627
- { value: 'equals', label: 'Equals' },
628
- { value: 'notEquals', label: 'Does not equal' },
629
- { value: 'startsWith', label: 'Starts with' },
630
- { value: 'endsWith', label: 'Ends with' },
631
- { value: 'blank', label: 'Is blank' },
632
- { value: 'notBlank', label: 'Is not blank' },
633
- ];
634
- const NUMBER_OPERATORS = [
635
- { value: '=', label: 'Equals' },
636
- { value: '!=', label: 'Does not equal' },
637
- { value: '>', label: 'Greater than' },
638
- { value: '<', label: 'Less than' },
639
- { value: '>=', label: 'Greater than or equal' },
640
- { value: '<=', label: 'Less than or equal' },
641
- { value: 'between', label: 'Between' },
642
- { value: 'blank', label: 'Is blank' },
643
- { value: 'notBlank', label: 'Is not blank' },
644
- ];
645
632
  const VALUE_LESS_TEXT_OPERATORS = ['blank', 'notBlank'];
646
633
  const VALUE_LESS_NUMBER_OPERATORS = ['blank', 'notBlank'];
647
634
  const MAX_CHECKBOX_VALUES = 100;
@@ -658,40 +645,24 @@ const defaultNumberCondition = () => ({
658
645
  valueTo: '',
659
646
  nextOperator: 'and',
660
647
  });
661
- const computeUniqueValues = (distinctValues, formatter) => {
662
- const seen = new Set();
663
- const result = [];
664
- for (const val of distinctValues) {
665
- if (val === null || val === undefined || val === '')
666
- continue;
667
- // Key by formatter output when available so filter-time comparison
668
- // (which also goes through the formatter) matches what the user selects.
669
- const key = formatter ? formatter(val) : String(val);
670
- if (!seen.has(key)) {
671
- seen.add(key);
672
- result.push({ key, label: key });
673
- }
674
- }
675
- return result.sort((a, b) => a.label.localeCompare(b.label, undefined, { numeric: true, sensitivity: 'base' }));
676
- };
677
- const initTextState = (filter, uniqueValues) => {
648
+ const initTextState = (filter, entries) => {
678
649
  if (!filter)
679
- return defaultTextState(uniqueValues);
650
+ return defaultTextState(entries);
680
651
  const textConds = filter.conditions.filter((c) => c.type === 'text');
681
652
  if (textConds.length === 0)
682
- return defaultTextState(uniqueValues);
653
+ return defaultTextState(entries);
683
654
  const firstCond = textConds[0];
684
655
  if (firstCond?.selectedValues !== undefined) {
685
656
  return {
686
657
  filterMode: 'values',
687
- selectedValues: new Set(firstCond.selectedValues),
658
+ selectedLabels: labelsForSelectedValues(entries, firstCond.selectedValues),
688
659
  includeBlanks: firstCond.includeBlank ?? true,
689
660
  textConditions: [defaultTextCondition()],
690
661
  };
691
662
  }
692
663
  return {
693
664
  filterMode: 'condition',
694
- selectedValues: new Set(uniqueValues),
665
+ selectedLabels: new Set(entries.map(e => e.label)),
695
666
  includeBlanks: true,
696
667
  textConditions: textConds.map((c, i) => ({
697
668
  operator: c.operator,
@@ -700,9 +671,9 @@ const initTextState = (filter, uniqueValues) => {
700
671
  })),
701
672
  };
702
673
  };
703
- const defaultTextState = (uniqueValues) => ({
674
+ const defaultTextState = (entries) => ({
704
675
  filterMode: 'values',
705
- selectedValues: new Set(uniqueValues),
676
+ selectedLabels: new Set(entries.map(e => e.label)),
706
677
  includeBlanks: true,
707
678
  textConditions: [defaultTextCondition()],
708
679
  });
@@ -726,14 +697,14 @@ const buildTextFilter = (input) => {
726
697
  return buildConditionTextFilter(input.textConditions);
727
698
  };
728
699
  const buildValuesFilter = (input) => {
729
- const allSelected = input.uniqueValues.every(v => input.selectedValues.has(v));
700
+ const allSelected = input.entries.every(e => input.selectedLabels.has(e.label));
730
701
  if (allSelected && input.includeBlanks)
731
702
  return null;
732
703
  return {
733
704
  conditions: [{
734
705
  type: 'text',
735
- operator: 'contains',
736
- selectedValues: new Set(input.selectedValues),
706
+ operator: 'equals',
707
+ selectedValues: rawValuesForLabels(input.entries, input.selectedLabels),
737
708
  includeBlank: input.includeBlanks,
738
709
  }],
739
710
  combination: 'or',
@@ -802,6 +773,7 @@ class FilterPopupComponent {
802
773
  anchorEl = input.required(...(ngDevMode ? [{ debugName: "anchorEl" }] : /* istanbul ignore next */ []));
803
774
  distinctValues = input.required(...(ngDevMode ? [{ debugName: "distinctValues" }] : /* istanbul ignore next */ []));
804
775
  currentFilter = input(undefined, ...(ngDevMode ? [{ debugName: "currentFilter" }] : /* istanbul ignore next */ []));
776
+ labels = input(defaultGridLabels, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
805
777
  apply = output();
806
778
  close = output();
807
779
  popupTop = signal(0, ...(ngDevMode ? [{ debugName: "popupTop" }] : /* istanbul ignore next */ []));
@@ -810,12 +782,23 @@ class FilterPopupComponent {
810
782
  positioned = signal(false, ...(ngDevMode ? [{ debugName: "positioned" }] : /* istanbul ignore next */ []));
811
783
  filterMode = 'values';
812
784
  searchText = '';
813
- selectedValues = new Set();
785
+ // Ticked display labels; raw values are resolved on apply (buildTextFilter).
786
+ selectedLabels = new Set();
814
787
  includeBlanks = true;
815
788
  textConditions = [defaultTextCondition()];
816
789
  numberConditions = [defaultNumberCondition()];
817
- textOperators = TEXT_OPERATORS;
818
- numberOperators = NUMBER_OPERATORS;
790
+ textOperators() {
791
+ return getTextOperatorOptions(this.labels());
792
+ }
793
+ numberOperators() {
794
+ return getNumberOperatorOptions(this.labels());
795
+ }
796
+ filterTitle() {
797
+ const column = this.column();
798
+ return formatLabel(this.labels().filterTitle, {
799
+ column: column.headerName ?? column.field,
800
+ });
801
+ }
819
802
  isValueLessTextOp = isValueLessTextOp;
820
803
  isValueLessNumberOp = isValueLessNumberOp;
821
804
  constructor() {
@@ -859,10 +842,12 @@ class FilterPopupComponent {
859
842
  return this.uniqueEntries().length <= MAX_CHECKBOX_VALUES;
860
843
  }
861
844
  uniqueEntries() {
862
- return computeUniqueValues(this.distinctValues(), this.column().valueFormatter);
845
+ return groupDistinctValues(this.distinctValues(), this.column().valueFormatter);
863
846
  }
864
- uniqueValues() {
865
- return this.uniqueEntries().map(e => e.key);
847
+ // Empty arrays count too (tags column with no tags), so the "(Blanks)"
848
+ // opt-out renders whenever blank rows exist — and only then.
849
+ hasBlanks() {
850
+ return this.distinctValues().some(isBlankCellValue);
866
851
  }
867
852
  filteredUniqueEntries() {
868
853
  const search = this.searchText.toLowerCase();
@@ -870,22 +855,22 @@ class FilterPopupComponent {
870
855
  return this.uniqueEntries();
871
856
  return this.uniqueEntries().filter(e => e.label.toLowerCase().includes(search));
872
857
  }
873
- toggleValue(val, checked) {
858
+ toggleValue(label, checked) {
874
859
  if (checked) {
875
- this.selectedValues.add(val);
860
+ this.selectedLabels.add(label);
876
861
  }
877
862
  else {
878
- this.selectedValues.delete(val);
863
+ this.selectedLabels.delete(label);
879
864
  }
880
865
  }
881
866
  selectAll() {
882
867
  this.includeBlanks = true;
883
- for (const v of this.uniqueValues())
884
- this.selectedValues.add(v);
868
+ for (const entry of this.uniqueEntries())
869
+ this.selectedLabels.add(entry.label);
885
870
  }
886
871
  deselectAll() {
887
872
  this.includeBlanks = false;
888
- this.selectedValues.clear();
873
+ this.selectedLabels.clear();
889
874
  }
890
875
  onTextOperatorChange(index, value) {
891
876
  setField(this.textConditions, index, 'operator', value);
@@ -925,8 +910,8 @@ class FilterPopupComponent {
925
910
  return buildNumberFilter(this.numberConditions);
926
911
  return buildTextFilter({
927
912
  filterMode: this.filterMode,
928
- uniqueValues: this.uniqueValues(),
929
- selectedValues: this.selectedValues,
913
+ entries: this.uniqueEntries(),
914
+ selectedLabels: this.selectedLabels,
930
915
  includeBlanks: this.includeBlanks,
931
916
  textConditions: this.textConditions,
932
917
  });
@@ -937,9 +922,9 @@ class FilterPopupComponent {
937
922
  this.numberConditions = initNumberConditions(filter);
938
923
  return;
939
924
  }
940
- const state = initTextState(filter, this.uniqueValues());
925
+ const state = initTextState(filter, this.uniqueEntries());
941
926
  this.filterMode = state.filterMode;
942
- this.selectedValues = state.selectedValues;
927
+ this.selectedLabels = state.selectedLabels;
943
928
  this.includeBlanks = state.includeBlanks;
944
929
  this.textConditions = state.textConditions;
945
930
  }
@@ -970,7 +955,7 @@ class FilterPopupComponent {
970
955
  });
971
956
  };
972
957
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: FilterPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
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 });
958
+ 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 }, labels: { classPropertyName: "labels", publicName: "labels", 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 {{ filterTitle() }}\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 {{ labels().and }}\n </button>\n <button\n type=\"button\"\n [class.active]=\"numberConditions[i - 1]?.nextOperator === 'or'\"\n (click)=\"setNumberNextOp(i - 1, 'or')\">\n {{ labels().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]=\"labels().valuePlaceholder\" />\n @if (cond.operator === 'between') {\n <span class=\"gp-grid-filter-to\">{{ labels().betweenSeparator }}</span>\n <input\n type=\"number\"\n [value]=\"cond.valueTo\"\n (input)=\"cond.valueTo = $any($event.target).value\"\n [placeholder]=\"labels().valuePlaceholder\" />\n }\n }\n @if (numberConditions.length > 1) {\n <button\n type=\"button\"\n class=\"gp-grid-filter-remove\"\n (click)=\"removeNumberCondition(i)\">{{ labels().removeCondition }}</button>\n }\n </div>\n </div>\n }\n <button type=\"button\" class=\"gp-grid-filter-add\" (click)=\"addNumberCondition()\">\n {{ labels().addCondition }}\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 {{ labels().valuesMode }}\n </button>\n <button\n type=\"button\"\n [class.active]=\"filterMode === 'condition'\"\n (click)=\"filterMode = 'condition'\">\n {{ labels().conditionMode }}\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]=\"labels().searchPlaceholder\" />\n <div class=\"gp-grid-filter-actions\">\n <button type=\"button\" (click)=\"selectAll()\">{{ labels().selectAll }}</button>\n <button type=\"button\" (click)=\"deselectAll()\">{{ labels().deselectAll }}</button>\n </div>\n <div class=\"gp-grid-filter-list\">\n @if (hasBlanks()) {\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\">{{ labels().blanks }}</span>\n </label>\n }\n @for (entry of filteredUniqueEntries(); track entry.label) {\n <label class=\"gp-grid-filter-option\">\n <input\n type=\"checkbox\"\n [checked]=\"selectedLabels.has(entry.label)\"\n (change)=\"toggleValue(entry.label, $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 {{ labels().and }}\n </button>\n <button\n type=\"button\"\n [class.active]=\"textConditions[i - 1]?.nextOperator === 'or'\"\n (click)=\"setTextNextOp(i - 1, 'or')\">\n {{ labels().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]=\"labels().valuePlaceholder\" />\n }\n @if (textConditions.length > 1) {\n <button\n type=\"button\"\n class=\"gp-grid-filter-remove\"\n (click)=\"removeTextCondition(i)\">{{ labels().removeCondition }}</button>\n }\n </div>\n </div>\n }\n <button type=\"button\" class=\"gp-grid-filter-add\" (click)=\"addTextCondition()\">\n {{ labels().addCondition }}\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 {{ labels().clear }}\n </button>\n <button type=\"button\" class=\"gp-grid-filter-btn-apply\" (click)=\"handleApply()\">\n {{ labels().apply }}\n </button>\n </div>\n </div>\n</div>\n", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
974
959
  }
975
960
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: FilterPopupComponent, decorators: [{
976
961
  type: Component,
@@ -984,7 +969,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
984
969
  }], ctorParameters: () => [], propDecorators: { popupEl: [{
985
970
  type: ViewChild,
986
971
  args: ['popupEl', { static: false }]
987
- }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], colIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "colIndex", required: true }] }], anchorEl: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchorEl", required: true }] }], distinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "distinctValues", required: true }] }], currentFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentFilter", required: false }] }], apply: [{ type: i0.Output, args: ["apply"] }], close: [{ type: i0.Output, args: ["close"] }], onEscape: [{
972
+ }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], colIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "colIndex", required: true }] }], anchorEl: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchorEl", required: true }] }], distinctValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "distinctValues", required: true }] }], currentFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentFilter", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], apply: [{ type: i0.Output, args: ["apply"] }], close: [{ type: i0.Output, args: ["close"] }], onEscape: [{
988
973
  type: HostListener,
989
974
  args: ['keydown.escape']
990
975
  }] } });
@@ -1002,6 +987,7 @@ const TEMPLATE$1 = `
1002
987
  [anchorEl]="fp.anchorEl!"
1003
988
  [distinctValues]="fp.distinctValues"
1004
989
  [currentFilter]="fp.currentFilter"
990
+ [labels]="labels()"
1005
991
  (apply)="filterApply.emit($event)"
1006
992
  (close)="filterClose.emit()"
1007
993
  />
@@ -1020,7 +1006,7 @@ const TEMPLATE$1 = `
1020
1006
  </div>
1021
1007
  }
1022
1008
  @if (errorMessage(); as msg) {
1023
- <div class="gp-grid-error">Error: {{ msg }}</div>
1009
+ <div class="gp-grid-error">{{ errorLabel(msg) }}</div>
1024
1010
  }
1025
1011
  @if (columnMove(); as cm) {
1026
1012
  <div
@@ -1051,6 +1037,7 @@ class GridOverlaysComponent {
1051
1037
  filterPopup = input(null, ...(ngDevMode ? [{ debugName: "filterPopup" }] : /* istanbul ignore next */ []));
1052
1038
  isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
1053
1039
  errorMessage = input(null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
1040
+ labels = input(defaultGridLabels, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
1054
1041
  headerHeight = input.required(...(ngDevMode ? [{ debugName: "headerHeight" }] : /* istanbul ignore next */ []));
1055
1042
  rowHeight = input.required(...(ngDevMode ? [{ debugName: "rowHeight" }] : /* istanbul ignore next */ []));
1056
1043
  dragState = input.required(...(ngDevMode ? [{ debugName: "dragState" }] : /* istanbul ignore next */ []));
@@ -1061,6 +1048,9 @@ class GridOverlaysComponent {
1061
1048
  totalWidth = input.required(...(ngDevMode ? [{ debugName: "totalWidth" }] : /* istanbul ignore next */ []));
1062
1049
  filterApply = output();
1063
1050
  filterClose = output();
1051
+ errorLabel(message) {
1052
+ return formatLabel(this.labels().errorPrefix, { message });
1053
+ }
1064
1054
  isResizing = computed(() => this.dragState().dragType === 'column-resize', ...(ngDevMode ? [{ debugName: "isResizing" }] : /* istanbul ignore next */ []));
1065
1055
  resizeLineLeft = computed(() => {
1066
1056
  const cr = this.dragState().columnResize;
@@ -1098,7 +1088,7 @@ class GridOverlaysComponent {
1098
1088
  }, ...(ngDevMode ? [{ debugName: "columnMoveDropLeft" }] : /* istanbul ignore next */ []));
1099
1089
  rowDragGhostWidth = computed(() => Math.min(300, this.totalWidth()), ...(ngDevMode ? [{ debugName: "rowDragGhostWidth" }] : /* istanbul ignore next */ []));
1100
1090
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GridOverlaysComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1101
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: GridOverlaysComponent, isStandalone: true, selector: "gp-grid-overlays", inputs: { filterPopup: { classPropertyName: "filterPopup", publicName: "filterPopup", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, headerHeight: { classPropertyName: "headerHeight", publicName: "headerHeight", isSignal: true, isRequired: true, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: true, transformFunction: null }, dragState: { classPropertyName: "dragState", publicName: "dragState", isSignal: true, isRequired: true, transformFunction: null }, visibleColumnWithIndices: { classPropertyName: "visibleColumnWithIndices", publicName: "visibleColumnWithIndices", isSignal: true, isRequired: true, transformFunction: null }, columnPositions: { classPropertyName: "columnPositions", publicName: "columnPositions", isSignal: true, isRequired: true, transformFunction: null }, scrollLeft: { classPropertyName: "scrollLeft", publicName: "scrollLeft", isSignal: true, isRequired: true, transformFunction: null }, effectiveColumns: { classPropertyName: "effectiveColumns", publicName: "effectiveColumns", isSignal: true, isRequired: true, transformFunction: null }, totalWidth: { classPropertyName: "totalWidth", publicName: "totalWidth", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { filterApply: "filterApply", filterClose: "filterClose" }, ngImport: i0, template: "\n @if (filterPopup(); as fp) {\n <gp-grid-filter-popup\n [column]=\"fp.column\"\n [colIndex]=\"fp.colIndex\"\n [anchorEl]=\"fp.anchorEl!\"\n [distinctValues]=\"fp.distinctValues\"\n [currentFilter]=\"fp.currentFilter\"\n (apply)=\"filterApply.emit($event)\"\n (close)=\"filterClose.emit()\"\n />\n }\n @if (isResizing()) {\n <div class=\"gp-grid-column-resize-line\" [style.left.px]=\"resizeLineLeft()\"></div>\n }\n @if (isLoading()) {\n <div\n style=\"position: absolute; left: 0; right: 0; bottom: 0; z-index: 50; pointer-events: none;\"\n [style.top.px]=\"headerHeight()\">\n <div class=\"gp-grid-loading-overlay\"></div>\n <div class=\"gp-grid-loading\">\n <div class=\"gp-grid-loading-spinner\"></div>\n </div>\n </div>\n }\n @if (errorMessage(); as msg) {\n <div class=\"gp-grid-error\">Error: {{ msg }}</div>\n }\n @if (columnMove(); as cm) {\n <div\n class=\"gp-grid-column-move-ghost\"\n [style.left.px]=\"cm.currentX - cm.ghostWidth / 2\"\n [style.top.px]=\"cm.currentY - cm.ghostHeight / 2\"\n [style.width.px]=\"cm.ghostWidth\"\n [style.height.px]=\"cm.ghostHeight\">\n {{ columnMoveGhostText() }}\n </div>\n @if (columnMoveDropLeft() !== null) {\n <div\n class=\"gp-grid-column-drop-indicator\"\n [style.left.px]=\"columnMoveDropLeft()\"\n [style.height.px]=\"headerHeight()\"></div>\n }\n }\n @if (rowDragGhost(); as rd) {\n <div\n class=\"gp-grid-row-drag-ghost\"\n [style.left.px]=\"rd.currentX + 12\"\n [style.top.px]=\"rd.currentY - rowHeight() / 2\"\n [style.width.px]=\"rowDragGhostWidth()\"\n [style.height.px]=\"rowHeight()\"></div>\n }\n", isInline: true, dependencies: [{ kind: "component", type: FilterPopupComponent, selector: "gp-grid-filter-popup", inputs: ["column", "colIndex", "anchorEl", "distinctValues", "currentFilter"], outputs: ["apply", "close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1091
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: GridOverlaysComponent, isStandalone: true, selector: "gp-grid-overlays", inputs: { filterPopup: { classPropertyName: "filterPopup", publicName: "filterPopup", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, headerHeight: { classPropertyName: "headerHeight", publicName: "headerHeight", isSignal: true, isRequired: true, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: true, transformFunction: null }, dragState: { classPropertyName: "dragState", publicName: "dragState", isSignal: true, isRequired: true, transformFunction: null }, visibleColumnWithIndices: { classPropertyName: "visibleColumnWithIndices", publicName: "visibleColumnWithIndices", isSignal: true, isRequired: true, transformFunction: null }, columnPositions: { classPropertyName: "columnPositions", publicName: "columnPositions", isSignal: true, isRequired: true, transformFunction: null }, scrollLeft: { classPropertyName: "scrollLeft", publicName: "scrollLeft", isSignal: true, isRequired: true, transformFunction: null }, effectiveColumns: { classPropertyName: "effectiveColumns", publicName: "effectiveColumns", isSignal: true, isRequired: true, transformFunction: null }, totalWidth: { classPropertyName: "totalWidth", publicName: "totalWidth", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { filterApply: "filterApply", filterClose: "filterClose" }, ngImport: i0, template: "\n @if (filterPopup(); as fp) {\n <gp-grid-filter-popup\n [column]=\"fp.column\"\n [colIndex]=\"fp.colIndex\"\n [anchorEl]=\"fp.anchorEl!\"\n [distinctValues]=\"fp.distinctValues\"\n [currentFilter]=\"fp.currentFilter\"\n [labels]=\"labels()\"\n (apply)=\"filterApply.emit($event)\"\n (close)=\"filterClose.emit()\"\n />\n }\n @if (isResizing()) {\n <div class=\"gp-grid-column-resize-line\" [style.left.px]=\"resizeLineLeft()\"></div>\n }\n @if (isLoading()) {\n <div\n style=\"position: absolute; left: 0; right: 0; bottom: 0; z-index: 50; pointer-events: none;\"\n [style.top.px]=\"headerHeight()\">\n <div class=\"gp-grid-loading-overlay\"></div>\n <div class=\"gp-grid-loading\">\n <div class=\"gp-grid-loading-spinner\"></div>\n </div>\n </div>\n }\n @if (errorMessage(); as msg) {\n <div class=\"gp-grid-error\">{{ errorLabel(msg) }}</div>\n }\n @if (columnMove(); as cm) {\n <div\n class=\"gp-grid-column-move-ghost\"\n [style.left.px]=\"cm.currentX - cm.ghostWidth / 2\"\n [style.top.px]=\"cm.currentY - cm.ghostHeight / 2\"\n [style.width.px]=\"cm.ghostWidth\"\n [style.height.px]=\"cm.ghostHeight\">\n {{ columnMoveGhostText() }}\n </div>\n @if (columnMoveDropLeft() !== null) {\n <div\n class=\"gp-grid-column-drop-indicator\"\n [style.left.px]=\"columnMoveDropLeft()\"\n [style.height.px]=\"headerHeight()\"></div>\n }\n }\n @if (rowDragGhost(); as rd) {\n <div\n class=\"gp-grid-row-drag-ghost\"\n [style.left.px]=\"rd.currentX + 12\"\n [style.top.px]=\"rd.currentY - rowHeight() / 2\"\n [style.width.px]=\"rowDragGhostWidth()\"\n [style.height.px]=\"rowHeight()\"></div>\n }\n", isInline: true, dependencies: [{ kind: "component", type: FilterPopupComponent, selector: "gp-grid-filter-popup", inputs: ["column", "colIndex", "anchorEl", "distinctValues", "currentFilter", "labels"], outputs: ["apply", "close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1102
1092
  }
1103
1093
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GridOverlaysComponent, decorators: [{
1104
1094
  type: Component,
@@ -1109,7 +1099,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
1109
1099
  changeDetection: ChangeDetectionStrategy.OnPush,
1110
1100
  template: TEMPLATE$1,
1111
1101
  }]
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"] }] } });
1102
+ }], 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 }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", 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"] }] } });
1113
1103
 
1114
1104
  const TEMPLATE = `
1115
1105
  <div
@@ -1315,6 +1305,7 @@ const GP_GRID_TEMPLATE = `
1315
1305
  [computeCellClasses]="computeCellClassesFn"
1316
1306
  [fillHandlePosition]="vm.fillHandlePosition()"
1317
1307
  [dragState]="vm.dragState()"
1308
+ [labels]="resolvedLabels()"
1318
1309
  (scrolled)="onBodyScroll($event)"
1319
1310
  (cellPointerDown)="onCellPointerDown($event)"
1320
1311
  (cellPointerEnter)="onCellPointerEnter($event)"
@@ -1327,6 +1318,7 @@ const GP_GRID_TEMPLATE = `
1327
1318
  />
1328
1319
  <gp-grid-overlays
1329
1320
  [filterPopup]="vm.filterPopup()"
1321
+ [labels]="resolvedLabels()"
1330
1322
  [isLoading]="vm.isLoading()"
1331
1323
  [errorMessage]="vm.errorMessage()"
1332
1324
  [headerHeight]="headerHeight()"
@@ -1643,6 +1635,8 @@ class GpGridComponent {
1643
1635
  onCellValueChanged = output();
1644
1636
  onColumnResized = output();
1645
1637
  onColumnMoved = output();
1638
+ labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
1639
+ resolvedLabels = computed(() => resolveGridLabels(this.labels()), ...(ngDevMode ? [{ debugName: "resolvedLabels" }] : /* istanbul ignore next */ []));
1646
1640
  vm = new GpGridViewModel({
1647
1641
  getColumns: () => this.columns(),
1648
1642
  getRows: () => this.rows(),
@@ -1822,7 +1816,7 @@ class GpGridComponent {
1822
1816
  this.bindings.pendingRowDrag.releaseLocks();
1823
1817
  };
1824
1818
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GpGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
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 });
1819
+ 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 }, labels: { classPropertyName: "labels", publicName: "labels", 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 [labels]=\"resolvedLabels()\"\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 [labels]=\"resolvedLabels()\"\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", "labels"], outputs: ["scrolled", "cellPointerDown", "cellPointerEnter", "cellPointerLeave", "cellDoubleClick", "editValueChange", "editCommit", "editCancel", "fillHandlePointerDown"] }, { kind: "component", type: GridOverlaysComponent, selector: "gp-grid-overlays", inputs: ["filterPopup", "isLoading", "errorMessage", "labels", "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 });
1826
1820
  }
1827
1821
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: GpGridComponent, decorators: [{
1828
1822
  type: Component,
@@ -1833,7 +1827,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
1833
1827
  }], body: [{
1834
1828
  type: ViewChild,
1835
1829
  args: [GridBodyComponent]
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"] }] } });
1830
+ }], 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"] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }] } });
1837
1831
 
1838
1832
  /**
1839
1833
  * 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.19.0",
4
+ "version": "0.21.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.19.0",
54
+ "@gp-grid/core": "0.21.0",
55
55
  "tslib": "^2.8.1"
56
56
  },
57
57
  "sideEffects": false,
@@ -1,6 +1,6 @@
1
1
  import * as _gp_grid_core from '@gp-grid/core';
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';
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';
2
+ import { HeaderRendererParams, SortDirection, VisibleColumnInfo, HeaderData, ColumnDefinition, SlotData, CellPosition, CellRange, CellValue, CellRendererParams, EditRendererParams, FillHandlePosition, DragState, GridLabels, ColumnFilterModel, getTextOperatorOptions, getNumberOperatorOptions, DistinctValueEntry, BatchChangeSetters, DataSource, RowId, HighlightingOptions, RowLoadingOptions, CellValueChangedEvent, ParallelSortOptions, MutableDataSource } from '@gp-grid/core';
3
+ export { CellDataType, CellPosition, CellRange, CellRendererParams, CellValue, CellValueChangedEvent, ColumnDefinition, ColumnFilterModel, DataSource, DataSourceLoadMode, DataSourceRange, DataSourceRequest, DataSourceResponse, EditRendererParams, FilterCondition, FilterModel, GridCore, GridFilterOperatorLabels, GridInstruction, GridLabels, HeaderRendererParams, HighlightContext, HighlightingOptions, MutableDataSource, RowCacheEviction, RowCacheOptions, RowId, RowLoadingMode, RowLoadingOptions, SortDirection, SortModel, createClientDataSource, createDataSourceFromArray, createMutableClientDataSource, createServerDataSource } from '@gp-grid/core';
4
4
  import * as _angular_core from '@angular/core';
5
5
  import { TemplateRef, ElementRef, AfterViewInit, OnDestroy, Signal, OnInit, InjectionToken, Provider } from '@angular/core';
6
6
 
@@ -113,6 +113,7 @@ declare class GridBodyComponent {
113
113
  computeCellClasses: _angular_core.InputSignal<CellClassFn>;
114
114
  fillHandlePosition: _angular_core.InputSignal<FillHandlePosition>;
115
115
  dragState: _angular_core.InputSignal<DragState>;
116
+ labels: _angular_core.InputSignal<GridLabels>;
116
117
  scrolled: _angular_core.OutputEmitterRef<number>;
117
118
  cellPointerDown: _angular_core.OutputEmitterRef<CellPointerDownEvent>;
118
119
  cellPointerEnter: _angular_core.OutputEmitterRef<CellPointerEnterEvent>;
@@ -141,7 +142,7 @@ declare class GridBodyComponent {
141
142
  protected onEditFocus(event: FocusEvent): void;
142
143
  protected onEditKeyDown(event: KeyboardEvent): void;
143
144
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridBodyComponent, never>;
144
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<GridBodyComponent, "gp-grid-body", never, { "rowHeight": { "alias": "rowHeight"; "required": true; "isSignal": true; }; "totalHeaderHeight": { "alias": "totalHeaderHeight"; "required": true; "isSignal": true; }; "contentWidth": { "alias": "contentWidth"; "required": true; "isSignal": true; }; "contentHeight": { "alias": "contentHeight"; "required": true; "isSignal": true; }; "rowsWrapperOffset": { "alias": "rowsWrapperOffset"; "required": true; "isSignal": true; }; "slotsArray": { "alias": "slotsArray"; "required": true; "isSignal": true; }; "visibleColumnWithIndices": { "alias": "visibleColumnWithIndices"; "required": true; "isSignal": true; }; "totalWidth": { "alias": "totalWidth"; "required": true; "isSignal": true; }; "columnPositions": { "alias": "columnPositions"; "required": true; "isSignal": true; }; "columnWidths": { "alias": "columnWidths"; "required": true; "isSignal": true; }; "totalRows": { "alias": "totalRows"; "required": true; "isSignal": true; }; "activeCell": { "alias": "activeCell"; "required": false; "isSignal": true; }; "selectionRange": { "alias": "selectionRange"; "required": false; "isSignal": true; }; "editingCell": { "alias": "editingCell"; "required": false; "isSignal": true; }; "cellRenderers": { "alias": "cellRenderers"; "required": false; "isSignal": true; }; "globalCellRenderer": { "alias": "globalCellRenderer"; "required": false; "isSignal": true; }; "editRenderers": { "alias": "editRenderers"; "required": false; "isSignal": true; }; "globalEditRenderer": { "alias": "globalEditRenderer"; "required": false; "isSignal": true; }; "hoverPosition": { "alias": "hoverPosition"; "required": false; "isSignal": true; }; "computeRowClasses": { "alias": "computeRowClasses"; "required": false; "isSignal": true; }; "computeCellClasses": { "alias": "computeCellClasses"; "required": false; "isSignal": true; }; "fillHandlePosition": { "alias": "fillHandlePosition"; "required": false; "isSignal": true; }; "dragState": { "alias": "dragState"; "required": false; "isSignal": true; }; }, { "scrolled": "scrolled"; "cellPointerDown": "cellPointerDown"; "cellPointerEnter": "cellPointerEnter"; "cellPointerLeave": "cellPointerLeave"; "cellDoubleClick": "cellDoubleClick"; "editValueChange": "editValueChange"; "editCommit": "editCommit"; "editCancel": "editCancel"; "fillHandlePointerDown": "fillHandlePointerDown"; }, never, never, true, never>;
145
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GridBodyComponent, "gp-grid-body", never, { "rowHeight": { "alias": "rowHeight"; "required": true; "isSignal": true; }; "totalHeaderHeight": { "alias": "totalHeaderHeight"; "required": true; "isSignal": true; }; "contentWidth": { "alias": "contentWidth"; "required": true; "isSignal": true; }; "contentHeight": { "alias": "contentHeight"; "required": true; "isSignal": true; }; "rowsWrapperOffset": { "alias": "rowsWrapperOffset"; "required": true; "isSignal": true; }; "slotsArray": { "alias": "slotsArray"; "required": true; "isSignal": true; }; "visibleColumnWithIndices": { "alias": "visibleColumnWithIndices"; "required": true; "isSignal": true; }; "totalWidth": { "alias": "totalWidth"; "required": true; "isSignal": true; }; "columnPositions": { "alias": "columnPositions"; "required": true; "isSignal": true; }; "columnWidths": { "alias": "columnWidths"; "required": true; "isSignal": true; }; "totalRows": { "alias": "totalRows"; "required": true; "isSignal": true; }; "activeCell": { "alias": "activeCell"; "required": false; "isSignal": true; }; "selectionRange": { "alias": "selectionRange"; "required": false; "isSignal": true; }; "editingCell": { "alias": "editingCell"; "required": false; "isSignal": true; }; "cellRenderers": { "alias": "cellRenderers"; "required": false; "isSignal": true; }; "globalCellRenderer": { "alias": "globalCellRenderer"; "required": false; "isSignal": true; }; "editRenderers": { "alias": "editRenderers"; "required": false; "isSignal": true; }; "globalEditRenderer": { "alias": "globalEditRenderer"; "required": false; "isSignal": true; }; "hoverPosition": { "alias": "hoverPosition"; "required": false; "isSignal": true; }; "computeRowClasses": { "alias": "computeRowClasses"; "required": false; "isSignal": true; }; "computeCellClasses": { "alias": "computeCellClasses"; "required": false; "isSignal": true; }; "fillHandlePosition": { "alias": "fillHandlePosition"; "required": false; "isSignal": true; }; "dragState": { "alias": "dragState"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "scrolled": "scrolled"; "cellPointerDown": "cellPointerDown"; "cellPointerEnter": "cellPointerEnter"; "cellPointerLeave": "cellPointerLeave"; "cellDoubleClick": "cellDoubleClick"; "editValueChange": "editValueChange"; "editCommit": "editCommit"; "editCancel": "editCancel"; "fillHandlePointerDown": "fillHandlePointerDown"; }, never, never, true, never>;
145
146
  }
146
147
 
147
148
  interface TextConditionState {
@@ -156,10 +157,6 @@ interface NumberConditionState {
156
157
  nextOperator: 'and' | 'or';
157
158
  }
158
159
  type FilterMode = 'values' | 'condition';
159
- interface FilterEntry {
160
- key: string;
161
- label: string;
162
- }
163
160
 
164
161
  declare class FilterPopupComponent implements AfterViewInit, OnDestroy {
165
162
  popupEl: ElementRef<HTMLDivElement>;
@@ -168,6 +165,7 @@ declare class FilterPopupComponent implements AfterViewInit, OnDestroy {
168
165
  anchorEl: _angular_core.InputSignal<HTMLElement>;
169
166
  distinctValues: _angular_core.InputSignal<CellValue[]>;
170
167
  currentFilter: _angular_core.InputSignal<ColumnFilterModel>;
168
+ labels: _angular_core.InputSignal<GridLabels>;
171
169
  apply: _angular_core.OutputEmitterRef<{
172
170
  colId: string;
173
171
  filter: ColumnFilterModel | null;
@@ -179,18 +177,13 @@ declare class FilterPopupComponent implements AfterViewInit, OnDestroy {
179
177
  positioned: _angular_core.WritableSignal<boolean>;
180
178
  filterMode: FilterMode;
181
179
  searchText: string;
182
- selectedValues: Set<string>;
180
+ selectedLabels: Set<string>;
183
181
  includeBlanks: boolean;
184
182
  textConditions: TextConditionState[];
185
183
  numberConditions: NumberConditionState[];
186
- readonly textOperators: readonly {
187
- value: _gp_grid_core.TextFilterOperator;
188
- label: string;
189
- }[];
190
- readonly numberOperators: readonly {
191
- value: _gp_grid_core.NumberFilterOperator;
192
- label: string;
193
- }[];
184
+ protected textOperators(): ReturnType<typeof getTextOperatorOptions>;
185
+ protected numberOperators(): ReturnType<typeof getNumberOperatorOptions>;
186
+ protected filterTitle(): string;
194
187
  protected readonly isValueLessTextOp: (operator: string) => boolean;
195
188
  protected readonly isValueLessNumberOp: (operator: string) => boolean;
196
189
  constructor();
@@ -199,10 +192,10 @@ declare class FilterPopupComponent implements AfterViewInit, OnDestroy {
199
192
  onEscape(): void;
200
193
  isNumberColumn(): boolean;
201
194
  showValuesMode(): boolean;
202
- uniqueEntries(): FilterEntry[];
203
- uniqueValues(): string[];
204
- filteredUniqueEntries(): FilterEntry[];
205
- toggleValue(val: string, checked: boolean): void;
195
+ uniqueEntries(): DistinctValueEntry[];
196
+ hasBlanks(): boolean;
197
+ filteredUniqueEntries(): DistinctValueEntry[];
198
+ toggleValue(label: string, checked: boolean): void;
206
199
  selectAll(): void;
207
200
  deselectAll(): void;
208
201
  onTextOperatorChange(index: number, value: string): void;
@@ -222,7 +215,7 @@ declare class FilterPopupComponent implements AfterViewInit, OnDestroy {
222
215
  private repositionRafId;
223
216
  private onWindowScrollOrResize;
224
217
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FilterPopupComponent, never>;
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>;
218
+ 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; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "apply": "apply"; "close": "close"; }, never, never, true, never>;
226
219
  }
227
220
 
228
221
  interface ActiveFilterPopup {
@@ -236,6 +229,7 @@ declare class GridOverlaysComponent {
236
229
  filterPopup: _angular_core.InputSignal<ActiveFilterPopup>;
237
230
  isLoading: _angular_core.InputSignal<boolean>;
238
231
  errorMessage: _angular_core.InputSignal<string>;
232
+ labels: _angular_core.InputSignal<GridLabels>;
239
233
  headerHeight: _angular_core.InputSignal<number>;
240
234
  rowHeight: _angular_core.InputSignal<number>;
241
235
  dragState: _angular_core.InputSignal<DragState>;
@@ -249,6 +243,7 @@ declare class GridOverlaysComponent {
249
243
  filter: ColumnFilterModel | null;
250
244
  }>;
251
245
  filterClose: _angular_core.OutputEmitterRef<void>;
246
+ protected errorLabel(message: string): string;
252
247
  protected isResizing: _angular_core.Signal<boolean>;
253
248
  protected resizeLineLeft: _angular_core.Signal<number>;
254
249
  protected columnMove: _angular_core.Signal<_gp_grid_core.ColumnMoveDragState>;
@@ -257,7 +252,7 @@ declare class GridOverlaysComponent {
257
252
  protected columnMoveDropLeft: _angular_core.Signal<number>;
258
253
  protected rowDragGhostWidth: _angular_core.Signal<number>;
259
254
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridOverlaysComponent, never>;
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>;
255
+ 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; }; "labels": { "alias": "labels"; "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>;
261
256
  }
262
257
 
263
258
  declare class CellPeekComponent implements AfterViewInit, OnDestroy {
@@ -395,6 +390,8 @@ declare class GpGridComponent implements OnInit, AfterViewInit, OnDestroy {
395
390
  fromIndex: number;
396
391
  toIndex: number;
397
392
  }>;
393
+ labels: _angular_core.InputSignal<Partial<GridLabels>>;
394
+ protected readonly resolvedLabels: _angular_core.Signal<GridLabels>;
398
395
  protected readonly vm: GpGridViewModel;
399
396
  private readonly bindings;
400
397
  constructor();
@@ -433,7 +430,7 @@ declare class GpGridComponent implements OnInit, AfterViewInit, OnDestroy {
433
430
  private onDocumentPointerMove;
434
431
  private onDocumentPointerUp;
435
432
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GpGridComponent, 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>;
433
+ 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; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "onRowDragEnd": "onRowDragEnd"; "onCellValueChanged": "onCellValueChanged"; "onColumnResized": "onColumnResized"; "onColumnMoved": "onColumnMoved"; }, never, never, true, never>;
437
434
  }
438
435
 
439
436
  interface CreateGridDataOptions<TData> {