Handsontable 11.0.0: Modularization for React, Angular, and Vue
Update: Use Handsontable 11.0.1 that fixes a regression in the Angular UMD package found in 11.0.0
We just released Handsontable 11.0.0. This version adds modularization features to the framework wrappers, improves the monorepo structure, adds a new locale
option, and more.
Modularization for React, Angular, and Vue
Modularization is a great way to focus on features that matter to you, customize your grid, and reduce the size of your app.
Since Handsontable 8.3.0, you’ve been able to use modules with the vanilla JavaScript version of Handsontable. Now, you can use modules with each of Handsontable’s framework versions (React, Angular, and Vue) as well.
While it’s great news for all our React, Angular and Vue users out there, it’s also a breaking change, as you now need to import each module that you want to use. For example, to import the UndoRedo
plugin’s module:
// import the `handsontable/base` module
import Handsontable from 'handsontable/base';
// import the `UndoRedo` module and the `registerPlugin()` function
import {
registerPlugin,
UndoRedo,
} from 'handsontable/plugins';
// register the `UndoRedo` module
registerPlugin(UndoRedo);
Not interested in modularization? Fear not: we also introduced new methods that let you import and register all modules of a given category at once.
To learn more about Handsontable’s modules, see our documentation.
To learn how to use modules with your framework, see one of those guides:
Revised & modularized TypeScript definitions
Ever since we introduced modularization in Handsontable 8.3.0, we wanted to give every module full TypeScript support.
To achieve this, we decided to remove the huge, cover-it-all TypeScript definitions file (previously located in the root directory: ./handsontable.d.ts
). Instead, we replaced it with a neatly-prepared set of smaller files (now located in a new directory: ./handsontable/types
), dedicated to individual parts of Handsontable.
As a result, we double-checked and revised nearly all of Handsontable’s type definitions. Why does it matter? For several reasons:
- All Handsontable modules now support TypeScript. Each module has its own TypeScript definitions files. You can use all modules in a TypeScript environment, importing them without errors.
- The structure of the TypeScript definitions files now follows the structure of the source files. Type definitions are now more transparent, and easier to understand.
- Any types you import are now consistent with what you’ll find in the runtime.
From a TypeScript user’s perspective, if you import the whole Handsontable library, everything stays the same. All type definitions are loaded on importing the Handsontable
package:
import Handsontable from 'handsontable';
The new thing is that now, the type definitions are also automatically loaded when you import individual modules, for example:
import Handsontable from 'handsontable/base';
import { registerPlugin, HiddenRows } from 'handsontable/plugins';
const hiddenRows = Handsontable.plugins.HiddenRows;
Cleaner monorepo structure
In Handsontable 8.3.2, we placed all Handsontable versions (JavaScript, Angular, React, and Vue) in a single monorepo.
Now, to manage the monorepo more easily, and add better support for third-party tools like Snyk or npm-audit, we placed Handsontable’s main JavaScript package in its own, dedicated workspace. We moved it from the root directory to a new subdirectory: ./handsontable
, placing it at the same level as the framework wrappers:
Before: |
After: |
This change may affect you if you were planning to contribute to Handsontable’s repository, or if you build your own versions of Handsontable locally. Other than that, it shouldn’t affect your app in any way.
To learn more about building Handsontable locally, see this guide.
Enhanced populateFromArray()
method
The populateFromArray()
method works differently now, when its method
argument is set to shift_down
or shift_right
.
Before, when set to shift_down
or shift_right
, populateFromArray()
performed a separate spliceRow
action for each row, or a separate spliceColumn
action for each column.
Now, when set to shift_down
or shift_right
, populateFromArray()
populates rows (or columns) with one large operation. The difference in performance is really impressive:
If you use the beforeChange
and afterChange
hooks triggered by each spliceRow
and spliceColumn
action, you’ll need to adapt to the changes. For details, see the migration guide.
New locale
option
To properly handle locale-based data, we gave Handsontable a new configuration option, called locale
. By default, it’s set to en-US
.
As of now, we only use locale
to ensure proper filtering of custom search input in Turkish, but we plan to expand its use in the future, to further customize features such as filtering, searching, or comparing different sets of locale-based data. It’s a great starting point for improving Handsontable’s built-in internationalization capabilities.
You can set the locale
option for the entire grid:
const hot = new Handsontable(container, {
// set the entire grid's locale to Turkish
locale: 'tr-TR',
});
But you can also set it for individual columns:
const hot = new Handsontable(container, {
columns: [
{
// set the first column's locale to Polish
locale: 'pl-PL',
},
{
// set the second column's locale to German
locale: 'de-DE',
},
{
// set the third column's locale to Japanese
locale: 'ja-JP',
},
],
});
To learn more, see the Handsontable documentation.
Updated documentation
As promised, we keep improving Handsontable’s documentation. Since the last Handsontable release, we did a complete overhaul of the API reference’s Options section, rewrote a few guides (e.g. Building), restructured some others (e.g. Modules), added completely new guides (e.g. React modules), added some new sections to existing guides (e.g. Locale settings), and more.
Migration guide
As we introduced a few backward-incompatible changes, we prepared a migration guide that takes you through upgrading from Handsontable 10 to Handsontable 11 step by step. You can check it out here.
Release notes: what we added
- Added TypeScript definition files for Handsontable’s modularized version. #7489 [breaking change]
- Vue: Added support for modularization to the Vue wrapper. #8820 [breaking change]
- React: Added support for modularization to the React wrapper. #8819 [breaking change]
- Angular: Added support for modularization to the Angular wrapper. #8818 [breaking change]
- Added a new package entry point that allows importing built-in modules in one function call:
import { registerAllEditors, registerAllRenderers, registerAllValidators, registerAllCellTypes, registerAllPlugins } from 'handsontable/registry'
. #8816 - Added a new
locale
option, to properly handle locale-based data. #8897 - Added a GitHub Actions workflow that covers testing Handsontable and the wrappers. #8652
- Added new direction helpers that lay ground for future RTL support. #8868
Release notes: what we changed
- Changed how the
populateFromArray()
method works with itsmethod
argument set toshift_down
orshift_right
. #888 [breaking change] - Moved the entire Handsontable package to its own, new subdirectory:
./handsontable
. #8759 - Replaced the license files with updated versions. #8877
Release notes: what we fixed
- Fixed an issue with incorrect filtering of locale-based data while using search input from a drop-down menu. #6095
- Fixed an error thrown when using the
populateFromArray()
method with itsmethod
argument set toshift_right
. #6929 - Fixed an issue with the
beforeOnCellMouseDown
andafterOnCellMouseDown
hooks using wrong coordinates. #8498 - Fixed a
TypeError
thrown when calling theupdateSettings()
method in Handsontable’s modularized version. #8830 - Fixed two issues with the documentation’s
canonicalUrl
entries. #8886 - Fixed an error thrown when autofill’s source is a
date
cell. #8894 - React: Fixed a React wrapper issue where it’s impossible to use different sets of props in editor components reused across multiple columns. #8527
You can find detailed release notes for this and previous Handsonable versions here.