@genesislcap/grid-pro 15.35.1 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,63 +1,113 @@
1
1
  import { __awaiter, __decorate, __rest } from "tslib";
2
- import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
3
- import { ComponentUtil, Events, Grid, ModuleRegistry } from '@ag-grid-community/core';
4
- import { CsvExportModule } from '@ag-grid-community/csv-export';
5
2
  import { DatasourceDefaults } from '@genesislcap/foundation-comms';
6
- import { avoidTreeShaking, insertDocumentCSSRule, LifecycleMixin, respondToVisibility, } from '@genesislcap/foundation-utils';
7
- import { attr, DOM, observable } from '@microsoft/fast-element';
3
+ import { avoidTreeShaking, LifecycleMixin, respondToVisibility, } from '@genesislcap/foundation-utils';
4
+ import { baseLayerLuminance, StandardLuminance } from '@microsoft/fast-components';
5
+ import { attr, css, DOM, observable } from '@microsoft/fast-element';
8
6
  import { FoundationElement } from '@microsoft/fast-foundation';
9
- import { classNames } from '@microsoft/fast-web-utilities';
7
+ import { CellApiModule, CellStyleModule, CheckboxEditorModule, ClientSideRowModelApiModule, ClientSideRowModelModule, ColumnApiModule, ColumnAutoSizeModule, createGrid, CsvExportModule, CustomEditorModule, CustomFilterModule, DateEditorModule, DateFilterModule, DragAndDropModule, EventApiModule, HighlightChangesModule, InfiniteRowModelModule, ModuleRegistry, NumberEditorModule, NumberFilterModule, PaginationModule, RenderApiModule, RowApiModule, RowDragModule, RowSelectionModule, RowStyleModule, SelectEditorModule, TextEditorModule, TextFilterModule, TooltipModule, _ColumnMoveModule as ColumnMoveModule, } from 'ag-grid-community';
10
8
  import * as changeCase from 'change-case';
11
9
  import debounce from 'lodash.debounce';
12
10
  import { GridProCell } from './cell';
13
11
  import { DateEditor, MultiselectEditor, NumberEditor, SelectEditor, StringEditor, } from './cell-editors';
14
12
  import { ActionRenderer, ActionsMenuRenderer, BooleanRenderer, EditableRenderer, IconRenderer, SelectRenderer, StatusPillRenderer, } from './cell-renderers';
15
13
  import { GridProColumn, resolveVisibleColumnFields } from './column';
16
- import { GridProClientSideDatasource, GridProServerSideDatasource } from './datasource';
14
+ import { EnumColumnFilter, EnumColumnFloatingFilter, GridProFilterTypes } from './column-filters';
15
+ import { ColumnSelection, gridProColumnSelectionHostStyles } from './column-selection';
16
+ import { GRID_PRO_COLUMN_DRAG_BRIDGE_CONTEXT_KEY, gridProColumnDragBridgeModule, } from './column-selection/grid-pro-column-drag-bridge';
17
+ import { GridProClientSideDatasource, GridProInfiniteDatasource, GridProServerSideDatasource, } from './datasource';
17
18
  import { baseDatasourceEventNames } from './datasource/base.types';
18
- import { agThemeFontFaceMap, defaultAgGridFontFace } from './external';
19
+ import { errorHandlerDialogStyles } from './datasource/error-handler.dialog';
19
20
  import { GridProGenesisDatasource, gridProGenesisDatasourceEventNames, } from './grid-pro-genesis-datasource';
20
21
  import { datasourceEventNames, } from './grid-pro-genesis-datasource/datasource-events.types';
21
- import { AG_PROPERTIES, copyAttributesToGridOptions, DEBOUNCED_RESIZE_TIME, gridProErrorNames, gridProEventNames, } from './grid-pro.definitions';
22
- import { foundationGridProStyles as styles } from './grid-pro.styles';
22
+ import { AG_PROPERTIES, copyAttributesToGridOptions, DEBOUNCED_RESIZE_TIME, defaultGridProConfig, foundationGridProShadowOptions, gridProErrorNames, gridProEventNames, } from './grid-pro.definitions';
23
+ import { agDragGhostShadowDomStyles, rowMatchAlertStyles } from './grid-pro.styles';
23
24
  import { gridProTemplate as template } from './grid-pro.template';
24
- import { AgGridTheme, agThemeFontsId, agThemeTokenMapClassname, DEFAULT_STATUS_BAR_CONFIG, EDITED_COLUMN_FIELD, ERROR_COLUMN_FIELD, GRID_READY_EVENT, GridOptionsConfig, GridProRendererTypes, GridProStatusBarTypes, } from './grid-pro.types';
25
+ import { DEFAULT_STATUS_BAR_CONFIG, EDITED_COLUMN_FIELD, ERROR_COLUMN_FIELD, GRID_READY_EVENT, GridOptionsConfig, GridProRendererTypes, GridProStatusBarTypes, } from './grid-pro.types';
25
26
  import { StatePersistence } from './state-persistence';
26
27
  import { LabelValueStatusBarComponent, LoadMoreStatusBarComponent, ReloadStatusBarComponent, RowCountStatusBarComponent, } from './status-bar-components';
27
28
  import { ErrorTooltip } from './tooltips';
28
- import { convertColDefsToColumnStates, convertToKebabCase, logger, mergeAndDedupColDefWithColumnState, sanitizeColumnState, } from './utils';
29
- avoidTreeShaking(GridProGenesisDatasource, GridProClientSideDatasource, GridProServerSideDatasource, GridProCell, GridProColumn);
30
- ModuleRegistry.registerModules([CsvExportModule, ClientSideRowModelModule]);
29
+ import { convertToKebabCase, logger, mergeAndDedupColDefWithColumnState, sanitizeColumnState, } from './utils';
30
+ avoidTreeShaking(GridProGenesisDatasource, GridProClientSideDatasource, GridProServerSideDatasource, GridProInfiniteDatasource, GridProCell, GridProColumn, ColumnSelection);
31
+ ModuleRegistry.registerModules([
32
+ CsvExportModule,
33
+ ClientSideRowModelModule,
34
+ PaginationModule,
35
+ RowStyleModule,
36
+ ClientSideRowModelApiModule,
37
+ EventApiModule,
38
+ TextFilterModule,
39
+ HighlightChangesModule,
40
+ ColumnApiModule,
41
+ // `gridApi.getCellValue` (used by consumers that read edited rows back, e.g. entity-management)
42
+ CellApiModule,
43
+ NumberFilterModule,
44
+ CellStyleModule,
45
+ DateFilterModule,
46
+ RowApiModule,
47
+ TooltipModule,
48
+ ColumnAutoSizeModule,
49
+ RenderApiModule,
50
+ RowDragModule,
51
+ RowSelectionModule,
52
+ CustomEditorModule,
53
+ TextEditorModule,
54
+ NumberEditorModule,
55
+ DateEditorModule,
56
+ SelectEditorModule,
57
+ CheckboxEditorModule,
58
+ CustomFilterModule,
59
+ InfiniteRowModelModule,
60
+ DragAndDropModule,
61
+ ColumnMoveModule,
62
+ gridProColumnDragBridgeModule,
63
+ // ValidationModule,
64
+ ]);
31
65
  const DEBOUNCE_TIME = 400;
32
- // Re-export AG_PROPERTIES from definitions for backwards compatibility
33
- export { AG_PROPERTIES };
66
+ const Events = {
67
+ EVENT_GRID_READY: 'gridReady',
68
+ };
69
+ /**
70
+ * Finds `key`'s accessor among the component's own prototypes.
71
+ * @remarks Own properties are skipped because the caller installs one: `connectedCallback` can run
72
+ * more than once, and starting from the instance would wrap the accessor it defined last time. The
73
+ * walk stops at `HTMLElement` so that a property merely sharing a name with a native one (such as
74
+ * `tabIndex`) is left alone instead of picking up DOM semantics through the caller.
75
+ * @internal
76
+ */
77
+ function findDeclaredAccessor(target, key) {
78
+ let proto = Object.getPrototypeOf(target);
79
+ while (proto && proto !== HTMLElement.prototype) {
80
+ const descriptor = Object.getOwnPropertyDescriptor(proto, key);
81
+ if (descriptor)
82
+ return descriptor;
83
+ proto = Object.getPrototypeOf(proto);
84
+ }
85
+ return undefined;
86
+ }
34
87
  /**
35
- * The Grid Pro element.
88
+ * The Grid Pro element (AG Grid v36 compatible).
36
89
  * @remarks Grid Pro is a Web Component wrapper around the AG Grid Community library.
37
90
  * @public
38
91
  * @tagname %%prefix%%-grid-pro
39
92
  *
40
- * @fires gridReady - Fired when AG Grid is ready (detail includes the grid-ready event and grid id)
41
- * @fires onGridReady - Deprecated alias for the grid-ready signal; prefer `gridReady`
93
+ * @fires gridReady - Fired when AG Grid is ready (detail includes the grid-ready event and grid id). detail: `GridReadyEventDetail`
94
+ * @fires onGridReady - Deprecated alias for the grid-ready signal; prefer `gridReady`. detail: `GridReadyEventDetail`
42
95
  * @fires gridready - Native `Event` from `globalEventListener` when AG Grid fires `gridReady` (`agGridDetails` holds the AG Grid event)
43
- * @remarks Re-emits AG Grid public API events when listeners are registered via `addEventListener` (event names match `ComponentUtil.PUBLIC_EVENTS` from `@ag-grid-community/core`). The same AG Grid events are also dispatched as native `Event`s with lowercased `type` and payload on `agGridDetails` (for example `addEventListener('columnresized', ...)`).
96
+ * @remarks Re-emits AG Grid public API events when listeners are registered via `addEventListener` (event names match AG Grid public event strings). The same AG Grid events are also dispatched as native `Event`s with lowercased `type` and payload on `agGridDetails` (for example `addEventListener('columnresized', ...)`).
44
97
  */
45
98
  export class GridPro extends LifecycleMixin(FoundationElement) {
99
+ /** @internal Shared AG column-drag bridge for custom tool panels. */
100
+ getColumnDragBridge() {
101
+ return this.columnDragBridge;
102
+ }
46
103
  rowDataChanged(_, rowData) {
47
- // `initialised` flips true before `gridApi` is assigned (mid-reinit), so relying on it
48
- // alone here can crash setRowData with an undefined api.
104
+ // `initialised` flips true right after createGrid(), but `gridApi` is only assigned in the
105
+ // async onGridReady callback — so a binding push in that window would crash on an undefined
106
+ // api. Skipping is lossless: onGridReady applies `this.rowData` itself once the api exists,
107
+ // and FAST has already stored the new value on the instance before calling this handler.
49
108
  if (this.initialised && this.gridApi) {
50
- this.gridApi.setRowData(rowData);
51
- }
52
- }
53
- themeChanged(oldValue, newValue) {
54
- if (!newValue) {
55
- this.classNames = '';
56
- this.destroyFontFace();
57
- return;
109
+ this.gridApi.setGridOption('rowData', rowData);
58
110
  }
59
- this.classNames = classNames(agThemeTokenMapClassname(newValue), newValue);
60
- this.insertFontFace(newValue);
61
111
  }
62
112
  /**
63
113
  * The slot ref binds asynchronously, and the queued `initGrid` skips any run that beats it. FAST
@@ -73,6 +123,9 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
73
123
  this.initGrid();
74
124
  }
75
125
  }
126
+ enableColumnSelectionChanged() {
127
+ this.syncColumnSelectionHostLayout();
128
+ }
76
129
  getfilterModel() {
77
130
  return __awaiter(this, void 0, void 0, function* () {
78
131
  if (!this.persistFilterModelKey) {
@@ -93,9 +146,6 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
93
146
  }
94
147
  constructor() {
95
148
  super();
96
- // Cache for total column width to avoid repeated calculations
97
- this.cachedTotalColumnWidth = null;
98
- this.columnCount = 0;
99
149
  this.gridErrorItems = [];
100
150
  this.disposed = false;
101
151
  this.debouncedSaveColumnState = debounce(this.saveColumnState.bind(this), DEBOUNCE_TIME);
@@ -106,64 +156,24 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
106
156
  // Genesis-specific attrs
107
157
  this.autoCellRendererByType = false;
108
158
  this.onlyTemplateColDefs = false;
109
- // AG-specific attrs
110
159
  /**
111
160
  * Boolean attribute to control whether the grid autosizes the columns upon interaction.
112
161
  * This will disable the column widths from being manually set, and doesn't save the widths
113
162
  * in local storage if you are using `persist-column-state-key`.
114
163
  */
115
164
  this.gridAutosizingEnabled = false;
116
- /**
117
- * Boolean attribute to control whether the grid automatically sizes columns to fit their content.
118
- * This will call AG Grid's autoSizeColumns() method to automatically adjust column widths based on content.
119
- * @public
120
- */
121
- this.sizeColumnsToContent = false;
122
- /**
123
- * Boolean attribute to adjust the size of columns to fit the available horizontal space.
124
- * This will call AG Grid's sizeColumnsToFit() method.
125
- * @public
126
- */
127
- this.sizeColumnsToFit = false;
128
- /**
129
- * The index to add new rows to when using `applyTransaction` or `applyTransactionAsync`
130
- */
131
- this.addIndex = 0;
132
- /**
133
- * Whether to use the `applyTransactionAsync` function for *add* transactions
134
- * @remarks Defaults to false
135
- */
136
- this.asyncAdd = false;
137
- /**
138
- * Whether to use the `applyTransactionAsync` function for *remove* transactions
139
- * @remarks Defaults to false
140
- */
141
- this.asyncRemove = false;
142
- /**
143
- * Whether to use the `applyTransactionAsync` function for *update* transactions
144
- * @remarks Defaults to true
145
- */
146
- this.asyncUpdate = true;
147
165
  /**
148
166
  * If false, will disable cell flashing for all cells by default, unless otherwise defined in custom colDef
149
167
  * @remarks Defaults to true
150
168
  */
151
169
  this.enableCellFlashing = false;
152
- /**
153
- * @deprecated - use `enableRowFlashing` instead.
154
- */
155
- this.enabledRowFlashing = false;
156
170
  /**
157
171
  * If true, will enable row flashing for all rows for `add` async transactions
158
172
  */
159
173
  this.enableRowFlashing = false;
160
- /**
161
- * The default column config to reset to when deleteColumnState is called.
162
- */
163
- this.defaultColumnConfig = [];
164
- this.gridFontFace = defaultAgGridFontFace;
174
+ /** Wired to `gridOptions.context` for columns picker → grid drag (see bridge module). */
175
+ this.columnDragBridge = {};
165
176
  this.columnComponentName = 'grid-pro-column';
166
- this.theme = AgGridTheme.alpine;
167
177
  this.themeMode = 'dark';
168
178
  /**
169
179
  * Configuration for the grid status bar components.
@@ -181,14 +191,27 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
181
191
  * This requires AG Grid Enterprise module to be available for the status bar to be displayed when enabled.
182
192
  */
183
193
  this.withStatusBar = false;
194
+ /**
195
+ * Shows a Column Selection button above the grid.
196
+ * @public
197
+ */
198
+ this.enableColumnSelection = false;
184
199
  this.applyingDatasourceGridOptions = false;
185
200
  this.rehydrationAttempted = false;
186
- this.eventHandlers = [];
201
+ this.rootEventsListeners = [];
202
+ this.datasourceEventHandlers = [];
187
203
  this.gridEventsQueue = [];
188
204
  this.registeredGridEvents = new Set();
189
205
  this.gridEventListeners = new Map();
190
206
  this.boundGlobalEventListener = this.globalEventListener.bind(this);
191
207
  this._filterConfig = undefined;
208
+ this.handleLuminanceChange = (record) => {
209
+ const luminance = baseLayerLuminance.getValueFor(record.target);
210
+ this.themeMode = luminance === StandardLuminance.DarkMode ? 'dark' : 'light';
211
+ };
212
+ this.luminanceObserver = {
213
+ handleChange: (record) => this.handleLuminanceChange(record),
214
+ };
192
215
  this.agAttributes = {};
193
216
  this.agPropertiesMap = AG_PROPERTIES.reduce((map, property) => {
194
217
  map[property.toLowerCase()] = property;
@@ -196,28 +219,65 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
196
219
  return map;
197
220
  }, {});
198
221
  const hideDataSourceError = this.hideDatasourceError.bind(this);
199
- // Bind all event handlers once to ensure proper add/remove of listeners
200
- this.eventHandlers.push(
201
- // Root event listeners
202
- [gridProGenesisDatasourceEventNames.dataInit, hideDataSourceError], [gridProEventNames.datasourceErrorClose, hideDataSourceError], [baseDatasourceEventNames.error, this.handleBaseDatasourceError.bind(this)], [baseDatasourceEventNames.connected, hideDataSourceError],
203
- // Datasource event listeners
204
- [datasourceEventNames.initialize, this.handleInitialize.bind(this)], [datasourceEventNames.dataLoaded, this.handleDataLoaded.bind(this)], [datasourceEventNames.dataChanged, this.handleDataChanged.bind(this)], [datasourceEventNames.schemaUpdated, this.handleSchemaUpdated.bind(this)], [datasourceEventNames.dataCleared, this.handleDataCleared.bind(this)], [datasourceEventNames.loadingStarted, this.handleLoadingStarted.bind(this)], [datasourceEventNames.loadingFinished, this.handleLoadingFinished.bind(this)], [datasourceEventNames.noDataAvailable, this.handleNoDataAvailable.bind(this)], [datasourceEventNames.filtersRestored, this.handleFiltersRestored.bind(this)], [datasourceEventNames.moreDataAvailable, this.handleMoreDataAvailable.bind(this)], [datasourceEventNames.error, this.handleDatasourceError.bind(this)], [datasourceEventNames.destroy, this.handleDatasourceDestroy.bind(this)],
205
- // Server-side specific events
206
- [datasourceEventNames.cacheFilterConfig, this.cacheFilterConfig.bind(this)], [datasourceEventNames.refreshServerSide, this.handleRefreshServerSide.bind(this)], [datasourceEventNames.setServerSideDatasource, this.handleSetServerSideDatasource.bind(this)], [datasourceEventNames.addGridCssClass, this.handleAddGridCssClass.bind(this)], [datasourceEventNames.removeGridCssClass, this.handleRemoveGridCssClass.bind(this)], [
207
- datasourceEventNames.applyServerSideTransaction,
208
- this.handleApplyServerSideTransaction.bind(this),
209
- ],
210
- // Infinite Row Model events: not supported by this legacy grid (it registers neither the
211
- // module nor the handlers). Fail loudly rather than leaving a silently empty grid.
212
- [datasourceEventNames.setInfiniteDatasource, this.refuseInfiniteDatasource.bind(this)]);
213
- }
214
- /**
215
- * The Infinite Row Model is only wired into the beta grid, so an infinite datasource placed
216
- * inside this element can never load data. Report it instead of ignoring the event.
217
- * @internal
218
- */
219
- refuseInfiniteDatasource() {
220
- logger.error('grid-pro does not support the Infinite Row Model; use the beta grid (GridProBeta) with grid-pro-infinite-datasource / datasource-type="infinite".');
222
+ this.rootEventsListeners.push([gridProGenesisDatasourceEventNames.dataInit, hideDataSourceError], [gridProEventNames.datasourceErrorClose, hideDataSourceError],
223
+ // Base datasource error handling for resource validation and initialization errors
224
+ [baseDatasourceEventNames.error, this.handleBaseDatasourceError.bind(this)], [baseDatasourceEventNames.connected, hideDataSourceError]);
225
+ this.datasourceEventHandlers = [
226
+ [datasourceEventNames.initialize, this.handleInitialize.bind(this)],
227
+ [datasourceEventNames.dataLoaded, this.handleDataLoaded.bind(this)],
228
+ [datasourceEventNames.dataChanged, this.handleDataChanged.bind(this)],
229
+ [datasourceEventNames.schemaUpdated, this.handleSchemaUpdated.bind(this)],
230
+ [datasourceEventNames.dataCleared, this.handleDataCleared.bind(this)],
231
+ [datasourceEventNames.loadingStarted, this.handleLoadingStarted.bind(this)],
232
+ [
233
+ datasourceEventNames.loadingFinished,
234
+ this.handleLoadingFinished.bind(this),
235
+ ],
236
+ [
237
+ datasourceEventNames.noDataAvailable,
238
+ this.handleNoDataAvailable.bind(this),
239
+ ],
240
+ [
241
+ datasourceEventNames.filtersRestored,
242
+ this.handleFiltersRestored.bind(this),
243
+ ],
244
+ [
245
+ datasourceEventNames.moreDataAvailable,
246
+ this.handleMoreDataAvailable.bind(this),
247
+ ],
248
+ [datasourceEventNames.error, this.handleDatasourceError.bind(this)],
249
+ [datasourceEventNames.destroy, this.handleDatasourceDestroy.bind(this)],
250
+ [datasourceEventNames.cacheFilterConfig, this.cacheFilterConfig.bind(this)],
251
+ [
252
+ datasourceEventNames.refreshServerSide,
253
+ this.handleRefreshServerSide.bind(this),
254
+ ],
255
+ [
256
+ datasourceEventNames.setServerSideDatasource,
257
+ this.handleSetServerSideDatasource.bind(this),
258
+ ],
259
+ [
260
+ datasourceEventNames.addGridCssClass,
261
+ this.handleAddGridCssClass.bind(this),
262
+ ],
263
+ [
264
+ datasourceEventNames.removeGridCssClass,
265
+ this.handleRemoveGridCssClass.bind(this),
266
+ ],
267
+ [
268
+ datasourceEventNames.applyServerSideTransaction,
269
+ this.handleApplyServerSideTransaction.bind(this),
270
+ ],
271
+ // Infinite Row Model specific events
272
+ [
273
+ datasourceEventNames.setInfiniteDatasource,
274
+ this.handleSetInfiniteDatasource.bind(this),
275
+ ],
276
+ [
277
+ datasourceEventNames.refreshInfiniteCache,
278
+ this.handleRefreshInfiniteCache.bind(this),
279
+ ],
280
+ ];
221
281
  }
222
282
  /**
223
283
  * Adds an event listener to the grid element.
@@ -229,14 +289,12 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
229
289
  */
230
290
  addEventListener(eventType, listener, options) {
231
291
  super.addEventListener(eventType, listener, options);
232
- if (ComponentUtil.PUBLIC_EVENTS.includes(eventType)) {
233
- if (this.gridApi) {
234
- this.addGridEventListener(eventType);
235
- }
236
- else {
237
- if (!this.gridEventsQueue.includes(eventType)) {
238
- this.gridEventsQueue.push(eventType);
239
- }
292
+ if (this.gridApi) {
293
+ this.addGridEventListener(eventType);
294
+ }
295
+ else {
296
+ if (!this.gridEventsQueue.includes(eventType)) {
297
+ this.gridEventsQueue.push(eventType);
240
298
  }
241
299
  }
242
300
  }
@@ -270,8 +328,12 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
270
328
  this.removeAttribute('ds-disconnected');
271
329
  }
272
330
  connectedCallback() {
331
+ var _a;
273
332
  super.connectedCallback();
333
+ this.syncColumnSelectionHostLayout();
274
334
  this.disposed = false;
335
+ const luminanceTarget = (_a = this.provider) !== null && _a !== void 0 ? _a : this;
336
+ this.luminanceSubscription = baseLayerLuminance.subscribe(this.luminanceObserver, luminanceTarget);
275
337
  if (this.gridAutosizingEnabled) {
276
338
  this.visibilityObserverCleanup = respondToVisibility(this, (gridVisible) => {
277
339
  if (gridVisible) {
@@ -280,25 +342,44 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
280
342
  });
281
343
  }
282
344
  this.rehydrationAttempted = false;
283
- this.eventHandlers.forEach(([eventName, handler]) => {
284
- this.addEventListener(eventName, handler);
285
- });
286
345
  if (!this.shouldRunConnect)
287
346
  return;
347
+ this.rootEventsListeners.forEach(([eventName, handler]) => {
348
+ this.addEventListener(eventName, handler);
349
+ });
350
+ // Property reflection for AG Grid properties, so `grid.rowHeight = 40` reaches AG.
351
+ // A few of these keys are also declared on the component as `@attr` (`headerHeight`,
352
+ // `rowHeight`), and FAST installs their accessors on the prototype. This shadows those, so
353
+ // delegate reads and writes to the accessor being covered up — a getter-less own property here
354
+ // would leave the declared attribute unreadable.
288
355
  AG_PROPERTIES.forEach((key) => {
356
+ const declared = findDeclaredAccessor(this, key);
289
357
  Object.defineProperty(this, key, {
358
+ get: declared === null || declared === void 0 ? void 0 : declared.get,
290
359
  set: (v) => {
291
- this.agAttributeChangedCallback(convertToKebabCase(key), undefined, v);
360
+ var _a, _b;
361
+ const previous = (_a = declared === null || declared === void 0 ? void 0 : declared.get) === null || _a === void 0 ? void 0 : _a.call(this);
362
+ (_b = declared === null || declared === void 0 ? void 0 : declared.set) === null || _b === void 0 ? void 0 : _b.call(this, v);
363
+ this.agAttributeChangedCallback(convertToKebabCase(key), previous, v);
292
364
  },
293
365
  enumerable: true,
294
366
  configurable: true,
295
367
  });
296
368
  });
369
+ // Add datasource event listeners
370
+ this.toggleDatasourceEventListeners(true);
297
371
  }
298
372
  disconnectedCallback() {
373
+ var _a;
299
374
  this.disposed = true;
300
375
  this.debouncedSaveColumnState.cancel();
301
376
  this.debouncedSaveFilterModel.cancel();
377
+ const luminanceTarget = (_a = this.provider) !== null && _a !== void 0 ? _a : this;
378
+ baseLayerLuminance.unsubscribe(this.luminanceObserver, luminanceTarget);
379
+ if (this.luminanceSubscription) {
380
+ this.luminanceSubscription.unsubscribe();
381
+ this.luminanceSubscription = undefined;
382
+ }
302
383
  if (this.visibilityObserverCleanup) {
303
384
  this.visibilityObserverCleanup();
304
385
  this.visibilityObserverCleanup = undefined;
@@ -306,12 +387,10 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
306
387
  super.disconnectedCallback();
307
388
  this.rehydrationAttempted = false;
308
389
  const shouldRunDisconnect = this.shouldRunDisconnect;
309
- this.eventHandlers.forEach(([eventName, handler]) => {
390
+ this.rootEventsListeners.forEach(([eventName, handler]) => {
310
391
  this.removeEventListener(eventName, handler);
311
392
  });
312
393
  if (!shouldRunDisconnect) {
313
- // If lifecycle is temporarily blocked (e.g. layout drag/reconnect path),
314
- // still tear down once the element remains detached on the next tick.
315
394
  queueMicrotask(() => {
316
395
  if (!this.isConnected) {
317
396
  this.performDisconnectCleanup();
@@ -321,6 +400,9 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
321
400
  }
322
401
  this.performDisconnectCleanup();
323
402
  }
403
+ syncColumnSelectionHostLayout() {
404
+ this.classList.toggle('has-column-selection', this.enableColumnSelection);
405
+ }
324
406
  performDisconnectCleanup() {
325
407
  if (this.debounced) {
326
408
  clearTimeout(this.debounced);
@@ -329,21 +411,19 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
329
411
  this.initialised = false;
330
412
  this.resetGridOptionsState();
331
413
  this.destroyGridInstance();
414
+ // Only remove datasource listeners on a real teardown. A blocked (reflow) disconnect must
415
+ // leave them in place, or a grid that survives the reflow stops reacting to datasource
416
+ // events (loading/no-rows overlays never update).
417
+ this.toggleDatasourceEventListeners(false);
332
418
  // Destroy can synchronously emit final grid events; cancel again to avoid
333
419
  // retaining this element through trailing debounce timers.
334
420
  this.debouncedSaveColumnState.cancel();
335
421
  this.debouncedSaveFilterModel.cancel();
336
- this.invalidateColumnWidthCache();
337
422
  // Clear registered events when grid is destroyed
338
423
  this.registeredGridEvents.clear();
339
424
  this.gridEventsQueue = [];
340
425
  }
341
- /**
342
- * Tear down the AG Grid instance. Prefer {@link GridApi#destroy}; if `gridApi` is not set yet
343
- * (e.g. disconnect before `grid-ready`), fall back to {@link Grid#destroy} on the vanilla wrapper.
344
- */
345
426
  destroyGridInstance() {
346
- var _a, _b;
347
427
  if (this.gridApi) {
348
428
  this.gridEventListeners.forEach((listener, eventType) => {
349
429
  this.gridApi.removeEventListener(eventType, listener);
@@ -351,46 +431,42 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
351
431
  }
352
432
  this.gridEventListeners.clear();
353
433
  if (this.gridApi) {
354
- // AG Grid's destroy() leaves the client-side row model populated and leaves
355
- // scroll/touch listeners on its detached DOM; since the unmounted view is cached
356
- // by FAST's `when`, the destroyed grid skeleton stays reachable and would retain
357
- // the entire dataset. Clear rows first so only the small skeleton can be retained.
358
- if (!this.isServerSide) {
359
- try {
360
- (_b = (_a = this.gridApi).flushAsyncTransactions) === null || _b === void 0 ? void 0 : _b.call(_a);
361
- this.gridApi.setRowData([]);
362
- }
363
- catch (e) {
364
- logger.debug('Grid Pro: failed to clear row data before destroy', e);
365
- }
366
- }
367
434
  this.gridApi.destroy();
368
435
  }
369
436
  else if (this.agGrid) {
370
437
  this.agGrid.destroy();
371
438
  }
372
439
  if (this.gridSlot) {
440
+ // Ensure AG Grid internal measurement/theme nodes are removed immediately.
373
441
  this.gridSlot.replaceChildren();
374
442
  }
375
443
  this.gridApi = undefined;
376
- this.columnApi = undefined;
377
444
  this.agGrid = undefined;
378
445
  }
446
+ /**
447
+ * Helper method to add or remove datasource event listeners
448
+ * @internal
449
+ */
450
+ toggleDatasourceEventListeners(add) {
451
+ const method = add ? 'addEventListener' : 'removeEventListener';
452
+ this.datasourceEventHandlers.forEach(([eventName, handler]) => {
453
+ // Bypass GridPro.addEventListener override: datasource events should not be
454
+ // mirrored/queued as AG Grid API events.
455
+ super[method](eventName, handler);
456
+ });
457
+ }
379
458
  /**
380
459
  * Handles datasource initialization
381
460
  * @internal
382
461
  */
383
462
  handleInitialize(event) {
384
463
  const { options, keepColDefsOnClearRowData } = event.detail;
385
- let columnDefinitions;
386
464
  if (keepColDefsOnClearRowData) {
387
- columnDefinitions = this.gridApi.getColumnDefs();
388
- this.columnState = this.columnApi.getColumnState();
465
+ this.columnState = this.gridApi.getColumnState();
389
466
  }
390
- const gridOptions = Object.assign(Object.assign(Object.assign({}, this.userProvidedGridOptions), (columnDefinitions && { columnDefs: columnDefinitions })), options);
391
467
  this.applyingDatasourceGridOptions = true;
392
468
  try {
393
- this.gridOptions = Object.assign({}, gridOptions);
469
+ this.gridOptions = Object.assign(Object.assign(Object.assign({}, this.userProvidedGridOptions), options), (keepColDefsOnClearRowData ? { columnDefs: this.gridApi.getColumnDefs() } : {}));
394
470
  this.initGrid();
395
471
  }
396
472
  finally {
@@ -404,7 +480,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
404
480
  handleDataLoaded(event) {
405
481
  const { data } = event.detail;
406
482
  if (this.gridApi) {
407
- this.gridApi.setRowData(data);
483
+ this.gridApi.setGridOption('rowData', data);
408
484
  }
409
485
  }
410
486
  /**
@@ -412,40 +488,25 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
412
488
  * @internal
413
489
  */
414
490
  handleDataChanged(event) {
415
- var _a, _b, _c;
416
491
  const { changes } = event.detail;
417
- // Every datasource emits this for consumers, but row transactions are a client-side row
418
- // model API: the server-side datasource drives the grid through apply-server-side-transaction,
419
- // and applyTransaction on that model is a no-op that logs an AG Grid warning per event.
420
- if (!this.gridApi || this.isServerSide)
492
+ // Every datasource emits this for consumers, but only the client-side row model takes row
493
+ // transactions: the infinite and server-side datasources drive the grid through
494
+ // refresh-infinite-cache / apply-server-side-transaction, and applyTransaction on those
495
+ // models is a no-op that logs an AG Grid warning per event.
496
+ if (!this.gridApi || !this.isClientSideRowModel)
421
497
  return;
422
- if (((_a = changes.add) === null || _a === void 0 ? void 0 : _a.length) > 0) {
423
- if (this.asyncAdd) {
424
- this.gridApi.applyTransactionAsync({ add: changes.add, addIndex: this.addIndex }, (result) => {
425
- this.flashAddedCells(result === null || result === void 0 ? void 0 : result.add);
426
- });
427
- }
428
- else {
429
- const result = this.gridApi.applyTransaction({ add: changes.add, addIndex: this.addIndex });
430
- this.flashAddedCells(result === null || result === void 0 ? void 0 : result.add);
431
- }
432
- }
433
- if (((_b = changes.update) === null || _b === void 0 ? void 0 : _b.length) > 0) {
434
- if (this.asyncUpdate) {
435
- this.gridApi.applyTransactionAsync({ update: changes.update });
436
- }
437
- else {
438
- this.gridApi.applyTransaction({ update: changes.update });
439
- }
440
- }
441
- if (((_c = changes.remove) === null || _c === void 0 ? void 0 : _c.length) > 0) {
442
- if (this.asyncRemove) {
443
- this.gridApi.applyTransactionAsync({ remove: changes.remove });
444
- }
445
- else {
446
- this.gridApi.applyTransaction({ remove: changes.remove });
447
- }
448
- }
498
+ const result = this.gridApi.applyTransaction(changes);
499
+ this.flashAddedCells(result === null || result === void 0 ? void 0 : result.add);
500
+ }
501
+ /**
502
+ * Whether the live grid runs AG Grid's client-side row model (the default when the datasource
503
+ * set no `rowModelType`).
504
+ * @internal
505
+ */
506
+ get isClientSideRowModel() {
507
+ var _a, _b, _c;
508
+ const rowModelType = (_c = (_b = (_a = this.gridApi) === null || _a === void 0 ? void 0 : _a.getGridOption) === null || _b === void 0 ? void 0 : _b.call(_a, 'rowModelType')) !== null && _c !== void 0 ? _c : 'clientSide';
509
+ return rowModelType === 'clientSide';
449
510
  }
450
511
  flashAddedCells(rowNodes) {
451
512
  if (this.enableRowFlashing && (rowNodes === null || rowNodes === void 0 ? void 0 : rowNodes.length)) {
@@ -458,8 +519,10 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
458
519
  */
459
520
  handleSchemaUpdated(event) {
460
521
  return __awaiter(this, void 0, void 0, function* () {
461
- // Can fire before `gridApi` is ready (mid-reinit). Unlike agAttributes/rowData, the schema
462
- // has no other home on the instance, so stash it and replay it in `onGridReady`.
522
+ // Can fire before `gridApi` is ready (mid-reinit). Unlike rowData — which onGridReady
523
+ // re-applies from `this.rowData` — the schema has no other home on the instance, so
524
+ // returning here used to drop it silently and leave the grid with no columns. Stash it
525
+ // and replay in onGridReady.
463
526
  if (!this.gridApi) {
464
527
  this.pendingSchemaUpdate = event.detail;
465
528
  return;
@@ -468,44 +531,81 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
468
531
  });
469
532
  }
470
533
  /**
471
- * Builds and applies column defs from a schema/metadata payload.
534
+ * Builds and applies column defs from a schema payload.
472
535
  * @internal
473
536
  */
474
537
  processSchemaUpdate(_a) {
475
- return __awaiter(this, arguments, void 0, function* ({ schema, metadata }) {
538
+ return __awaiter(this, arguments, void 0, function* ({ schema }) {
539
+ // Only auto-generate columns from the datasource schema when the consumer has NOT already
540
+ // supplied their own column defs (e.g. via `gridOptions`/`deferredGridOptions.columnDefs` or
541
+ // `grid-pro-column` templates). Overwriting here would discard user-provided definitions —
542
+ // including `ColGroupDef` group structure and custom header names — and replace them with flat
543
+ // metadata columns. This mirrors the legacy `GridProLegacy` behaviour.
476
544
  const preSetColumnDefs = this.gridApi.getColumnDefs();
477
- if (!preSetColumnDefs || preSetColumnDefs.length === 0) {
478
- const colDefs = metadata
479
- .map((field) => {
480
- var _a;
481
- return (Object.assign(Object.assign({}, schema.find((colDef) => colDef.field === field.name)), (_a = this.gridApi) === null || _a === void 0 ? void 0 : _a.getColumnDef(field.name)));
482
- })
483
- .map((colDef) => (Object.assign(Object.assign({}, colDef), { cellRenderer: this.autoCellRendererByType ? colDef.cellRenderer : undefined, cellEditor: this.autoCellRendererByType ? colDef.cellEditor : undefined })));
484
- const colDefsMergedWithTemplateDefs = yield this.mergeAllColumnDefsAndStates(colDefs, true);
485
- if (colDefsMergedWithTemplateDefs) {
486
- // AG's internals will check if group/pivot are NOT NULL to trigger module registration warning for `row-grouping`.
487
- // When using gridApi to get the currentState to save, all boolean will return false when they were not set at all.
488
- // ColDef type is `boolean` while ColumnState is `boolean | null`.
489
- // `rowGroup`/`pivot` only exist on leaf `ColDef`s, not on `ColGroupDef`s, so skip groups.
490
- colDefsMergedWithTemplateDefs.forEach((col) => {
491
- if ('children' in col) {
492
- return;
493
- }
494
- if (!col.rowGroup) {
495
- col.rowGroup = null;
496
- }
497
- if (!col.pivot) {
498
- col.pivot = null;
499
- }
500
- });
501
- this.gridApi.setColumnDefs(colDefsMergedWithTemplateDefs);
502
- // Restore the persisted filter model now that the columns exist. The datasource
503
- // emits `filtersRestored` synchronously right after `schemaUpdated`, but this handler
504
- // is async (it awaits column-state hydration before `setColumnDefs`), so the
505
- // `filtersRestored` restore can run before the columns exist and be silently dropped.
506
- // Restoring here guarantees the columns are present for `gridApi.setFilterModel`.
507
- this.restoreCachedFilterConfig();
545
+ if (preSetColumnDefs && preSetColumnDefs.length > 0) {
546
+ return;
547
+ }
548
+ this.applyCommunityFilterFallbacks(schema);
549
+ // Merge with template definitions
550
+ const mergedColumnDefs = yield this.mergeAllColumnDefsAndStates(schema, true);
551
+ this.gridApi.setGridOption('columnDefs', mergedColumnDefs);
552
+ // Restore the persisted filter model now that the columns exist. The datasource
553
+ // emits `filtersRestored` synchronously right after `schemaUpdated`, but this handler
554
+ // is async (it awaits column-state hydration before applying columnDefs), so the
555
+ // `filtersRestored` restore can run before the columns exist and be silently dropped.
556
+ // Restoring here guarantees the columns are present for `gridApi.setFilterModel`.
557
+ this.restoreCachedFilterConfig();
558
+ });
559
+ }
560
+ /**
561
+ * Downgrades enterprise filters in metadata-generated colDefs when their modules are not
562
+ * registered — from v35 AG Grid throws on unregistered filters instead of falling back.
563
+ * Enum columns (recognised by their metadata-sourced set-filter values) keep those values by
564
+ * falling back to the community `EnumColumnFilter` instead of a plain text filter.
565
+ *
566
+ * The enum floating filter is only wired as the column's component, not enabled: AG's floating
567
+ * filter is a full-width header row, so enabling it for one column changes the layout of every
568
+ * column. Active-filter state is surfaced instead by AG's native header filter icon plus the
569
+ * header tooltip the enum filter maintains; consumers wanting the floating row opt in with
570
+ * `floatingFilter: true`.
571
+ * @internal
572
+ */
573
+ applyCommunityFilterFallbacks(schema) {
574
+ const hasSetFilter = this.gridApi.isModuleRegistered('SetFilterModule');
575
+ const hasMultiFilter = this.gridApi.isModuleRegistered('MultiFilterModule');
576
+ schema.forEach((colDef) => {
577
+ var _a, _b, _c, _d, _e;
578
+ if (colDef.filter === 'agSetColumnFilter' && !hasSetFilter) {
579
+ logger.debug(`SetFilterModule is not registered; column '${colDef.field}' falls back to the enum filter`);
580
+ colDef.filter = GridProFilterTypes.enumFilter;
581
+ (_a = colDef.floatingFilterComponent) !== null && _a !== void 0 ? _a : (colDef.floatingFilterComponent = GridProFilterTypes.enumFloatingFilter);
582
+ return;
583
+ }
584
+ if (colDef.filter !== 'agMultiColumnFilter') {
585
+ return;
586
+ }
587
+ const setSubFilter = (_c = (_b = colDef.filterParams) === null || _b === void 0 ? void 0 : _b.filters) === null || _c === void 0 ? void 0 : _c.find((subFilter) => subFilter.filter === 'agSetColumnFilter');
588
+ if (!hasMultiFilter) {
589
+ if ((_d = setSubFilter === null || setSubFilter === void 0 ? void 0 : setSubFilter.filterParams) === null || _d === void 0 ? void 0 : _d.values) {
590
+ logger.debug(`MultiFilterModule is not registered; enum column '${colDef.field}' falls back to the enum filter`);
591
+ colDef.filter = GridProFilterTypes.enumFilter;
592
+ // Carry the whole sub-filter config over, not just `values` — a consumer-authored
593
+ // multi filter may also set valueFormatter, blanks, etc.
594
+ colDef.filterParams = Object.assign({}, setSubFilter.filterParams);
595
+ (_e = colDef.floatingFilterComponent) !== null && _e !== void 0 ? _e : (colDef.floatingFilterComponent = GridProFilterTypes.enumFloatingFilter);
508
596
  }
597
+ else {
598
+ logger.warn('MultiFilterModule is not registered, falling back to text filter');
599
+ colDef.filter = 'agTextColumnFilter';
600
+ }
601
+ return;
602
+ }
603
+ // The multi filter itself is available but its set sub-filter's module is not — opening
604
+ // the filter would throw AG error #256. The multi filter hosts custom child filters, so
605
+ // only the nested set filter is swapped for the enum filter (same params, same model).
606
+ if (!hasSetFilter && setSubFilter) {
607
+ logger.debug(`SetFilterModule is not registered; the set sub-filter of column '${colDef.field}' falls back to the enum filter`);
608
+ setSubFilter.filter = GridProFilterTypes.enumFilter;
509
609
  }
510
610
  });
511
611
  }
@@ -514,27 +614,18 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
514
614
  * @internal
515
615
  */
516
616
  handleDataCleared(event) {
517
- var _a, _b;
518
617
  const { includeSchema } = event.detail;
519
618
  if (!this.gridApi)
520
619
  return;
521
- // For server-side, these methods are handled via server-side transactions
522
- // Only flush async transactions for client-side row model
523
- if (!this.isServerSide) {
524
- // Flush any pending async transactions
525
- if (this.asyncAdd || this.asyncUpdate || this.asyncRemove) {
526
- (_b = (_a = this.gridApi).flushAsyncTransactions) === null || _b === void 0 ? void 0 : _b.call(_a);
527
- }
528
- }
529
620
  if (includeSchema) {
530
- this.gridApi.setColumnDefs([]);
621
+ this.gridApi.setGridOption('columnDefs', []);
531
622
  }
532
- // setRowData only works for client-side row model
533
- // For server-side, data clearing is handled via server-side transactions
534
- if (!this.isServerSide) {
535
- this.gridApi.setRowData([]);
536
- this.gridApi.refreshCells({ force: true });
623
+ // rowData belongs to the client-side row model; the infinite and server-side caches are
624
+ // cleared by their own refresh / transaction events.
625
+ if (this.isClientSideRowModel) {
626
+ this.gridApi.setGridOption('rowData', []);
537
627
  }
628
+ this.gridApi.refreshCells({ force: true });
538
629
  }
539
630
  /**
540
631
  * Handles loading started from datasource
@@ -542,7 +633,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
542
633
  */
543
634
  handleLoadingStarted() {
544
635
  if (this.gridApi) {
545
- this.gridApi.showLoadingOverlay();
636
+ this.gridApi.setGridOption('loading', true);
546
637
  }
547
638
  }
548
639
  /**
@@ -551,6 +642,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
551
642
  */
552
643
  handleLoadingFinished() {
553
644
  if (this.gridApi) {
645
+ this.gridApi.setGridOption('loading', false);
554
646
  this.gridApi.hideOverlay();
555
647
  }
556
648
  }
@@ -560,6 +652,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
560
652
  */
561
653
  handleNoDataAvailable() {
562
654
  if (this.gridApi) {
655
+ this.gridApi.setGridOption('loading', false);
563
656
  this.gridApi.showNoRowsOverlay();
564
657
  }
565
658
  }
@@ -591,8 +684,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
591
684
  * Handles datasource errors
592
685
  * @internal
593
686
  */
594
- handleDatasourceError(event) {
595
- // Set visual indicator on grid
687
+ handleDatasourceError() {
596
688
  this.setAttribute('ds-disconnected', 'ds-disconnected');
597
689
  }
598
690
  /**
@@ -619,7 +711,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
619
711
  handleSetServerSideDatasource(event) {
620
712
  const { datasource } = event.detail;
621
713
  if (this.gridApi) {
622
- this.gridApi.setServerSideDatasource(datasource);
714
+ this.gridApi.setGridOption('serverSideDatasource', datasource);
623
715
  }
624
716
  }
625
717
  /**
@@ -672,6 +764,33 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
672
764
  }
673
765
  }
674
766
  }
767
+ /**
768
+ * Handles setting infinite datasource
769
+ * @internal
770
+ */
771
+ handleSetInfiniteDatasource(event) {
772
+ const { datasource } = event.detail;
773
+ if (this.gridApi) {
774
+ this.gridApi.setGridOption('datasource', datasource);
775
+ }
776
+ }
777
+ /**
778
+ * Handles refreshing the infinite cache.
779
+ * @remarks Mirrors {@link GridPro.handleRefreshServerSide}: `purge` drops the block cache
780
+ * and re-reads, otherwise the loaded blocks are re-read in place.
781
+ * @internal
782
+ */
783
+ handleRefreshInfiniteCache(event) {
784
+ var _a;
785
+ if (!this.gridApi)
786
+ return;
787
+ if ((_a = event.detail) === null || _a === void 0 ? void 0 : _a.purge) {
788
+ this.gridApi.purgeInfiniteCache();
789
+ }
790
+ else {
791
+ this.gridApi.refreshInfiniteCache();
792
+ }
793
+ }
675
794
  combineAllGridComponents(gridOptionsComponents) {
676
795
  const defaultFoundationAgComponents = {
677
796
  [GridProRendererTypes.action]: ActionRenderer,
@@ -686,6 +805,8 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
686
805
  [GridProRendererTypes.multiselectEditor]: MultiselectEditor,
687
806
  [GridProRendererTypes.dateEditor]: DateEditor,
688
807
  [GridProRendererTypes.stringEditor]: StringEditor,
808
+ [GridProFilterTypes.enumFilter]: EnumColumnFilter,
809
+ [GridProFilterTypes.enumFloatingFilter]: EnumColumnFloatingFilter,
689
810
  [GridProStatusBarTypes.labelValue]: LabelValueStatusBarComponent,
690
811
  [GridProStatusBarTypes.loadMore]: LoadMoreStatusBarComponent,
691
812
  [GridProStatusBarTypes.reload]: ReloadStatusBarComponent,
@@ -832,7 +953,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
832
953
  saveColumnState() {
833
954
  return __awaiter(this, void 0, void 0, function* () {
834
955
  if (this.rehydrationAttempted && this.statePersistanceEnabled()) {
835
- let colState = this.columnApi.getColumnState();
956
+ let colState = this.gridApi.getColumnState();
836
957
  colState = sanitizeColumnState(colState);
837
958
  colState = this.gridAutosizingEnabled
838
959
  ? this.removeConfigWidthsToAutosize(colState)
@@ -840,7 +961,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
840
961
  const allHeadersHidden = colState.filter((c) => {
841
962
  if (c.hide)
842
963
  return false;
843
- const col = this.columnApi.getColumn(c.colId);
964
+ const col = this.gridApi.getColumn(c.colId);
844
965
  return Boolean(col.getColDef().headerName);
845
966
  }).length === 0;
846
967
  if (colState.length === 0 ||
@@ -862,40 +983,11 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
862
983
  return __awaiter(this, void 0, void 0, function* () {
863
984
  this.columnState = [];
864
985
  if (this.statePersistanceEnabled()) {
865
- this.columnState = yield this.statePersistence.getColumnState(this.persistColumnStateKey);
986
+ this.columnState = (yield this.statePersistence.getColumnState(this.persistColumnStateKey));
866
987
  }
867
988
  return this.columnState;
868
989
  });
869
990
  }
870
- /**
871
- * Deletes the saved column state for the current grid
872
- * @param resetToDefault - Whether to reset columns to their default configuration. Defaults to true.
873
- * @remarks This removes the persisted column state from storage, allowing the grid to use default column configuration
874
- * @public
875
- */
876
- deleteColumnState() {
877
- return __awaiter(this, arguments, void 0, function* (resetToDefault = true) {
878
- var _a;
879
- if (this.statePersistanceEnabled()) {
880
- yield this.statePersistence.deleteColumnState(this.persistColumnStateKey);
881
- this.columnState = [];
882
- }
883
- if (resetToDefault && this.columnApi) {
884
- if (((_a = this.defaultColumnConfig) === null || _a === void 0 ? void 0 : _a.length) > 0) {
885
- // Convert ColDef[] to ColumnState[] using utility function
886
- const columnState = convertColDefsToColumnStates(this.defaultColumnConfig);
887
- this.columnApi.applyColumnState({
888
- state: columnState,
889
- applyOrder: true,
890
- });
891
- }
892
- else {
893
- this.columnApi.resetColumnState();
894
- }
895
- this.handleColumnSizing();
896
- }
897
- });
898
- }
899
991
  restoreColumnState() {
900
992
  return __awaiter(this, void 0, void 0, function* () {
901
993
  var _a;
@@ -903,7 +995,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
903
995
  const colState = yield this.getSavedColumnState();
904
996
  const sanitizedColState = sanitizeColumnState(colState);
905
997
  if (sanitizedColState && sanitizedColState.length > 0) {
906
- (_a = this.columnApi) === null || _a === void 0 ? void 0 : _a.applyColumnState({
998
+ (_a = this.gridApi) === null || _a === void 0 ? void 0 : _a.applyColumnState({
907
999
  state: sanitizedColState,
908
1000
  applyOrder: true,
909
1001
  });
@@ -941,7 +1033,8 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
941
1033
  */
942
1034
  get gridParams() {
943
1035
  return {
944
- globalEventListener: this.boundGlobalEventListener,
1036
+ globalListener: this.boundGlobalEventListener,
1037
+ modules: [gridProColumnDragBridgeModule, ColumnMoveModule, DragAndDropModule],
945
1038
  };
946
1039
  }
947
1040
  /**
@@ -952,7 +1045,14 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
952
1045
  get gridProDatasource() {
953
1046
  return (this.querySelector('grid-pro-genesis-datasource') ||
954
1047
  this.querySelector('grid-pro-client-side-datasource') ||
955
- this.querySelector('grid-pro-server-side-datasource'));
1048
+ this.querySelector('grid-pro-server-side-datasource') ||
1049
+ this.querySelector('grid-pro-infinite-datasource'));
1050
+ }
1051
+ /**
1052
+ * @public
1053
+ */
1054
+ get isInfiniteRowModel() {
1055
+ return this.gridProDatasource instanceof GridProInfiniteDatasource;
956
1056
  }
957
1057
  /**
958
1058
  * Reports the currently visible columns to the datasource. The datasource decides what to do with
@@ -964,9 +1064,9 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
964
1064
  const datasource = this.gridProDatasource;
965
1065
  if (!datasource)
966
1066
  return;
967
- const visibleFields = resolveVisibleColumnFields((_b = (_a = this.columnApi) === null || _a === void 0 ? void 0 : _a.getAllDisplayedColumns) === null || _b === void 0 ? void 0 : _b.call(_a), (_d = (_c = this.gridApi) === null || _c === void 0 ? void 0 : _c.getColumnDefs) === null || _d === void 0 ? void 0 : _d.call(_c));
1067
+ const visibleFields = resolveVisibleColumnFields((_b = (_a = this.gridApi) === null || _a === void 0 ? void 0 : _a.getAllDisplayedColumns) === null || _b === void 0 ? void 0 : _b.call(_a), (_d = (_c = this.gridApi) === null || _c === void 0 ? void 0 : _c.getColumnDefs) === null || _d === void 0 ? void 0 : _d.call(_c));
968
1068
  // Skip empty results so we never overwrite a known visible set with nothing (e.g. when the
969
- // column API/defs aren't populated yet during early lifecycle).
1069
+ // grid API/defs aren't populated yet during early lifecycle).
970
1070
  if (!visibleFields.length)
971
1071
  return;
972
1072
  datasource.setVisibleColumns(visibleFields);
@@ -983,45 +1083,52 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
983
1083
  return;
984
1084
  this.debouncedSaveColumnState();
985
1085
  this.debouncedColumnAutosize();
986
- this.invalidateColumnWidthCache();
987
1086
  };
988
1087
  const notifyVisibilityChanged = () => {
989
1088
  if (this.disposed || !this.isConnected)
990
1089
  return;
991
1090
  this.debouncedNotifyDatasourceVisibleColumns();
992
1091
  };
1092
+ // Collect attributes and map them to AG Grid properties
993
1093
  Array.from(this.attributes).forEach((attribute) => {
994
1094
  const attrName = this.agPropertiesMap[attribute.name];
995
1095
  if (!attrName)
996
1096
  return;
997
1097
  this.agAttributes[attrName] = attribute.value;
998
1098
  });
999
- const _a = options, { columnDefs, components, defaultColDef, getRowId, onGridReady, onFilterChanged, onFirstDataRendered } = _a, rest = __rest(_a, ["columnDefs", "components", "defaultColDef", "getRowId", "onGridReady", "onFilterChanged", "onFirstDataRendered"]);
1000
- const gridOptionsConfig = this.gridOptionsConfig;
1001
- const derivedOptions = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, gridOptionsConfig), { defaultColDef: Object.assign({ enableCellChangeFlash: this.enableCellFlashing, filter: true, resizable: true, sortable: true }, defaultColDef), components: this.combineAllGridComponents(components), suppressDragLeaveHidesColumns: true }), this.eventsAndCallbacks), { onGridReady: (event) => __awaiter(this, void 0, void 0, function* () {
1002
- var _a, _b;
1099
+ const { columnDefs, components, defaultColDef, getRowId, onGridReady, onFilterChanged, onFirstDataRendered } = options, rest = __rest(options, ["columnDefs", "components", "defaultColDef", "getRowId", "onGridReady", "onFilterChanged", "onFirstDataRendered"]);
1100
+ const derivedOptions = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.gridOptionsConfig), { defaultColDef: Object.assign({ enableCellChangeFlash: this.enableCellFlashing, filter: true, resizable: true, sortable: true }, defaultColDef), components: this.combineAllGridComponents(components), headerHeight: this.headerHeight, rowHeight: this.rowHeight, animateRows: false, suppressDragLeaveHidesColumns: true }), this.eventsAndCallbacks), { onGridReady: (event) => __awaiter(this, void 0, void 0, function* () {
1101
+ var _a, _b, _c;
1003
1102
  this.gridApi = event.api;
1004
- this.columnApi = event.columnApi;
1005
1103
  if (this.gridEventsQueue.length) {
1006
1104
  this.gridEventsQueue.forEach((type) => {
1007
1105
  this.addGridEventListener(type);
1008
1106
  });
1009
1107
  }
1010
- // Await so columns land before rowData/columnState/ready below - otherwise they'd
1011
- // race against an empty column model.
1108
+ // Awaited so the columns land before rowData/columnState below — otherwise they
1109
+ // would race against an empty column model. Caught because ag-grid neither awaits
1110
+ // nor handles this callback's promise: a rejection (mergeAllColumnDefsAndStates
1111
+ // hydrates column state) would surface as an unhandled rejection AND skip the rest
1112
+ // of init — rowData, the consumer's onGridReady, the grid-ready emit. A grid with
1113
+ // no columns beats one that never finishes starting.
1012
1114
  if (this.pendingSchemaUpdate) {
1013
1115
  const pendingSchemaUpdate = this.pendingSchemaUpdate;
1014
1116
  this.pendingSchemaUpdate = undefined;
1015
- yield this.processSchemaUpdate(pendingSchemaUpdate);
1117
+ try {
1118
+ yield this.processSchemaUpdate(pendingSchemaUpdate);
1119
+ }
1120
+ catch (error) {
1121
+ logger.error('Grid Pro: failed to apply the pending schema update on grid ready:', error);
1122
+ }
1016
1123
  }
1017
1124
  if (this.rowData) {
1018
- this.gridApi.setRowData(this.rowData);
1125
+ this.gridApi.setGridOption('rowData', this.rowData);
1019
1126
  }
1020
1127
  if (onGridReady) {
1021
1128
  onGridReady(event);
1022
1129
  }
1023
- if (this.columnState && ((_a = this.columnState) === null || _a === void 0 ? void 0 : _a.length) > 0) {
1024
- this.columnApi.applyColumnState({
1130
+ if (((_a = this.gridProDatasource) === null || _a === void 0 ? void 0 : _a.keepColDefsOnClearRowData) && ((_b = this.columnState) === null || _b === void 0 ? void 0 : _b.length) > 0) {
1131
+ this.gridApi.applyColumnState({
1025
1132
  state: this.columnState,
1026
1133
  applyOrder: true,
1027
1134
  });
@@ -1038,20 +1145,16 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1038
1145
  // Seed the datasource with the initially visible columns before the load is kicked off, so
1039
1146
  // a datasource that scopes its request to visible columns can narrow the first request.
1040
1147
  this.notifyDatasourceVisibleColumns();
1041
- // Emit datasource ready event, signals that the datasource is ready to be used
1042
1148
  // TODO: prevent rendering datasource slot until grid is ready
1043
1149
  // so there is no need for this even and handling it in datasources
1044
- (_b = this.gridProDatasource) === null || _b === void 0 ? void 0 : _b.$emit(datasourceEventNames.ready);
1150
+ (_c = this.gridProDatasource) === null || _c === void 0 ? void 0 : _c.$emit(datasourceEventNames.ready);
1045
1151
  this.restoreColumnState();
1046
1152
  this.restoreCachedFilterConfig();
1047
1153
  this.debouncedColumnAutosize();
1048
1154
  }), onFirstDataRendered: (event) => {
1049
- // Handle column sizing
1050
- this.handleColumnSizing();
1051
- // Safety net: by now the column API is populated, so (re)seed the datasource's visible
1155
+ // Safety net: by now the grid columns are populated, so (re)seed the datasource's visible
1052
1156
  // columns in case the initial grid-ready seed ran before columns were available.
1053
1157
  this.notifyDatasourceVisibleColumns();
1054
- // Call the original onFirstDataRendered if provided
1055
1158
  if (onFirstDataRendered) {
1056
1159
  onFirstDataRendered(event);
1057
1160
  }
@@ -1076,12 +1179,9 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1076
1179
  onFilterChanged(filterChangedEvent);
1077
1180
  }
1078
1181
  }, onGridSizeChanged: gridOnChangeCallback, onSortChanged: gridOnChangeCallback }), rest);
1079
- const hasGetRowId = 'getRowId' in (options !== null && options !== void 0 ? options : {});
1080
1182
  if (this.gridProDatasource) {
1081
1183
  derivedOptions.columnDefs = columnDefs;
1082
- if (hasGetRowId) {
1083
- derivedOptions.getRowId = getRowId;
1084
- }
1184
+ derivedOptions.getRowId = getRowId;
1085
1185
  this.setupStatusBar(derivedOptions);
1086
1186
  this.setLocalGridOptions(derivedOptions);
1087
1187
  }
@@ -1091,9 +1191,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1091
1191
  return;
1092
1192
  }
1093
1193
  derivedOptions.columnDefs = value;
1094
- if (hasGetRowId) {
1095
- derivedOptions.getRowId = getRowId;
1096
- }
1194
+ derivedOptions.getRowId = getRowId;
1097
1195
  this.setupStatusBar(derivedOptions);
1098
1196
  this.setLocalGridOptions(derivedOptions);
1099
1197
  this.initGrid();
@@ -1101,7 +1199,12 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1101
1199
  }
1102
1200
  }
1103
1201
  setLocalGridOptions(derivedOptions) {
1202
+ // Merge options with reflected AG properties from attributes
1104
1203
  this.agGridOptions = Object.assign(Object.assign({}, this.agGridOptions), copyAttributesToGridOptions(derivedOptions, this.agAttributes));
1204
+ this.agGridOptions.context = Object.assign(Object.assign({}, this.agGridOptions.context), { [GRID_PRO_COLUMN_DRAG_BRIDGE_CONTEXT_KEY]: this.columnDragBridge });
1205
+ if (this.agGridOptions.allowDragFromColumnsToolPanel == null) {
1206
+ this.agGridOptions.allowDragFromColumnsToolPanel = true;
1207
+ }
1105
1208
  }
1106
1209
  /**
1107
1210
  * Clears the local grid options, this is used to clear the grid options when the grid is restarted.
@@ -1110,25 +1213,17 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1110
1213
  clearLocalGridOptions() {
1111
1214
  this.agGridOptions = undefined;
1112
1215
  }
1113
- /**
1114
- * Clears all grid option state when the grid element is fully torn down.
1115
- * @internal
1116
- */
1117
1216
  resetGridOptionsState() {
1118
1217
  this.userProvidedGridOptions = undefined;
1119
1218
  this.agGridOptions = undefined;
1120
1219
  }
1121
1220
  initGrid() {
1122
1221
  DOM.queueUpdate(() => {
1123
- // `gridSlot` belongs in this readiness check, not just `disposed`/`isConnected`: it is a
1124
- // template ref, so it is undefined until the view binds, and this task runs on the shared
1125
- // update queue — an options change can queue it ahead of the binding that fills the ref.
1126
- // Every other reader in this file already guards it; these two lines did not, so that
1127
- // ordering threw `Cannot read properties of undefined (reading 'firstChild')` from INSIDE a
1128
- // queued task. Such a throw is not attributable to whatever caused it: web-test-runner
1129
- // reports it as an uncaught page exception against whichever test happens to be running,
1130
- // which is how it surfaced — as an unrelated datasource test failing only under CI load.
1131
- // Skipping is safe because both callers re-run on the next grid-options change.
1222
+ // `gridSlot` is a template ref, so it is undefined until the view binds, and this task runs
1223
+ // on the shared update queue — an options change can queue it ahead of that binding. Reading
1224
+ // `.firstChild` off it unguarded then throws from INSIDE a queued task, which the runner can
1225
+ // only report against whichever test is running. Same guard as `grid-pro.ts`; both callers
1226
+ // re-run on the next grid-options change, so skipping strands nothing.
1132
1227
  if (this.disposed || !this.isConnected || !this.gridSlot) {
1133
1228
  return;
1134
1229
  }
@@ -1140,21 +1235,10 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1140
1235
  this.gridSlot.removeChild(this.gridSlot.firstChild);
1141
1236
  }
1142
1237
  }
1143
- this.agGrid = new Grid(this.gridSlot, this.agGridOptions, this.gridParams);
1238
+ this.agGrid = createGrid(this.gridSlot, this.agGridOptions, this.gridParams);
1144
1239
  this.initialised = true;
1145
1240
  });
1146
1241
  }
1147
- /**
1148
- * Will merge templated column definitions with `columnDefs` plus localStorage's column state or `deferredColumnStates`.
1149
- * @deprecated use `applyTemplateDefinitions` instead.
1150
- * @param columnDefs - The column definitions to apply to the grid.
1151
- * @param deferredColumnDefsOrState - If true, will merge the column definitions with the saved column state or the `deferredColumnStates` property on the `grid-pro-genesis-datasource` element.
1152
- * @returns The merged column definitions.
1153
- */
1154
- applyTemplateDefinitions(columnDefs, deferredColumnDefsOrState = false) {
1155
- logger.deprecated('applyTemplateDefinitions', 'Use `mergeAllColumnDefsAndStates` instead.');
1156
- return this.mergeAllColumnDefsAndStates(columnDefs, deferredColumnDefsOrState);
1157
- }
1158
1242
  /**
1159
1243
  * Will merge templated column definitions with `columnDefs` plus localStorage's column state or `deferredColumnStates`.
1160
1244
  * @public
@@ -1182,7 +1266,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1182
1266
  const templateColumnDefs = Array.from(this.querySelectorAll(this.columnComponentName))
1183
1267
  .map((templateColumn) => templateColumn.definition)
1184
1268
  .map((columnDef) => {
1185
- var _a, _b;
1269
+ var _a, _b, _c, _d, _e, _f;
1186
1270
  // enable cell flashing for each column if unspecified on column level but enabled on grid level
1187
1271
  if (this.enableCellFlashing && columnDef.enableCellChangeFlash === undefined) {
1188
1272
  columnDef.enableCellChangeFlash = true;
@@ -1193,21 +1277,25 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1193
1277
  * respect that choice and don't inject metadata values. This allows consumers to
1194
1278
  * opt out of metadata values and let AG Grid extract values from row data instead.
1195
1279
  */
1196
- if (columnDef.filter === 'agSetColumnFilter') {
1280
+ if (columnDef.filter === 'agSetColumnFilter' ||
1281
+ columnDef.filter === GridProFilterTypes.enumFilter) {
1197
1282
  const hasExplicitValues = columnDef.filterParams != null && 'values' in columnDef.filterParams;
1198
1283
  if (!hasExplicitValues) {
1199
- const metadataValues = (_b = (_a = columnDefinitionsFromMetadata.find((colDef) => colDef.field === columnDef.field)) === null || _a === void 0 ? void 0 : _a.filterParams) === null || _b === void 0 ? void 0 : _b.values;
1284
+ const metadataFilterParams = (_a = columnDefinitionsFromMetadata.find((colDef) => colDef.field === columnDef.field)) === null || _a === void 0 ? void 0 : _a.filterParams;
1285
+ // Metadata enum values are flat ({ values }) on the server-side datasource path, but
1286
+ // nested inside a multi-filter's set sub-filter on the client-side datasource path.
1287
+ const metadataValues = (_b = metadataFilterParams === null || metadataFilterParams === void 0 ? void 0 : metadataFilterParams.values) !== null && _b !== void 0 ? _b : (_e = (_d = (_c = metadataFilterParams === null || metadataFilterParams === void 0 ? void 0 : metadataFilterParams.filters) === null || _c === void 0 ? void 0 : _c.find((subFilter) => subFilter.filter === 'agSetColumnFilter')) === null || _d === void 0 ? void 0 : _d.filterParams) === null || _e === void 0 ? void 0 : _e.values;
1200
1288
  if (metadataValues) {
1201
1289
  columnDef.filterParams = Object.assign(Object.assign({}, columnDef.filterParams), { values: metadataValues });
1202
1290
  }
1203
1291
  }
1292
+ if (columnDef.filter === GridProFilterTypes.enumFilter) {
1293
+ (_f = columnDef.floatingFilterComponent) !== null && _f !== void 0 ? _f : (columnDef.floatingFilterComponent = GridProFilterTypes.enumFloatingFilter);
1294
+ }
1204
1295
  }
1205
1296
  if (columnDef.editable) {
1206
1297
  if (!columnDef.cellRenderer && !columnDef.cellRendererSelector) {
1207
1298
  columnDef.cellRendererSelector = (params) => {
1208
- if (!(params === null || params === void 0 ? void 0 : params.data)) {
1209
- return undefined;
1210
- }
1211
1299
  if (params.data[EDITED_COLUMN_FIELD] === columnDef.field) {
1212
1300
  return {
1213
1301
  component: GridProRendererTypes.editable,
@@ -1218,9 +1306,6 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1218
1306
  if (!columnDef.tooltipComponent && !columnDef.tooltipValueGetter) {
1219
1307
  columnDef.tooltipComponent = ErrorTooltip;
1220
1308
  columnDef.tooltipValueGetter = (params) => {
1221
- if (!(params === null || params === void 0 ? void 0 : params.data)) {
1222
- return undefined;
1223
- }
1224
1309
  const error = params.data[ERROR_COLUMN_FIELD];
1225
1310
  if (error && error.column === columnDef.field) {
1226
1311
  return error.message;
@@ -1229,13 +1314,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1229
1314
  }
1230
1315
  if (!columnDef.cellClassRules) {
1231
1316
  columnDef.cellClassRules = {
1232
- error: (params) => {
1233
- var _a;
1234
- if (!(params === null || params === void 0 ? void 0 : params.colDef) || !(params === null || params === void 0 ? void 0 : params.data)) {
1235
- return false;
1236
- }
1237
- return ((_a = params.data[ERROR_COLUMN_FIELD]) === null || _a === void 0 ? void 0 : _a.column) === params.colDef.field;
1238
- },
1317
+ error: (params) => { var _a; return ((_a = params.data[ERROR_COLUMN_FIELD]) === null || _a === void 0 ? void 0 : _a.column) === params.colDef.field; },
1239
1318
  };
1240
1319
  }
1241
1320
  }
@@ -1268,7 +1347,13 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1268
1347
  // The custom rowCount panel is used for server-side infinite scroll (load more) scenarios;
1269
1348
  // client-side row models use AG Grid's own row count component instead.
1270
1349
  if (this.statusBarConfig && this.statusBarConfig.rows === true) {
1271
- const isServerSide = this.isServerSide || (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowModelType) === 'serverSide';
1350
+ // Check the derived gridOptions parameter, not this.gridOptions: setupStatusBar runs
1351
+ // before setLocalGridOptions populates the field, so on first init the field is still
1352
+ // undefined and a standalone grid's rowModelType would be missed.
1353
+ const isServerSide = this.isServerSide ||
1354
+ this.isInfiniteRowModel ||
1355
+ (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowModelType) === 'infinite' ||
1356
+ (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.rowModelType) === 'serverSide';
1272
1357
  if (isServerSide) {
1273
1358
  if (!this.panelExists(GridProStatusBarTypes.rowCount, statusPanels)) {
1274
1359
  statusPanels.push({
@@ -1315,7 +1400,9 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1315
1400
  }
1316
1401
  addDatasourcePanels(statusPanels) {
1317
1402
  if (this.gridProDatasource) {
1318
- const datasourceStatusPanels = this.gridProDatasource.getDatasourceStatusBarPanels(this.isServerSide, this.statusBarConfig);
1403
+ // The infinite row model loads on scroll, so its loadMore() is a no-op: suppress the
1404
+ // Load More panel for it the same way it is suppressed for the server-side row model.
1405
+ const datasourceStatusPanels = this.gridProDatasource.getDatasourceStatusBarPanels(this.isServerSide || this.isInfiniteRowModel, this.statusBarConfig);
1319
1406
  // Filter out duplicate datasource panels
1320
1407
  const newDatasourcePanels = datasourceStatusPanels.filter((panel) => !this.panelExists(panel.statusPanel, statusPanels));
1321
1408
  statusPanels.push(...newDatasourcePanels);
@@ -1343,94 +1430,6 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1343
1430
  };
1344
1431
  }
1345
1432
  }
1346
- /**
1347
- * Handles column sizing based on sizeColumnsToContent and sizeColumnsToFit attributes
1348
- * @private
1349
- */
1350
- handleColumnSizing() {
1351
- if (!this.sizeColumnsToContent && !this.sizeColumnsToFit)
1352
- return;
1353
- if (this.sizeColumnsToContent && this.sizeColumnsToFit && this.columnApi && this.gridApi) {
1354
- this.handleBothSizingModes();
1355
- }
1356
- else {
1357
- this.handleIndividualSizingModes();
1358
- }
1359
- }
1360
- /**
1361
- * Handles when both sizeColumnsToContent and sizeColumnsToFit are enabled
1362
- * @private
1363
- */
1364
- handleBothSizingModes() {
1365
- const totalColumnWidth = this.calculateTotalColumnWidth();
1366
- const gridWidth = this.getGridWidth();
1367
- if (totalColumnWidth > gridWidth) {
1368
- if (!this.columnApi)
1369
- return;
1370
- this.columnApi.autoSizeAllColumns();
1371
- }
1372
- else {
1373
- if (!this.gridApi)
1374
- return;
1375
- this.gridApi.sizeColumnsToFit();
1376
- }
1377
- }
1378
- /**
1379
- * Handles individual sizing modes when only one is enabled
1380
- * @private
1381
- */
1382
- handleIndividualSizingModes() {
1383
- if (this.sizeColumnsToContent && this.columnApi) {
1384
- this.columnApi.autoSizeAllColumns();
1385
- }
1386
- if (this.sizeColumnsToFit && this.gridApi) {
1387
- this.gridApi.sizeColumnsToFit();
1388
- }
1389
- }
1390
- /**
1391
- * Calculates the total width of all columns
1392
- * @private
1393
- */
1394
- calculateTotalColumnWidth() {
1395
- if (!this.columnApi) {
1396
- return 0;
1397
- }
1398
- const allColumns = this.columnApi.getAllGridColumns();
1399
- const currentColumnCount = allColumns.length;
1400
- // Check if cache is still valid (same number of columns)
1401
- if (this.cachedTotalColumnWidth !== null && this.columnCount === currentColumnCount) {
1402
- return this.cachedTotalColumnWidth;
1403
- }
1404
- // Calculate and cache the total width
1405
- this.cachedTotalColumnWidth = allColumns.reduce((sum, col) => sum + (col.getActualWidth() || 0), 0);
1406
- this.columnCount = currentColumnCount;
1407
- return this.cachedTotalColumnWidth;
1408
- }
1409
- /**
1410
- * Invalidates the cached column width calculation
1411
- * @private
1412
- * @remarks This method is called automatically when column changes occur (resize, move, pin, etc.)
1413
- * to ensure the cached width calculation remains accurate.
1414
- */
1415
- invalidateColumnWidthCache() {
1416
- this.cachedTotalColumnWidth = null;
1417
- this.columnCount = 0;
1418
- }
1419
- /**
1420
- * Gets the available grid width with fallbacks
1421
- * @private
1422
- */
1423
- getGridWidth() {
1424
- const gridElement = this;
1425
- let gridWidth = (gridElement === null || gridElement === void 0 ? void 0 : gridElement.clientWidth) || 0;
1426
- if (gridWidth === 0 && this.gridSlot) {
1427
- gridWidth = this.gridSlot.clientWidth || 0;
1428
- }
1429
- if (gridWidth === 0) {
1430
- gridWidth = this.clientWidth || 0;
1431
- }
1432
- return gridWidth;
1433
- }
1434
1433
  get observedAttributes() {
1435
1434
  // allow properties to be supplied either lowercased or kebab-cased
1436
1435
  // this allows the user to either supply (for example) enableSorting or enabled-sorting
@@ -1441,6 +1440,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1441
1440
  return lowerCasedPropertyNames.concat(kebabCasePropertyNames);
1442
1441
  }
1443
1442
  agAttributeChangedCallback(attName, oldValue, newValue) {
1443
+ var _a;
1444
1444
  if (oldValue === newValue) {
1445
1445
  return;
1446
1446
  }
@@ -1448,13 +1448,9 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1448
1448
  if (gridPropertyName) {
1449
1449
  // for properties set before gridOptions is called
1450
1450
  this.agAttributes[gridPropertyName] = newValue;
1451
- // `initialised` flips true before `gridApi` is assigned (mid-reinit), so relying on it
1452
- // alone here can crash processOnChange with an undefined api.
1453
- if (this.initialised && this.gridApi) {
1454
- // for subsequent (post gridOptions) changes
1455
- const changeObject = {};
1456
- changeObject[gridPropertyName] = { currentValue: newValue };
1457
- ComponentUtil.processOnChange(changeObject, this.gridApi);
1451
+ if (this.initialised) {
1452
+ // for subsequent (post gridOptions) changes - use setGridOption API for v35
1453
+ (_a = this.gridApi) === null || _a === void 0 ? void 0 : _a.setGridOption(gridPropertyName, newValue);
1458
1454
  }
1459
1455
  }
1460
1456
  }
@@ -1471,24 +1467,7 @@ export class GridPro extends LifecycleMixin(FoundationElement) {
1471
1467
  this[callbackMethod](browserEvent);
1472
1468
  }
1473
1469
  }
1474
- insertFontFace(newValue) {
1475
- const fontFaceRule = agThemeFontFaceMap[newValue] || this.gridFontFace;
1476
- this.destroyFontFace();
1477
- const newDestroy = insertDocumentCSSRule(fontFaceRule, agThemeFontsId(newValue));
1478
- if (newDestroy) {
1479
- this.fontFaceDestroy = newDestroy;
1480
- }
1481
- }
1482
- destroyFontFace() {
1483
- if (this.fontFaceDestroy) {
1484
- this.fontFaceDestroy();
1485
- this.fontFaceDestroy = null;
1486
- }
1487
- }
1488
1470
  }
1489
- __decorate([
1490
- observable
1491
- ], GridPro.prototype, "columnApi", void 0);
1492
1471
  __decorate([
1493
1472
  observable
1494
1473
  ], GridPro.prototype, "gridApi", void 0);
@@ -1507,30 +1486,9 @@ __decorate([
1507
1486
  __decorate([
1508
1487
  attr({ mode: 'boolean', attribute: 'grid-autosizing' })
1509
1488
  ], GridPro.prototype, "gridAutosizingEnabled", void 0);
1510
- __decorate([
1511
- attr({ mode: 'boolean', attribute: 'size-columns-to-content' })
1512
- ], GridPro.prototype, "sizeColumnsToContent", void 0);
1513
- __decorate([
1514
- attr({ mode: 'boolean', attribute: 'size-columns-to-fit' })
1515
- ], GridPro.prototype, "sizeColumnsToFit", void 0);
1516
- __decorate([
1517
- attr({ attribute: 'add-index' })
1518
- ], GridPro.prototype, "addIndex", void 0);
1519
- __decorate([
1520
- attr({ mode: 'boolean', attribute: 'async-add' })
1521
- ], GridPro.prototype, "asyncAdd", void 0);
1522
- __decorate([
1523
- attr({ mode: 'boolean', attribute: 'async-remove' })
1524
- ], GridPro.prototype, "asyncRemove", void 0);
1525
- __decorate([
1526
- attr({ mode: 'boolean', attribute: 'async-update' })
1527
- ], GridPro.prototype, "asyncUpdate", void 0);
1528
1489
  __decorate([
1529
1490
  attr({ mode: 'boolean', attribute: 'enable-cell-flashing' })
1530
1491
  ], GridPro.prototype, "enableCellFlashing", void 0);
1531
- __decorate([
1532
- attr({ mode: 'boolean', attribute: 'enabled-row-flashing' })
1533
- ], GridPro.prototype, "enabledRowFlashing", void 0);
1534
1492
  __decorate([
1535
1493
  attr({ mode: 'boolean', attribute: 'enable-row-flashing' })
1536
1494
  ], GridPro.prototype, "enableRowFlashing", void 0);
@@ -1540,18 +1498,12 @@ __decorate([
1540
1498
  __decorate([
1541
1499
  attr({ attribute: 'persist-filter-model-key' })
1542
1500
  ], GridPro.prototype, "persistFilterModelKey", void 0);
1543
- __decorate([
1544
- attr({ attribute: 'default-column-config' })
1545
- ], GridPro.prototype, "defaultColumnConfig", void 0);
1546
1501
  __decorate([
1547
1502
  attr({ attribute: 'header-case-type' })
1548
1503
  ], GridPro.prototype, "headerCaseType", void 0);
1549
1504
  __decorate([
1550
1505
  observable
1551
1506
  ], GridPro.prototype, "rowData", void 0);
1552
- __decorate([
1553
- observable
1554
- ], GridPro.prototype, "gridFontFace", void 0);
1555
1507
  __decorate([
1556
1508
  attr
1557
1509
  ], GridPro.prototype, "columnComponentName", void 0);
@@ -1564,9 +1516,6 @@ __decorate([
1564
1516
  __decorate([
1565
1517
  attr
1566
1518
  ], GridPro.prototype, "rowHeight", void 0);
1567
- __decorate([
1568
- attr
1569
- ], GridPro.prototype, "theme", void 0);
1570
1519
  __decorate([
1571
1520
  observable
1572
1521
  ], GridPro.prototype, "classNames", void 0);
@@ -1588,26 +1537,18 @@ __decorate([
1588
1537
  __decorate([
1589
1538
  attr({ mode: 'boolean', attribute: 'with-status-bar' })
1590
1539
  ], GridPro.prototype, "withStatusBar", void 0);
1540
+ __decorate([
1541
+ attr({ mode: 'boolean', attribute: 'enable-column-selection' })
1542
+ ], GridPro.prototype, "enableColumnSelection", void 0);
1591
1543
  __decorate([
1592
1544
  observable
1593
1545
  ], GridPro.prototype, "customErrorHandlerTemplate", void 0);
1594
1546
  __decorate([
1595
1547
  GridOptionsConfig
1596
1548
  ], GridPro.prototype, "gridOptionsConfig", void 0);
1597
- /**
1598
- * GridPro shadow root options.
1599
- * @public
1600
- * @remarks
1601
- * For extensibility, this can be used to set the shadow root mode and delegatesFocus
1602
- */
1603
- export const foundationGridProShadowOptions = undefined;
1604
- /**
1605
- * Grid Pro default configuration.
1606
- * @public
1607
- */
1608
- export const defaultGridProConfig = {
1609
- shadowOptions: undefined,
1610
- };
1549
+ __decorate([
1550
+ observable
1551
+ ], GridPro.prototype, "provider", void 0);
1611
1552
  /**
1612
1553
  * A function that returns a Foundation Grid Pro registration for configuring the component with a DesignSystem.
1613
1554
  *
@@ -1615,5 +1556,39 @@ export const defaultGridProConfig = {
1615
1556
  * @remarks
1616
1557
  * HTML Element: \<foundation-grid-pro\>
1617
1558
  */
1618
- export const foundationGridPro = GridPro.compose(Object.assign({ baseName: 'grid-pro', styles,
1619
- template, shadowOptions: foundationGridProShadowOptions }, defaultGridProConfig));
1559
+ export const foundationGridPro = GridPro.compose(Object.assign({ baseName: 'grid-pro', template,
1560
+ // Mirrors what `foundationGridProStyles` gives the legacy grid, minus the AG Grid v29 stock CSS:
1561
+ // the error-handler dialog positions itself against the host, and the column-selection toolbar
1562
+ // needs the host to lay out as a column.
1563
+ styles: css `
1564
+ ${errorHandlerDialogStyles}
1565
+ ${agDragGhostShadowDomStyles}
1566
+ ${gridProColumnSelectionHostStyles}
1567
+ ${rowMatchAlertStyles}
1568
+
1569
+ :host {
1570
+ --datasource-error-background-color: var(--neutral-layer-4);
1571
+ --datasource-error-background-opacity: 0.5;
1572
+ --datasource-error-dialog-max-width: 50%;
1573
+ --datasource-error-dialog-min-width: auto;
1574
+ --ag-status-bar-height: 32.5px;
1575
+
1576
+ position: relative;
1577
+ width: 100%;
1578
+ height: 100%;
1579
+ }
1580
+
1581
+ :host([ds-disconnected]) {
1582
+ display: block;
1583
+ }
1584
+
1585
+ :host([ds-disconnected])::part(grid) {
1586
+ cursor: not-allowed;
1587
+ opacity: 40%;
1588
+ pointer-events: none;
1589
+ }
1590
+
1591
+ .ag-status-bar {
1592
+ height: var(--ag-status-bar-height);
1593
+ }
1594
+ `, shadowOptions: foundationGridProShadowOptions }, defaultGridProConfig));