-
Notifications
You must be signed in to change notification settings - Fork 424
Major version 5.0 ‐ ES6 ESM and TypeScript Support
This new version is all about modernizing the project (modern toolings and a modern look), it brings a lot of changes:
- Node 18 is required (since Node 16 is already EOL by a few months already)
- Migrated to TypeScript build which also provides Types (
d.ts
) - ES6 / ESM support while still providing standalone scripts (IIFE)
- New Modern Alpine Theme (inspired by Ag-Grid) that can be customized via SASS and/or CSS variables (Classic Theme is also still available)
- Replaced (removed) all images with a small subset of SVGs that can also be colorized via pure CSS (see SlickGrid Icons)
With this latest version release, we can now say that our journey into modernizing the project is, for the most part, completed (it started with v3 by removing jQueryUI, it was followed by jQuery removal in v4 and today we are modernizing the project in v5). Finally all of that being said, we do not expect any major (aka breaking) changes & versions for the foreseeable future... we're pretty much done!!!
See Migration below for instructions or keep reading for more details about this release.
Bringing ES6/ESM with TypeScript support was the main focus of this release and it also closes our oldest issue #41 while still providing standalone scripts for users who still prefer them. However please note that in order to support this new rewrite, we needed to change the folder structure (all source files were moved to src/
and all builds now exist in the dist/
folder), this also mean that every single users will have to update their script imports to the new dist/[target]
folders in order to use SlickGrid. Also note that all users will no longer be able to use any of the core file directly since they are now TypeScript files.
We now use esbuild in order to support multiple build targets and the new folder structure, we now have the following build output targets
-
IIFE
to still provide standalone<script>
that SlickGrid provided for years (located underdist/browser
with ES2018 build target) -
CJS
for CommonJS build for NodeJS legacy importing viarequire(...)
(located underdist/cjs
with ES2020 build target) -
ESM
for ES6/ESM support which will give us Tree Shaking support (located underdist/esm
with ES2020 build target)
Note I did a lot of research to make sure that we get the smallest possible build sizes for every build formats, for example I did not want to have code that won't be used by the
IIFE
format but is required byESM
and vice versa (i.e.import
s are used by ESM but irrelevant inIIFE
). It took me a while to find the best approach, I even asked on SO with this question: esbuild hybrid plugin to bundle multiple files iife and single esm bundle and opened an issue on esbuild as well. I eventually made it all work with an hybrid approach with the smallest footprint possible for each build types, woohoo 🚀
Since we are now using esbuild, it supports TypeScript out of the box and it is also providing us with a few other benefits
- by using TypeScript we can spot errors early even before publishing any new release when bundling the code (we did actually spot a few small errors in the code)
- provide TS Types
.d.ts
(interfaces, enums, types, ...) - TypeScript extendable (see below for some examples)
- we use
protected
everywhere to make it easily extendable (instead ofprivate
) - we now also provide TS Generics to optionally define your items interface via
SlickGrid<TData>
and/orSlickDataView<TData>
, which then flows to all SlickGrid/DataView sub-methods
- we use
Note if you are using TypeScript and are saving it as a
.ts
file, then make sure to add types to your columns (i.e.:let columns: Column[]
) or else you might get a TypeScript error as displayed in this Stack Overflow. Adding theGridOption
type is also a good idea to make sure that you only use valid options.
Note also make sure that your
import
isfrom 'slickgrid';
notslickgrid/*
since that can also cause issues.
Here's a quick example of how we can now use TypeScript with SlickGrid (see TypeScript Examples Wiki for more details)
// example.ts (TypeScript file)
import { Column, GridOption, SlickDataView, SlickGrid } from 'slickgrid';
let data: any[] = []; // or `data: User[] = [];` with a User interface then provide it as a Generic to SlickGrid (see below)
let columns: Column[] = [{ id: 'firstName', name: 'First Name', field: 'firstName' }, ...]; // or `Column<User>[]` if you want add column type
let options: GridOption = { enableCellNavigation: true, ... };
let grid = new SlickGrid('#myGrid', data, columns, options);
// let grid = new SlickGrid<User>('#myGrid', data, columns, options); // or with a User provided to SlickGrid as Generic type
// similarly for DataView
let dataView = new SlickDataView({ inlineFilter: true });
// let dataView = new SlickDataView<User>({ inlineFilter: true }); // same Generic can be used as data interface
We have a new optional Alpine Theme which is now imported in most examples (but not all of them), if you wanted to compare both the classic (previous theme) and the new Alpine Theme, you could just go to the new ESM Example and toggle the 2 themes by using the associated Theme buttons.
We welcome any new contributions, for example it shouldn't be too hard to add a dark Alpine theme and a contribution would be more than welcome. Please do remember that this is an Open Source project and most of this work is achieved in our spare time (for free) and so we certainly welcome any contributions but please be respectful.
Please note that to align all Menu plugins, we decided to rename all menu item array lists as commandItems
, these changes are preferred but the old names will still work for now with console warnings of the deprecations, these warnings will only be removed in a future major version (if it ever happen). The changes are focused on just these 2 plugins:
- Header Menu
- renamed
items
tocommandItems
- renamed
- Grid Menu
- renamed
customItems
tocommandItems
- renamed
customTitle
tocommandTitle
- renamed
DataView setAggregators
and groupBy
methods were marked as deprecated many years ago by the original author and were finally removed them in this release. They were replaced by setGrouping
a while ago, so just make sure to use the newer setGrouping
method if you haven't already.
We also remove all firebugx
code (they are no longer necessary since all browsers now have much improved developer tools).
All images (.gif
, .png
, ...) were deleted and replaced by a small subset of SVG icons in pure CSS (icons are prefixed with sgi
keyword for "Slick Grid Icons") which can also be colorized via CSS (see SlickGrid Icons page).
We used the technique that Anthony Fu, creator of UnoCSS, wrote in his article Reimagine Atomic CSS, this article was very helpful to learn how easy it is to colorize SVG with pure CSS.
Some might ask, why use SVGs instead of perhaps Data URI or something else? You can read this article Probably Don’t Base64 SVG to understand why SVGs are simply better suited and much smaller than images or fonts.
For example, if you were previously using images in DraggableGrouping (or any other plugins), you might want to replace some of the images by the new SlickGrid SVGs by using .sgi
CSS classes
const draggableGrouping = new Slick.DraggableGrouping({
- deleteIconImage:'../images/delete.png',
- groupIconImage: '../images/column-grouping.png',
+ deleteIconCssClass: 'sgi sgi-close',
+ groupIconCssClass: 'sgi sgi-drag-vertical'
});
Since we migrated to TypeScript Classes and we no longer use any global var
iables, then please note that this caused a scoping issue when using the DraggableGrouping
plugin, so you will need to add a .bind(...)
on the plugin instance to point it to the correct scope.
const draggableGrouping = new Slick.DraggableGrouping();
const gridOptions = {
- enableColumnReorder: draggableGrouping.getSetupColumnReorder(draggableGrouping)
+ enableColumnReorder: draggableGrouping.getSetupColumnReorder.bind(draggableGrouping)
createPreHeaderPanel: true,
showPreHeaderPanel: true,
preHeaderPanelHeight: 25,
}
For users who still want to use standalone <script>
, the migration is quite simple and you will simply have to update your script locations and that's about it. Using standalone scripts will keep providing users with independent scripts the same as before (slick.grid.js
, plugins/slick.headermenu.js
, ...) but from a different location dist/browser/...
Note it is very important that
slick.core.js
andslick.interaction.js
are imported first because core is the script that creates theSlick
namespace andslick.interaction
is also required by the grid. The order might not have been important in the past, but it is important today so that all 3 build types are supported.
- <script src="slickgrid/slick.core.js"></script>
- <script src="slickgrid/slick.grid.js"></script>
+ <script src="slickgrid/dist/browser/slick.core.js"></script>
+ <script src="slickgrid/dist/browser/slick.interactions.js"></script>
+ <script src="slickgrid/dist/browser/slick.grid.js"></script>
or from a CDN like JsDelivr
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/styles/css/slick-alpine-theme.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/slick.core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/slick.interactions.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/slick.grid.min.js"></script>
By using esbuild we can provide multiple new targets (iife
same as before and our new cjs
and esm
), the last 2 are the new ones for the project which allows us to close our oldest issue #41
Note all core files and plugins are exported with the
Slick
prefix (e.g.SlickGrid
,SlickDataView
,SlickColumnPicker
, ...) with some exceptions (Aggregators
,Editors
,Formatters
and all enums likeColAutosizeMode
,RowSelectionMode
, ...)
For a demo, you can take a look at this ESM - Example 4 or our new awesome demo of a Realtime Trading - High Frequency Update dashboard.
- <script src="slickgrid/slick.core.js"></script>
- <script src="slickgrid/slick.grid.js"></script>
+ <script type="module">
+ import {
+ Editors,
+ Formatters,
+ SlickGlobalEditorLock,
+ SlickRowSelectionModel,
+ SlickColumnPicker,
+ SlickDataView,
+ SlickGridPager,
+ SlickGrid,
+ Utils,
+ } from 'slickgrid';
- const dv = new Slick.DataView();
- const grid = new Slick.Grid('#myGrid', dv, columns, options);
// the only difference is the "." which is removed, there's no more Slick namespace
+ const dataView = new SlickDataView();
+ const grid = new SlickGrid('#myGrid', dataView, columns, options);
Note since SortableJS is a hard dependency, you will also need to make sure that you import it and you assign it to the
window
object (unless you load it through<script>
, if so then there's nothing to do). Another way would to be to configure it in your WebPack or Vite config to make it globally available.
+ import Sortable from 'sortablejs';
+ window.Sortable = Sortable;
With the new SlickGrid Alpine Theme, if you are using it, we needed an extra (but optional) CSS class to identify the grid div container, we opted to use slick-container
and even though it is optional, it's probably better to add it to your grids. Again, this extra container CSS class is optional but some of the styling from the new Alpine Theme might not show up correctly without it.
For example, the grid border outline requires this container class to exist for showing the border correctly
- <div id="myGrid" style="width:100%;height:500px;"></div>
+ <div id="myGrid" class="slick-container" style="width:100%;height:500px;"></div>
We now also use CSS flexbox for some part of the grid, like the column headers and that could help in supporting RTL.
With the new Alpine Theme, we went all in and we also provide both CSS and SASS variables for easy customization, both of them are available under the dist/styles/css
or dist/styles/sass
folders. For example if you want to use SASS, you can simply import it.
See available SASS variables, also note that the CSS variables are named with the same name except that you simply need to replace the $
prefix with --
prefix (e.g.: for SASS $alpine-font-size
and for CSS --alpine-font-size
)
Note since CSS Variables offers a fallback when first option is not found, we can use that to our advantage and offer CSS variables as the first choice and SASS variables as a fallback. This mean that if the user is defining both a CSS & SASS variable using the same name, then the CSS variable will win because the SASS is a fallback, however if only a SASS variable is defined then the SASS variable will be used.
with CSS (located under dist/styles/css
)
/* optional CSS variables can be used */
:root {
--alpine-font-size: 14px;
--alpine-font-color: #111;
}
// import the new Alpine Theme
@import 'slickgrid/dist/styles/css/slick-alpine-theme.css';
// or import the old Classic Theme
@import 'slickgrid/dist/styles/css/slick-default-theme.css';
with SASS (located under dist/styles/sass
)
/* change any SASS variables before loading the theme */
$alpine-font-size: 14px;
$alpine-font-color: #111;
// use the new Alpine Theme (currently only SASS theme available)
@import 'slickgrid/dist/styles/sass/slick-alpine-theme.scss';
Below is a list of other ports which extends from this SlickGrid fork and could be used when developing for specific platforms
- Slickgrid-Universal (all)
- Angular-Slickgrid (Angular)
- Aurelia-Slickgrid (Aurelia)
- Slickgrid-React (React)
Since we now use TypeScript, we can now provide extra features for free, we now have Types (interfaces, enums, types, ...), Generics and it's also extendable as shown below.
We added optional TS Generics to provide the item data context interface on the SlickGrid and/or SlickDataView so that you can call any methods from them and automatically get the associated item interface type for them.
import { SlickGrid, SlickDataView } from 'slickgrid';
interface User {
firstName: string;
lastName: string;
age: number;
}
// Generics on SlickGrid
const grid = new SlickGrid<User>('#myGrid', data, columns, options);
const item = grid.getDataItem(0); // item will be User TS type
// or Generics on SlickDataView
const dataView = new SlickDataView<User>();
const grid = new SlickGrid('#myGrid', dataView, columns, options);
const item = dataView.getItemByIdx(0); // item will be User TS type
The SlickGrid class actually has 3 optional Generics, but you will rarely use the last 2. The 1st Generic is the data item type (as shown above), the 2nd is if you want to extend the Column
interface and finally the 3rd and last Generic is if you want to extend the GridOption
interface (these extra Generics were mainly added for Slickgrid-Universal usage since that external project also has extra Column & GridOption properties)
Since we opted to use protected
(instead of private
) across all our TypeScript code, it makes it easy to extends
(or override) any of these TS classes whenever you wish to customize or add extra methods on any of the SlickGrid classes (not just core files but also Controls and Plugins as well).
// for example let's extend Slick DataView
import { SlickDataView } from 'slickgrid';
class CustomSlickDataView extends SlickDataView {
// for example let's add a custom event on the destroy method
onDestroy = new SlickEvent();
constructor() {
super();
}
destroy() {
super.destroy();
this.onDestroy.notify();
}
}
// use our new extended DataView
const dv = new CustomSlickDataView();
dv.onDestroy.subscribe(() => console.log('DataView was destroyed'));
That's it, enjoy the lib and feel free to contribute to the project. If you encounter any problems, create a new issue or a Discussion. Please remember to keep Questions on Stack Overflow, cheers ⭐🍺🚀
We made a quick little poll for fun, it would be nice to hear from you, thanks for taking the time to participate and tell us what you like. Cheers
SlickGrid Repo
- Home
- The SlickGrid Manifesto
- The SlickGrid Community
- BugFix List
- Enhancement List
- Sharing Sample Pages
- Announcement & Migration to 3.0.0
- Announcement & Migration to 4.0.0
- Announcement & Migration to 5.0.0
Jump Start
Resources
- API Reference
- Grid
- Grid Options
- Auto Column Sizing
- Column Options
- Grid Events
- DataView
- DataView Events
- Providing data to the grid
- Plugins & Third-party packages
- CSP Compliance
Learning
Tests
Contact/Support