virtual-scroller 1.13.1 → 1.15.0
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/CHANGELOG.md +36 -0
- package/README.md +825 -578
- package/bundle/index-dom-bypass.html +198 -0
- package/bundle/index-dom-grid.html +204 -0
- package/bundle/index-dom-scrollableContainer.html +215 -0
- package/bundle/index-dom-tbody-scrollableContainer.html +81 -0
- package/bundle/index-dom-tbody.html +65 -0
- package/bundle/index-dom.html +116 -83
- package/bundle/{index-bypass.html → index-react-bypass.html} +83 -78
- package/bundle/{index-grid.html → index-react-grid.html} +78 -91
- package/bundle/{index-scrollableContainer.html → index-react-scrollableContainer.html} +96 -91
- package/bundle/index-react-strictMode.html +199 -0
- package/bundle/index-react-tbody-scrollableContainer.html +96 -0
- package/bundle/index-react-tbody.html +80 -0
- package/bundle/{messages.js → items.js} +1 -1
- package/bundle/lib/babel.min.js +25 -0
- package/bundle/lib/prop-types.min.js +1 -0
- package/bundle/lib/react-dom.development.js +29924 -0
- package/bundle/lib/react-dom.production.min.js +267 -0
- package/bundle/lib/react.development.js +3343 -0
- package/bundle/lib/react.production.min.js +31 -0
- package/bundle/style.base.css +33 -0
- package/{website/style.css → bundle/style.list.css} +10 -43
- package/bundle/style.list.grid.css +23 -0
- package/bundle/virtual-scroller-dom.js +1 -1
- package/bundle/virtual-scroller-dom.js.map +1 -1
- package/bundle/virtual-scroller-react.js +1 -1
- package/bundle/virtual-scroller-react.js.map +1 -1
- package/bundle/virtual-scroller.js +1 -1
- package/bundle/virtual-scroller.js.map +1 -1
- package/commonjs/BeforeResize.js +1 -2
- package/commonjs/BeforeResize.js.map +1 -1
- package/commonjs/DOM/VirtualScroller.js +67 -44
- package/commonjs/DOM/VirtualScroller.js.map +1 -1
- package/commonjs/DOM/tbody.js +15 -15
- package/commonjs/DOM/tbody.js.map +1 -1
- package/commonjs/ItemHeights.js +10 -13
- package/commonjs/ItemHeights.js.map +1 -1
- package/commonjs/Layout.defaults.js +21 -0
- package/commonjs/Layout.defaults.js.map +1 -0
- package/commonjs/Layout.js +78 -67
- package/commonjs/Layout.js.map +1 -1
- package/commonjs/Layout.test.js +8 -4
- package/commonjs/Layout.test.js.map +1 -1
- package/commonjs/Scroll.js +3 -3
- package/commonjs/Scroll.js.map +1 -1
- package/commonjs/ScrollableContainerResizeHandler.js +4 -5
- package/commonjs/ScrollableContainerResizeHandler.js.map +1 -1
- package/commonjs/VirtualScroller.constructor.js +53 -31
- package/commonjs/VirtualScroller.constructor.js.map +1 -1
- package/commonjs/VirtualScroller.items.js +50 -4
- package/commonjs/VirtualScroller.items.js.map +1 -1
- package/commonjs/VirtualScroller.js +44 -28
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +42 -31
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.onContainerResize.js +1 -2
- package/commonjs/VirtualScroller.onContainerResize.js.map +1 -1
- package/commonjs/VirtualScroller.onRender.js +1 -1
- package/commonjs/VirtualScroller.onRender.js.map +1 -1
- package/commonjs/VirtualScroller.state.js +18 -9
- package/commonjs/VirtualScroller.state.js.map +1 -1
- package/commonjs/VirtualScroller.verticalSpacing.js +39 -6
- package/commonjs/VirtualScroller.verticalSpacing.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +98 -37
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/useClassName.js +2 -2
- package/commonjs/react/useClassName.js.map +1 -1
- package/commonjs/react/useForwardedRef.js +50 -0
- package/commonjs/react/useForwardedRef.js.map +1 -0
- package/commonjs/react/useInstanceMethods.js +4 -4
- package/commonjs/react/useInstanceMethods.js.map +1 -1
- package/commonjs/react/useItemKeys.js +28 -5
- package/commonjs/react/useItemKeys.js.map +1 -1
- package/commonjs/react/useOnItemHeightDidChange.js +28 -12
- package/commonjs/react/useOnItemHeightDidChange.js.map +1 -1
- package/commonjs/react/useSetItemState.js +31 -12
- package/commonjs/react/useSetItemState.js.map +1 -1
- package/commonjs/react/useState.js +10 -11
- package/commonjs/react/useState.js.map +1 -1
- package/commonjs/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +3 -3
- package/commonjs/react/useStateWithRepeatableRead.js.map +1 -0
- package/commonjs/react/useStyle.js +10 -4
- package/commonjs/react/useStyle.js.map +1 -1
- package/commonjs/react/useValidateTableBodyItemsContainer.js +24 -0
- package/commonjs/react/useValidateTableBodyItemsContainer.js.map +1 -0
- package/commonjs/react/useVirtualScroller.js +12 -14
- package/commonjs/react/useVirtualScroller.js.map +1 -1
- package/commonjs/test/ItemsContainer.js +10 -10
- package/commonjs/test/ItemsContainer.js.map +1 -1
- package/commonjs/test/VirtualScroller.js +25 -10
- package/commonjs/test/VirtualScroller.js.map +1 -1
- package/dom/index.d.ts +11 -9
- package/index.d.ts +19 -9
- package/modules/BeforeResize.js +1 -2
- package/modules/BeforeResize.js.map +1 -1
- package/modules/DOM/VirtualScroller.js +67 -44
- package/modules/DOM/VirtualScroller.js.map +1 -1
- package/modules/DOM/tbody.js +14 -13
- package/modules/DOM/tbody.js.map +1 -1
- package/modules/ItemHeights.js +11 -14
- package/modules/ItemHeights.js.map +1 -1
- package/modules/Layout.defaults.js +11 -0
- package/modules/Layout.defaults.js.map +1 -0
- package/modules/Layout.js +77 -67
- package/modules/Layout.js.map +1 -1
- package/modules/Layout.test.js +8 -4
- package/modules/Layout.test.js.map +1 -1
- package/modules/Scroll.js +3 -3
- package/modules/Scroll.js.map +1 -1
- package/modules/ScrollableContainerResizeHandler.js +4 -5
- package/modules/ScrollableContainerResizeHandler.js.map +1 -1
- package/modules/VirtualScroller.constructor.js +53 -31
- package/modules/VirtualScroller.constructor.js.map +1 -1
- package/modules/VirtualScroller.items.js +51 -5
- package/modules/VirtualScroller.items.js.map +1 -1
- package/modules/VirtualScroller.js +44 -28
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +42 -31
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.onContainerResize.js +1 -2
- package/modules/VirtualScroller.onContainerResize.js.map +1 -1
- package/modules/VirtualScroller.onRender.js +1 -1
- package/modules/VirtualScroller.onRender.js.map +1 -1
- package/modules/VirtualScroller.state.js +18 -9
- package/modules/VirtualScroller.state.js.map +1 -1
- package/modules/VirtualScroller.verticalSpacing.js +38 -6
- package/modules/VirtualScroller.verticalSpacing.js.map +1 -1
- package/modules/react/VirtualScroller.js +97 -38
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/useClassName.js +3 -3
- package/modules/react/useClassName.js.map +1 -1
- package/modules/react/useForwardedRef.js +42 -0
- package/modules/react/useForwardedRef.js.map +1 -0
- package/modules/react/useInstanceMethods.js +4 -4
- package/modules/react/useInstanceMethods.js.map +1 -1
- package/modules/react/useItemKeys.js +28 -5
- package/modules/react/useItemKeys.js.map +1 -1
- package/modules/react/useOnItemHeightDidChange.js +28 -12
- package/modules/react/useOnItemHeightDidChange.js.map +1 -1
- package/modules/react/useSetItemState.js +31 -12
- package/modules/react/useSetItemState.js.map +1 -1
- package/modules/react/useState.js +10 -11
- package/modules/react/useState.js.map +1 -1
- package/modules/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +2 -2
- package/modules/react/useStateWithRepeatableRead.js.map +1 -0
- package/modules/react/useStyle.js +10 -4
- package/modules/react/useStyle.js.map +1 -1
- package/modules/react/useValidateTableBodyItemsContainer.js +16 -0
- package/modules/react/useValidateTableBodyItemsContainer.js.map +1 -0
- package/modules/react/useVirtualScroller.js +10 -12
- package/modules/react/useVirtualScroller.js.map +1 -1
- package/modules/test/ItemsContainer.js +10 -10
- package/modules/test/ItemsContainer.js.map +1 -1
- package/modules/test/VirtualScroller.js +25 -10
- package/modules/test/VirtualScroller.js.map +1 -1
- package/package.json +1 -1
- package/react/as.d.ts +42 -0
- package/react/index.d.ts +204 -63
- package/source/BeforeResize.js +1 -2
- package/source/DOM/VirtualScroller.js +65 -40
- package/source/DOM/tbody.js +15 -14
- package/source/ItemHeights.js +11 -12
- package/source/Layout.defaults.js +8 -0
- package/source/Layout.js +69 -56
- package/source/Layout.test.js +7 -2
- package/source/Scroll.js +3 -3
- package/source/ScrollableContainerResizeHandler.js +4 -4
- package/source/VirtualScroller.constructor.js +40 -31
- package/source/VirtualScroller.items.js +47 -2
- package/source/VirtualScroller.js +49 -27
- package/source/VirtualScroller.layout.js +43 -30
- package/source/VirtualScroller.onContainerResize.js +1 -2
- package/source/VirtualScroller.onRender.js +1 -1
- package/source/VirtualScroller.state.js +18 -11
- package/source/VirtualScroller.verticalSpacing.js +32 -6
- package/source/react/VirtualScroller.js +111 -36
- package/source/react/useClassName.js +3 -3
- package/source/react/useForwardedRef.js +39 -0
- package/source/react/useInstanceMethods.js +12 -4
- package/source/react/useItemKeys.js +22 -4
- package/source/react/useOnItemHeightDidChange.js +29 -10
- package/source/react/useSetItemState.js +32 -10
- package/source/react/useState.js +7 -8
- package/source/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +1 -1
- package/source/react/useStyle.js +3 -2
- package/source/react/useValidateTableBodyItemsContainer.js +16 -0
- package/source/react/useVirtualScroller.js +4 -6
- package/source/test/ItemsContainer.js +10 -10
- package/source/test/VirtualScroller.js +16 -10
- package/website/index-dom-bypass.html +198 -0
- package/website/index-dom-grid.html +204 -0
- package/website/index-dom-scrollableContainer.html +215 -0
- package/website/index-dom-tbody-scrollableContainer.html +81 -0
- package/website/index-dom-tbody.html +65 -0
- package/website/index-dom.html +117 -84
- package/website/index-react-bypass.html +200 -0
- package/website/{index-grid.html → index-react-grid.html} +79 -92
- package/website/index-react-scrollableContainer.html +213 -0
- package/website/index-react-strictMode.html +199 -0
- package/website/index-react-tbody-scrollableContainer.html +96 -0
- package/website/index-react-tbody.html +80 -0
- package/website/{index-bypass.html → index-react.html} +84 -70
- package/website/index.html +84 -69
- package/website/{messages.js → items.js} +1 -1
- package/website/lib/babel.min.js +25 -0
- package/website/lib/prop-types.min.js +1 -0
- package/website/lib/react-dom.development.js +29924 -0
- package/website/lib/react-dom.production.min.js +267 -0
- package/website/lib/react.development.js +3343 -0
- package/website/lib/react.production.min.js +31 -0
- package/website/style.base.css +33 -0
- package/website/style.list.css +92 -0
- package/website/style.list.grid.css +23 -0
- package/bundle/index-tbody-scrollableContainer.html +0 -70
- package/bundle/index-tbody.html +0 -57
- package/bundle/on-scroll-to-dom.js +0 -2
- package/bundle/on-scroll-to-dom.js.map +0 -1
- package/bundle/on-scroll-to-react.js +0 -2
- package/bundle/on-scroll-to-react.js.map +0 -1
- package/bundle/on-scroll-to.js +0 -2
- package/bundle/on-scroll-to.js.map +0 -1
- package/commonjs/react/useStateNoStaleBug.js.map +0 -1
- package/modules/react/useStateNoStaleBug.js.map +0 -1
- package/website/index-scrollableContainer.html +0 -208
- package/website/index-tbody-scrollableContainer.html +0 -70
- package/website/index-tbody.html +0 -57
- package/website/lib/on-scroll-to-dom.js +0 -2
- package/website/lib/on-scroll-to-dom.js.map +0 -1
- package/website/lib/on-scroll-to-react.js +0 -2
- package/website/lib/on-scroll-to-react.js.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useForwardedRef;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
// import type { MutableRefObject } from 'react'
|
|
11
|
+
// When a React component receives a `ref` which it is supposed to "forward"
|
|
12
|
+
// and when it would like to also read that `ref` in its internal implementation,
|
|
13
|
+
// this `useForwardedRef()` hook could be used to get read access to such "forwarded" ref
|
|
14
|
+
// inside the component's internal implementation.
|
|
15
|
+
//
|
|
16
|
+
// ```js
|
|
17
|
+
// const FormWithAutoFocus = forwardRef((props, ref) => {
|
|
18
|
+
// const { setRef, internalRef } = useForwardedRef<RefValueType>(ref)
|
|
19
|
+
//
|
|
20
|
+
// useEffect(() => {
|
|
21
|
+
// internalRef.current.focus()
|
|
22
|
+
// }, [])
|
|
23
|
+
//
|
|
24
|
+
// return (
|
|
25
|
+
// <Form ref={setRef} {...props}/>
|
|
26
|
+
// )
|
|
27
|
+
// })
|
|
28
|
+
// ```
|
|
29
|
+
//
|
|
30
|
+
// export default function useForwardedRef<T extends MutableRefObject<any>>(ref) {
|
|
31
|
+
function useForwardedRef(ref) {
|
|
32
|
+
var internalRef = (0, _react.useRef)(); // as T
|
|
33
|
+
|
|
34
|
+
var setRef = (0, _react.useCallback)(function (instance) {
|
|
35
|
+
internalRef.current = instance;
|
|
36
|
+
|
|
37
|
+
if (ref) {
|
|
38
|
+
if (typeof ref === 'function') {
|
|
39
|
+
ref(instance);
|
|
40
|
+
} else {
|
|
41
|
+
ref.current = instance;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}, [ref]);
|
|
45
|
+
return {
|
|
46
|
+
setRef: setRef,
|
|
47
|
+
internalRef: internalRef
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=useForwardedRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForwardedRef.js","names":["useForwardedRef","ref","internalRef","useRef","setRef","useCallback","instance","current"],"sources":["../../source/react/useForwardedRef.js"],"sourcesContent":["// import type { MutableRefObject } from 'react'\r\nimport { useCallback, useRef } from 'react'\r\n\r\n// When a React component receives a `ref` which it is supposed to \"forward\"\r\n// and when it would like to also read that `ref` in its internal implementation,\r\n// this `useForwardedRef()` hook could be used to get read access to such \"forwarded\" ref\r\n// inside the component's internal implementation.\r\n//\r\n// ```js\r\n// const FormWithAutoFocus = forwardRef((props, ref) => {\r\n// const { setRef, internalRef } = useForwardedRef<RefValueType>(ref)\r\n//\r\n// useEffect(() => {\r\n// internalRef.current.focus()\r\n// }, [])\r\n//\r\n// return (\r\n// <Form ref={setRef} {...props}/>\r\n// )\r\n// })\r\n// ```\r\n//\r\n// export default function useForwardedRef<T extends MutableRefObject<any>>(ref) {\r\nexport default function useForwardedRef(ref) {\r\n\tconst internalRef = useRef() // as T\r\n\r\n\tconst setRef = useCallback((instance) => {\r\n\t\tinternalRef.current = instance\r\n\t\tif (ref) {\r\n\t\t\tif (typeof ref === 'function') {\r\n\t\t\t\tref(instance)\r\n\t\t\t} else {\r\n\t\t\t\tref.current = instance\r\n\t\t\t}\r\n\t\t}\r\n\t}, [ref])\r\n\r\n\treturn { setRef, internalRef }\r\n}\r\n"],"mappings":";;;;;;;AACA;;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,eAAT,CAAyBC,GAAzB,EAA8B;EAC5C,IAAMC,WAAW,GAAG,IAAAC,aAAA,GAApB,CAD4C,CACf;;EAE7B,IAAMC,MAAM,GAAG,IAAAC,kBAAA,EAAY,UAACC,QAAD,EAAc;IACxCJ,WAAW,CAACK,OAAZ,GAAsBD,QAAtB;;IACA,IAAIL,GAAJ,EAAS;MACR,IAAI,OAAOA,GAAP,KAAe,UAAnB,EAA+B;QAC9BA,GAAG,CAACK,QAAD,CAAH;MACA,CAFD,MAEO;QACNL,GAAG,CAACM,OAAJ,GAAcD,QAAd;MACA;IACD;EACD,CATc,EASZ,CAACL,GAAD,CATY,CAAf;EAWA,OAAO;IAAEG,MAAM,EAANA,MAAF;IAAUF,WAAW,EAAXA;EAAV,CAAP;AACA"}
|
|
@@ -16,20 +16,20 @@ function useInstanceMethods(ref, _ref) {
|
|
|
16
16
|
return {
|
|
17
17
|
// This is a proxy for `VirtualScroller`'s `.updateLayout` instance method.
|
|
18
18
|
updateLayout: function updateLayout() {
|
|
19
|
-
|
|
19
|
+
virtualScroller.updateLayout();
|
|
20
20
|
},
|
|
21
21
|
// (deprecated)
|
|
22
22
|
// `.layout()` method name is deprecated, use `.updateLayout()` instead.
|
|
23
23
|
layout: function layout() {
|
|
24
|
-
|
|
24
|
+
virtualScroller.updateLayout();
|
|
25
25
|
},
|
|
26
26
|
// (deprecated)
|
|
27
27
|
updateItem: function updateItem(i) {
|
|
28
|
-
|
|
28
|
+
(0, _debug.reportError)("[virtual-scroller] \".updateItem(i)\" method of React <VirtualScroller/> has been removed");
|
|
29
29
|
},
|
|
30
30
|
// (deprecated)
|
|
31
31
|
renderItem: function renderItem(i) {
|
|
32
|
-
|
|
32
|
+
(0, _debug.reportError)("[virtual-scroller] \".renderItem(i)\" method of React <VirtualScroller/> has been removed");
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
}, [virtualScroller]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInstanceMethods.js","names":["useInstanceMethods","ref","virtualScroller","useImperativeHandle","updateLayout","layout","updateItem","i","reportError","renderItem"],"sources":["../../source/react/useInstanceMethods.js"],"sourcesContent":["import { useImperativeHandle } from 'react'\r\n\r\nimport { reportError } from '../utility/debug.js'\r\n\r\n// Adds instance methods to the React component.\r\nexport default function useInstanceMethods(ref, {\r\n\tvirtualScroller\r\n}) {\r\n\tuseImperativeHandle(ref, () => ({\r\n\t\t// This is a proxy for `VirtualScroller`'s `.updateLayout` instance method.\r\n\t\tupdateLayout: () =>
|
|
1
|
+
{"version":3,"file":"useInstanceMethods.js","names":["useInstanceMethods","ref","virtualScroller","useImperativeHandle","updateLayout","layout","updateItem","i","reportError","renderItem"],"sources":["../../source/react/useInstanceMethods.js"],"sourcesContent":["import { useImperativeHandle } from 'react'\r\n\r\nimport { reportError } from '../utility/debug.js'\r\n\r\n// Adds instance methods to the React component.\r\nexport default function useInstanceMethods(ref, {\r\n\tvirtualScroller\r\n}) {\r\n\tuseImperativeHandle(ref, () => ({\r\n\t\t// This is a proxy for `VirtualScroller`'s `.updateLayout` instance method.\r\n\t\tupdateLayout: () => {\r\n\t\t\tvirtualScroller.updateLayout()\r\n\t\t},\r\n\r\n\t\t// (deprecated)\r\n\t\t// `.layout()` method name is deprecated, use `.updateLayout()` instead.\r\n layout: () => {\r\n\t\t\tvirtualScroller.updateLayout()\r\n\t\t},\r\n\r\n\t\t// (deprecated)\r\n\t\tupdateItem: (i) => {\r\n\t\t\treportError(`[virtual-scroller] \".updateItem(i)\" method of React <VirtualScroller/> has been removed`)\r\n\t\t},\r\n\r\n\t\t// (deprecated)\r\n\t\trenderItem: (i) => {\r\n\t\t\treportError(`[virtual-scroller] \".renderItem(i)\" method of React <VirtualScroller/> has been removed`)\r\n\t\t}\r\n\t}), [\r\n\t\tvirtualScroller\r\n\t])\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;;AAEA;AACe,SAASA,kBAAT,CAA4BC,GAA5B,QAEZ;EAAA,IADFC,eACE,QADFA,eACE;EACF,IAAAC,0BAAA,EAAoBF,GAApB,EAAyB;IAAA,OAAO;MAC/B;MACAG,YAAY,EAAE,wBAAM;QACnBF,eAAe,CAACE,YAAhB;MACA,CAJ8B;MAM/B;MACA;MACEC,MAAM,EAAE,kBAAM;QACfH,eAAe,CAACE,YAAhB;MACA,CAV8B;MAY/B;MACAE,UAAU,EAAE,oBAACC,CAAD,EAAO;QAClB,IAAAC,kBAAA;MACA,CAf8B;MAiB/B;MACAC,UAAU,EAAE,oBAACF,CAAD,EAAO;QAClB,IAAAC,kBAAA;MACA;IApB8B,CAAP;EAAA,CAAzB,EAqBI,CACHN,eADG,CArBJ;AAwBA"}
|
|
@@ -11,17 +11,39 @@ var _react = require("react");
|
|
|
11
11
|
|
|
12
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
13
|
|
|
14
|
+
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
15
|
+
|
|
16
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
17
|
+
|
|
18
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
19
|
+
|
|
14
20
|
function useItemKeys(_ref) {
|
|
15
21
|
var getItemId = _ref.getItemId;
|
|
16
|
-
//
|
|
22
|
+
// These "listeners" will be called in case the auto-generated item keys are reset
|
|
23
|
+
// due to the prefix counter number reaching its maximum allowed value.
|
|
24
|
+
var itemKeysResetEventListeners = (0, _react.useMemo)(function () {
|
|
25
|
+
return [];
|
|
26
|
+
}, []); // Adds an "on item keys reset" listener.
|
|
27
|
+
|
|
28
|
+
var onItemKeysReset = (0, _react.useCallback)(function (listener) {
|
|
29
|
+
itemKeysResetEventListeners.push(listener);
|
|
30
|
+
}, []); // List items are rendered with `key`s so that React doesn't
|
|
17
31
|
// "reuse" `itemComponent`s in cases when `items` are changed.
|
|
18
|
-
|
|
32
|
+
|
|
33
|
+
var itemKeyPrefix = (0, _react.useRef)(); // When no `getItemId()` function is specified, it creates an item key
|
|
34
|
+
// from an auto-generated unique prefix and the item's index in the `items` array.
|
|
35
|
+
// This way, when the `items` change, their keys are also changed.
|
|
19
36
|
|
|
20
37
|
var generateItemKeyPrefix = (0, _react.useMemo)(function () {
|
|
21
38
|
var counter = 0;
|
|
22
39
|
|
|
23
40
|
function getNextCounter() {
|
|
24
41
|
if (counter === Number.MAX_SAFE_INTEGER) {
|
|
42
|
+
for (var _iterator = _createForOfIteratorHelperLoose(itemKeysResetEventListeners), _step; !(_step = _iterator()).done;) {
|
|
43
|
+
var listener = _step.value;
|
|
44
|
+
listener();
|
|
45
|
+
}
|
|
46
|
+
|
|
25
47
|
counter = 0;
|
|
26
48
|
}
|
|
27
49
|
|
|
@@ -32,9 +54,9 @@ function useItemKeys(_ref) {
|
|
|
32
54
|
return function () {
|
|
33
55
|
itemKeyPrefix.current = String(getNextCounter());
|
|
34
56
|
};
|
|
35
|
-
}, [itemKeyPrefix]);
|
|
57
|
+
}, [itemKeyPrefix, itemKeysResetEventListeners]);
|
|
36
58
|
(0, _react.useMemo)(function () {
|
|
37
|
-
// Generate an initial unique `key` prefix for list
|
|
59
|
+
// Generate an initial unique `key` prefix for list items.
|
|
38
60
|
generateItemKeyPrefix();
|
|
39
61
|
}, []); // If `getItemId()` function is defined, then item `id`s are gonna be the item element `key`s.
|
|
40
62
|
|
|
@@ -54,13 +76,14 @@ function useItemKeys(_ref) {
|
|
|
54
76
|
|
|
55
77
|
var getItemKey = (0, _react.useCallback)(function (item, i) {
|
|
56
78
|
if (getItemId) {
|
|
57
|
-
return getItemId(item);
|
|
79
|
+
return String(getItemId(item));
|
|
58
80
|
}
|
|
59
81
|
|
|
60
82
|
return "".concat(itemKeyPrefix.current, ":").concat(i);
|
|
61
83
|
}, [getItemId, itemKeyPrefix]);
|
|
62
84
|
return {
|
|
63
85
|
getItemKey: getItemKey,
|
|
86
|
+
onItemKeysReset: onItemKeysReset,
|
|
64
87
|
usesAutogeneratedItemKeys: usesAutogeneratedItemKeys,
|
|
65
88
|
updateItemKeysForNewItems: generateItemKeyPrefixIfNotUsingItemIds
|
|
66
89
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useItemKeys.js","names":["useItemKeys","getItemId","itemKeyPrefix","useRef","generateItemKeyPrefix","
|
|
1
|
+
{"version":3,"file":"useItemKeys.js","names":["useItemKeys","getItemId","itemKeysResetEventListeners","useMemo","onItemKeysReset","useCallback","listener","push","itemKeyPrefix","useRef","generateItemKeyPrefix","counter","getNextCounter","Number","MAX_SAFE_INTEGER","current","String","usesAutogeneratedItemKeys","generateItemKeyPrefixIfNotUsingItemIds","log","getItemKey","item","i","updateItemKeysForNewItems"],"sources":["../../source/react/useItemKeys.js"],"sourcesContent":["import log from '../utility/debug.js'\r\n\r\nimport { useRef, useMemo, useCallback } from 'react'\r\n\r\nexport default function useItemKeys({ getItemId }) {\r\n\t// These \"listeners\" will be called in case the auto-generated item keys are reset\r\n\t// due to the prefix counter number reaching its maximum allowed value.\r\n\tconst itemKeysResetEventListeners = useMemo(() => {\r\n\t\treturn []\r\n\t}, [])\r\n\r\n\t// Adds an \"on item keys reset\" listener.\r\n\tconst onItemKeysReset = useCallback((listener) => {\r\n\t\titemKeysResetEventListeners.push(listener)\r\n\t}, [])\r\n\r\n\t// List items are rendered with `key`s so that React doesn't\r\n\t// \"reuse\" `itemComponent`s in cases when `items` are changed.\r\n const itemKeyPrefix = useRef()\r\n\r\n\t// When no `getItemId()` function is specified, it creates an item key\r\n\t// from an auto-generated unique prefix and the item's index in the `items` array.\r\n\t// This way, when the `items` change, their keys are also changed.\r\n\tconst generateItemKeyPrefix = useMemo(() => {\r\n\t\tlet counter = 0\r\n\t\tfunction getNextCounter() {\r\n\t\t\tif (counter === Number.MAX_SAFE_INTEGER) {\r\n\t\t\t\tfor (const listener of itemKeysResetEventListeners) {\r\n\t\t\t\t\tlistener()\r\n\t\t\t\t}\r\n\t\t\t\tcounter = 0\r\n\t\t\t}\r\n\t\t\tcounter++\r\n\t\t\treturn counter\r\n\t\t}\r\n\t\treturn () => {\r\n\t\t\titemKeyPrefix.current = String(getNextCounter())\r\n\t\t}\r\n\t}, [\r\n\t\titemKeyPrefix,\r\n\t\titemKeysResetEventListeners\r\n\t])\r\n\r\n\tuseMemo(() => {\r\n\t\t// Generate an initial unique `key` prefix for list items.\r\n\t\tgenerateItemKeyPrefix()\r\n\t}, [])\r\n\r\n\t// If `getItemId()` function is defined, then item `id`s are gonna be the item element `key`s.\r\n\tconst usesAutogeneratedItemKeys = !getItemId\r\n\r\n\tconst generateItemKeyPrefixIfNotUsingItemIds = useCallback(() => {\r\n\t\tif (usesAutogeneratedItemKeys) {\r\n\t\t\tgenerateItemKeyPrefix()\r\n\t\t\tlog('React: ~ Item key prefix:', itemKeyPrefix.current)\r\n\t\t}\r\n\t}, [\r\n\t\tusesAutogeneratedItemKeys,\r\n\t\tgenerateItemKeyPrefix\r\n\t])\r\n\r\n\t/**\r\n\t * Returns a `key` for an `item`'s element.\r\n\t * @param {object} item — The item.\r\n\t * @param {number} i — Item's index in `items` list.\r\n\t * @return {any}\r\n\t */\r\n\tconst getItemKey = useCallback((item, i) => {\r\n\t\tif (getItemId) {\r\n\t\t\treturn String(getItemId(item))\r\n\t\t}\r\n\t\treturn `${itemKeyPrefix.current}:${i}`\r\n\t}, [\r\n\t\tgetItemId,\r\n\t\titemKeyPrefix\r\n\t])\r\n\r\n\treturn {\r\n\t\tgetItemKey,\r\n\t\tonItemKeysReset,\r\n\t\tusesAutogeneratedItemKeys,\r\n\t\tupdateItemKeysForNewItems: generateItemKeyPrefixIfNotUsingItemIds\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;;;;;;;;;;AAEe,SAASA,WAAT,OAAoC;EAAA,IAAbC,SAAa,QAAbA,SAAa;EAClD;EACA;EACA,IAAMC,2BAA2B,GAAG,IAAAC,cAAA,EAAQ,YAAM;IACjD,OAAO,EAAP;EACA,CAFmC,EAEjC,EAFiC,CAApC,CAHkD,CAOlD;;EACA,IAAMC,eAAe,GAAG,IAAAC,kBAAA,EAAY,UAACC,QAAD,EAAc;IACjDJ,2BAA2B,CAACK,IAA5B,CAAiCD,QAAjC;EACA,CAFuB,EAErB,EAFqB,CAAxB,CARkD,CAYlD;EACA;;EACC,IAAME,aAAa,GAAG,IAAAC,aAAA,GAAtB,CAdiD,CAgBlD;EACA;EACA;;EACA,IAAMC,qBAAqB,GAAG,IAAAP,cAAA,EAAQ,YAAM;IAC3C,IAAIQ,OAAO,GAAG,CAAd;;IACA,SAASC,cAAT,GAA0B;MACzB,IAAID,OAAO,KAAKE,MAAM,CAACC,gBAAvB,EAAyC;QACxC,qDAAuBZ,2BAAvB,wCAAoD;UAAA,IAAzCI,QAAyC;UACnDA,QAAQ;QACR;;QACDK,OAAO,GAAG,CAAV;MACA;;MACDA,OAAO;MACP,OAAOA,OAAP;IACA;;IACD,OAAO,YAAM;MACZH,aAAa,CAACO,OAAd,GAAwBC,MAAM,CAACJ,cAAc,EAAf,CAA9B;IACA,CAFD;EAGA,CAf6B,EAe3B,CACFJ,aADE,EAEFN,2BAFE,CAf2B,CAA9B;EAoBA,IAAAC,cAAA,EAAQ,YAAM;IACb;IACAO,qBAAqB;EACrB,CAHD,EAGG,EAHH,EAvCkD,CA4ClD;;EACA,IAAMO,yBAAyB,GAAG,CAAChB,SAAnC;EAEA,IAAMiB,sCAAsC,GAAG,IAAAb,kBAAA,EAAY,YAAM;IAChE,IAAIY,yBAAJ,EAA+B;MAC9BP,qBAAqB;MACrB,IAAAS,iBAAA,EAAI,2BAAJ,EAAiCX,aAAa,CAACO,OAA/C;IACA;EACD,CAL8C,EAK5C,CACFE,yBADE,EAEFP,qBAFE,CAL4C,CAA/C;EAUA;AACD;AACA;AACA;AACA;AACA;;EACC,IAAMU,UAAU,GAAG,IAAAf,kBAAA,EAAY,UAACgB,IAAD,EAAOC,CAAP,EAAa;IAC3C,IAAIrB,SAAJ,EAAe;MACd,OAAOe,MAAM,CAACf,SAAS,CAACoB,IAAD,CAAV,CAAb;IACA;;IACD,iBAAUb,aAAa,CAACO,OAAxB,cAAmCO,CAAnC;EACA,CALkB,EAKhB,CACFrB,SADE,EAEFO,aAFE,CALgB,CAAnB;EAUA,OAAO;IACNY,UAAU,EAAVA,UADM;IAENhB,eAAe,EAAfA,eAFM;IAGNa,yBAAyB,EAAzBA,yBAHM;IAINM,yBAAyB,EAAEL;EAJrB,CAAP;AAMA"}
|
|
@@ -8,25 +8,41 @@ exports["default"] = useOnItemHeightDidChange;
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
10
|
function useOnItemHeightDidChange(_ref) {
|
|
11
|
-
var
|
|
11
|
+
var getItemKey = _ref.getItemKey,
|
|
12
|
+
onItemKeysReset = _ref.onItemKeysReset,
|
|
12
13
|
virtualScroller = _ref.virtualScroller;
|
|
13
|
-
// Only
|
|
14
|
-
var
|
|
15
|
-
return
|
|
16
|
-
}, []); //
|
|
14
|
+
// Only create the initial cache once.
|
|
15
|
+
var initialCache = (0, _react.useMemo)(function () {
|
|
16
|
+
return createCache();
|
|
17
|
+
}, []); // A cache of `onItemHeightDidChange()` functions.
|
|
17
18
|
|
|
18
|
-
var cache = (0, _react.useRef)(
|
|
19
|
+
var cache = (0, _react.useRef)(initialCache); // Adds an "on item keys reset" listener that clears the cache when item keys are reset.
|
|
20
|
+
|
|
21
|
+
(0, _react.useMemo)(function () {
|
|
22
|
+
onItemKeysReset(function () {
|
|
23
|
+
cache.current = createCache();
|
|
24
|
+
});
|
|
25
|
+
}, []); // Caches per-item `onItemHeightDidChange` functions' "references"
|
|
19
26
|
// so that item components don't get re-rendered needlessly.
|
|
20
27
|
|
|
21
|
-
var getOnItemHeightDidChange = (0, _react.useCallback)(function (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
var getOnItemHeightDidChange = (0, _react.useCallback)(function (item) {
|
|
29
|
+
var itemKey = getItemKey(item);
|
|
30
|
+
|
|
31
|
+
if (!cache.current[itemKey]) {
|
|
32
|
+
cache.current[itemKey] = function () {
|
|
33
|
+
virtualScroller.onItemHeightDidChange(item);
|
|
25
34
|
};
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
return cache.current[
|
|
29
|
-
}, [virtualScroller, cache]);
|
|
37
|
+
return cache.current[itemKey];
|
|
38
|
+
}, [virtualScroller, getItemKey, cache]);
|
|
30
39
|
return getOnItemHeightDidChange;
|
|
31
40
|
}
|
|
41
|
+
|
|
42
|
+
function createCache() {
|
|
43
|
+
// It could also use a `new Map()` here and then use `item` as a key.
|
|
44
|
+
// Although, sometimes an `item` "reference" might change while it still being
|
|
45
|
+
// the same item, i.e. having the same `getItemId(item)` value.
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
32
48
|
//# sourceMappingURL=useOnItemHeightDidChange.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOnItemHeightDidChange.js","names":["useOnItemHeightDidChange","
|
|
1
|
+
{"version":3,"file":"useOnItemHeightDidChange.js","names":["useOnItemHeightDidChange","getItemKey","onItemKeysReset","virtualScroller","initialCache","useMemo","createCache","cache","useRef","current","getOnItemHeightDidChange","useCallback","item","itemKey","onItemHeightDidChange"],"sources":["../../source/react/useOnItemHeightDidChange.js"],"sourcesContent":["import { useMemo, useRef, useCallback } from 'react'\r\n\r\nexport default function useOnItemHeightDidChange({\r\n\tgetItemKey,\r\n\tonItemKeysReset,\r\n\tvirtualScroller\r\n}) {\r\n\t// Only create the initial cache once.\r\n\tconst initialCache = useMemo(() => {\r\n\t\treturn createCache()\r\n\t}, [])\r\n\r\n\t// A cache of `onItemHeightDidChange()` functions.\r\n\tconst cache = useRef(initialCache)\r\n\r\n\t// Adds an \"on item keys reset\" listener that clears the cache when item keys are reset.\r\n\tuseMemo(() => {\r\n\t\tonItemKeysReset(() => {\r\n\t\t\tcache.current = createCache()\r\n\t\t})\r\n\t}, [])\r\n\r\n\t// Caches per-item `onItemHeightDidChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemHeightDidChange = useCallback((item) => {\r\n\t\tconst itemKey = getItemKey(item)\r\n\t\tif (!cache.current[itemKey]) {\r\n\t\t\tcache.current[itemKey] = () => {\r\n\t\t\t\tvirtualScroller.onItemHeightDidChange(item)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn cache.current[itemKey]\r\n\t}, [\r\n\t\tvirtualScroller,\r\n\t\tgetItemKey,\r\n\t\tcache\r\n\t])\r\n\r\n\treturn getOnItemHeightDidChange\r\n}\r\n\r\nfunction createCache() {\r\n\t// It could also use a `new Map()` here and then use `item` as a key.\r\n\t// Although, sometimes an `item` \"reference\" might change while it still being\r\n\t// the same item, i.e. having the same `getItemId(item)` value.\r\n\treturn {}\r\n}"],"mappings":";;;;;;;AAAA;;AAEe,SAASA,wBAAT,OAIZ;EAAA,IAHFC,UAGE,QAHFA,UAGE;EAAA,IAFFC,eAEE,QAFFA,eAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,YAAY,GAAG,IAAAC,cAAA,EAAQ,YAAM;IAClC,OAAOC,WAAW,EAAlB;EACA,CAFoB,EAElB,EAFkB,CAArB,CAFE,CAMF;;EACA,IAAMC,KAAK,GAAG,IAAAC,aAAA,EAAOJ,YAAP,CAAd,CAPE,CASF;;EACA,IAAAC,cAAA,EAAQ,YAAM;IACbH,eAAe,CAAC,YAAM;MACrBK,KAAK,CAACE,OAAN,GAAgBH,WAAW,EAA3B;IACA,CAFc,CAAf;EAGA,CAJD,EAIG,EAJH,EAVE,CAgBF;EACA;;EACA,IAAMI,wBAAwB,GAAG,IAAAC,kBAAA,EAAY,UAACC,IAAD,EAAU;IACtD,IAAMC,OAAO,GAAGZ,UAAU,CAACW,IAAD,CAA1B;;IACA,IAAI,CAACL,KAAK,CAACE,OAAN,CAAcI,OAAd,CAAL,EAA6B;MAC5BN,KAAK,CAACE,OAAN,CAAcI,OAAd,IAAyB,YAAM;QAC9BV,eAAe,CAACW,qBAAhB,CAAsCF,IAAtC;MACA,CAFD;IAGA;;IACD,OAAOL,KAAK,CAACE,OAAN,CAAcI,OAAd,CAAP;EACA,CARgC,EAQ9B,CACFV,eADE,EAEFF,UAFE,EAGFM,KAHE,CAR8B,CAAjC;EAcA,OAAOG,wBAAP;AACA;;AAED,SAASJ,WAAT,GAAuB;EACtB;EACA;EACA;EACA,OAAO,EAAP;AACA"}
|
|
@@ -8,25 +8,44 @@ exports["default"] = useSetItemState;
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
10
|
function useSetItemState(_ref) {
|
|
11
|
-
var
|
|
11
|
+
var getItemKey = _ref.getItemKey,
|
|
12
|
+
onItemKeysReset = _ref.onItemKeysReset,
|
|
12
13
|
virtualScroller = _ref.virtualScroller;
|
|
13
|
-
// Only
|
|
14
|
-
var
|
|
15
|
-
return
|
|
16
|
-
}, []); //
|
|
14
|
+
// Only create the initial cache once.
|
|
15
|
+
var initialCache = (0, _react.useMemo)(function () {
|
|
16
|
+
return createCache();
|
|
17
|
+
}, []); // A cache of `setItemState()` functions.
|
|
17
18
|
|
|
18
|
-
var cache = (0, _react.useRef)(
|
|
19
|
+
var cache = (0, _react.useRef)(initialCache); // Adds an "on item keys reset" listener that clears the cache when item keys are reset.
|
|
20
|
+
|
|
21
|
+
(0, _react.useMemo)(function () {
|
|
22
|
+
onItemKeysReset(function () {
|
|
23
|
+
cache.current = createCache();
|
|
24
|
+
});
|
|
25
|
+
}, []); // Caches per-item `setItemState` functions' "references"
|
|
19
26
|
// so that item components don't get re-rendered needlessly.
|
|
27
|
+
// I.e. it could just re-create this function every time
|
|
28
|
+
// but that would also make React re-render the item component every time
|
|
29
|
+
// which wouldn't be efficient.
|
|
30
|
+
|
|
31
|
+
var getSetItemState = (0, _react.useCallback)(function (item) {
|
|
32
|
+
var itemKey = getItemKey(item);
|
|
20
33
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return virtualScroller.setItemState(i, itemState);
|
|
34
|
+
if (!cache.current[itemKey]) {
|
|
35
|
+
cache.current[itemKey] = function (itemState) {
|
|
36
|
+
virtualScroller.setItemState(item, itemState);
|
|
25
37
|
};
|
|
26
38
|
}
|
|
27
39
|
|
|
28
|
-
return cache.current[
|
|
29
|
-
}, [virtualScroller, cache]);
|
|
40
|
+
return cache.current[itemKey];
|
|
41
|
+
}, [virtualScroller, getItemKey, cache]);
|
|
30
42
|
return getSetItemState;
|
|
31
43
|
}
|
|
44
|
+
|
|
45
|
+
function createCache() {
|
|
46
|
+
// It could also use a `new Map()` here and then use `item` as a key.
|
|
47
|
+
// Although, sometimes an `item` "reference" might change while it still being
|
|
48
|
+
// the same item, i.e. having the same `getItemId(item)` value.
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
32
51
|
//# sourceMappingURL=useSetItemState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSetItemState.js","names":["useSetItemState","
|
|
1
|
+
{"version":3,"file":"useSetItemState.js","names":["useSetItemState","getItemKey","onItemKeysReset","virtualScroller","initialCache","useMemo","createCache","cache","useRef","current","getSetItemState","useCallback","item","itemKey","itemState","setItemState"],"sources":["../../source/react/useSetItemState.js"],"sourcesContent":["import { useMemo, useRef, useCallback } from 'react'\r\n\r\nexport default function useSetItemState({\r\n\tgetItemKey,\r\n\tonItemKeysReset,\r\n\tvirtualScroller\r\n}) {\r\n\t// Only create the initial cache once.\r\n\tconst initialCache = useMemo(() => {\r\n\t\treturn createCache()\r\n\t}, [])\r\n\r\n\t// A cache of `setItemState()` functions.\r\n\tconst cache = useRef(initialCache)\r\n\r\n\t// Adds an \"on item keys reset\" listener that clears the cache when item keys are reset.\r\n\tuseMemo(() => {\r\n\t\tonItemKeysReset(() => {\r\n\t\t\tcache.current = createCache()\r\n\t\t})\r\n\t}, [])\r\n\r\n\t// Caches per-item `setItemState` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\t// I.e. it could just re-create this function every time\r\n\t// but that would also make React re-render the item component every time\r\n\t// which wouldn't be efficient.\r\n\tconst getSetItemState = useCallback((item) => {\r\n\t\tconst itemKey = getItemKey(item)\r\n\t\tif (!cache.current[itemKey]) {\r\n\t\t\tcache.current[itemKey] = (itemState) => {\r\n\t\t\t\tvirtualScroller.setItemState(item, itemState)\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn cache.current[itemKey]\r\n\t}, [\r\n\t\tvirtualScroller,\r\n\t\tgetItemKey,\r\n\t\tcache\r\n\t])\r\n\r\n\treturn getSetItemState\r\n}\r\n\r\nfunction createCache() {\r\n\t// It could also use a `new Map()` here and then use `item` as a key.\r\n\t// Although, sometimes an `item` \"reference\" might change while it still being\r\n\t// the same item, i.e. having the same `getItemId(item)` value.\r\n\treturn {}\r\n}"],"mappings":";;;;;;;AAAA;;AAEe,SAASA,eAAT,OAIZ;EAAA,IAHFC,UAGE,QAHFA,UAGE;EAAA,IAFFC,eAEE,QAFFA,eAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,YAAY,GAAG,IAAAC,cAAA,EAAQ,YAAM;IAClC,OAAOC,WAAW,EAAlB;EACA,CAFoB,EAElB,EAFkB,CAArB,CAFE,CAMF;;EACA,IAAMC,KAAK,GAAG,IAAAC,aAAA,EAAOJ,YAAP,CAAd,CAPE,CASF;;EACA,IAAAC,cAAA,EAAQ,YAAM;IACbH,eAAe,CAAC,YAAM;MACrBK,KAAK,CAACE,OAAN,GAAgBH,WAAW,EAA3B;IACA,CAFc,CAAf;EAGA,CAJD,EAIG,EAJH,EAVE,CAgBF;EACA;EACA;EACA;EACA;;EACA,IAAMI,eAAe,GAAG,IAAAC,kBAAA,EAAY,UAACC,IAAD,EAAU;IAC7C,IAAMC,OAAO,GAAGZ,UAAU,CAACW,IAAD,CAA1B;;IACA,IAAI,CAACL,KAAK,CAACE,OAAN,CAAcI,OAAd,CAAL,EAA6B;MAC5BN,KAAK,CAACE,OAAN,CAAcI,OAAd,IAAyB,UAACC,SAAD,EAAe;QACvCX,eAAe,CAACY,YAAhB,CAA6BH,IAA7B,EAAmCE,SAAnC;MACA,CAFD;IAGA;;IACD,OAAOP,KAAK,CAACE,OAAN,CAAcI,OAAd,CAAP;EACA,CARuB,EAQrB,CACFV,eADE,EAEFF,UAFE,EAGFM,KAHE,CARqB,CAAxB;EAcA,OAAOG,eAAP;AACA;;AAED,SAASJ,WAAT,GAAuB;EACtB;EACA;EACA;EACA,OAAO,EAAP;AACA"}
|
|
@@ -13,7 +13,7 @@ var _getStateSnapshot = _interopRequireDefault(require("../utility/getStateSnaps
|
|
|
13
13
|
|
|
14
14
|
var _react = require("react");
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _useStateWithRepeatableRead = _interopRequireDefault(require("./useStateWithRepeatableRead.js"));
|
|
17
17
|
|
|
18
18
|
var _useInsertionEffectDontMountTwiceInStrictMode = _interopRequireDefault(require("./useInsertionEffectDontMountTwiceInStrictMode.js"));
|
|
19
19
|
|
|
@@ -40,18 +40,17 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
40
40
|
// Creates state management functions.
|
|
41
41
|
function _useState(_ref) {
|
|
42
42
|
var initialState = _ref.initialState,
|
|
43
|
-
onRender = _ref.onRender
|
|
44
|
-
itemsProperty = _ref.itemsProperty;
|
|
43
|
+
onRender = _ref.onRender;
|
|
45
44
|
|
|
46
45
|
// This is a state variable that is used to re-render the component.
|
|
47
46
|
// Right after the component has finished re-rendering,
|
|
48
47
|
// `VirtualScroller` state gets updated from this variable.
|
|
49
48
|
// The reason for that is that `VirtualScroller` state must always
|
|
50
49
|
// correspond exactly to what's currently rendered on the screen.
|
|
51
|
-
var
|
|
52
|
-
|
|
53
|
-
_newState =
|
|
54
|
-
_setNewState =
|
|
50
|
+
var _useStateWithRepeatab = (0, _useStateWithRepeatableRead["default"])(initialState),
|
|
51
|
+
_useStateWithRepeatab2 = _slicedToArray(_useStateWithRepeatab, 2),
|
|
52
|
+
_newState = _useStateWithRepeatab2[0],
|
|
53
|
+
_setNewState = _useStateWithRepeatab2[1]; // This `state` reference is what `VirtualScroller` uses internally.
|
|
55
54
|
// It's the "source of truth" on the actual `VirtualScroller` state.
|
|
56
55
|
|
|
57
56
|
|
|
@@ -69,11 +68,11 @@ function _useState(_ref) {
|
|
|
69
68
|
// called `onHeightDidChange()` from its own `useLayoutEffect()`.
|
|
70
69
|
// In those cases, the `itemCompoent`'s effect would run before
|
|
71
70
|
// the `<VirtualScroller/>`'s effect, resulting in
|
|
72
|
-
// `VirtualScroller.onItemHeightDidChange(
|
|
71
|
+
// `VirtualScroller.onItemHeightDidChange(item)` being run at a moment in time
|
|
73
72
|
// when the DOM has already been updated for the next `VirtualScroller` state
|
|
74
73
|
// but the actual `VirtualScroller` state is still a previous ("stale") one
|
|
75
74
|
// containing "stale" first/last shown item indexes, which would result in an
|
|
76
|
-
// "index out of bounds" error when `onItemHeightDidChange(
|
|
75
|
+
// "index out of bounds" error when `onItemHeightDidChange(item)` tries to access
|
|
77
76
|
// and measure the DOM element from item index `i` which doesn't already/yet exist.
|
|
78
77
|
//
|
|
79
78
|
// An example of such situation could be seen from a `VirtualScroller` debug log
|
|
@@ -127,11 +126,11 @@ function _useState(_ref) {
|
|
|
127
126
|
//
|
|
128
127
|
// ~ Rendered ~
|
|
129
128
|
// "~ Rendered ~" is what gets output when `onRender()` function gets called.
|
|
130
|
-
// It means that `useLayoutEffect()` was triggered after `onItemHeightDidChange(
|
|
129
|
+
// It means that `useLayoutEffect()` was triggered after `onItemHeightDidChange(item)`
|
|
131
130
|
// was called and after the "ERROR" happened.
|
|
132
131
|
//
|
|
133
132
|
// The "ERROR" happened because new item indexes 4…5 were actually rendered instead of
|
|
134
|
-
// item indexes 2…5 by the time the application called `onItemHeightDidChange(
|
|
133
|
+
// item indexes 2…5 by the time the application called `onItemHeightDidChange(item)` function
|
|
135
134
|
// inside `itemComponent`'s `useLayoutEffect()`.
|
|
136
135
|
// Item indexes 4…5 is what was requested in a `setState()` call, which called `_setNewState()`.
|
|
137
136
|
// This means that `_newState` changes have been applied to the DOM
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useState.js","names":["_useState","initialState","onRender","itemsProperty","useStateNoStaleBug","_newState","_setNewState","state","useRef","getState","useCallback","current","setState","newState","useInsertionEffectDontMountTwiceInStrictMode","isDebug","log","getStateSnapshot","useLayoutEffectDontMountTwiceInStrictMode","stateToRender"],"sources":["../../source/react/useState.js"],"sourcesContent":["import log, { isDebug } from '../utility/debug.js'\r\nimport getStateSnapshot from '../utility/getStateSnapshot.js'\r\n\r\nimport { useRef, useCallback } from 'react'\r\nimport useStateNoStaleBug from './useStateNoStaleBug.js'\r\nimport useInsertionEffectDontMountTwiceInStrictMode from './useInsertionEffectDontMountTwiceInStrictMode.js'\r\nimport useLayoutEffectDontMountTwiceInStrictMode from './useLayoutEffectDontMountTwiceInStrictMode.js'\r\n\r\n// Creates state management functions.\r\nexport default function _useState({\r\n\tinitialState,\r\n\tonRender,\r\n\titemsProperty\r\n}) {\r\n\t// This is a state variable that is used to re-render the component.\r\n\t// Right after the component has finished re-rendering,\r\n\t// `VirtualScroller` state gets updated from this variable.\r\n\t// The reason for that is that `VirtualScroller` state must always\r\n\t// correspond exactly to what's currently rendered on the screen.\r\n\tconst [_newState, _setNewState] = useStateNoStaleBug(initialState)\r\n\r\n\t// This `state` reference is what `VirtualScroller` uses internally.\r\n\t// It's the \"source of truth\" on the actual `VirtualScroller` state.\r\n\tconst state = useRef(initialState)\r\n\r\n\tconst getState = useCallback(() => {\r\n\t\treturn state.current\r\n\t}, [])\r\n\r\n\tconst setState = useCallback((newState) => {\r\n\t\tstate.current = newState\r\n\t}, [])\r\n\r\n\t// Updating of the actual `VirtualScroller` state is done in a\r\n\t// `useInsertionEffect()` rather than in a `useLayoutEffect()`.\r\n\t//\r\n\t// The reason is that using `useLayoutEffect()` would result in\r\n\t// \"breaking\" the `<VirtualScroller/>` when an `itemComponent`\r\n\t// called `onHeightDidChange()` from its own `useLayoutEffect()`.\r\n\t// In those cases, the `itemCompoent`'s effect would run before\r\n\t// the `<VirtualScroller/>`'s effect, resulting in\r\n\t// `VirtualScroller.onItemHeightDidChange(i)` being run at a moment in time\r\n\t// when the DOM has already been updated for the next `VirtualScroller` state\r\n\t// but the actual `VirtualScroller` state is still a previous (\"stale\") one\r\n\t// containing \"stale\" first/last shown item indexes, which would result in an\r\n\t// \"index out of bounds\" error when `onItemHeightDidChange(i)` tries to access\r\n\t// and measure the DOM element from item index `i` which doesn't already/yet exist.\r\n\t//\r\n\t// An example of such situation could be seen from a `VirtualScroller` debug log\r\n\t// which was captured for a case when using `useLayoutEffect()` to update the\r\n\t// \"actual\" `VirtualScroller` state after the corresponding DOM changes have been applied:\r\n\r\n\t// The user has scrolled far enough: perform a re-layout\r\n\t// ~ Update Layout (on scroll) ~\r\n\t//\r\n\t// Item index 2 height is required for calculations but hasn't been measured yet. Mark the item as \"shown\", rerender the list, measure the item's height and redo the layout.\r\n\t//\r\n\t// ~ Calculated Layout ~\r\n\t// Columns count 1\r\n\t// First shown item index 2\r\n\t// Last shown item index 5\r\n\t// …\r\n\t// Item heights (231) [1056.578125, 783.125, empty × 229]\r\n\t// Item states (231) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]\r\n\t//\r\n\t// ~ Set state ~\r\n\t// {firstShownItemIndex: 2, lastShownItemIndex: 5, …}\r\n\t//\r\n\t// ~ Rendered ~\r\n\t// State {firstShownItemIndex: 2, lastShownItemIndex: 5, …}\r\n\t//\r\n\t// ~ Measure item heights ~\r\n\t// Item index 2 height 719.8828125\r\n\t// Item index 3 height 961.640625\r\n\t// Item index 4 height 677.6640625\r\n\t// Item index 5 height 1510.1953125\r\n\t//\r\n\t// ~ Update Layout (on non-measured item heights have been measured) ~\r\n\t//\r\n\t// ~ Calculated Layout ~\r\n\t// Columns count 1\r\n\t// First shown item index 4\r\n\t// Last shown item index 5\r\n\t// …\r\n\t// Item heights (231) [1056.578125, 783.125, 719.8828125, 961.640625, 677.6640625, 1510.1953125, empty × 225]\r\n\t// Item states (231) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]\r\n\t//\r\n\t// ~ Set state ~\r\n\t// {firstShownItemIndex: 4, lastShownItemIndex: 5, beforeItemsHeight: 3521.2265625, afterItemsHeight: 214090.72265624942}\r\n\t//\r\n\t// ~ On Item Height Did Change was called ~\r\n\t// Item index 5\r\n\t// ~ Re-measure item height ~\r\n\t// ERROR \"onItemHeightDidChange()\" has been called for item index 5 but the item is not currently rendered and can't be measured. The exact error was: Element with index 3 was not found in the list of Rendered Item Elements in the Items Container of Virtual Scroller. There're only 2 Elements there.\r\n\t//\r\n\t// React: ~ The requested state is about to be applied in DOM. Set it as the `VirtualScroller` state. ~\r\n\t// {firstShownItemIndex: 4, lastShownItemIndex: 5, …}\r\n\t//\r\n\t// ~ Rendered ~\r\n\r\n\t// \"~ Rendered ~\" is what gets output when `onRender()` function gets called.\r\n\t// It means that `useLayoutEffect()` was triggered after `onItemHeightDidChange(i)`\r\n\t// was called and after the \"ERROR\" happened.\r\n\t//\r\n\t// The \"ERROR\" happened because new item indexes 4…5 were actually rendered instead of\r\n\t// item indexes 2…5 by the time the application called `onItemHeightDidChange(i)` function\r\n\t// inside `itemComponent`'s `useLayoutEffect()`.\r\n\t// Item indexes 4…5 is what was requested in a `setState()` call, which called `_setNewState()`.\r\n\t// This means that `_newState` changes have been applied to the DOM\r\n\t// but `useLayoutEffect()` wasn't triggered immediately after that.\r\n\t// Instead, it was triggered a right after the `itemComponent`'s `useLayoutEffect()`\r\n\t// because child effects run before parent effects.\r\n\t// So, the `itemComponent`'s `onHeightDidChange()` function call caught the\r\n\t// `VirtualScroller` in an inconsistent state.\r\n\t//\r\n\t// To fix that, `useLayoutEffect()` gets replaced with `useInsertionEffect()`:\r\n\t// https://blog.saeloun.com/2022/06/02/react-18-useinsertioneffect\r\n\t// https://beta.reactjs.org/reference/react/useInsertionEffect\r\n\t//\r\n\t// After replacing `useLayoutEffect()` with `useInsertionEffect()`,\r\n\t// the log shows that there's no more error:\r\n\t//\r\n\t// ~ Set state ~\r\n\t// {firstShownItemIndex: 0, lastShownItemIndex: 2, …}\r\n\t//\r\n\t// React: ~ The requested state is about to be applied in DOM. Set it as the `VirtualScroller` state. ~\r\n\t// {firstShownItemIndex: 0, lastShownItemIndex: 2, …}\r\n\t//\r\n\t// ~ On Item Height Did Change was called ~\r\n\t// Item index 0\r\n\t// ~ Re-measure item height ~\r\n\t// Previous height 917\r\n\t// New height 1064.453125\r\n\t// ~ Item height has changed ~\r\n\t//\r\n\t// An alternative solution would be demanding the `itemComponent` to\r\n\t// accept a `ref` and then measuring the corresponding DOM element height\r\n\t// directly using the `ref`-ed DOM element rather than searching for that\r\n\t// DOM element in the `ItemsContainer`.\r\n\t// So if `useInsertionEffect()` gets removed from React in some hypothetical future,\r\n\t// it could be replaced with using `ref`s on `ItemComponent`s to measure the DOM element heights.\r\n\t//\r\n\tuseInsertionEffectDontMountTwiceInStrictMode(() => {\r\n\t\t// Update the actual `VirtualScroller` state right before the DOM changes\r\n\t\t// are going to be applied for the requested state update.\r\n\t\t//\r\n\t\t// This hook will run right before `useLayoutEffect()`.\r\n\t\t//\r\n\t\t// It doesn't make any difference which one of the two hooks to use to update\r\n\t\t// the actual `VirtualScroller` state in this scenario because the two hooks\r\n\t\t// run synchronously one right after another (insertion effect → DOM update → layout effect)\r\n\t\t// without any free space for any `VirtualScroller` code (like the scroll event handler)\r\n\t\t// to squeeze in and run in-between them, so the `VirtualScroller`'s `state`\r\n\t\t// is always gonna stay consistent with what's currently rendered on screen\r\n\t\t// from the `VirtualScroler`'s point of view, and the short transition period\r\n\t\t// it simply doesn't see because it doesn't \"wake up\" during that period.\r\n\t\t//\r\n\t\t// Updating the actual `VirtualScroller` state right before `useLayoutEffect()`\r\n\t\t// fixes the bug when an `itemComponent` calls `onHeightDidChange()` in its own\r\n\t\t// `useLayoutEffect()` which would run before this `useLayoutEffect()`\r\n\t\t// because children's effects run before parent's.\r\n\t\t//\r\n\t\t// This hook doesn't do anything at the initial render.\r\n\t\t//\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('React: ~ The requested state is about to be applied in DOM. Setting it as the `VirtualScroller` state. ~')\r\n\t\t\tlog(getStateSnapshot(_newState))\r\n\t\t}\r\n\t\tsetState(_newState)\r\n\t}, [_newState])\r\n\r\n\tuseLayoutEffectDontMountTwiceInStrictMode(() => {\r\n\t\t// Call `onRender()` right after a requested state update has been applied,\r\n\t\t// and also right after the initial render.\r\n\t\tonRender()\r\n\t}, [_newState])\r\n\r\n\treturn {\r\n\t\t// This is the state the component should render.\r\n\t\tstateToRender: _newState,\r\n\r\n\t\t// Returns the current state of the `VirtualScroller`.\r\n\t\t// This function is used in the `VirtualScroller` itself\r\n\t\t// because the `state` is managed outside of it.\r\n\t\tgetState,\r\n\r\n\t\t// Requests a state update.\r\n\t\tsetState: _setNewState\r\n\t}\r\n}"],"mappings":";;;;;;;;;AAAA;;AACA;;AAEA;;AACA;;AACA;;AACA;;;;;;;;;;;;;;;;;;;;AAEA;AACe,SAASA,SAAT,OAIZ;EAAA,IAHFC,YAGE,QAHFA,YAGE;EAAA,IAFFC,QAEE,QAFFA,QAEE;EAAA,IADFC,aACE,QADFA,aACE;;EACF;EACA;EACA;EACA;EACA;EACA,0BAAkC,IAAAC,+BAAA,EAAmBH,YAAnB,CAAlC;EAAA;EAAA,IAAOI,SAAP;EAAA,IAAkBC,YAAlB,2BANE,CAQF;EACA;;;EACA,IAAMC,KAAK,GAAG,IAAAC,aAAA,EAAOP,YAAP,CAAd;EAEA,IAAMQ,QAAQ,GAAG,IAAAC,kBAAA,EAAY,YAAM;IAClC,OAAOH,KAAK,CAACI,OAAb;EACA,CAFgB,EAEd,EAFc,CAAjB;EAIA,IAAMC,QAAQ,GAAG,IAAAF,kBAAA,EAAY,UAACG,QAAD,EAAc;IAC1CN,KAAK,CAACI,OAAN,GAAgBE,QAAhB;EACA,CAFgB,EAEd,EAFc,CAAjB,CAhBE,CAoBF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACA,IAAAC,wDAAA,EAA6C,YAAM;IAClD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,IAAAC,cAAA,GAAJ,EAAe;MACd,IAAAC,iBAAA,EAAI,0GAAJ;MACA,IAAAA,iBAAA,EAAI,IAAAC,4BAAA,EAAiBZ,SAAjB,CAAJ;IACA;;IACDO,QAAQ,CAACP,SAAD,CAAR;EACA,CA3BD,EA2BG,CAACA,SAAD,CA3BH;EA6BA,IAAAa,qDAAA,EAA0C,YAAM;IAC/C;IACA;IACAhB,QAAQ;EACR,CAJD,EAIG,CAACG,SAAD,CAJH;EAMA,OAAO;IACN;IACAc,aAAa,EAAEd,SAFT;IAIN;IACA;IACA;IACAI,QAAQ,EAARA,QAPM;IASN;IACAG,QAAQ,EAAEN;EAVJ,CAAP;AAYA"}
|
|
1
|
+
{"version":3,"file":"useState.js","names":["_useState","initialState","onRender","useStateWithRepeatableRead","_newState","_setNewState","state","useRef","getState","useCallback","current","setState","newState","useInsertionEffectDontMountTwiceInStrictMode","isDebug","log","getStateSnapshot","useLayoutEffectDontMountTwiceInStrictMode","stateToRender"],"sources":["../../source/react/useState.js"],"sourcesContent":["import log, { isDebug } from '../utility/debug.js'\r\nimport getStateSnapshot from '../utility/getStateSnapshot.js'\r\n\r\nimport { useRef, useCallback } from 'react'\r\nimport useStateWithRepeatableRead from './useStateWithRepeatableRead.js'\r\nimport useInsertionEffectDontMountTwiceInStrictMode from './useInsertionEffectDontMountTwiceInStrictMode.js'\r\nimport useLayoutEffectDontMountTwiceInStrictMode from './useLayoutEffectDontMountTwiceInStrictMode.js'\r\n\r\n// Creates state management functions.\r\nexport default function _useState({\r\n\tinitialState,\r\n\tonRender\r\n}) {\r\n\t// This is a state variable that is used to re-render the component.\r\n\t// Right after the component has finished re-rendering,\r\n\t// `VirtualScroller` state gets updated from this variable.\r\n\t// The reason for that is that `VirtualScroller` state must always\r\n\t// correspond exactly to what's currently rendered on the screen.\r\n\tconst [_newState, _setNewState] = useStateWithRepeatableRead(initialState)\r\n\r\n\t// This `state` reference is what `VirtualScroller` uses internally.\r\n\t// It's the \"source of truth\" on the actual `VirtualScroller` state.\r\n\tconst state = useRef(initialState)\r\n\r\n\tconst getState = useCallback(() => {\r\n\t\treturn state.current\r\n\t}, [])\r\n\r\n\tconst setState = useCallback((newState) => {\r\n\t\tstate.current = newState\r\n\t}, [])\r\n\r\n\t// Updating of the actual `VirtualScroller` state is done in a\r\n\t// `useInsertionEffect()` rather than in a `useLayoutEffect()`.\r\n\t//\r\n\t// The reason is that using `useLayoutEffect()` would result in\r\n\t// \"breaking\" the `<VirtualScroller/>` when an `itemComponent`\r\n\t// called `onHeightDidChange()` from its own `useLayoutEffect()`.\r\n\t// In those cases, the `itemCompoent`'s effect would run before\r\n\t// the `<VirtualScroller/>`'s effect, resulting in\r\n\t// `VirtualScroller.onItemHeightDidChange(item)` being run at a moment in time\r\n\t// when the DOM has already been updated for the next `VirtualScroller` state\r\n\t// but the actual `VirtualScroller` state is still a previous (\"stale\") one\r\n\t// containing \"stale\" first/last shown item indexes, which would result in an\r\n\t// \"index out of bounds\" error when `onItemHeightDidChange(item)` tries to access\r\n\t// and measure the DOM element from item index `i` which doesn't already/yet exist.\r\n\t//\r\n\t// An example of such situation could be seen from a `VirtualScroller` debug log\r\n\t// which was captured for a case when using `useLayoutEffect()` to update the\r\n\t// \"actual\" `VirtualScroller` state after the corresponding DOM changes have been applied:\r\n\r\n\t// The user has scrolled far enough: perform a re-layout\r\n\t// ~ Update Layout (on scroll) ~\r\n\t//\r\n\t// Item index 2 height is required for calculations but hasn't been measured yet. Mark the item as \"shown\", rerender the list, measure the item's height and redo the layout.\r\n\t//\r\n\t// ~ Calculated Layout ~\r\n\t// Columns count 1\r\n\t// First shown item index 2\r\n\t// Last shown item index 5\r\n\t// …\r\n\t// Item heights (231) [1056.578125, 783.125, empty × 229]\r\n\t// Item states (231) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]\r\n\t//\r\n\t// ~ Set state ~\r\n\t// {firstShownItemIndex: 2, lastShownItemIndex: 5, …}\r\n\t//\r\n\t// ~ Rendered ~\r\n\t// State {firstShownItemIndex: 2, lastShownItemIndex: 5, …}\r\n\t//\r\n\t// ~ Measure item heights ~\r\n\t// Item index 2 height 719.8828125\r\n\t// Item index 3 height 961.640625\r\n\t// Item index 4 height 677.6640625\r\n\t// Item index 5 height 1510.1953125\r\n\t//\r\n\t// ~ Update Layout (on non-measured item heights have been measured) ~\r\n\t//\r\n\t// ~ Calculated Layout ~\r\n\t// Columns count 1\r\n\t// First shown item index 4\r\n\t// Last shown item index 5\r\n\t// …\r\n\t// Item heights (231) [1056.578125, 783.125, 719.8828125, 961.640625, 677.6640625, 1510.1953125, empty × 225]\r\n\t// Item states (231) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]\r\n\t//\r\n\t// ~ Set state ~\r\n\t// {firstShownItemIndex: 4, lastShownItemIndex: 5, beforeItemsHeight: 3521.2265625, afterItemsHeight: 214090.72265624942}\r\n\t//\r\n\t// ~ On Item Height Did Change was called ~\r\n\t// Item index 5\r\n\t// ~ Re-measure item height ~\r\n\t// ERROR \"onItemHeightDidChange()\" has been called for item index 5 but the item is not currently rendered and can't be measured. The exact error was: Element with index 3 was not found in the list of Rendered Item Elements in the Items Container of Virtual Scroller. There're only 2 Elements there.\r\n\t//\r\n\t// React: ~ The requested state is about to be applied in DOM. Set it as the `VirtualScroller` state. ~\r\n\t// {firstShownItemIndex: 4, lastShownItemIndex: 5, …}\r\n\t//\r\n\t// ~ Rendered ~\r\n\r\n\t// \"~ Rendered ~\" is what gets output when `onRender()` function gets called.\r\n\t// It means that `useLayoutEffect()` was triggered after `onItemHeightDidChange(item)`\r\n\t// was called and after the \"ERROR\" happened.\r\n\t//\r\n\t// The \"ERROR\" happened because new item indexes 4…5 were actually rendered instead of\r\n\t// item indexes 2…5 by the time the application called `onItemHeightDidChange(item)` function\r\n\t// inside `itemComponent`'s `useLayoutEffect()`.\r\n\t// Item indexes 4…5 is what was requested in a `setState()` call, which called `_setNewState()`.\r\n\t// This means that `_newState` changes have been applied to the DOM\r\n\t// but `useLayoutEffect()` wasn't triggered immediately after that.\r\n\t// Instead, it was triggered a right after the `itemComponent`'s `useLayoutEffect()`\r\n\t// because child effects run before parent effects.\r\n\t// So, the `itemComponent`'s `onHeightDidChange()` function call caught the\r\n\t// `VirtualScroller` in an inconsistent state.\r\n\t//\r\n\t// To fix that, `useLayoutEffect()` gets replaced with `useInsertionEffect()`:\r\n\t// https://blog.saeloun.com/2022/06/02/react-18-useinsertioneffect\r\n\t// https://beta.reactjs.org/reference/react/useInsertionEffect\r\n\t//\r\n\t// After replacing `useLayoutEffect()` with `useInsertionEffect()`,\r\n\t// the log shows that there's no more error:\r\n\t//\r\n\t// ~ Set state ~\r\n\t// {firstShownItemIndex: 0, lastShownItemIndex: 2, …}\r\n\t//\r\n\t// React: ~ The requested state is about to be applied in DOM. Set it as the `VirtualScroller` state. ~\r\n\t// {firstShownItemIndex: 0, lastShownItemIndex: 2, …}\r\n\t//\r\n\t// ~ On Item Height Did Change was called ~\r\n\t// Item index 0\r\n\t// ~ Re-measure item height ~\r\n\t// Previous height 917\r\n\t// New height 1064.453125\r\n\t// ~ Item height has changed ~\r\n\t//\r\n\t// An alternative solution would be demanding the `itemComponent` to\r\n\t// accept a `ref` and then measuring the corresponding DOM element height\r\n\t// directly using the `ref`-ed DOM element rather than searching for that\r\n\t// DOM element in the `ItemsContainer`.\r\n\t// So if `useInsertionEffect()` gets removed from React in some hypothetical future,\r\n\t// it could be replaced with using `ref`s on `ItemComponent`s to measure the DOM element heights.\r\n\t//\r\n\tuseInsertionEffectDontMountTwiceInStrictMode(() => {\r\n\t\t// Update the actual `VirtualScroller` state right before the DOM changes\r\n\t\t// are going to be applied for the requested state update.\r\n\t\t//\r\n\t\t// This hook will run right before `useLayoutEffect()`.\r\n\t\t//\r\n\t\t// It doesn't make any difference which one of the two hooks to use to update\r\n\t\t// the actual `VirtualScroller` state in this scenario because the two hooks\r\n\t\t// run synchronously one right after another (insertion effect → DOM update → layout effect)\r\n\t\t// without any free space for any `VirtualScroller` code (like the scroll event handler)\r\n\t\t// to squeeze in and run in-between them, so the `VirtualScroller`'s `state`\r\n\t\t// is always gonna stay consistent with what's currently rendered on screen\r\n\t\t// from the `VirtualScroler`'s point of view, and the short transition period\r\n\t\t// it simply doesn't see because it doesn't \"wake up\" during that period.\r\n\t\t//\r\n\t\t// Updating the actual `VirtualScroller` state right before `useLayoutEffect()`\r\n\t\t// fixes the bug when an `itemComponent` calls `onHeightDidChange()` in its own\r\n\t\t// `useLayoutEffect()` which would run before this `useLayoutEffect()`\r\n\t\t// because children's effects run before parent's.\r\n\t\t//\r\n\t\t// This hook doesn't do anything at the initial render.\r\n\t\t//\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('React: ~ The requested state is about to be applied in DOM. Setting it as the `VirtualScroller` state. ~')\r\n\t\t\tlog(getStateSnapshot(_newState))\r\n\t\t}\r\n\t\tsetState(_newState)\r\n\t}, [_newState])\r\n\r\n\tuseLayoutEffectDontMountTwiceInStrictMode(() => {\r\n\t\t// Call `onRender()` right after a requested state update has been applied,\r\n\t\t// and also right after the initial render.\r\n\t\tonRender()\r\n\t}, [_newState])\r\n\r\n\treturn {\r\n\t\t// This is the state the component should render.\r\n\t\tstateToRender: _newState,\r\n\r\n\t\t// Returns the current state of the `VirtualScroller`.\r\n\t\t// This function is used in the `VirtualScroller` itself\r\n\t\t// because the `state` is managed outside of it.\r\n\t\tgetState,\r\n\r\n\t\t// Requests a state update.\r\n\t\tsetState: _setNewState\r\n\t}\r\n}"],"mappings":";;;;;;;;;AAAA;;AACA;;AAEA;;AACA;;AACA;;AACA;;;;;;;;;;;;;;;;;;;;AAEA;AACe,SAASA,SAAT,OAGZ;EAAA,IAFFC,YAEE,QAFFA,YAEE;EAAA,IADFC,QACE,QADFA,QACE;;EACF;EACA;EACA;EACA;EACA;EACA,4BAAkC,IAAAC,sCAAA,EAA2BF,YAA3B,CAAlC;EAAA;EAAA,IAAOG,SAAP;EAAA,IAAkBC,YAAlB,6BANE,CAQF;EACA;;;EACA,IAAMC,KAAK,GAAG,IAAAC,aAAA,EAAON,YAAP,CAAd;EAEA,IAAMO,QAAQ,GAAG,IAAAC,kBAAA,EAAY,YAAM;IAClC,OAAOH,KAAK,CAACI,OAAb;EACA,CAFgB,EAEd,EAFc,CAAjB;EAIA,IAAMC,QAAQ,GAAG,IAAAF,kBAAA,EAAY,UAACG,QAAD,EAAc;IAC1CN,KAAK,CAACI,OAAN,GAAgBE,QAAhB;EACA,CAFgB,EAEd,EAFc,CAAjB,CAhBE,CAoBF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACA,IAAAC,wDAAA,EAA6C,YAAM;IAClD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,IAAAC,cAAA,GAAJ,EAAe;MACd,IAAAC,iBAAA,EAAI,0GAAJ;MACA,IAAAA,iBAAA,EAAI,IAAAC,4BAAA,EAAiBZ,SAAjB,CAAJ;IACA;;IACDO,QAAQ,CAACP,SAAD,CAAR;EACA,CA3BD,EA2BG,CAACA,SAAD,CA3BH;EA6BA,IAAAa,qDAAA,EAA0C,YAAM;IAC/C;IACA;IACAf,QAAQ;EACR,CAJD,EAIG,CAACE,SAAD,CAJH;EAMA,OAAO;IACN;IACAc,aAAa,EAAEd,SAFT;IAIN;IACA;IACA;IACAI,QAAQ,EAARA,QAPM;IASN;IACAG,QAAQ,EAAEN;EAVJ,CAAP;AAYA"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports["default"] =
|
|
6
|
+
exports["default"] = useStateWithRepeatableRead;
|
|
7
7
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
@@ -21,7 +21,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
21
21
|
|
|
22
22
|
// This hook fixes any weird intermediate inconsistent/invalid/stale state values.
|
|
23
23
|
// https://github.com/facebook/react/issues/25023#issuecomment-1480463544
|
|
24
|
-
function
|
|
24
|
+
function useStateWithRepeatableRead(initialState) {
|
|
25
25
|
// const latestValidState = useRef(initialState)
|
|
26
26
|
var latestWrittenState = (0, _react.useRef)(initialState);
|
|
27
27
|
|
|
@@ -56,4 +56,4 @@ function useStateNoStaleBug(initialState) {
|
|
|
56
56
|
}, []);
|
|
57
57
|
return [state, setState];
|
|
58
58
|
}
|
|
59
|
-
//# sourceMappingURL=
|
|
59
|
+
//# sourceMappingURL=useStateWithRepeatableRead.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateWithRepeatableRead.js","names":["useStateWithRepeatableRead","initialState","latestWrittenState","useRef","useState","_state","_setState","state","current","setState","useCallback","newState","Error"],"sources":["../../source/react/useStateWithRepeatableRead.js"],"sourcesContent":["import { useRef, useState, useCallback } from 'react'\r\n\r\n// This hook fixes any weird intermediate inconsistent/invalid/stale state values.\r\n// https://github.com/facebook/react/issues/25023#issuecomment-1480463544\r\nexport default function useStateWithRepeatableRead(initialState) {\r\n // const latestValidState = useRef(initialState)\r\n const latestWrittenState = useRef(initialState)\r\n const [_state, _setState] = useState(initialState)\r\n\r\n // Instead of dealing with a potentially out-of-sync (stale) state value,\r\n // simply use the correct latest one.\r\n const state = latestWrittenState.current\r\n\r\n /*\r\n let state\r\n if (_state === latestWrittenState.current) {\r\n state = _state\r\n latestValidState.current = _state\r\n } else {\r\n // React bug detected: an out-of-sync (stale) state value received.\r\n // Ignore the out-of-sync (stale) state value.\r\n state = latestValidState.current\r\n }\r\n */\r\n\r\n const setState = useCallback((newState) => {\r\n if (typeof newState === 'function') {\r\n throw new Error('Function argument of `setState()` function is not supported by this hook')\r\n }\r\n latestWrittenState.current = newState\r\n _setState(newState)\r\n }, [])\r\n\r\n return [state, setState]\r\n}"],"mappings":";;;;;;;AAAA;;;;;;;;;;;;;;AAEA;AACA;AACe,SAASA,0BAAT,CAAoCC,YAApC,EAAkD;EAC/D;EACA,IAAMC,kBAAkB,GAAG,IAAAC,aAAA,EAAOF,YAAP,CAA3B;;EACA,gBAA4B,IAAAG,eAAA,EAASH,YAAT,CAA5B;EAAA;EAAA,IAAOI,MAAP;EAAA,IAAeC,SAAf,iBAH+D,CAK/D;EACA;;;EACA,IAAMC,KAAK,GAAGL,kBAAkB,CAACM,OAAjC;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAEE,IAAMC,QAAQ,GAAG,IAAAC,kBAAA,EAAY,UAACC,QAAD,EAAc;IACzC,IAAI,OAAOA,QAAP,KAAoB,UAAxB,EAAoC;MAClC,MAAM,IAAIC,KAAJ,CAAU,0EAAV,CAAN;IACD;;IACDV,kBAAkB,CAACM,OAAnB,GAA6BG,QAA7B;;IACAL,SAAS,CAACK,QAAD,CAAT;EACD,CANgB,EAMd,EANc,CAAjB;EAQA,OAAO,CAACJ,KAAD,EAAQE,QAAR,CAAP;AACD"}
|
|
@@ -9,19 +9,25 @@ var _px = _interopRequireDefault(require("../utility/px.js"));
|
|
|
9
9
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
11
11
|
|
|
12
|
-
function
|
|
12
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
13
|
+
|
|
14
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
15
|
+
|
|
16
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
17
|
+
|
|
18
|
+
function useStyle(style, _ref) {
|
|
13
19
|
var tbody = _ref.tbody,
|
|
14
20
|
state = _ref.state;
|
|
15
21
|
|
|
16
22
|
if (tbody) {
|
|
17
|
-
return;
|
|
23
|
+
return style;
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
var beforeItemsHeight = state.beforeItemsHeight,
|
|
21
27
|
afterItemsHeight = state.afterItemsHeight;
|
|
22
|
-
return {
|
|
28
|
+
return _objectSpread(_objectSpread({}, style), {}, {
|
|
23
29
|
paddingTop: (0, _px["default"])(beforeItemsHeight),
|
|
24
30
|
paddingBottom: (0, _px["default"])(afterItemsHeight)
|
|
25
|
-
};
|
|
31
|
+
});
|
|
26
32
|
}
|
|
27
33
|
//# sourceMappingURL=useStyle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStyle.js","names":["useStyle","tbody","state","beforeItemsHeight","afterItemsHeight","paddingTop","px","paddingBottom"],"sources":["../../source/react/useStyle.js"],"sourcesContent":["import px from '../utility/px.js'\r\n\r\nexport default function useStyle({\r\n\ttbody,\r\n\tstate\r\n}) {\r\n\tif (tbody) {\r\n\t\treturn\r\n\t}\r\n\r\n\tconst {\r\n\t\tbeforeItemsHeight,\r\n\t\tafterItemsHeight\r\n\t} = state\r\n\r\n\treturn {\r\n\t\tpaddingTop: px(beforeItemsHeight),\r\n\t\tpaddingBottom: px(afterItemsHeight)\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA
|
|
1
|
+
{"version":3,"file":"useStyle.js","names":["useStyle","style","tbody","state","beforeItemsHeight","afterItemsHeight","paddingTop","px","paddingBottom"],"sources":["../../source/react/useStyle.js"],"sourcesContent":["import px from '../utility/px.js'\r\n\r\nexport default function useStyle(style, {\r\n\ttbody,\r\n\tstate\r\n}) {\r\n\tif (tbody) {\r\n\t\treturn style\r\n\t}\r\n\r\n\tconst {\r\n\t\tbeforeItemsHeight,\r\n\t\tafterItemsHeight\r\n\t} = state\r\n\r\n\treturn {\r\n\t\t...style,\r\n\t\tpaddingTop: px(beforeItemsHeight),\r\n\t\tpaddingBottom: px(afterItemsHeight)\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;;;;;;;;;AAEe,SAASA,QAAT,CAAkBC,KAAlB,QAGZ;EAAA,IAFFC,KAEE,QAFFA,KAEE;EAAA,IADFC,KACE,QADFA,KACE;;EACF,IAAID,KAAJ,EAAW;IACV,OAAOD,KAAP;EACA;;EAED,IACCG,iBADD,GAGID,KAHJ,CACCC,iBADD;EAAA,IAECC,gBAFD,GAGIF,KAHJ,CAECE,gBAFD;EAKA,uCACIJ,KADJ;IAECK,UAAU,EAAE,IAAAC,cAAA,EAAGH,iBAAH,CAFb;IAGCI,aAAa,EAAE,IAAAD,cAAA,EAAGF,gBAAH;EAHhB;AAKA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useValidateTableBodyItemsContainer;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
// A developer might "forget" to pass `itemsContainerComponent="tbody"` property
|
|
11
|
+
// when using a `<tbody/>` as a container for list items.
|
|
12
|
+
// This hook validates that the developer didn't "forget" to do that in such case.
|
|
13
|
+
function useValidateTableBodyItemsContainer(_ref) {
|
|
14
|
+
var virtualScroller = _ref.virtualScroller,
|
|
15
|
+
tbody = _ref.tbody;
|
|
16
|
+
(0, _react.useEffect)(function () {
|
|
17
|
+
var isTableBodyItemsContainer = virtualScroller.isItemsContainerElementTableBody();
|
|
18
|
+
|
|
19
|
+
if (isTableBodyItemsContainer && !tbody) {
|
|
20
|
+
console.error('[virtual-scroller] When using `<tbody/>` as a container for list items, `itemsContainerComponent` property must be `"tbody"`');
|
|
21
|
+
}
|
|
22
|
+
}, []);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=useValidateTableBodyItemsContainer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useValidateTableBodyItemsContainer.js","names":["useValidateTableBodyItemsContainer","virtualScroller","tbody","useEffect","isTableBodyItemsContainer","isItemsContainerElementTableBody","console","error"],"sources":["../../source/react/useValidateTableBodyItemsContainer.js"],"sourcesContent":["import { useEffect } from 'react'\r\n\r\n// A developer might \"forget\" to pass `itemsContainerComponent=\"tbody\"` property\r\n// when using a `<tbody/>` as a container for list items.\r\n// This hook validates that the developer didn't \"forget\" to do that in such case.\r\nexport default function useValidateTableBodyItemsContainer({\r\n\tvirtualScroller,\r\n\ttbody\r\n}) {\r\n\tuseEffect(() => {\r\n\t\tconst isTableBodyItemsContainer = virtualScroller.isItemsContainerElementTableBody()\r\n\t\tif (isTableBodyItemsContainer && !tbody) {\r\n\t\t\tconsole.error('[virtual-scroller] When using `<tbody/>` as a container for list items, `itemsContainerComponent` property must be `\"tbody\"`')\r\n\t\t}\r\n\t}, [])\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;AACA;AACA;AACe,SAASA,kCAAT,OAGZ;EAAA,IAFFC,eAEE,QAFFA,eAEE;EAAA,IADFC,KACE,QADFA,KACE;EACF,IAAAC,gBAAA,EAAU,YAAM;IACf,IAAMC,yBAAyB,GAAGH,eAAe,CAACI,gCAAhB,EAAlC;;IACA,IAAID,yBAAyB,IAAI,CAACF,KAAlC,EAAyC;MACxCI,OAAO,CAACC,KAAR,CAAc,8HAAd;IACA;EACD,CALD,EAKG,EALH;AAMA"}
|