@handsontable/react-wrapper 17.1.0-rc9 → 18.0.0-rc1
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.
- package/README.md +0 -3
- package/commonjs/react-handsontable.js +87 -58
- package/dist/react-handsontable.js +88 -59
- package/dist/react-handsontable.js.map +1 -1
- package/dist/react-handsontable.min.js +2 -2
- package/dist/react-handsontable.min.js.map +1 -1
- package/es/react-handsontable.mjs +88 -59
- package/hotTableContext.d.ts +7 -0
- package/hotTableInner.d.ts +1 -1
- package/package.json +5 -3
- package/types.d.ts +9 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useContext,
|
|
1
|
+
import React, { useEffect, useContext, useRef, useCallback, useMemo, createContext, useState, useDeferredValue, useImperativeHandle, forwardRef, Fragment, Children, useId } from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import Handsontable from 'handsontable/base';
|
|
4
4
|
import { getRenderer } from 'handsontable/renderers/registry';
|
|
@@ -176,7 +176,7 @@ function _toPrimitive(t, r) {
|
|
|
176
176
|
if ("object" != typeof i) return i;
|
|
177
177
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
178
178
|
}
|
|
179
|
-
return (String )(t);
|
|
179
|
+
return ("string" === r ? String : Number)(t);
|
|
180
180
|
}
|
|
181
181
|
function _toPropertyKey(t) {
|
|
182
182
|
var i = _toPrimitive(t, "string");
|
|
@@ -345,11 +345,18 @@ function createPortal(rElement) {
|
|
|
345
345
|
if (!ownerDocument) {
|
|
346
346
|
ownerDocument = document;
|
|
347
347
|
}
|
|
348
|
-
|
|
349
|
-
|
|
348
|
+
var portalContainer = cachedContainer;
|
|
349
|
+
|
|
350
|
+
// A new container needs an anchor before React mounts into it. A cached
|
|
351
|
+
// container is already attached (typically inside its TD) and must be
|
|
352
|
+
// left in place to avoid wiping the DOM on every grid render.
|
|
353
|
+
if (!portalContainer) {
|
|
354
|
+
if (!bulkComponentContainer) {
|
|
355
|
+
bulkComponentContainer = ownerDocument.createDocumentFragment();
|
|
356
|
+
}
|
|
357
|
+
portalContainer = ownerDocument.createElement('DIV');
|
|
358
|
+
bulkComponentContainer.appendChild(portalContainer);
|
|
350
359
|
}
|
|
351
|
-
var portalContainer = cachedContainer !== null && cachedContainer !== void 0 ? cachedContainer : ownerDocument.createElement('DIV');
|
|
352
|
-
bulkComponentContainer.appendChild(portalContainer);
|
|
353
360
|
return {
|
|
354
361
|
portal: /*#__PURE__*/ReactDOM.createPortal(rElement, portalContainer, portalKey),
|
|
355
362
|
portalContainer: portalContainer
|
|
@@ -525,6 +532,9 @@ var HotTableContextProvider = function HotTableContextProvider(_ref) {
|
|
|
525
532
|
var setHotColumnSettings = useCallback(function (columnSettings, columnIndex) {
|
|
526
533
|
columnsSettings.current[columnIndex] = columnSettings;
|
|
527
534
|
}, []);
|
|
535
|
+
var trimColumnSettings = useCallback(function (length) {
|
|
536
|
+
columnsSettings.current.length = length;
|
|
537
|
+
}, []);
|
|
528
538
|
var componentRendererColumns = useRef(new Map());
|
|
529
539
|
var renderedCellCache = useRef(new Map());
|
|
530
540
|
var clearRenderedCellCache = useCallback(function () {
|
|
@@ -543,38 +553,36 @@ var HotTableContextProvider = function HotTableContextProvider(_ref) {
|
|
|
543
553
|
var instanceGuid = instance.guid;
|
|
544
554
|
var portalContainerKey = "".concat(instanceGuid, "-").concat(key);
|
|
545
555
|
var portalKey = "".concat(key, "-").concat(instanceGuid);
|
|
546
|
-
if (renderedCellCache.current.has(key)) {
|
|
547
|
-
TD.innerHTML = renderedCellCache.current.get(key).innerHTML;
|
|
548
|
-
}
|
|
549
556
|
if (TD && !TD.getAttribute('ghost-table')) {
|
|
550
|
-
var cachedPortal = portalCache.current.get(portalKey);
|
|
551
557
|
var cachedPortalContainer = portalContainerCache.current.get(portalContainerKey);
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
//
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
558
|
+
// When the cached portal container is still attached to the same
|
|
559
|
+
// TD as the previous render, the DOM is already correct and must
|
|
560
|
+
// not be wiped. Wiping detaches the React-managed children, which
|
|
561
|
+
// forces a full remount of the renderer component on every grid
|
|
562
|
+
// render (see issue #10800).
|
|
563
|
+
var containerInPlace = !!cachedPortalContainer && cachedPortalContainer.parentNode === TD;
|
|
564
|
+
var rendererElement = /*#__PURE__*/React.createElement(Renderer, {
|
|
565
|
+
instance: instance,
|
|
566
|
+
TD: TD,
|
|
567
|
+
row: row,
|
|
568
|
+
col: col,
|
|
569
|
+
prop: prop,
|
|
570
|
+
value: value,
|
|
571
|
+
cellProperties: cellProperties
|
|
572
|
+
});
|
|
573
|
+
var _createPortal = createPortal(rendererElement, TD.ownerDocument, portalKey, cachedPortalContainer),
|
|
574
|
+
portal = _createPortal.portal,
|
|
575
|
+
portalContainer = _createPortal.portalContainer;
|
|
576
|
+
if (!containerInPlace) {
|
|
577
|
+
while (TD.firstChild) {
|
|
578
|
+
TD.removeChild(TD.firstChild);
|
|
579
|
+
}
|
|
573
580
|
TD.appendChild(portalContainer);
|
|
574
|
-
portalCache.current.set(portalKey, portal);
|
|
575
581
|
}
|
|
582
|
+
portalContainerCache.current.set(portalContainerKey, portalContainer);
|
|
583
|
+
portalCache.current.set(portalKey, portal);
|
|
576
584
|
}
|
|
577
|
-
renderedCellCache.current.set(
|
|
585
|
+
renderedCellCache.current.set(key, TD);
|
|
578
586
|
return TD;
|
|
579
587
|
};
|
|
580
588
|
}, []);
|
|
@@ -592,13 +600,14 @@ var HotTableContextProvider = function HotTableContextProvider(_ref) {
|
|
|
592
600
|
componentRendererColumns: componentRendererColumns.current,
|
|
593
601
|
columnsSettings: columnsSettings.current,
|
|
594
602
|
emitColumnSettings: setHotColumnSettings,
|
|
603
|
+
trimColumnSettings: trimColumnSettings,
|
|
595
604
|
getRendererWrapper: getRendererWrapper,
|
|
596
605
|
clearPortalCache: clearPortalCache,
|
|
597
606
|
clearRenderedCellCache: clearRenderedCellCache,
|
|
598
607
|
setRenderersPortalManagerRef: setRenderersPortalManagerRef,
|
|
599
608
|
pushCellPortalsIntoPortalManager: pushCellPortalsIntoPortalManager
|
|
600
609
|
};
|
|
601
|
-
}, [setHotColumnSettings, getRendererWrapper, clearRenderedCellCache, setRenderersPortalManagerRef, pushCellPortalsIntoPortalManager]);
|
|
610
|
+
}, [setHotColumnSettings, trimColumnSettings, getRendererWrapper, clearRenderedCellCache, setRenderersPortalManagerRef, pushCellPortalsIntoPortalManager]);
|
|
602
611
|
return /*#__PURE__*/React.createElement(HotTableContext.Provider, {
|
|
603
612
|
value: contextImpl
|
|
604
613
|
}, children);
|
|
@@ -667,11 +676,12 @@ function makeEditorClass(hooksRef, instanceRef) {
|
|
|
667
676
|
args[_key] = arguments[_key];
|
|
668
677
|
}
|
|
669
678
|
if (!AbstractMethods.includes(propName)) {
|
|
670
|
-
|
|
679
|
+
var _ref;
|
|
680
|
+
result = (_ref = baseMethod).call.apply(_ref, [this].concat(args)); // call super
|
|
671
681
|
}
|
|
672
682
|
if (MethodsMap[propName] && (_hooksRef$current = hooksRef.current) !== null && _hooksRef$current !== void 0 && _hooksRef$current[MethodsMap[propName]]) {
|
|
673
|
-
var
|
|
674
|
-
result = (
|
|
683
|
+
var _ref2;
|
|
684
|
+
result = (_ref2 = hooksRef.current[MethodsMap[propName]]).call.apply(_ref2, [this].concat(args));
|
|
675
685
|
}
|
|
676
686
|
return result;
|
|
677
687
|
}.bind(_this);
|
|
@@ -712,10 +722,10 @@ var EditorContext = /*#__PURE__*/createContext(undefined);
|
|
|
712
722
|
* @param {Ref} hooksRef Reference for component-based editor overridden hooks object.
|
|
713
723
|
* @param {RefObject} hotCustomEditorInstanceRef Reference to Handsontable-native editor instance.
|
|
714
724
|
*/
|
|
715
|
-
var EditorContextProvider = function EditorContextProvider(
|
|
716
|
-
var hooksRef =
|
|
717
|
-
hotCustomEditorInstanceRef =
|
|
718
|
-
children =
|
|
725
|
+
var EditorContextProvider = function EditorContextProvider(_ref3) {
|
|
726
|
+
var hooksRef = _ref3.hooksRef,
|
|
727
|
+
hotCustomEditorInstanceRef = _ref3.hotCustomEditorInstanceRef,
|
|
728
|
+
children = _ref3.children;
|
|
719
729
|
return /*#__PURE__*/React.createElement(EditorContext.Provider, {
|
|
720
730
|
value: {
|
|
721
731
|
hooksRef: hooksRef,
|
|
@@ -784,9 +794,9 @@ function applyEditorPosition(el, editor, hot, td) {
|
|
|
784
794
|
* @returns {UseHotEditorImpl} Editor API methods
|
|
785
795
|
*/
|
|
786
796
|
function useHotEditor(overriddenHooks, deps) {
|
|
787
|
-
var
|
|
788
|
-
hooksRef =
|
|
789
|
-
hotCustomEditorInstanceRef =
|
|
797
|
+
var _ref4 = useContext(EditorContext),
|
|
798
|
+
hooksRef = _ref4.hooksRef,
|
|
799
|
+
hotCustomEditorInstanceRef = _ref4.hotCustomEditorInstanceRef;
|
|
790
800
|
var _useState = useState(0),
|
|
791
801
|
_useState2 = _slicedToArray(_useState, 2),
|
|
792
802
|
rerenderTrigger = _useState2[0],
|
|
@@ -830,11 +840,13 @@ function useHotEditor(overriddenHooks, deps) {
|
|
|
830
840
|
},
|
|
831
841
|
get row() {
|
|
832
842
|
var _hotCustomEditorInsta6;
|
|
833
|
-
|
|
843
|
+
var row = (_hotCustomEditorInsta6 = hotCustomEditorInstanceRef.current) === null || _hotCustomEditorInsta6 === void 0 ? void 0 : _hotCustomEditorInsta6.row;
|
|
844
|
+
return row !== null && row !== void 0 ? row : undefined;
|
|
834
845
|
},
|
|
835
846
|
get col() {
|
|
836
847
|
var _hotCustomEditorInsta7;
|
|
837
|
-
|
|
848
|
+
var col = (_hotCustomEditorInsta7 = hotCustomEditorInstanceRef.current) === null || _hotCustomEditorInsta7 === void 0 ? void 0 : _hotCustomEditorInsta7.col;
|
|
849
|
+
return col !== null && col !== void 0 ? col : undefined;
|
|
838
850
|
}
|
|
839
851
|
};
|
|
840
852
|
}, [rerenderTrigger, hotCustomEditorInstanceRef, deferredValue]);
|
|
@@ -844,23 +856,23 @@ function useHotEditor(overriddenHooks, deps) {
|
|
|
844
856
|
|
|
845
857
|
// EditorComponent props - children typed to work with JSX syntax
|
|
846
858
|
|
|
847
|
-
function EditorComponent(
|
|
848
|
-
var _onPrepare =
|
|
849
|
-
_onClose =
|
|
850
|
-
_onOpen =
|
|
851
|
-
_onFocus =
|
|
852
|
-
children =
|
|
853
|
-
|
|
854
|
-
shortcutsGroup =
|
|
855
|
-
shortcuts =
|
|
859
|
+
function EditorComponent(_ref5) {
|
|
860
|
+
var _onPrepare = _ref5.onPrepare,
|
|
861
|
+
_onClose = _ref5.onClose,
|
|
862
|
+
_onOpen = _ref5.onOpen,
|
|
863
|
+
_onFocus = _ref5.onFocus,
|
|
864
|
+
children = _ref5.children,
|
|
865
|
+
_ref5$shortcutsGroup = _ref5.shortcutsGroup,
|
|
866
|
+
shortcutsGroup = _ref5$shortcutsGroup === void 0 ? "custom-editor" : _ref5$shortcutsGroup,
|
|
867
|
+
shortcuts = _ref5.shortcuts;
|
|
856
868
|
var mainElementRef = useRef(null);
|
|
857
869
|
var currentValue = useRef(undefined);
|
|
858
870
|
var _useState5 = useState(),
|
|
859
871
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
860
872
|
themeClassName = _useState6[0],
|
|
861
873
|
setThemeClassName = _useState6[1];
|
|
862
|
-
var
|
|
863
|
-
hotCustomEditorInstanceRef =
|
|
874
|
+
var _ref6 = useContext(EditorContext),
|
|
875
|
+
hotCustomEditorInstanceRef = _ref6.hotCustomEditorInstanceRef;
|
|
864
876
|
var registerShortcuts = useCallback(function () {
|
|
865
877
|
var _hotCustomEditorInsta8, _hotCustomEditorInsta9, _hotCustomEditorInsta0;
|
|
866
878
|
if (!((_hotCustomEditorInsta8 = hotCustomEditorInstanceRef.current) !== null && _hotCustomEditorInsta8 !== void 0 && _hotCustomEditorInsta8.hot)) return;
|
|
@@ -1064,7 +1076,7 @@ var HotColumn = function HotColumn(props) {
|
|
|
1064
1076
|
}, editorPortal);
|
|
1065
1077
|
};
|
|
1066
1078
|
|
|
1067
|
-
var version="
|
|
1079
|
+
var version="18.0.0-rc1";
|
|
1068
1080
|
|
|
1069
1081
|
/**
|
|
1070
1082
|
* Component used to manage the renderer component portals.
|
|
@@ -2320,6 +2332,12 @@ var HotTableInner = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
2320
2332
|
* Initialize Handsontable after the component has mounted.
|
|
2321
2333
|
*/
|
|
2322
2334
|
useEffect(function () {
|
|
2335
|
+
// React guarantees child effects run before parent effects on each
|
|
2336
|
+
// commit, so by the time this parent useEffect runs, every HotColumn
|
|
2337
|
+
// has already written its slot. Trim to drop any leftover slots from
|
|
2338
|
+
// a previous mount (e.g. StrictMode's double-invoke or HMR).
|
|
2339
|
+
var hotColumnCount = Children.toArray(props.children).filter(isHotColumn).length;
|
|
2340
|
+
context.trimColumnSettings(hotColumnCount);
|
|
2323
2341
|
var newGlobalSettings = createNewGlobalSettings(true);
|
|
2324
2342
|
|
|
2325
2343
|
// Update prevProps with the current props
|
|
@@ -2362,6 +2380,13 @@ var HotTableInner = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
2362
2380
|
useUpdateEffect(function () {
|
|
2363
2381
|
clearCache();
|
|
2364
2382
|
var hotInstance = getHotInstance();
|
|
2383
|
+
|
|
2384
|
+
// React guarantees child effects run before parent effects on each
|
|
2385
|
+
// commit, so by the time this parent useUpdateEffect runs, every
|
|
2386
|
+
// surviving HotColumn has already written its slot. Trim to drop
|
|
2387
|
+
// stale entries left behind by HotColumns that unmounted.
|
|
2388
|
+
var hotColumnCount = Children.toArray(props.children).filter(isHotColumn).length;
|
|
2389
|
+
context.trimColumnSettings(hotColumnCount);
|
|
2365
2390
|
var newGlobalSettings = createNewGlobalSettings(false, prevProps.current);
|
|
2366
2391
|
|
|
2367
2392
|
// Update prevProps with the current props
|
|
@@ -2399,7 +2424,11 @@ var HotTableInner = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
2399
2424
|
var editorPortal = createEditorPortal(getOwnerDocument(), props.editor);
|
|
2400
2425
|
return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", _extends({
|
|
2401
2426
|
ref: hotElementRef
|
|
2402
|
-
}, containerProps
|
|
2427
|
+
}, containerProps, {
|
|
2428
|
+
style: _objectSpread2({
|
|
2429
|
+
height: '100%'
|
|
2430
|
+
}, containerProps.style)
|
|
2431
|
+
}), hotColumnWrapped), /*#__PURE__*/React.createElement(RenderersPortalManager, {
|
|
2403
2432
|
ref: context.setRenderersPortalManagerRef
|
|
2404
2433
|
}), /*#__PURE__*/React.createElement(EditorContextProvider, {
|
|
2405
2434
|
hooksRef: globalEditorHooksRef,
|
package/hotTableContext.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export interface HotTableContextImpl {
|
|
|
19
19
|
* @param {Number} columnIndex Column index.
|
|
20
20
|
*/
|
|
21
21
|
readonly emitColumnSettings: (columnSettings: Handsontable.ColumnSettings, columnIndex: number) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Trim the column settings array to the given length. Used to drop slots
|
|
24
|
+
* left over from HotColumn children that have unmounted.
|
|
25
|
+
*
|
|
26
|
+
* @param {Number} length Target length for the column settings array.
|
|
27
|
+
*/
|
|
28
|
+
readonly trimColumnSettings: (length: number) => void;
|
|
22
29
|
/**
|
|
23
30
|
* Return a renderer wrapper function for the provided renderer component.
|
|
24
31
|
*
|
package/hotTableInner.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { HotTableProps, HotTableRef } from './types';
|
|
3
|
-
declare const HotTableInner: React.ForwardRefExoticComponent<HotTableProps & React.RefAttributes<HotTableRef>>;
|
|
3
|
+
declare const HotTableInner: React.ForwardRefExoticComponent<Pick<HotTableProps, string | number> & React.RefAttributes<HotTableRef>>;
|
|
4
4
|
export default HotTableInner;
|
|
5
5
|
export { HotTableInner };
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@handsontable/react-wrapper",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.0.0-rc1",
|
|
4
4
|
"description": "Best Data Grid for React with Spreadsheet Look and Feel.",
|
|
5
5
|
"author": "Handsoncode <hello@handsoncode.net> (https://handsoncode.net)",
|
|
6
6
|
"homepage": "https://handsontable.com",
|
|
7
7
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
8
|
+
"sideEffects": false,
|
|
8
9
|
"main": "./commonjs/react-handsontable.js",
|
|
9
10
|
"module": "./es/react-handsontable.mjs",
|
|
10
11
|
"jsdelivr": "./dist/react-handsontable.min.js",
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"@types/react-dom": "^18.2.0",
|
|
73
74
|
"@types/react-redux": "^7.1.7",
|
|
74
75
|
"cross-env": "^7.0.3",
|
|
75
|
-
"handsontable": "^
|
|
76
|
+
"handsontable": "^18.0.0",
|
|
76
77
|
"jest": "^27.5.1",
|
|
77
78
|
"jest-environment-jsdom": "^27.5.1",
|
|
78
79
|
"prop-types": "^15.7.2",
|
|
@@ -87,7 +88,7 @@
|
|
|
87
88
|
"uglify-js": "^3.4.9"
|
|
88
89
|
},
|
|
89
90
|
"peerDependencies": {
|
|
90
|
-
"handsontable": "^
|
|
91
|
+
"handsontable": "^18.0.0"
|
|
91
92
|
},
|
|
92
93
|
"scripts": {
|
|
93
94
|
"build": "npm run clean && npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:min && npm run prepare:types",
|
|
@@ -107,6 +108,7 @@
|
|
|
107
108
|
"jest": {
|
|
108
109
|
"testEnvironment": "jsdom",
|
|
109
110
|
"testURL": "http://localhost/",
|
|
111
|
+
"testTimeout": 60000,
|
|
110
112
|
"transform": {
|
|
111
113
|
"^.+\\.tsx?$": "babel-jest",
|
|
112
114
|
"^.+\\.js$": "babel-jest"
|
package/types.d.ts
CHANGED
|
@@ -38,12 +38,17 @@ export interface UseHotEditorImpl<T> {
|
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* Helper type to expose GridSettings/ColumnSettings props with native renderers/editors separately
|
|
41
|
-
*
|
|
41
|
+
* from component-based render prop. Uses conditional types so it works with both GridSettings
|
|
42
|
+
* and ColumnSettings (ColumnSettings' index signature can make it incompatible with strict Pick<>).
|
|
42
43
|
*/
|
|
43
|
-
declare type ReplaceRenderersEditors<T
|
|
44
|
-
hotRenderer?: T
|
|
44
|
+
declare type ReplaceRenderersEditors<T> = Omit<T, 'renderer' | 'editor'> & {
|
|
45
|
+
hotRenderer?: T extends {
|
|
46
|
+
renderer?: infer R;
|
|
47
|
+
} ? R : never;
|
|
45
48
|
renderer?: ComponentType<HotRendererProps>;
|
|
46
|
-
hotEditor?: T
|
|
49
|
+
hotEditor?: T extends {
|
|
50
|
+
editor?: infer E;
|
|
51
|
+
} ? E : never;
|
|
47
52
|
editor?: ComponentType | boolean;
|
|
48
53
|
};
|
|
49
54
|
/**
|