Skip to content

Migration to 5.x

Ghislain B edited this page May 6, 2024 · 24 revisions

Version 5 - Better UI and Dark Mode with Pure CSS SVG icons ✨

This new release brings a lot of changes oriented towards better UI/UX, our SVG icons are now pure CSS and can be colorized like any other text via the native CSS color property (which helps a lot improving the Dark Mode Theme).

Another noticeable UI change is the migration from Flatpickr to Vanilla-Calendar-Picker (which is a fork of Vanilla-Calendar-Pro and we'll hopefully drop the fork in the near future if possible), there are multiple reasons to migrate our date picker to another library:

  • Flatpickr cons:

    • barely supported (lots of opened PR but nothing merged for the past 2 years)
    • not fully ESM ready (it's only partially ESM, for example it is detected as CJS in Angular-Slickgrid and requires to be added to allowedCommonJsDependencies)
    • styling could be a bit more modern (the use of native select/input to change year/month/time is a bit outdated and rudimentary)
    • date range selection is not very user friendly (UX)
  • Vanilla-Calendar (VC)

    • pros:
      • ESM ready
      • modern styling and also includes Dark Mode theme
      • date range becomes a lot more easy by displaying a picker with 2 months
    • cons:
      • build size is slightly larger but its UI/UX is awesome
      • settings are named differently and are not using flat config (complex object settings) and requires code change
        • for example Flatpickr minDate: 'today' is instead range: { min: 'today' } in VC
      • some settings were missing, like the 'today' shortcut which is why I forked the VC project
        • I did open a few PRs on the main project, so the hope is to drop the fork in the future while being a totally transparent change to you when it happens.

With this release, and after 7 years of development with a 1 man show (myself @ghiscoding), I believe that I have achieved all goals and even more than I originally planned to accomplish. I am not expecting to roll that many major releases for the foreseable future, because like I just said, most goals of this project have been accomplished. I think the biggest challenge and transition was the removal of jQuery/jQueryUI which took couple of years to accomplish of which that I am very proud to have achieved.

The goal of this new release was mainly to improve UI/UX (mostly for Dark Mode) and also to make it fully ESM ready. Also noteworthy, the project now has a similar or slightly smaller size in comparison to what it was in v2.x (that was when the user had to install jQuery/jQueryUI separately). So, considering that we're no longer requiring the install of jQuery/jQueryUI, and also considering that these 2 dependencies have a total of well over 200kb. So, we can safely assume that our project build size is in fact a lot smaller than it was 2 years ago, that is really nice to know considering that we kept adding features (like Dark Mode and others) while still maintainging, or slightly decreasing, its size :)

Major Changes - Quick Summary

  • minimum requirements bump
    • Node >=v18.x
    • Bootstrap >=v5.x (or any other UI framework)
    • SASS >=v1.35 (dart-sass)
    • migrated from Flatpickr to Vanilla-Calendar (visit Vanilla-Calendar-Pro for demos and docs)
    • migrated from MomentJS to Tempo (by the FormKit team)

Note for the entire list of tasks & code changes applied in this release, you may want to take a look at the Roadmap to 5.0 Discussion.

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

For most breaking changes, a quick Search & Replace in your code editor should suffice.

Changes

Styling

CSS classes .color-xx are all removed (use .text-color-xx or native color instead)

Note these extra colors are only available in the Material & Salesforce Themes (it is not included in the Bootstrap Theme since Bootstrap have their own coloring utils).

Since the SVG icons are now pure CSS, we can now colorize any of them the same way that we would do for any other text via the color CSS property 🌈. For that reason, we no longer need any of the .color-xx CSS classes (which were created via CSS filter). They were useful to override the SVG icon colors (by using CSS filter), but since we can now use the regular CSS color property, the color-xx are no longer necessary and were all removed (just use text-color-xx instead or simply plain colors).

<button class="button is-small">
-  <span class="mdi mdi-undo color-primary"></span>
+  <span class="mdi mdi-undo text-color-primary"></span>
   <span class="text-color-primary">Undo Last Edit</span>
</button>

or move the class to the parent container and have both the icon & the text inherit the color :)

+ <button class="button is-small text-color-primary">
-   <span class="mdi mdi-undo color-primary"></span>
+   <span class="mdi mdi-undo"></span>
-   <span class="text-color-primary">Undo Last Edit</span>
  </button>

SASS variables

A lot of SASS variables were changed, we recommend that you take a look at the _variables.scss file to compare them with yours SASS overrides and fix any SASS build issues. For example a lot of the ms-select variables and all Flatpickr related variables were deleted (note that Vanilla-Calendar doesn't have any variales). Also a lot of the icon related variables got updated (icons now have the suffix -icon-svg-path for the SVG vector path).

Note if you want create your own SVGs in pure CSS, you can use the generateSvgStyle() function from our svg-utilities.scss (take a look at the slickgrid-icons.scss for usage)

SASS (dart-sass) math polyfills are removed

When SASS (dart-sass) released their version 1.33 (~3 years ago), it caused a ton of console warnings (and a lot of unhappy users) in projects that were using / in their SASS files (for math division) instead of their new math.div() function. To avoid seeing all these warnings, I added a temporary polyfill at the time (that piece of code was actually copied from the Bootstrap project). That polyfill patch was put in place about 3 years ago, so I'm assuming that most users have already upgraded their SASS version and already fixed all of these warnings... So, I think it's time to remove this polyfill because it was really meant to be a temp patch. If you see some warnings coming back, then a suggestion would be to use the SASS option --quiet-upstream via the CLI.

For reference, below is an example of these old Math warnings when we used to compile it with SASS CLI

Recommendation: math.div($m, $columns)
More info and automated migrator: https://sass-lang.com/d/slash-div
╷
94 │ margin-right: $m / $columns * 100%
│ ^^^^^^^^^^^^^^^^^^

Font-Awesome references are all removed

Since this release introduces pure CSS SVG icons, I went ahead and deleted all Font-Awesome references (mostly in the Bootstrap Theme), that is because all the built-in icons are now all SVG icons (sort, grouping, row detail, row move, row selection). You can also change these icons via SASS (or CSS variables with a bit more work). However, there are a few plugins that use external icons via CSS classes (mostly all menu plugins like Header Menu, Grid Menu, Content Menu, ...) and for that reason all Styling Themes now include the Slickgrid-Universal Material icons subset by default (not just Material & Salesforce but now also the Bootstrap Theme as well). In short, the grid now uses SVG icons by default and Font-Awesome icons will no longer be used internally (you can still use them in your project but it won't be used by the grid unless you set them in your grid options).

If you no longer need Font-Awesome, then consider removing it completely

# package.json
{
  dependencies: {
-   "font-awesome": "^4.7.0"
  }
}

What if you don't want to use the Slickgrid-Universal icons (.mdi) subset and would rather use a different font/SVG library? In that case, it's suggested to use the "lite" Themes (which do not include the colors & icons subset) and then make sure to update all the menu plugins with the correct CSS classes. For example the global grid options of the Grid Menu is now configured with the following icon classes (notice that we no longer provide any Font-Awesome "fa" icon references in our global grid options). Also note that what is shown below is just 1 of the multiple menu plugins to configure, make sure to review them all (you can review the global-grid-options.ts file).

// default global grid options
export const GlobalGridOptions = {
  gridMenu: {
    iconCssClass: 'mdi mdi-menu',
    iconClearAllFiltersCommand: 'mdi mdi-filter-remove-outline',
    iconClearAllSortingCommand: 'mdi mdi-sort-variant-off',
    iconClearFrozenColumnsCommand: 'mdi mdi-pin-off-outline',
    iconExportCsvCommand: 'mdi mdi-download',
    iconExportExcelCommand: 'mdi mdi-file-excel-outline',
    iconExportTextDelimitedCommand: 'mdi mdi-download',
    iconRefreshDatasetCommand: 'mdi mdi-sync',
    iconToggleDarkModeCommand: 'mdi mdi-brightness-4',
    iconToggleFilterCommand: 'mdi mdi-flip-vertical',
    iconTogglePreHeaderCommand: 'mdi mdi-flip-vertical',
  },
  headerMenu: {
    // icon...
  }
}

and below is a quick snapshot of the file size diff with the "lite" themes (without icons) vs the default themes (with colors & icons subset). However note that the built-in icons are of course always included.

image

Deprecated code removed/renamed

getHTMLFromFragment() removed

The util getHTMLFromFragment() function was removed in favor of getHtmlStringOutput(), the new function will auto-detect if it's a DocumentFragment, an HTMLElement or an HTML string and will execute the appropriate action.

jQueryUI CSS classes leftovers

There were a few traces of jQueryUI with .ui-state-default, and other similar classes in the core lib and they were all removed in this release. If you were querying any of them for styling purposes, you can simply rename them to .slick-state-*

- .ui-state-default, .ui-state-hover {
+ .slick-state-default, .slick-state-hover {
}

Formatters Cleanup & Removals

Since we now use SVGs everywhere and we got rid of any Font usage (no more Font-Awesome code anywhere), the checkmark Formatter no longer has any reason to exist and was removed. If you were using it and also still use Font-Awesome in your project, you'll have to either recreate the Formatter yourself or use alternatives. You could use the Formatters.icon or Formatters.iconBoolean which require the CSS classes to be provided via params. Or as a last alternative, and if you are importing the optional SVG icons .mdi, then we recommend you simply switch to the checkmarkMaterial Formatter.

this.columnDefinitions = [
  {
    id: 'isActive', name: 'Active', field: 'isActive',
-   formatter: Formatters.checkmark
+   formatter: Formatters.checkmarkMaterial
  },
];

or create a Custom Formatter

// create a custom Formatter and returning a string and/or an object of type FormatterResultObject
const myCheckmarkFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {
  // via native HTML (for CSP safe), you could also use our `createDomElement()` util for 1 liner
  const iconElm = document.createElement('i');
  iconElm.className = value ? 'mdi mdi-check' : '';
  return iconElm;

  // or via simple HTML string
  return value ? '<i class="mdi mdi-check"></i>' : '';
}

Column Functionalities

Native Select Filter (removed)

I would be very surprised if anyone would ever use the Filters.select and so it was removed in this release. You should simply use the Filters.singleSelect or Filters.multipleSelect

prepareGrid() {
  this.columnDefinitions = [{
    id: 'isActive', name: 'Active', field: 'isActive',
    filter: {
-      model: Filters.select,
+      model: Filters.singleSelect,
       collection: [ { value: '', label: '' }, { value: true, label: 'true' }, { value: false, label: 'false' } ],
    }
  }];
}

Date Editor/Filter

We migrated from Flatpicker to Vanilla-Calendar and this require some changes since the setting option names are different. Same changes will be required for both the Filter and the Editor.

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

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

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

Note the 'today' shortcut currently only exist in Vanilla-Calendar-Picker fork, however the rest of the settings should be similar, visit Vanilla-Calendar-Pro settings website for all other options. The hope is to hopefully drop the fork whenever the original project receives all missing features.

internalColumnEditor is completely removed

The work on this subject started over a month ago in version v4.6.0 to progressively remove internalColumnEditor because it was confusing and with this new release, it is now completely removed. This mean that the column editor property will remain untouch (in previous version the editor was moved to internalColumnEditor and then overriden with the editor.model for SlickGrid to work but that was confusing to the user)... in short, the internalColumnEditor is removed and the associated confusion is also gone with it.

An example of the previous internalColumnEditor usage was when you wanted to modify or push a new item to the editor collection array (see below). In the past, you could not simply push directly to collection.editor.collection, you really had to use the mapped collection.internalColumnEditor.collection 😵... this is now thankfully gone, you can now use the same and original collection.editor.collection 👍

For example, previously, to add an item to the editor/filter collection

this.columnDefinitions = [{ id: 'complexity', editor: { model: Editors.singleSelect, collection: [{ value: 1, label: 'Simple' }, /*...*/ ] } }];

// then adding an item would previously require to use `internalColumnEditor`
// after grid init, our `editor` became `internalColumnEditor
- const complexityEditor = this.columnDefinitions[0].internalColumnEditor;
complexityEditor.collection.push({ value: 9, label: 'Hard' });

// NOW with this new release, adding a new item to the collection is as simple as referencing the original object
+ const complexityEditor = this.columnDefinitions[0].editor;
complexityEditor.collection.push({ value: 9, label: 'Hard' });

if you want to read the Editor class (e.g. Editors.longText), you can now reference it via column.editor.model or via column.editorClass

Grid Functionalities

Sanitizer (DOMPurify)

DOMPurify is now completely optional via the sanitizer grid option and you must now provide it yourself. The main reason to make it optional was because most users would use dompurify but some users who require SSR support would want to use isomorphic-dompurify. You could also skip the sanitizer configuration, but that is not recommended.

Note even if the sanitizer is optional, we strongly suggest that you configure it as a global grid option to avoid possible XSS attacks from your data and also to be CSP compliant. Note that for Salesforce users, you do not have to configure it since Salesforce already use DOMPurify internally.

// prefer the global grid options if possible
this.gridOptions = {
  sanitizer: (dirtyHtml) => DOMPurify.sanitize(dirtyHtml, { ADD_ATTR: ['level'], RETURN_TRUSTED_TYPE: true })
};

Note If you're wondering about the ADD_ATTR: ['level'], well the "level" is a custom attribute used by SlickGrid Grouping/Draggable Grouping to track the grouping level depth and it must be kept.

From MomentJS to Tempo

I wanted to replace MomentJS for a long time now (it's been deprecated for years and is CJS only), but it was really hard to find a good replacement (I tried DayJS, Luxon, date-fns and they all had problems)... and here comes Tempo! With Tempo, I was finally able to migrate by taking advantage of parse() and format() Tempo functions which are the most important for our use case. The library also has plenty of extra optional functions as well, like addDay(), diffDays(), ... Another great thing about Tempo is that they use the same format tokens as MomentJS, so the conversion on that side was super easy.

This migration should be transparent to most users like you, however if you were using MomentJS then I would suggest to consider trying Tempo in your project in order to modernize your project and also lower your dependencies count. The other great advantage of Tempo is that it's ESM and it helps a lot in decreasing our build size footprint because of ESM Tree Shacking feature.

Clone this wiki locally