Migration Guide to 9.x (2025-05-10)

Embracing ESM-only builds ⚡

This new release is focused around 2 things, we now ship ESM-only builds (in other words, CommonJS builds are fully dropped and only ESM will remain), this move will cut the npm download size by half. The other big change is an internal one which is an organizational one, I'm moving all framework wrappers directly into Slickgrid-Universal (Angular, Aurelia, React and Vue wrappers are now all located under the Slickgrid-Universal frameworks/ folder). This change will help tremendously with the project maintenance (any new PR will now run against all frameworks all at once (catching bugs early), publishing a new version is now a single click execution for all frameworks all at once, and finally having a single codebase to test & troubleshoot all wrappers, etc... will be so much easier to handle). With this new structure change, Slickgrid-Universal name now makes so much more sense. 🌐

The other great thing about having everything under the same roof/project is that every package will now be released at the same time with the exact same version number across the board. Everything will be released under v9.0 and whenever any new feature/bugfix comes in, then every package will be bumped to v9.1 and so on (no more version discrepancies).

Wait, what happened to version 6 to 8?

I'm skipping versions 6-8 and going straight to v9.0 because some of the wrappers (Angular-Slickgrid, Aurelia-Slickgrid) were already at v8.x and so the next available major version bump for everything was v9.0

Major Changes - Quick Summary

  • minimum requirements bump

    • Node v20+

  • upgrade Vanilla-Calendar-Pro to v3 with flat config

  • skipping v6-8 and going straight to v9.0

  • now using clipboard API, used in ExcelCopyBuffer/ContextMenu/CellCopy, which might requires end user permissions

  • removing Arrow pointer from Custom Tooltip addon (because it was often offset with the cell text)

Note: if you come from an earlier version, please make sure to follow each migrations in their respected order (review previous migration guides)

Changes

Removed @deprecated code

  1. colspanCallback was deprecated and removed, please use the globalItemMetadataProvider instead

gridOptions = {
- colspanCallback: this.renderDifferentColspan.bind(this),
+ dataView: {
+   globalItemMetadataProvider: {
+     getRowMetadata: this.renderDifferentColspan.bind(this)
+   }
+ }
}
  1. Row Detail changes

  • itemDetail property is removed, just use item (there's no reason to keep duplicate props)

  • parent property renamed to parentRef

  • OnRowBackToViewportRangeArgs and OnRowOutOfViewportRangeArgs were equal, so it was merged into a new OnRowBackOrOutOfViewportRangeArgs interface

export class Component {
  notifyTemplate(itemDetail: ItemDetail) {
    this.rowDetail.onAsyncResponse.notify(
-     { item: itemDetail, itemDetail },
+     { item: itemDetail },
      {}, // params
      this
    );
  }

  // `parent` renamed as `parentRef`
  callParentMethod(model: any) {
-    this.parent!.someParentFunction(`We just called Parent Method from the Row Detail Child Component on ${model.title}`);
+    this.parentRef!.someParentFunction(`We just called Parent Method from the Row Detail Child Component on ${model.title}`);
  }
}
  1. Draggable Grouping setDroppedGroups to load grid with initial Groups was deprecated and now removed, simply use initialGroupBy instead

this.gridOptions = {
  enableDraggableGrouping: true,
  // frozenColumn: 2,
  draggableGrouping: {
-   setDroppedGroups: () => ['duration', 'cost'],
+   initialGroupBy: ['duration', 'cost'],
  },
};
  1. for Header Menu, we had 2 similar events onHeaderMenuHideColumns and onHideColumns that were doing basically the same thing, so I decided to drop onHeaderMenuHideColumns

- onHeaderMenuHideColumns
+ onHideColumns

Grid Options

rowTopOffsetRenderType default is changing from 'top' to 'transform' and the reason is because transform is known to have better styling perf, especially on large dataset, and that is also what Ag-Grid uses by default.

previous default
new default

rowTopOffsetRenderType: 'top'

rowTopOffsetRenderType: 'transform'

  • if you are using Cypress to get the row X in the grid, which is what we do ourselves, then you will need to adjust your tests

Cypress before
Cypress after

cy.get([style="top: ${GRID_ROW_HEIGHT * 0}px;"])

cy.get([style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"])

OR cy.get([data-row=0])

Please note that you will have to change the option back to rowTopOffsetRenderType: 'top' when using either RowSpan and/or Row Detail features.

Column Functionalities

Date Editor/Filter

Vanilla-Calendar-Pro was upgraded to v3.0 and their main breaking change was the move to flat config (instead of complex object config) and this mean that if you use any of their option, you'll have to update them to use the new flat options.

The biggest change that you will most probably have to update is the min/max date setting when using the 'today' shortcut as shown below:

import { type VanillaCalendarOption } from '@slickgrid-universal/common';

prepareGrid() {
  this.columnDefinitions = [{
    id: 'finish', field: 'finish', name: 'Finish',
    editor: {
      model: Editors.date,
-      editorOptions: { range: { min: 'today' } } as VanillaCalendarOption,
+      editorOptions: { displayDateMin: 'today' } as VanillaCalendarOption,
    }
  }];
}

[!NOTE] for a complete list of option changes, visit the Vanilla-Calendar-Pro migration page, which details every single options with their new associated option names.

Grid Functionalities

Services

The GridService has CRUD methods that were sometime returning a single item and other times an array of items and for that reason we had to rely on code like onItemAdded.subscribe(item => { const items = Array.isArray(item) ? item : [item] }. So for that reason, I decided to change the event names to plural and always return an array of items which is a lot more predictable.

  • onItemAdded renamed to onItemsAdded

  • onItemDeleted renamed to onItemsDeleted

  • onItemUpdated renamed to onItemsUpdated

  • onItemUpserted renamed to onItemsUpserted


Future Changes (next major)

Code being Deprecated (to be removed in the future, but not until another year)

You can start using these new properties and options (shown below) in v9.0 and above.

So when I created the project, I used a few TypeScript Enums and I thought that was great, however what I didn't know at the time is that all of these Enums are ending up in the final transpiled JS bundle and that takes space (but type do not). So in the next major, I'm planning to remove most of these Enums and replace them with string literal types (type instead of enum because type aren't transpiled and enum are). So you should consider using string types as much, and as soon, as possible in all your new grids and eventually make the changes in your older grids. Note that at the moment, these are only tagged as deprecations and they will only be dropped in the future (not now, but still, you should consider making this change in the near future), for example:

columns = [{
  id: 'age', ...
- type: FieldType.number,
+ type: 'number',
}];

Note that using the string types (ie: 'number') instead of FieldType was already doable for the past couple years, so this is far from new.

Below are a list of Enums being deprecated and you should think about migrating them eventually because they will be removed in the next major release (whenever that happens, but that won't be before another year). Note that the list below are only a summary of these deprecations and replacements.

Enum Name

from enum

to string type

Note

FieldType

FieldType.boolean

'boolean'

FieldType.number

'number'

-

-

-

FileType

FileType.csv

'csv'

FileType.xlsx

'xlsx'

-

-

-

GridStateType

GridStateType.columns

'columns'

GridStateType.filters

'filters'

GridStateType.sorters

'sorters'

-

-

-

Operator

Operator.greaterThan

'>'

See Operator list for all available opeators

Operator.lessThanOrEqual

'<='

Operator.contains

'Contains' or 'CONTAINS'

Operators are written as PascalCase

Operator.equal

'EQ'

Operator.rangeExclusive

'RangeExclusive'

-

-

-

SortDirection

SortDirection.ASC

'ASC' or 'asc'

SortDirection.DESC

'DESC' or 'desc'

-

-

-

deprecating editorOptions and filterOptions, they are being renamed as a more generic options name

in order to make it easier to merge and simplify editor/filter options, I'm renaming the options to a single options property which will make it more easily transportable (you will be able to reuse the same options for both the editor/filter if you wanted). You can start using options in v9.0 and above (or keep using editorOptions, filterOptions).

import { type MultipleSelectOption } from '@slickgrid-universal/common';

columnDefinitions = [{
  id: 'duration', field: 'duration', name: 'Duration',
  editor: {
-   editorOptions: {
+   options: {
      maxHeight: 250, useSelectOptionLabelToHtml: true,
    } as MultipleSelectOption,
  },
  filter: {
-   filterOptions: {
+   options: {
      maxHeight: 250, useSelectOptionLabelToHtml: true,
    } as MultipleSelectOption,
  }
}];

// or reuse the same `options`
+ const msOptions = { maxHeight: 250, useSelectOptionLabelToHtml: true } as MultipleSelectOption;

columnDefinitions = [{
  id: 'duration', field: 'duration', name: 'Duration',
  editor: {
+   options: msOptions,
  },
  filter: {
+   options: msOptions,
  },
}];

Last updated