@xh/hoist 76.0.0-SNAPSHOT.1758565564006 → 76.0.0-SNAPSHOT.1758671078490

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/admin/tabs/userData/roles/details/members/BaseMembersModel.ts +2 -2
  3. package/build/types/admin/tabs/userData/roles/details/members/BaseMembersModel.d.ts +2 -2
  4. package/build/types/cmp/dataview/DataViewModel.d.ts +1 -1
  5. package/build/types/cmp/grid/Grid.d.ts +4 -4
  6. package/build/types/cmp/grid/GridModel.d.ts +16 -6
  7. package/build/types/cmp/grid/Types.d.ts +1 -2
  8. package/build/types/cmp/grid/columns/Column.d.ts +1 -2
  9. package/build/types/cmp/grid/impl/ColumnGroupHeader.d.ts +3 -3
  10. package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +1 -1
  11. package/build/types/desktop/cmp/grid/editors/EditorProps.d.ts +1 -1
  12. package/build/types/desktop/cmp/rest/RestGridModel.d.ts +1 -1
  13. package/build/types/kit/ag-grid/index.d.ts +5 -2
  14. package/cmp/ag-grid/AgGrid.ts +0 -1
  15. package/cmp/ag-grid/AgGridModel.ts +9 -60
  16. package/cmp/dataview/DataViewModel.ts +1 -1
  17. package/cmp/grid/Grid.ts +31 -20
  18. package/cmp/grid/GridModel.ts +46 -18
  19. package/cmp/grid/Types.ts +2 -2
  20. package/cmp/grid/columns/Column.ts +3 -3
  21. package/cmp/grid/impl/ColumnGroupHeader.ts +5 -3
  22. package/cmp/grid/impl/ColumnHeader.ts +2 -3
  23. package/cmp/grid/impl/MenuSupport.ts +2 -1
  24. package/cmp/zoneGrid/ZoneGrid.ts +1 -2
  25. package/cmp/zoneGrid/ZoneGridModel.ts +1 -1
  26. package/desktop/cmp/grid/editors/BooleanEditor.ts +1 -1
  27. package/desktop/cmp/grid/editors/DateEditor.ts +2 -7
  28. package/desktop/cmp/grid/editors/EditorProps.ts +1 -1
  29. package/desktop/cmp/grid/editors/NumberEditor.ts +1 -1
  30. package/desktop/cmp/grid/editors/impl/InlineEditorModel.ts +2 -2
  31. package/desktop/cmp/rest/RestGridModel.ts +1 -1
  32. package/inspector/instances/InstancesPanel.ts +1 -2
  33. package/kit/ag-grid/index.ts +20 -5
  34. package/package.json +3 -4
  35. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -2,7 +2,22 @@
2
2
 
3
3
  ## 76.0.0-SNAPSHOT - unreleased
4
4
 
5
- ### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - upgrade to Hoist Core, change to Tab constructor)
5
+ ### 💥 Breaking Changes (upgrade difficulty: 🟠 MEDIUM - AG Grid update, Hoist React upgrade)
6
+
7
+ * Hoist v76 upgrades AG Grid to v34 (from v31), covering three major AG Grid releases with their own
8
+ potentially breaking changes. Fortunately, internal Hoist updates to our managed API wrappers mean
9
+ that most apps will see very minimal changes, although there are required adjustments to app-level
10
+ `package.json` to install updated grid dependencies and `Bootstrap.ts` to import and register
11
+ your licensed grid modules at their new import paths.
12
+
13
+ Applications implementing `groupRowRenderer` should note that the `value` property passed to this
14
+ function is no longer stringified, but is instead the raw field value for the group.
15
+
16
+ See AG's upgrade guides for more details:
17
+ ** [Upgrade to v32](https://www.ag-grid.com/react-data-grid/upgrading-to-ag-grid-32/)
18
+ ** [Upgrade to v33](https://www.ag-grid.com/react-data-grid/upgrading-to-ag-grid-33/)
19
+ ** [Upgrade to v34](https://www.ag-grid.com/react-data-grid/upgrading-to-ag-grid-34/)
20
+
6
21
  * The constructor for `TabModel` has changed to take its owning container as a second argument.
7
22
  (Most applications do not create `TabModels` directly, but it is possible.)
8
23
  * The `Exception` class and `HoistException` type have been moved from `@xh\hoist\core` to a new
@@ -29,6 +44,10 @@
29
44
  * New constraint rule: `validEmails` - to validate one or more email addresses in an input field.
30
45
  * `DashCanvas` accepts a new prop `rglOptions` to pass additional options to the underlying
31
46
  `react-grid-layout`.
47
+ * * Experimental grid feature `enableFullWidthScroll` has been promoted to a first-class property
48
+ on `GridModel`. Set to true to ensure that the grid will have a single horizontal scrollbar
49
+ spanning the width of all columns, including any pinned columns.
50
+
32
51
 
33
52
  ### 🐞 Bug Fixes
34
53
 
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
- import {RowClickedEvent} from '@ag-grid-community/core';
7
+ import {RowDoubleClickedEvent} from '@xh/hoist/kit/ag-grid';
8
8
  import {ColumnRenderer, GridModel} from '@xh/hoist/cmp/grid';
9
9
  import {hbox} from '@xh/hoist/cmp/layout';
10
10
  import {HoistModel, lookup, managed, PlainObject} from '@xh/hoist/core';
@@ -91,7 +91,7 @@ export abstract class BaseMembersModel extends HoistModel {
91
91
  .join(', ');
92
92
  };
93
93
 
94
- protected onRowDoubleClicked: (e: RowClickedEvent) => void = null;
94
+ protected onRowDoubleClicked: (e: RowDoubleClickedEvent) => void = null;
95
95
 
96
96
  //-----------------
97
97
  // Implementation
@@ -1,4 +1,4 @@
1
- import { RowClickedEvent } from '@ag-grid-community/core';
1
+ import { RowDoubleClickedEvent } from '@xh/hoist/kit/ag-grid';
2
2
  import { ColumnRenderer, GridModel } from '@xh/hoist/cmp/grid';
3
3
  import { HoistModel, PlainObject } from '@xh/hoist/core';
4
4
  import { ReactNode } from 'react';
@@ -19,7 +19,7 @@ export declare abstract class BaseMembersModel extends HoistModel {
19
19
  protected nameRenderer: ColumnRenderer;
20
20
  protected sourcesRenderer: ColumnRenderer;
21
21
  protected sourcesExportRenderer: ColumnRenderer;
22
- protected onRowDoubleClicked: (e: RowClickedEvent) => void;
22
+ protected onRowDoubleClicked: (e: RowDoubleClickedEvent) => void;
23
23
  private createGridModel;
24
24
  private loadGridData;
25
25
  }
@@ -1,4 +1,4 @@
1
- import { RowClickedEvent, RowDoubleClickedEvent, RowHeightParams } from '@ag-grid-community/core';
1
+ import { RowClickedEvent, RowDoubleClickedEvent, RowHeightParams } from '@xh/hoist/kit/ag-grid';
2
2
  import { ColumnRenderer, GridConfig, GridModel, GroupRowRenderer, RowClassFn, RowClassRuleFn, GridSorterLike, GridContextMenuSpec, GridGroupSortFn } from '@xh/hoist/cmp/grid';
3
3
  import { HoistModel, LoadSpec, PlainObject, Some } from '@xh/hoist/core';
4
4
  import { Store, StoreConfig, StoreRecord, StoreRecordOrId, StoreSelectionConfig, StoreSelectionModel, StoreTransaction } from '@xh/hoist/data';
@@ -1,4 +1,4 @@
1
- import { GridApi } from '@ag-grid-community/core';
1
+ import { GridApi } from '@xh/hoist/kit/ag-grid';
2
2
  import { ColumnState } from '@xh/hoist/cmp/grid';
3
3
  import { HoistModel, HoistProps, LayoutProps, PlainObject, ReactionSpec, TestSupportProps } from '@xh/hoist/core';
4
4
  import { RecordSet } from '@xh/hoist/data/impl/RecordSet';
@@ -53,7 +53,7 @@ export declare class GridLocalModel extends HoistModel {
53
53
  onLinked(): void;
54
54
  private createDefaultAgOptions;
55
55
  getColumnDefs(): Array<ColDef | ColGroupDef>;
56
- getContextMenuItems: (params: GetContextMenuItemsParams) => (string | import("@ag-grid-community/core").MenuItemDef<any, any>)[];
56
+ getContextMenuItems: (params: GetContextMenuItemsParams) => (string | import("@xh/hoist/kit/ag-grid").MenuItemDef<any, any>)[];
57
57
  dataReaction(): {
58
58
  track: () => (boolean | RecordSet | import("../../data").StoreRecord[] | import("@xh/hoist/core").VSide)[];
59
59
  run: () => void;
@@ -120,10 +120,10 @@ export declare class GridLocalModel extends HoistModel {
120
120
  nodeB: any;
121
121
  }) => number;
122
122
  doWithPreservedState({ filters }: PlainObject, fn: any): void;
123
- readFilterState(): import("@ag-grid-community/core").FilterModel;
123
+ readFilterState(): import("ag-grid-community").FilterModel;
124
124
  writeFilterState(filterState: any): void;
125
125
  processCellForClipboard: ({ value, node, column }: ProcessCellForExportParams) => any;
126
- navigateToNextCell: (agParams: any) => import("@ag-grid-community/core").CellPosition;
126
+ navigateToNextCell: (agParams: any) => import("@xh/hoist/kit/ag-grid").CellPosition;
127
127
  onCellMouseDown: (evt: any) => void;
128
128
  onKeyDown: (evt: any) => void;
129
129
  onRowClicked: (evt: any) => void;
@@ -1,11 +1,11 @@
1
- import { CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, ColumnState as AgColumnState, RowClickedEvent, RowDoubleClickedEvent } from '@ag-grid-community/core';
1
+ import { CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, CellEditingStartedEvent, CellEditingStoppedEvent, AgColumnState, RowClickedEvent, RowDoubleClickedEvent } from '@xh/hoist/kit/ag-grid';
2
2
  import { AgGridModel } from '@xh/hoist/cmp/ag-grid';
3
3
  import { Column, ColumnGroup, ColumnGroupSpec, ColumnSpec, GridAutosizeMode, GridFilterModelConfig, GridGroupSortFn, TreeStyle } from '@xh/hoist/cmp/grid';
4
4
  import { GridFilterModel } from '@xh/hoist/cmp/grid/filter/GridFilterModel';
5
5
  import { Awaitable, HoistModel, HSide, PlainObject, SizingMode, Some, TaskObserver, Thunkable, VSide } from '@xh/hoist/core';
6
6
  import { Store, StoreConfig, StoreRecord, StoreRecordId, StoreRecordOrId, StoreSelectionConfig, StoreSelectionModel, StoreTransaction } from '@xh/hoist/data';
7
7
  import { ExportOptions } from '@xh/hoist/svc/GridExportService';
8
- import { ReactNode } from 'react';
8
+ import { ReactNode, RefObject } from 'react';
9
9
  import { GridAutosizeOptions } from './GridAutosizeOptions';
10
10
  import { GridContextMenuSpec } from './GridContextMenu';
11
11
  import { GridSorter, GridSorterLike } from './GridSorter';
@@ -191,6 +191,12 @@ export interface GridConfig {
191
191
  * otherwise false.
192
192
  */
193
193
  highlightRowOnClick?: boolean;
194
+ /**
195
+ * Set to true to ensure that the grid will have a single horizontal scrollbar spanning the
196
+ * width of all columns, including any pinned columns. A value of false (default) will show
197
+ * the scrollbar only under the scrollable area.
198
+ */
199
+ enableFullWidthScroll?: boolean;
194
200
  /**
195
201
  * Flags for experimental features. These features are designed for early client-access and
196
202
  * testing, but are not yet part of the Hoist API.
@@ -232,6 +238,7 @@ export declare class GridModel extends HoistModel {
232
238
  showGroupRowCounts: boolean;
233
239
  enableColumnPinning: boolean;
234
240
  enableExport: boolean;
241
+ enableFullWidthScroll: boolean;
235
242
  externalSort: boolean;
236
243
  exportOptions: ExportOptions;
237
244
  useVirtualColumns: boolean;
@@ -257,6 +264,7 @@ export declare class GridModel extends HoistModel {
257
264
  appData: PlainObject;
258
265
  filterModel: GridFilterModel;
259
266
  agGridModel: AgGridModel;
267
+ viewRef: RefObject<HTMLDivElement>;
260
268
  columns: Array<ColumnGroup | Column>;
261
269
  columnState: ColumnState[];
262
270
  expandState: any;
@@ -271,7 +279,7 @@ export declare class GridModel extends HoistModel {
271
279
  * Flag to track inline editing at a granular level. Will toggle each time row
272
280
  * or cell editing is activated or ended.
273
281
  */
274
- isEditing: boolean;
282
+ get isEditing(): boolean;
275
283
  /**
276
284
  * Flag to track inline editing at a general level.
277
285
  * Will not change during transient navigation from cell to cell or row to row,
@@ -280,6 +288,7 @@ export declare class GridModel extends HoistModel {
280
288
  */
281
289
  isInEditingMode: boolean;
282
290
  static defaultContextMenu: string[];
291
+ private editingCell;
283
292
  private _defaultState;
284
293
  /**
285
294
  * Is autosizing enabled on this grid?
@@ -287,6 +296,7 @@ export declare class GridModel extends HoistModel {
287
296
  */
288
297
  get autosizeEnabled(): boolean;
289
298
  get maxDepth(): number;
299
+ get bodyViewport(): HTMLElement;
290
300
  /** Tracks execution of filtering operations.*/
291
301
  filterTask: TaskObserver;
292
302
  /** Tracks execution of autosize operations. */
@@ -403,7 +413,7 @@ export declare class GridModel extends HoistModel {
403
413
  /** True if this grid has no records to show in its store. */
404
414
  get empty(): boolean;
405
415
  get isReady(): boolean;
406
- get agApi(): import("@ag-grid-community/core").GridApi<any>;
416
+ get agApi(): import("@xh/hoist/kit/ag-grid").GridApi<any>;
407
417
  get sizingMode(): SizingMode;
408
418
  set sizingMode(v: SizingMode);
409
419
  setSizingMode(v: SizingMode): void;
@@ -543,9 +553,9 @@ export declare class GridModel extends HoistModel {
543
553
  */
544
554
  endEditAsync(dropPendingChanges?: boolean): Promise<void>;
545
555
  /** @internal */
546
- onCellEditingStarted: () => void;
556
+ onCellEditingStarted: (e: CellEditingStartedEvent) => void;
547
557
  /** @internal*/
548
- onCellEditingStopped: () => void;
558
+ onCellEditingStopped: (e: CellEditingStoppedEvent) => void;
549
559
  /**
550
560
  * Returns true as soon as the underlying agGridModel is ready, waiting a limited period
551
561
  * of time if needed to allow the component to initialize. Returns false if grid not ready
@@ -1,4 +1,3 @@
1
- import { CustomCellEditorProps } from '@ag-grid-community/react';
2
1
  import { GridFilterFieldSpecConfig } from '@xh/hoist/cmp/grid/filter/GridFilterFieldSpec';
3
2
  import { HSide, PersistOptions, Some } from '@xh/hoist/core';
4
3
  import { Store, StoreRecord, View } from '@xh/hoist/data';
@@ -6,7 +5,7 @@ import { ReactElement, ReactNode } from 'react';
6
5
  import { Column } from './columns/Column';
7
6
  import { ColumnGroup } from './columns/ColumnGroup';
8
7
  import { GridModel } from './GridModel';
9
- import type { CellClassParams, HeaderClassParams, HeaderValueGetterParams, ICellRendererParams, IRowNode, ITooltipParams, RowClassParams, ValueSetterParams } from '@xh/hoist/kit/ag-grid';
8
+ import type { CellClassParams, HeaderClassParams, HeaderValueGetterParams, ICellRendererParams, IRowNode, ITooltipParams, RowClassParams, ValueSetterParams, CustomCellEditorProps } from '@xh/hoist/kit/ag-grid';
10
9
  export interface ColumnState {
11
10
  colId: string;
12
11
  width: number;
@@ -3,8 +3,7 @@ import { CubeFieldSpec, FieldSpec, RecordAction, RecordActionSpec, StoreRecord }
3
3
  import { FunctionComponent, ReactNode } from 'react';
4
4
  import { GridModel } from '../GridModel';
5
5
  import { ColumnCellClassFn, ColumnCellClassRuleFn, ColumnComparator, ColumnEditableFn, ColumnEditorFn, ColumnEditorProps, ColumnExcelFormatFn, ColumnExportValueFn, ColumnGetValueFn, ColumnHeaderClassFn, ColumnHeaderNameFn, ColumnRenderer, ColumnSetValueFn, ColumnSortSpec, ColumnSortValueFn, ColumnTooltipFn } from '../Types';
6
- import type { ColDef } from '@xh/hoist/kit/ag-grid';
7
- import { CellClickedEvent } from '@ag-grid-community/core';
6
+ import type { ColDef, CellClickedEvent } from '@xh/hoist/kit/ag-grid';
8
7
  export interface ColumnSpec {
9
8
  /**
10
9
  * Name of data store field to display within the column, or object containing properties
@@ -1,6 +1,6 @@
1
1
  import { ColumnGroup, GridModel } from '@xh/hoist/cmp/grid';
2
2
  import { HoistModel, HoistProps } from '@xh/hoist/core';
3
- import type { AgColumnGroup, IHeaderGroupParams } from '@xh/hoist/kit/ag-grid';
3
+ import type { AgProvidedColumnGroup, IHeaderGroupParams } from '@xh/hoist/kit/ag-grid';
4
4
  export interface ColumnGroupHeaderProps extends HoistProps<ColumnGroupHeaderModel>, IHeaderGroupParams {
5
5
  gridModel: GridModel;
6
6
  xhColumnGroup: ColumnGroup;
@@ -15,10 +15,10 @@ declare class ColumnGroupHeaderModel extends HoistModel {
15
15
  xhImpl: boolean;
16
16
  isExpanded: boolean;
17
17
  get isExpandable(): boolean;
18
- get agColumnGroup(): AgColumnGroup;
18
+ get agColumnGroup(): AgProvidedColumnGroup;
19
19
  constructor();
20
20
  onLinked(): void;
21
21
  destroy(): void;
22
- syncIsExpanded: () => boolean;
22
+ syncIsExpanded: () => void;
23
23
  }
24
24
  export {};
@@ -1,4 +1,4 @@
1
- import { CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, RowClickedEvent, RowDoubleClickedEvent } from '@ag-grid-community/core';
1
+ import { CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, RowClickedEvent, RowDoubleClickedEvent } from '@xh/hoist/kit/ag-grid';
2
2
  import { ColumnRenderer, ColumnSpec, GridContextMenuSpec, GridGroupSortFn, GridModel, GridSorter, GridSorterLike, GroupRowRenderer, RowClassFn, RowClassRuleFn, TreeStyle } from '@xh/hoist/cmp/grid';
3
3
  import { Awaitable, HoistModel, LoadSpec, PlainObject, Some, Thunkable, VSide } from '@xh/hoist/core';
4
4
  import { RecordAction, Store, StoreConfig, StoreRecordOrId, StoreSelectionConfig, StoreSelectionModel, StoreTransaction } from '@xh/hoist/data';
@@ -1,4 +1,4 @@
1
- import { CustomCellEditorProps } from '@ag-grid-community/react';
1
+ import { CustomCellEditorProps } from '@xh/hoist/kit/ag-grid';
2
2
  import { Column, GridModel } from '@xh/hoist/cmp/grid';
3
3
  import { HoistInputProps } from '@xh/hoist/cmp/input';
4
4
  import { HoistProps } from '@xh/hoist/core';
@@ -1,4 +1,4 @@
1
- import { RowDoubleClickedEvent } from '@ag-grid-community/core';
1
+ import { RowDoubleClickedEvent } from '@xh/hoist/kit/ag-grid';
2
2
  import { BaseFieldConfig } from '@xh/hoist/cmp/form';
3
3
  import { GridConfig, GridModel } from '@xh/hoist/cmp/grid';
4
4
  import { ElementSpec, HoistModel, PlainObject } from '@xh/hoist/core';
@@ -1,3 +1,4 @@
1
+ import { Component } from 'react';
1
2
  /**
2
3
  * The exports below are ag-Grid components provided at runtime by applications.
3
4
  *
@@ -11,9 +12,11 @@ export declare let agGridVersion: any;
11
12
  * However Hoist does import the following community-only TYPES to help validate its internal
12
13
  * implementations.
13
14
  */
14
- export type { GridOptions, GridApi, SortDirection, ColDef, ColGroupDef, GetContextMenuItemsParams, GridReadyEvent, IHeaderGroupParams, IHeaderParams, ProcessCellForExportParams, CellClassParams, HeaderClassParams, HeaderValueGetterParams, ICellRendererParams, ITooltipParams, IRowNode, RowClassParams, ValueGetterParams, ValueSetterParams, MenuItemDef, CellPosition, NavigateToNextCellParams, Column as AgColumn, ColumnGroup as AgColumnGroup } from '@ag-grid-community/core';
15
+ export type { GridOptions, GridApi, SortDirection, ColDef, ColGroupDef, GetContextMenuItemsParams, GridReadyEvent, IHeaderGroupParams, IHeaderParams, ProcessCellForExportParams, CellClassParams, HeaderClassParams, HeaderValueGetterParams, ICellRendererParams, ITooltipParams, IRowNode, RowClassParams, ValueGetterParams, ValueSetterParams, MenuItemDef, CellPosition, NavigateToNextCellParams, ColumnEvent, ColumnState as AgColumnState, Column as AgColumn, ColumnGroup as AgColumnGroup, AgProvidedColumnGroup, RowDoubleClickedEvent, RowClickedEvent, RowHeightParams, CellClickedEvent, CellContextMenuEvent, CellDoubleClickedEvent, CellEditingStartedEvent, CellEditingStoppedEvent } from 'ag-grid-community';
16
+ export type { CustomCellEditorProps } from 'ag-grid-react';
17
+ export { useGridCellEditor } from 'ag-grid-react';
15
18
  /**
16
19
  * Expose application versions of ag-Grid to Hoist.
17
20
  * Typically called in the Bootstrap.js. of the application.
18
21
  */
19
- export declare function installAgGrid(ComponentReactWrapper: any, version: string): void;
22
+ export declare function installAgGrid(ComponentReactWrapper: Component, version: string): void;
@@ -100,7 +100,6 @@ export const [AgGrid, agGrid] = hoistCmp.withFactory<AgGridProps>({
100
100
  item: createElement(AgGridReact, {
101
101
  ...AgGrid['DEFAULT_PROPS'],
102
102
  // Default some ag-grid props, but allow overriding.
103
- reactiveCustomComponents: true, // will be default in ag-grid v32
104
103
  getRowHeight: impl.getRowHeight,
105
104
  // Pass others on directly.
106
105
  ...agGridProps,
@@ -305,65 +305,22 @@ export class AgGridModel extends HoistModel {
305
305
  it => !isArray(it.colId)
306
306
  ),
307
307
  {agApi} = this,
308
- isPivot = agApi.isPivotMode(),
309
- havePivotCols = !isEmpty(agApi.getPivotColumns()),
310
308
  defaultState = {
311
309
  sort: null,
312
310
  sortIndex: null
313
311
  };
314
312
 
315
- // ag-Grid does not allow "secondary" columns to be manipulated by applyColumnState
316
- // so this approach is required for setting sort config on secondary columns.
317
- if (isPivot && havePivotCols && !isEmpty(secondaryColumnState)) {
318
- // 1st clear all pre-existing primary column sorts
319
- // with an explicit clear of the auto_group column,
320
- // which is not cleared by the defaultState config.
321
- agApi.applyColumnState({
322
- state: [
323
- {
324
- colId: AgGridModel.AUTO_GROUP_COL_ID,
325
- sort: null,
326
- sortIndex: null
327
- }
328
- ],
329
- defaultState
330
- });
331
-
332
- // 2nd clear all pre-existing secondary column sorts
333
- agApi.getPivotResultColumns().forEach(col => {
334
- if (col) {
335
- // When using `applyColumnState`, `undefined` means do nothing, `null` means set to none, not cleared.
336
- // But when using the setSort & setSortIndex methods directly, to clear all sort settings as if no sort
337
- // had ever been specified, `undefined` must be used.
338
- col.setSort(undefined, null);
339
- col.setSortIndex(undefined);
340
- }
341
- });
342
-
343
- // finally apply sorts from state to secondary columns
344
- secondaryColumnState.forEach(state => {
345
- // TODO -- state saving for pivot appears broken.
346
- // Related to TS error below? Need to analyze and tear down if no longer needed.
347
- // @ts-ignore
348
- const col = agApi.getPivotResultColumn(state.colId[0], state.colId[1]);
349
- if (col) {
350
- col.setSort(state.sort, null);
351
- col.setSortIndex(state.sortIndex);
352
- } else {
353
- this.logWarn(
354
- 'Could not find a secondary column to associate with the pivot column path',
355
- state.colId
356
- );
357
- }
358
- });
359
- }
313
+ // ag-Grid has had issues manipulating secondary columns with applyColumnState
314
+ // If support here deemed necessary, more investigation could be done.
315
+ throwIf(
316
+ agApi.isPivotMode() &&
317
+ !isEmpty(agApi.getPivotColumns()) &&
318
+ !isEmpty(secondaryColumnState),
319
+ 'setSortState not currently supported for PivotGrid with secondary column state '
320
+ );
360
321
 
361
322
  // always apply any sorts on primary columns (includes the auto_group column on pivot grids)
362
- agApi.applyColumnState({
363
- state: primaryColumnState,
364
- defaultState
365
- });
366
-
323
+ agApi.applyColumnState({state: primaryColumnState, defaultState});
367
324
  agApi.onSortChanged();
368
325
  }
369
326
 
@@ -416,7 +373,6 @@ export class AgGridModel extends HoistModel {
416
373
  const sortBy = castArray(value).map(it => GridSorter.parse(it));
417
374
  const {agApi} = this,
418
375
  prevSortBy = this._prevSortBy;
419
- let togglingAbsSort = false;
420
376
 
421
377
  if (isEqual(prevSortBy, sortBy)) return;
422
378
 
@@ -429,7 +385,6 @@ export class AgGridModel extends HoistModel {
429
385
  )
430
386
  )
431
387
  ) {
432
- togglingAbsSort = true;
433
388
  agApi.applyColumnState({defaultState: {sort: null, sortIndex: null}});
434
389
  }
435
390
 
@@ -447,12 +402,6 @@ export class AgGridModel extends HoistModel {
447
402
  defaultState: {sort: null, sortIndex: null}
448
403
  });
449
404
 
450
- // Workaround needed for ag v27.
451
- // https://github.com/xh/hoist-react/issues/2997
452
- if (togglingAbsSort) {
453
- agApi.redrawRows();
454
- }
455
-
456
405
  this._prevSortBy = sortBy;
457
406
  }
458
407
 
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
- import {RowClickedEvent, RowDoubleClickedEvent, RowHeightParams} from '@ag-grid-community/core';
7
+ import {RowClickedEvent, RowDoubleClickedEvent, RowHeightParams} from '@xh/hoist/kit/ag-grid';
8
8
  import {
9
9
  ColumnRenderer,
10
10
  ColumnSpec,
package/cmp/grid/Grid.ts CHANGED
@@ -4,7 +4,8 @@
4
4
  *
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
- import {ColumnState as AgColumnState, GridApi} from '@ag-grid-community/core';
7
+ import {GridApi, AgColumnState} from '@xh/hoist/kit/ag-grid';
8
+
8
9
  import composeRefs from '@seznam/compose-react-refs';
9
10
  import {agGrid, AgGrid} from '@xh/hoist/cmp/ag-grid';
10
11
  import {ColumnState, getTreeStyleClasses} from '@xh/hoist/cmp/grid';
@@ -94,11 +95,19 @@ export const [Grid, grid] = hoistCmp.withFactory<GridProps>({
94
95
  className: 'xh-grid',
95
96
 
96
97
  render({model, className, testId, ...props}, ref) {
97
- const {store, treeMode, treeStyle, highlightRowOnClick, colChooserModel, filterModel} =
98
- model,
98
+ const {
99
+ store,
100
+ treeMode,
101
+ treeStyle,
102
+ highlightRowOnClick,
103
+ colChooserModel,
104
+ filterModel,
105
+ enableFullWidthScroll
106
+ } = model,
99
107
  impl = useLocalModel(GridLocalModel),
100
108
  platformColChooser = XH.isMobileApp ? mobileColChooser : desktopColChooser,
101
- maxDepth = impl.isHierarchical ? store.maxDepth : null;
109
+ maxDepth = impl.isHierarchical ? store.maxDepth : null,
110
+ container = enableFullWidthScroll ? vframe : frame;
102
111
 
103
112
  className = classNames(
104
113
  className,
@@ -109,9 +118,6 @@ export const [Grid, grid] = hoistCmp.withFactory<GridProps>({
109
118
  highlightRowOnClick ? 'xh-grid--highlight-row-on-click' : null
110
119
  );
111
120
 
112
- const {enableFullWidthScroll} = model.experimental,
113
- container = enableFullWidthScroll ? vframe : frame;
114
-
115
121
  return fragment(
116
122
  container({
117
123
  className,
@@ -128,7 +134,7 @@ export const [Grid, grid] = hoistCmp.withFactory<GridProps>({
128
134
  ],
129
135
  testId,
130
136
  onKeyDown: impl.onKeyDown,
131
- ref: composeRefs(impl.viewRef, ref)
137
+ ref: composeRefs(impl.viewRef, model.viewRef, ref)
132
138
  }),
133
139
  colChooserModel ? platformColChooser({model: colChooserModel}) : null,
134
140
  filterModel ? gridFilterDialog({model: filterModel}) : null
@@ -193,13 +199,13 @@ export class GridLocalModel extends HoistModel {
193
199
  {clicksToEdit, selModel} = model;
194
200
 
195
201
  let ret: GridOptions = {
196
- reactiveCustomComponents: true, // will be default in ag-grid v32
197
202
  animateRows: false,
198
203
  suppressColumnVirtualisation: !model.useVirtualColumns,
199
204
  getRowId: ({data}) => data.agId,
200
205
  defaultColDef: {
201
206
  sortable: true,
202
207
  resizable: true,
208
+ suppressHeaderContextMenu: true,
203
209
  suppressHeaderMenuButton: true,
204
210
  menuTabs: ['filterMenuTab']
205
211
  },
@@ -220,9 +226,6 @@ export class GridLocalModel extends HoistModel {
220
226
  agColumnHeader: props => columnHeader({...props, gridModel: model}),
221
227
  agColumnGroupHeader: props => columnGroupHeader({...props, gridModel: model})
222
228
  },
223
- rowSelection: selModel.mode == 'disabled' ? undefined : selModel.mode,
224
- suppressRowClickSelection: !selModel.isEnabled,
225
- isRowSelectable: () => selModel.isEnabled,
226
229
  tooltipShowDelay: 0,
227
230
  getRowHeight: this.defaultGetRowHeight,
228
231
  getRowClass: ({data}) => (model.rowClassFn ? model.rowClassFn(data) : null),
@@ -255,8 +258,7 @@ export class GridLocalModel extends HoistModel {
255
258
  autoGroupColumnDef: {
256
259
  suppressSizeToFit: true // Without this the auto group col will get shrunk when we size to fit
257
260
  },
258
- autoSizePadding: 3, // tighten up cells for ag-Grid native autosizing. Remove when Hoist autosizing no longer experimental,
259
- editType: model.fullRowEditing ? 'fullRow' : undefined,
261
+ editType: model.fullRowEditing ? 'fullRow' : 'singleCell',
260
262
  singleClickEdit: clicksToEdit === 1,
261
263
  suppressClickEdit: clicksToEdit !== 1 && clicksToEdit !== 2,
262
264
  stopEditingWhenCellsLoseFocus: true,
@@ -266,6 +268,16 @@ export class GridLocalModel extends HoistModel {
266
268
  processUnpinnedColumns: () => []
267
269
  };
268
270
 
271
+ if (selModel.mode != 'disabled') {
272
+ ret.rowSelection = {
273
+ mode: selModel.mode == 'single' ? 'singleRow' : 'multiRow',
274
+ enableClickSelection: selModel.isEnabled,
275
+ isRowSelectable: () => selModel.isEnabled,
276
+ checkboxes: false,
277
+ headerCheckbox: false
278
+ };
279
+ }
280
+
269
281
  // Platform specific defaults
270
282
  if (XH.isMobileApp) {
271
283
  ret = {
@@ -277,7 +289,7 @@ export class GridLocalModel extends HoistModel {
277
289
  ret = {
278
290
  ...ret,
279
291
  allowContextMenuWithControlKey: true,
280
- getContextMenuItems: this.getContextMenuItems
292
+ getContextMenuItems: this.getContextMenuItems as any
281
293
  };
282
294
  }
283
295
 
@@ -292,7 +304,7 @@ export class GridLocalModel extends HoistModel {
292
304
  }
293
305
 
294
306
  // Support for FullWidthScroll
295
- if (model.experimental.enableFullWidthScroll) {
307
+ if (model.enableFullWidthScroll) {
296
308
  ret.suppressHorizontalScroll = true;
297
309
  }
298
310
 
@@ -307,12 +319,12 @@ export class GridLocalModel extends HoistModel {
307
319
  }
308
320
 
309
321
  getContextMenuItems = (params: GetContextMenuItemsParams) => {
310
- const {model, agOptions} = this,
322
+ const {model} = this,
311
323
  {contextMenu} = model;
312
324
  if (!contextMenu || XH.isMobileApp || model.isEditing) return null;
313
325
 
314
326
  // Manipulate selection if needed.
315
- if (!agOptions.suppressRowClickSelection) {
327
+ if (model.selModel.isEnabled) {
316
328
  const record = params.node?.data,
317
329
  {selModel} = model;
318
330
 
@@ -431,8 +443,7 @@ export class GridLocalModel extends HoistModel {
431
443
  return (
432
444
  agOptions.getRowHeight &&
433
445
  !agOptions.rowHeight &&
434
- !model.getVisibleLeafColumns().some(c => c.autoHeight) &&
435
- model.experimental.useScrollOptimization !== false
446
+ !model.getVisibleLeafColumns().some(c => c.autoHeight)
436
447
  );
437
448
  }
438
449