virtual-scroller 1.14.0 → 1.15.1
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 +29 -0
- package/README.md +403 -254
- package/bundle/index-dom-bypass.html +197 -0
- package/bundle/index-dom-grid.html +203 -0
- package/bundle/index-dom-scrollableContainer.html +214 -0
- package/bundle/index-dom-tbody-scrollableContainer.html +81 -0
- package/bundle/index-dom-tbody.html +65 -0
- package/bundle/index-dom.html +114 -84
- package/bundle/index-react-bypass.html +194 -0
- package/bundle/{index-bypass.html → index-react-grid.html} +122 -120
- package/bundle/index-react-hook.html +209 -0
- package/bundle/index-react-scrollableContainer.html +207 -0
- package/bundle/index-react-strictMode.html +193 -0
- package/bundle/index-react-tbody-scrollableContainer.html +94 -0
- package/bundle/index-react-tbody.html +78 -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 +7 -13
- package/commonjs/DOM/VirtualScroller.js.map +1 -1
- package/commonjs/DOM/tbody.js +6 -6
- 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 +75 -64
- package/commonjs/Layout.js.map +1 -1
- package/commonjs/Layout.test.js +8 -4
- package/commonjs/Layout.test.js.map +1 -1
- package/commonjs/VirtualScroller.constructor.js +38 -4
- 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 +23 -14
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +40 -29
- 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.state.js +10 -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 +124 -131
- 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/useCreateVirtualScroller.js +64 -0
- package/commonjs/react/useCreateVirtualScroller.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/useMergeRefs.js +52 -0
- package/commonjs/react/useMergeRefs.js.map +1 -0
- 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/{useVirtualScrollerStartStop.js → useStartStopVirtualScroller.js} +1 -1
- package/commonjs/react/{useVirtualScrollerStartStop.js.map → useStartStopVirtualScroller.js.map} +1 -1
- package/commonjs/react/useState.js +9 -9
- 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 +28 -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 +142 -42
- 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 +6 -5
- package/index.d.ts +19 -8
- package/modules/BeforeResize.js +1 -2
- package/modules/BeforeResize.js.map +1 -1
- package/modules/DOM/VirtualScroller.js +7 -13
- package/modules/DOM/VirtualScroller.js.map +1 -1
- package/modules/DOM/tbody.js +4 -4
- 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 +74 -64
- package/modules/Layout.js.map +1 -1
- package/modules/Layout.test.js +8 -4
- package/modules/Layout.test.js.map +1 -1
- package/modules/VirtualScroller.constructor.js +37 -4
- 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 +23 -14
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +40 -29
- 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.state.js +10 -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 +122 -124
- 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/useCreateVirtualScroller.js +53 -0
- package/modules/react/useCreateVirtualScroller.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/useMergeRefs.js +44 -0
- package/modules/react/useMergeRefs.js.map +1 -0
- 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/{useVirtualScrollerStartStop.js → useStartStopVirtualScroller.js} +1 -1
- package/modules/react/{useVirtualScrollerStartStop.js.map → useStartStopVirtualScroller.js.map} +1 -1
- package/modules/react/useState.js +9 -9
- 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 +27 -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 +136 -42
- 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 +4 -1
- package/react/as.d.ts +42 -0
- package/react/index.cjs +2 -1
- package/react/index.d.ts +248 -63
- package/react/index.js +1 -0
- package/rollup.config.mjs +15 -1
- package/source/BeforeResize.js +1 -2
- package/source/DOM/VirtualScroller.js +7 -13
- package/source/DOM/tbody.js +5 -5
- package/source/ItemHeights.js +11 -12
- package/source/Layout.defaults.js +8 -0
- package/source/Layout.js +66 -53
- package/source/Layout.test.js +7 -2
- package/source/VirtualScroller.constructor.js +27 -4
- package/source/VirtualScroller.items.js +47 -2
- package/source/VirtualScroller.js +23 -14
- package/source/VirtualScroller.layout.js +41 -28
- package/source/VirtualScroller.onContainerResize.js +1 -2
- package/source/VirtualScroller.state.js +10 -11
- package/source/VirtualScroller.verticalSpacing.js +32 -6
- package/source/react/VirtualScroller.js +135 -133
- package/source/react/useClassName.js +3 -3
- package/source/react/useCreateVirtualScroller.js +65 -0
- package/source/react/useInstanceMethods.js +12 -4
- package/source/react/useItemKeys.js +22 -4
- package/source/react/useMergeRefs.js +45 -0
- package/source/react/useOnItemHeightDidChange.js +29 -10
- package/source/react/useSetItemState.js +32 -10
- package/source/react/useState.js +6 -6
- package/source/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +1 -1
- package/source/react/useStyle.js +18 -2
- package/source/react/useValidateTableBodyItemsContainer.js +16 -0
- package/source/react/useVirtualScroller.js +155 -47
- package/source/test/ItemsContainer.js +10 -10
- package/source/test/VirtualScroller.js +16 -10
- package/website/index-dom-bypass.html +197 -0
- package/website/index-dom-grid.html +203 -0
- package/website/index-dom-scrollableContainer.html +214 -0
- package/website/index-dom-tbody-scrollableContainer.html +81 -0
- package/website/index-dom-tbody.html +65 -0
- package/website/index-dom.html +116 -84
- package/website/index-react-bypass.html +194 -0
- package/website/index-react-grid.html +197 -0
- package/website/index-react-hook.html +209 -0
- package/website/index-react-scrollableContainer.html +207 -0
- package/website/index-react-strictMode.html +193 -0
- package/website/index-react-tbody-scrollableContainer.html +94 -0
- package/website/index-react-tbody.html +78 -0
- package/website/index-react.html +193 -0
- package/website/index.html +120 -111
- 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-grid.html +0 -216
- package/bundle/index-scrollableContainer.html +0 -208
- 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-bypass.html +0 -185
- package/website/index-grid.html +0 -216
- 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
- /package/source/react/{useVirtualScrollerStartStop.js → useStartStopVirtualScroller.js} +0 -0
|
@@ -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
|
|
|
@@ -47,10 +47,10 @@ function _useState(_ref) {
|
|
|
47
47
|
// `VirtualScroller` state gets updated from this variable.
|
|
48
48
|
// The reason for that is that `VirtualScroller` state must always
|
|
49
49
|
// correspond exactly to what's currently rendered on the screen.
|
|
50
|
-
var
|
|
51
|
-
|
|
52
|
-
_newState =
|
|
53
|
-
_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.
|
|
54
54
|
// It's the "source of truth" on the actual `VirtualScroller` state.
|
|
55
55
|
|
|
56
56
|
|
|
@@ -68,11 +68,11 @@ function _useState(_ref) {
|
|
|
68
68
|
// called `onHeightDidChange()` from its own `useLayoutEffect()`.
|
|
69
69
|
// In those cases, the `itemCompoent`'s effect would run before
|
|
70
70
|
// the `<VirtualScroller/>`'s effect, resulting in
|
|
71
|
-
// `VirtualScroller.onItemHeightDidChange(
|
|
71
|
+
// `VirtualScroller.onItemHeightDidChange(item)` being run at a moment in time
|
|
72
72
|
// when the DOM has already been updated for the next `VirtualScroller` state
|
|
73
73
|
// but the actual `VirtualScroller` state is still a previous ("stale") one
|
|
74
74
|
// containing "stale" first/last shown item indexes, which would result in an
|
|
75
|
-
// "index out of bounds" error when `onItemHeightDidChange(
|
|
75
|
+
// "index out of bounds" error when `onItemHeightDidChange(item)` tries to access
|
|
76
76
|
// and measure the DOM element from item index `i` which doesn't already/yet exist.
|
|
77
77
|
//
|
|
78
78
|
// An example of such situation could be seen from a `VirtualScroller` debug log
|
|
@@ -126,11 +126,11 @@ function _useState(_ref) {
|
|
|
126
126
|
//
|
|
127
127
|
// ~ Rendered ~
|
|
128
128
|
// "~ Rendered ~" is what gets output when `onRender()` function gets called.
|
|
129
|
-
// It means that `useLayoutEffect()` was triggered after `onItemHeightDidChange(
|
|
129
|
+
// It means that `useLayoutEffect()` was triggered after `onItemHeightDidChange(item)`
|
|
130
130
|
// was called and after the "ERROR" happened.
|
|
131
131
|
//
|
|
132
132
|
// The "ERROR" happened because new item indexes 4…5 were actually rendered instead of
|
|
133
|
-
// 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
|
|
134
134
|
// inside `itemComponent`'s `useLayoutEffect()`.
|
|
135
135
|
// Item indexes 4…5 is what was requested in a `setState()` call, which called `_setNewState()`.
|
|
136
136
|
// This means that `_newState` changes have been applied to the DOM
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useState.js","names":["_useState","initialState","onRender","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}) {\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,OAGZ;EAAA,IAFFC,YAEE,QAFFA,YAEE;EAAA,IADFC,QACE,QADFA,QACE;;EACF;EACA;EACA;EACA;EACA;EACA,0BAAkC,IAAAC,+BAAA,EAAmBF,YAAnB,CAAlC;EAAA;EAAA,IAAOG,SAAP;EAAA,IAAkBC,YAAlB,2BANE,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"}
|
|
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"}
|
|
@@ -7,21 +7,45 @@ exports["default"] = useStyle;
|
|
|
7
7
|
|
|
8
8
|
var _px = _interopRequireDefault(require("../utility/px.js"));
|
|
9
9
|
|
|
10
|
+
var _debug = require("../utility/debug.js");
|
|
11
|
+
|
|
10
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
11
13
|
|
|
12
|
-
function
|
|
14
|
+
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; }
|
|
15
|
+
|
|
16
|
+
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; }
|
|
17
|
+
|
|
18
|
+
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; }
|
|
19
|
+
|
|
20
|
+
function useStyle(style, _ref) {
|
|
13
21
|
var tbody = _ref.tbody,
|
|
14
22
|
state = _ref.state;
|
|
15
23
|
|
|
16
24
|
if (tbody) {
|
|
17
|
-
return;
|
|
25
|
+
return style;
|
|
26
|
+
} // Validate that the passed `style` property doesn't include
|
|
27
|
+
// `padding-top` or `padding-bottom` or `padding`.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if (style) {
|
|
31
|
+
if (typeof style.padding === 'number') {
|
|
32
|
+
(0, _debug.reportError)('`style` property can\'t include any `padding`');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (typeof style.paddingTop === 'number') {
|
|
36
|
+
(0, _debug.reportError)('`style` property can\'t include any `paddingTop`');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (typeof style.paddingBottom === 'number') {
|
|
40
|
+
(0, _debug.reportError)('`style` property can\'t include any `paddingBottom`');
|
|
41
|
+
}
|
|
18
42
|
}
|
|
19
43
|
|
|
20
44
|
var beforeItemsHeight = state.beforeItemsHeight,
|
|
21
45
|
afterItemsHeight = state.afterItemsHeight;
|
|
22
|
-
return {
|
|
46
|
+
return _objectSpread(_objectSpread({}, style), {}, {
|
|
23
47
|
paddingTop: (0, _px["default"])(beforeItemsHeight),
|
|
24
48
|
paddingBottom: (0, _px["default"])(afterItemsHeight)
|
|
25
|
-
};
|
|
49
|
+
});
|
|
26
50
|
}
|
|
27
51
|
//# sourceMappingURL=useStyle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStyle.js","names":["useStyle","tbody","state","
|
|
1
|
+
{"version":3,"file":"useStyle.js","names":["useStyle","style","tbody","state","padding","reportError","paddingTop","paddingBottom","beforeItemsHeight","afterItemsHeight","px"],"sources":["../../source/react/useStyle.js"],"sourcesContent":["import px from '../utility/px.js'\r\nimport { reportError } from '../utility/debug.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\t// Validate that the passed `style` property doesn't include\r\n\t// `padding-top` or `padding-bottom` or `padding`.\r\n\tif (style) {\r\n\t\tif (typeof style.padding === 'number') {\r\n\t\t\treportError('`style` property can\\'t include any `padding`')\r\n\t\t}\r\n\t\tif (typeof style.paddingTop === 'number') {\r\n\t\t\treportError('`style` property can\\'t include any `paddingTop`')\r\n\t\t}\r\n\t\tif (typeof style.paddingBottom === 'number') {\r\n\t\t\treportError('`style` property can\\'t include any `paddingBottom`')\r\n\t\t}\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;;AACA;;;;;;;;;;AAEe,SAASA,QAAT,CAAkBC,KAAlB,QAGZ;EAAA,IAFFC,KAEE,QAFFA,KAEE;EAAA,IADFC,KACE,QADFA,KACE;;EACF,IAAID,KAAJ,EAAW;IACV,OAAOD,KAAP;EACA,CAHC,CAKF;EACA;;;EACA,IAAIA,KAAJ,EAAW;IACV,IAAI,OAAOA,KAAK,CAACG,OAAb,KAAyB,QAA7B,EAAuC;MACtC,IAAAC,kBAAA,EAAY,+CAAZ;IACA;;IACD,IAAI,OAAOJ,KAAK,CAACK,UAAb,KAA4B,QAAhC,EAA0C;MACzC,IAAAD,kBAAA,EAAY,kDAAZ;IACA;;IACD,IAAI,OAAOJ,KAAK,CAACM,aAAb,KAA+B,QAAnC,EAA6C;MAC5C,IAAAF,kBAAA,EAAY,qDAAZ;IACA;EACD;;EAED,IACCG,iBADD,GAGIL,KAHJ,CACCK,iBADD;EAAA,IAECC,gBAFD,GAGIN,KAHJ,CAECM,gBAFD;EAKA,uCACIR,KADJ;IAECK,UAAU,EAAE,IAAAI,cAAA,EAAGF,iBAAH,CAFb;IAGCD,aAAa,EAAE,IAAAG,cAAA,EAAGD,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"}
|
|
@@ -7,59 +7,159 @@ exports["default"] = useVirtualScroller;
|
|
|
7
7
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _useState2 = _interopRequireDefault(require("./useState.js"));
|
|
11
|
+
|
|
12
|
+
var _useCreateVirtualScroller = _interopRequireDefault(require("./useCreateVirtualScroller.js"));
|
|
13
|
+
|
|
14
|
+
var _useStartStopVirtualScroller = _interopRequireDefault(require("./useStartStopVirtualScroller.js"));
|
|
15
|
+
|
|
16
|
+
var _useSetNewItemsOnItemsPropertyChange = _interopRequireDefault(require("./useSetNewItemsOnItemsPropertyChange.js"));
|
|
17
|
+
|
|
18
|
+
var _useValidateTableBodyItemsContainer = _interopRequireDefault(require("./useValidateTableBodyItemsContainer.js"));
|
|
19
|
+
|
|
20
|
+
var _useClassName = _interopRequireDefault(require("./useClassName.js"));
|
|
21
|
+
|
|
22
|
+
var _useStyle = _interopRequireDefault(require("./useStyle.js"));
|
|
11
23
|
|
|
12
24
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
25
|
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
// When `items` property changes:
|
|
27
|
+
// * A new `items` property is supplied to the React component.
|
|
28
|
+
// * The React component re-renders itself.
|
|
29
|
+
// * `useSetNewItemsOnItemsPropertyChange()` hook is run.
|
|
30
|
+
// * `useSetNewItemsOnItemsPropertyChange()` hook detects that the `items` property
|
|
31
|
+
// has changed and calls `VirtualScroller.setItems(items)`.
|
|
32
|
+
// * `VirtualScroller.setItems(items)` calls `VirtualScroller.setState()`.
|
|
33
|
+
// * `VirtualScroller.setState()` calls the `setState()` function.
|
|
34
|
+
// * The `setState()` function calls a setter from a `useState()` hook.
|
|
35
|
+
// * The React component re-renders itself the second time.
|
|
36
|
+
function useVirtualScroller(_ref) {
|
|
37
|
+
var itemsProperty = _ref.items,
|
|
38
|
+
tbody = _ref.tbody,
|
|
39
|
+
readyToStart = _ref.readyToStart,
|
|
40
|
+
styleProperty = _ref.style,
|
|
41
|
+
classNameProperty = _ref.className,
|
|
20
42
|
bypass = _ref.bypass,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
initialScrollPosition = _ref.initialScrollPosition,
|
|
24
|
-
onScrollPositionChange = _ref.onScrollPositionChange,
|
|
43
|
+
preserveScrollPosition = _ref.preserveScrollPosition,
|
|
44
|
+
preserveScrollPositionOnPrependItems = _ref.preserveScrollPositionOnPrependItems,
|
|
25
45
|
measureItemsBatchSize = _ref.measureItemsBatchSize,
|
|
26
46
|
scrollableContainer = _ref.scrollableContainer,
|
|
27
47
|
getScrollableContainer = _ref.getScrollableContainer,
|
|
28
48
|
getColumnsCount = _ref.getColumnsCount,
|
|
29
49
|
getItemId = _ref.getItemId,
|
|
30
|
-
|
|
50
|
+
onItemFirstRender = _ref.onItemFirstRender,
|
|
51
|
+
onItemInitialRender = _ref.onItemInitialRender,
|
|
52
|
+
initialScrollPosition = _ref.initialScrollPosition,
|
|
53
|
+
onScrollPositionChange = _ref.onScrollPositionChange,
|
|
31
54
|
initialState = _ref.initialState,
|
|
32
55
|
getInitialItemState = _ref.getInitialItemState,
|
|
33
|
-
onStateChange = _ref.onStateChange
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
onStateChange = _ref.onStateChange,
|
|
57
|
+
getEstimatedItemHeight = _ref.getEstimatedItemHeight,
|
|
58
|
+
getEstimatedVisibleItemRowsCount = _ref.getEstimatedVisibleItemRowsCount,
|
|
59
|
+
getEstimatedInterItemVerticalSpacing = _ref.getEstimatedInterItemVerticalSpacing;
|
|
60
|
+
// A `ref` to the items container element.
|
|
61
|
+
var itemsContainerRef = (0, _react.useRef)(); // Use `hasMounted` flag to decide if `itemsContainerRef` value should be validated.
|
|
62
|
+
|
|
63
|
+
var hasMounted = (0, _react.useRef)(false);
|
|
64
|
+
(0, _react.useLayoutEffect)(function () {
|
|
65
|
+
hasMounted.current = true;
|
|
66
|
+
}, []); // Create a `VirtualScroller` instance.
|
|
67
|
+
|
|
68
|
+
var virtualScroller = (0, _useCreateVirtualScroller["default"])({
|
|
69
|
+
items: itemsProperty,
|
|
70
|
+
getEstimatedItemHeight: getEstimatedItemHeight,
|
|
71
|
+
getEstimatedVisibleItemRowsCount: getEstimatedVisibleItemRowsCount,
|
|
72
|
+
getEstimatedInterItemVerticalSpacing: getEstimatedInterItemVerticalSpacing,
|
|
73
|
+
bypass: bypass,
|
|
74
|
+
// bypassBatchSize,
|
|
75
|
+
onItemInitialRender: onItemInitialRender,
|
|
76
|
+
// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.
|
|
77
|
+
onItemFirstRender: onItemFirstRender,
|
|
78
|
+
initialScrollPosition: initialScrollPosition,
|
|
79
|
+
onScrollPositionChange: onScrollPositionChange,
|
|
80
|
+
measureItemsBatchSize: measureItemsBatchSize,
|
|
81
|
+
// `scrollableContainer` property is deprecated.
|
|
82
|
+
// Use `getScrollableContainer()` property instead.
|
|
83
|
+
scrollableContainer: scrollableContainer,
|
|
84
|
+
getScrollableContainer: getScrollableContainer,
|
|
85
|
+
getColumnsCount: getColumnsCount,
|
|
86
|
+
getItemId: getItemId,
|
|
87
|
+
initialState: initialState,
|
|
88
|
+
getInitialItemState: getInitialItemState,
|
|
89
|
+
onStateChange: onStateChange
|
|
90
|
+
}, {
|
|
91
|
+
getItemsContainerElement: function getItemsContainerElement() {
|
|
92
|
+
// Validate that the developer has correctly passed the returned `itemsContainerRef` property
|
|
93
|
+
// as the items container component's `ref`.
|
|
94
|
+
//
|
|
95
|
+
// `getItemsContainerElement()` function is called both before it has mounted
|
|
96
|
+
// and after it has mounted. Only validate the ref's value after it has mounted.
|
|
97
|
+
//
|
|
98
|
+
if (hasMounted.current) {
|
|
99
|
+
if (!itemsContainerRef.current) {
|
|
100
|
+
throw new Error('[virtual-scroller] Did you forget to pass the returned `itemsContainerRef` property as the items container component\'s `ref`?');
|
|
101
|
+
}
|
|
102
|
+
} // Return the items container element.
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
return itemsContainerRef.current;
|
|
106
|
+
}
|
|
107
|
+
}); // Only compute the initial state once.
|
|
108
|
+
|
|
109
|
+
var _initialState = (0, _react.useMemo)(function () {
|
|
110
|
+
return virtualScroller.getInitialState();
|
|
111
|
+
}, []); // Use React's `useState()` hook for managing `VirtualScroller`'s state lifecycle.
|
|
112
|
+
// This way, React will re-render the component on every state update.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
var _useState = (0, _useState2["default"])({
|
|
116
|
+
initialState: _initialState,
|
|
117
|
+
onRender: virtualScroller.onRender
|
|
118
|
+
}),
|
|
119
|
+
getState = _useState.getState,
|
|
120
|
+
setState = _useState.setState,
|
|
121
|
+
stateToRender = _useState.stateToRender; // Use custom (external) state storage in the `VirtualScroller`.
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
(0, _react.useMemo)(function () {
|
|
125
|
+
virtualScroller.useState({
|
|
126
|
+
getState: getState,
|
|
127
|
+
setState: setState
|
|
62
128
|
});
|
|
63
|
-
}, []);
|
|
129
|
+
}, []); // Start `VirtualScroller` on mount.
|
|
130
|
+
// Stop `VirtualScroller` on unmount.
|
|
131
|
+
|
|
132
|
+
(0, _useStartStopVirtualScroller["default"])(virtualScroller, {
|
|
133
|
+
readyToStart: readyToStart
|
|
134
|
+
}); // Calls `.setItems()` if `items` property has changed.
|
|
135
|
+
|
|
136
|
+
(0, _useSetNewItemsOnItemsPropertyChange["default"])(itemsProperty, {
|
|
137
|
+
virtualScroller: virtualScroller,
|
|
138
|
+
// `preserveScrollPosition` property name is deprecated,
|
|
139
|
+
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
140
|
+
preserveScrollPosition: preserveScrollPosition,
|
|
141
|
+
preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems
|
|
142
|
+
}); // A developer might "forget" to pass `itemsContainerComponent="tbody"` property
|
|
143
|
+
// when using a `<tbody/>` as a container for list items.
|
|
144
|
+
// This hook validates that the developer didn't "forget" to do that in such case.
|
|
145
|
+
|
|
146
|
+
(0, _useValidateTableBodyItemsContainer["default"])({
|
|
147
|
+
virtualScroller: virtualScroller,
|
|
148
|
+
tbody: tbody
|
|
149
|
+
});
|
|
150
|
+
var className = (0, _useClassName["default"])(classNameProperty, {
|
|
151
|
+
tbody: tbody
|
|
152
|
+
});
|
|
153
|
+
var style = (0, _useStyle["default"])(styleProperty, {
|
|
154
|
+
tbody: tbody,
|
|
155
|
+
state: stateToRender
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
state: stateToRender,
|
|
159
|
+
style: style,
|
|
160
|
+
className: className,
|
|
161
|
+
itemsContainerRef: itemsContainerRef,
|
|
162
|
+
virtualScroller: virtualScroller
|
|
163
|
+
};
|
|
64
164
|
}
|
|
65
165
|
//# sourceMappingURL=useVirtualScroller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVirtualScroller.js","names":["useVirtualScroller","items","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","bypass","onItemInitialRender","onItemFirstRender","initialScrollPosition","onScrollPositionChange","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","AsComponent","initialState","getInitialItemState","onStateChange","container","useMemo","VirtualScroller","current","_useTimeoutInRenderLoop","state"],"sources":["../../source/react/useVirtualScroller.js"],"sourcesContent":["import { useMemo } from 'react'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\n\r\n// Creates a `VirtualScroller` instance.\r\nexport default function useVirtualScroller({\r\n\titems,\r\n\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tbypass,\r\n\t// bypassBatchSize,\r\n\tonItemInitialRender,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tmeasureItemsBatchSize,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer,\r\n\tgetScrollableContainer,\r\n\tgetColumnsCount,\r\n\tgetItemId,\r\n\tAsComponent,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\tonStateChange\r\n}, {\r\n\tcontainer\r\n}) {\r\n\treturn useMemo(() => {\r\n\t\t// Create `virtual-scroller` instance.\r\n\t\treturn new VirtualScroller(\r\n\t\t\t() => container.current,\r\n\t\t\titems,\r\n\t\t\t{\r\n\t\t\t\t_useTimeoutInRenderLoop: true,\r\n\t\t\t\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\t\t\t\testimatedItemHeight,\r\n\t\t\t\tgetEstimatedItemHeight,\r\n\t\t\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\t\t\tbypass,\r\n\t\t\t\t// bypassBatchSize,\r\n\t\t\t\tonItemInitialRender,\r\n\t\t\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\t\t\tonItemFirstRender,\r\n\t\t\t\tinitialScrollPosition,\r\n\t\t\t\tonScrollPositionChange,\r\n\t\t\t\tmeasureItemsBatchSize,\r\n\t\t\t\t// `scrollableContainer` property is deprecated.\r\n\t\t\t\t// Use `getScrollableContainer()` property instead.\r\n\t\t\t\tscrollableContainer,\r\n\t\t\t\tgetScrollableContainer,\r\n\t\t\t\tgetColumnsCount,\r\n\t\t\t\tgetItemId,\r\n\t\t\t\tstate: initialState,\r\n\t\t\t\tgetInitialItemState,\r\n\t\t\t\tonStateChange\r\n\t\t\t}\r\n\t\t)\r\n\t}, [])\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;;;;AAEA;AACe,SAASA,kBAAT,cA0BZ;EAAA,IAzBFC,KAyBE,QAzBFA,KAyBE;EAAA,IAvBFC,mBAuBE,QAvBFA,mBAuBE;EAAA,IAtBFC,sBAsBE,QAtBFA,sBAsBE;EAAA,IArBFC,gCAqBE,QArBFA,gCAqBE;EAAA,IApBFC,MAoBE,QApBFA,MAoBE;EAAA,IAlBFC,mBAkBE,QAlBFA,mBAkBE;EAAA,IAhBFC,iBAgBE,QAhBFA,iBAgBE;EAAA,IAfFC,qBAeE,QAfFA,qBAeE;EAAA,IAdFC,sBAcE,QAdFA,sBAcE;EAAA,IAbFC,qBAaE,QAbFA,qBAaE;EAAA,IAVFC,mBAUE,QAVFA,mBAUE;EAAA,IATFC,sBASE,QATFA,sBASE;EAAA,IARFC,eAQE,QARFA,eAQE;EAAA,IAPFC,SAOE,QAPFA,SAOE;EAAA,IANFC,WAME,QANFA,WAME;EAAA,IALFC,YAKE,QALFA,YAKE;EAAA,IAJFC,mBAIE,QAJFA,mBAIE;EAAA,IAHFC,aAGE,QAHFA,aAGE;EAAA,IADFC,SACE,SADFA,SACE;EACF,OAAO,IAAAC,cAAA,EAAQ,YAAM;IACpB;IACA,OAAO,IAAIC,2BAAJ,CACN;MAAA,OAAMF,SAAS,CAACG,OAAhB;IAAA,CADM,EAENrB,KAFM,EAGN;MACCsB,uBAAuB,EAAE,IAD1B;MAEC;MACArB,mBAAmB,EAAnBA,mBAHD;MAICC,sBAAsB,EAAtBA,sBAJD;MAKCC,gCAAgC,EAAhCA,gCALD;MAMCC,MAAM,EAANA,MAND;MAOC;MACAC,mBAAmB,EAAnBA,mBARD;MASC;MACAC,iBAAiB,EAAjBA,iBAVD;MAWCC,qBAAqB,EAArBA,qBAXD;MAYCC,sBAAsB,EAAtBA,sBAZD;MAaCC,qBAAqB,EAArBA,qBAbD;MAcC;MACA;MACAC,mBAAmB,EAAnBA,mBAhBD;MAiBCC,sBAAsB,EAAtBA,sBAjBD;MAkBCC,eAAe,EAAfA,eAlBD;MAmBCC,SAAS,EAATA,SAnBD;MAoBCU,KAAK,EAAER,YApBR;MAqBCC,mBAAmB,EAAnBA,mBArBD;MAsBCC,aAAa,EAAbA;IAtBD,CAHM,CAAP;EA4BA,CA9BM,EA8BJ,EA9BI,CAAP;AA+BA"}
|
|
1
|
+
{"version":3,"file":"useVirtualScroller.js","names":["useVirtualScroller","itemsProperty","items","tbody","readyToStart","styleProperty","style","classNameProperty","className","bypass","preserveScrollPosition","preserveScrollPositionOnPrependItems","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","onItemFirstRender","onItemInitialRender","initialScrollPosition","onScrollPositionChange","initialState","getInitialItemState","onStateChange","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","getEstimatedInterItemVerticalSpacing","itemsContainerRef","useRef","hasMounted","useLayoutEffect","current","virtualScroller","useCreateVirtualScroller","getItemsContainerElement","Error","_initialState","useMemo","getInitialState","useState","onRender","getState","setState","stateToRender","useStartStopVirtualScroller","useSetNewItemsOnItemsPropertyChange","useValidateTableBodyItemsContainer","useClassName","useStyle","state"],"sources":["../../source/react/useVirtualScroller.js"],"sourcesContent":["import { useLayoutEffect, useMemo, useRef } from 'react'\r\n\r\nimport useState from './useState.js'\r\nimport useCreateVirtualScroller from './useCreateVirtualScroller.js'\r\nimport useStartStopVirtualScroller from './useStartStopVirtualScroller.js'\r\nimport useSetNewItemsOnItemsPropertyChange from './useSetNewItemsOnItemsPropertyChange.js'\r\nimport useValidateTableBodyItemsContainer from './useValidateTableBodyItemsContainer.js'\r\nimport useClassName from './useClassName.js'\r\nimport useStyle from './useStyle.js'\r\n\r\n// When `items` property changes:\r\n// * A new `items` property is supplied to the React component.\r\n// * The React component re-renders itself.\r\n// * `useSetNewItemsOnItemsPropertyChange()` hook is run.\r\n// * `useSetNewItemsOnItemsPropertyChange()` hook detects that the `items` property\r\n// has changed and calls `VirtualScroller.setItems(items)`.\r\n// * `VirtualScroller.setItems(items)` calls `VirtualScroller.setState()`.\r\n// * `VirtualScroller.setState()` calls the `setState()` function.\r\n// * The `setState()` function calls a setter from a `useState()` hook.\r\n// * The React component re-renders itself the second time.\r\n\r\nexport default function useVirtualScroller({\r\n\t// The following are `<VirtualScroller/>` properties.\r\n\t//\r\n\titems: itemsProperty,\r\n\t// Because the use of a `<tbody/>` tag as an items container component can't always be auto-detected,\r\n\t// a developer could manually pass a `tbody: boolean` property.\r\n\t// Futhermore, when using `useVirtualScroller()` hook instead of `<VirtualScroller/>` component,\r\n\t// `itemsContainerComponent` property is not accessible for tag name detection.\r\n\ttbody,\r\n\treadyToStart,\r\n\tstyle: styleProperty,\r\n\tclassName: classNameProperty,\r\n\r\n\t// The following are the \"core\" component options.\r\n\t//\r\n\tbypass,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\tpreserveScrollPosition,\r\n\tpreserveScrollPositionOnPrependItems,\r\n\tmeasureItemsBatchSize,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer,\r\n\tgetScrollableContainer,\r\n\tgetColumnsCount,\r\n\tgetItemId,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tonItemInitialRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\tonStateChange,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tgetEstimatedInterItemVerticalSpacing\r\n}) {\r\n\t// A `ref` to the items container element.\r\n\tconst itemsContainerRef = useRef()\r\n\r\n\t// Use `hasMounted` flag to decide if `itemsContainerRef` value should be validated.\r\n\tconst hasMounted = useRef(false)\r\n\tuseLayoutEffect(() => {\r\n\t\thasMounted.current = true\r\n\t}, [])\r\n\r\n\t// Create a `VirtualScroller` instance.\r\n\tconst virtualScroller = useCreateVirtualScroller({\r\n\t\titems: itemsProperty,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tgetEstimatedInterItemVerticalSpacing,\r\n\t\tbypass,\r\n\t\t// bypassBatchSize,\r\n\t\tonItemInitialRender,\r\n\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\tonItemFirstRender,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tmeasureItemsBatchSize,\r\n\t\t// `scrollableContainer` property is deprecated.\r\n\t\t// Use `getScrollableContainer()` property instead.\r\n\t\tscrollableContainer,\r\n\t\tgetScrollableContainer,\r\n\t\tgetColumnsCount,\r\n\t\tgetItemId,\r\n\t\tinitialState,\r\n\t\tgetInitialItemState,\r\n\t\tonStateChange\r\n\t}, {\r\n\t\tgetItemsContainerElement: () => {\r\n\t\t\t// Validate that the developer has correctly passed the returned `itemsContainerRef` property\r\n\t\t\t// as the items container component's `ref`.\r\n\t\t\t//\r\n\t\t\t// `getItemsContainerElement()` function is called both before it has mounted\r\n\t\t\t// and after it has mounted. Only validate the ref's value after it has mounted.\r\n\t\t\t//\r\n\t\t\tif (hasMounted.current) {\r\n\t\t\t\tif (!itemsContainerRef.current) {\r\n\t\t\t\t\tthrow new Error('[virtual-scroller] Did you forget to pass the returned `itemsContainerRef` property as the items container component\\'s `ref`?')\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Return the items container element.\r\n\t\t\treturn itemsContainerRef.current\r\n\t\t}\r\n\t})\r\n\r\n\t// Only compute the initial state once.\r\n\tconst _initialState = useMemo(() => {\r\n\t\treturn virtualScroller.getInitialState()\r\n\t}, [])\r\n\r\n\t// Use React's `useState()` hook for managing `VirtualScroller`'s state lifecycle.\r\n\t// This way, React will re-render the component on every state update.\r\n\tconst {\r\n\t\tgetState,\r\n\t\tsetState,\r\n\t\tstateToRender\r\n\t} = useState({\r\n\t\tinitialState: _initialState,\r\n\t\tonRender: virtualScroller.onRender\r\n\t})\r\n\r\n\t// Use custom (external) state storage in the `VirtualScroller`.\r\n\tuseMemo(() => {\r\n\t\tvirtualScroller.useState({\r\n\t\t\tgetState,\r\n\t\t\tsetState\r\n\t\t})\r\n\t}, [])\r\n\r\n\t// Start `VirtualScroller` on mount.\r\n\t// Stop `VirtualScroller` on unmount.\r\n\tuseStartStopVirtualScroller(virtualScroller, { readyToStart })\r\n\r\n\t// Calls `.setItems()` if `items` property has changed.\r\n\tuseSetNewItemsOnItemsPropertyChange(itemsProperty, {\r\n\t\tvirtualScroller,\r\n\t\t// `preserveScrollPosition` property name is deprecated,\r\n\t\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\t\tpreserveScrollPosition,\r\n\t\tpreserveScrollPositionOnPrependItems\r\n\t})\r\n\r\n\t// A developer might \"forget\" to pass `itemsContainerComponent=\"tbody\"` property\r\n\t// when using a `<tbody/>` as a container for list items.\r\n\t// This hook validates that the developer didn't \"forget\" to do that in such case.\r\n\tuseValidateTableBodyItemsContainer({\r\n\t\tvirtualScroller,\r\n\t\ttbody\r\n\t})\r\n\r\n\tconst className = useClassName(classNameProperty, {\r\n\t\ttbody\r\n\t})\r\n\r\n\tconst style = useStyle(styleProperty, {\r\n\t\ttbody,\r\n\t\tstate: stateToRender\r\n\t})\r\n\r\n\treturn {\r\n\t\tstate: stateToRender,\r\n\t\tstyle,\r\n\t\tclassName,\r\n\t\titemsContainerRef,\r\n\t\tvirtualScroller\r\n\t}\r\n}"],"mappings":"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"}
|
|
@@ -52,14 +52,14 @@ var ItemsContainer = /*#__PURE__*/function () {
|
|
|
52
52
|
var i = 0;
|
|
53
53
|
|
|
54
54
|
while (i <= renderedElementIndex) {
|
|
55
|
-
if (startNewRow || rowWidth + children[i].
|
|
55
|
+
if (startNewRow || rowWidth + children[i].getWidth() > maxWidth) {
|
|
56
56
|
if (i > 0) {
|
|
57
57
|
topOffset += rowHeight;
|
|
58
|
-
topOffset += children[i].
|
|
58
|
+
topOffset += children[i].getMarginTop();
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
rowWidth = children[i].
|
|
62
|
-
rowHeight = children[i].
|
|
61
|
+
rowWidth = children[i].getWidth();
|
|
62
|
+
rowHeight = children[i].getHeight();
|
|
63
63
|
|
|
64
64
|
if (rowWidth > maxWidth) {
|
|
65
65
|
startNewRow = true;
|
|
@@ -67,8 +67,8 @@ var ItemsContainer = /*#__PURE__*/function () {
|
|
|
67
67
|
startNewRow = false;
|
|
68
68
|
}
|
|
69
69
|
} else {
|
|
70
|
-
rowWidth += children[i].
|
|
71
|
-
rowHeight = Math.max(rowHeight, children[i].
|
|
70
|
+
rowWidth += children[i].getWidth();
|
|
71
|
+
rowHeight = Math.max(rowHeight, children[i].getHeight());
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
i++;
|
|
@@ -94,7 +94,7 @@ var ItemsContainer = /*#__PURE__*/function () {
|
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
return children[renderedElementIndex].
|
|
97
|
+
return children[renderedElementIndex].getHeight();
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Returns items container height.
|
|
@@ -115,12 +115,12 @@ var ItemsContainer = /*#__PURE__*/function () {
|
|
|
115
115
|
|
|
116
116
|
while (rowWidth <= maxWidth && i < children.length) {
|
|
117
117
|
if (rowWidth === 0 && i > 0) {
|
|
118
|
-
var verticalSpacing = children[i].
|
|
118
|
+
var verticalSpacing = children[i].getMarginTop();
|
|
119
119
|
contentHeight += verticalSpacing;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
rowWidth += children[i].
|
|
123
|
-
rowHeight = Math.max(rowHeight, children[i].
|
|
122
|
+
rowWidth += children[i].getWidth();
|
|
123
|
+
rowHeight = Math.max(rowHeight, children[i].getHeight());
|
|
124
124
|
i++;
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemsContainer.js","names":["ItemsContainer","getElement","renderedElementIndex","children","maxWidth","width","topOffset","paddingTop","rowWidth","rowHeight","startNewRow","length","ItemNotRenderedError","renderedElementsCount","i","
|
|
1
|
+
{"version":3,"file":"ItemsContainer.js","names":["ItemsContainer","getElement","renderedElementIndex","children","maxWidth","width","topOffset","paddingTop","rowWidth","rowHeight","startNewRow","length","ItemNotRenderedError","renderedElementsCount","i","getWidth","getMarginTop","getHeight","Math","max","contentHeight","verticalSpacing","paddingBottom"],"sources":["../../source/test/ItemsContainer.js"],"sourcesContent":["import ItemNotRenderedError from '../ItemNotRenderedError.js'\r\n\r\nexport default class ItemsContainer {\r\n\t/**\r\n\t * Constructs a new \"container\" from an element.\r\n\t * @param {function} getElement\r\n\t */\r\n\tconstructor(getElement) {\r\n\t\tthis.getElement = getElement\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an item element's \"top offset\", relative to the items `container`'s top edge.\r\n\t * @param {number} renderedElementIndex — An index of an item relative to the \"first shown item index\". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.\r\n\t * @return {number}\r\n\t */\r\n\tgetNthRenderedItemTopOffset(renderedElementIndex) {\r\n\t\tconst children = this.getElement().children\r\n\t\tconst maxWidth = this.getElement().width\r\n\t\tlet topOffset = this.getElement().paddingTop\r\n\r\n\t\tlet rowWidth\r\n\t\tlet rowHeight\r\n\t\tlet startNewRow = true\r\n\r\n\t\tif (renderedElementIndex > children.length - 1) {\r\n\t\t\tthrow new ItemNotRenderedError({\r\n\t\t\t\trenderedElementIndex,\r\n\t\t\t\trenderedElementsCount: children.length\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tlet i = 0\r\n\t\twhile (i <= renderedElementIndex) {\r\n\t\t\tif (startNewRow || rowWidth + children[i].getWidth() > maxWidth) {\r\n\t\t\t\tif (i > 0) {\r\n\t\t\t\t\ttopOffset += rowHeight\r\n\t\t\t\t\ttopOffset += children[i].getMarginTop()\r\n\t\t\t\t}\r\n\t\t\t\trowWidth = children[i].getWidth()\r\n\t\t\t\trowHeight = children[i].getHeight()\r\n\t\t\t\tif (rowWidth > maxWidth) {\r\n\t\t\t\t\tstartNewRow = true\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstartNewRow = false\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\trowWidth += children[i].getWidth()\r\n\t\t\t\trowHeight = Math.max(rowHeight, children[i].getHeight())\r\n\t\t\t}\r\n\t\t\ti++\r\n\t\t}\r\n\r\n\t\treturn topOffset\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an item element's height.\r\n\t * @param {number} renderedElementIndex — An index of an item relative to the \"first shown item index\". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.\r\n\t * @return {number}\r\n\t */\r\n\tgetNthRenderedItemHeight(renderedElementIndex) {\r\n\t\tconst children = this.getElement().children\r\n\r\n\t\tif (renderedElementIndex > children.length - 1) {\r\n\t\t\tthrow new ItemNotRenderedError({\r\n\t\t\t\trenderedElementIndex,\r\n\t\t\t\trenderedElementsCount: children.length\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn children[renderedElementIndex].getHeight()\r\n\t}\r\n\r\n\t/**\r\n\t * Returns items container height.\r\n\t * @return {number}\r\n\t */\r\n\tgetHeight() {\r\n\t\tconst children = this.getElement().children\r\n\t\tconst maxWidth = this.getElement().width\r\n\t\tlet contentHeight = this.getElement().paddingTop\r\n\t\tlet i = 0\r\n\t\twhile (i < children.length) {\r\n\t\t\tlet rowWidth = 0\r\n\t\t\tlet rowHeight = 0\r\n\t\t\twhile (rowWidth <= maxWidth && i < children.length) {\r\n\t\t\t\tif (rowWidth === 0 && i > 0) {\r\n\t\t\t\t\tconst verticalSpacing = children[i].getMarginTop()\r\n\t\t\t\t\tcontentHeight += verticalSpacing\r\n\t\t\t\t}\r\n\t\t\t\trowWidth += children[i].getWidth()\r\n\t\t\t\trowHeight = Math.max(rowHeight, children[i].getHeight())\r\n\t\t\t\ti++\r\n\t\t\t}\r\n\t\t\tcontentHeight += rowHeight\r\n\t\t}\r\n\t\tcontentHeight += this.getElement().paddingBottom\r\n\t\treturn contentHeight\r\n\t}\r\n\r\n\t/**\r\n\t * Removes all item elements of an items container.\r\n\t */\r\n\tclear() {\r\n\t\tthis.getElement().children = []\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;;;;;;;;;IAEqBA,c;EACpB;AACD;AACA;AACA;EACC,wBAAYC,UAAZ,EAAwB;IAAA;;IACvB,KAAKA,UAAL,GAAkBA,UAAlB;EACA;EAED;AACD;AACA;AACA;AACA;;;;;WACC,qCAA4BC,oBAA5B,EAAkD;MACjD,IAAMC,QAAQ,GAAG,KAAKF,UAAL,GAAkBE,QAAnC;MACA,IAAMC,QAAQ,GAAG,KAAKH,UAAL,GAAkBI,KAAnC;MACA,IAAIC,SAAS,GAAG,KAAKL,UAAL,GAAkBM,UAAlC;MAEA,IAAIC,QAAJ;MACA,IAAIC,SAAJ;MACA,IAAIC,WAAW,GAAG,IAAlB;;MAEA,IAAIR,oBAAoB,GAAGC,QAAQ,CAACQ,MAAT,GAAkB,CAA7C,EAAgD;QAC/C,MAAM,IAAIC,gCAAJ,CAAyB;UAC9BV,oBAAoB,EAApBA,oBAD8B;UAE9BW,qBAAqB,EAAEV,QAAQ,CAACQ;QAFF,CAAzB,CAAN;MAIA;;MAED,IAAIG,CAAC,GAAG,CAAR;;MACA,OAAOA,CAAC,IAAIZ,oBAAZ,EAAkC;QACjC,IAAIQ,WAAW,IAAIF,QAAQ,GAAGL,QAAQ,CAACW,CAAD,CAAR,CAAYC,QAAZ,EAAX,GAAoCX,QAAvD,EAAiE;UAChE,IAAIU,CAAC,GAAG,CAAR,EAAW;YACVR,SAAS,IAAIG,SAAb;YACAH,SAAS,IAAIH,QAAQ,CAACW,CAAD,CAAR,CAAYE,YAAZ,EAAb;UACA;;UACDR,QAAQ,GAAGL,QAAQ,CAACW,CAAD,CAAR,CAAYC,QAAZ,EAAX;UACAN,SAAS,GAAGN,QAAQ,CAACW,CAAD,CAAR,CAAYG,SAAZ,EAAZ;;UACA,IAAIT,QAAQ,GAAGJ,QAAf,EAAyB;YACxBM,WAAW,GAAG,IAAd;UACA,CAFD,MAEO;YACNA,WAAW,GAAG,KAAd;UACA;QACD,CAZD,MAYO;UACNF,QAAQ,IAAIL,QAAQ,CAACW,CAAD,CAAR,CAAYC,QAAZ,EAAZ;UACAN,SAAS,GAAGS,IAAI,CAACC,GAAL,CAASV,SAAT,EAAoBN,QAAQ,CAACW,CAAD,CAAR,CAAYG,SAAZ,EAApB,CAAZ;QACA;;QACDH,CAAC;MACD;;MAED,OAAOR,SAAP;IACA;IAED;AACD;AACA;AACA;AACA;;;;WACC,kCAAyBJ,oBAAzB,EAA+C;MAC9C,IAAMC,QAAQ,GAAG,KAAKF,UAAL,GAAkBE,QAAnC;;MAEA,IAAID,oBAAoB,GAAGC,QAAQ,CAACQ,MAAT,GAAkB,CAA7C,EAAgD;QAC/C,MAAM,IAAIC,gCAAJ,CAAyB;UAC9BV,oBAAoB,EAApBA,oBAD8B;UAE9BW,qBAAqB,EAAEV,QAAQ,CAACQ;QAFF,CAAzB,CAAN;MAIA;;MAED,OAAOR,QAAQ,CAACD,oBAAD,CAAR,CAA+Be,SAA/B,EAAP;IACA;IAED;AACD;AACA;AACA;;;;WACC,qBAAY;MACX,IAAMd,QAAQ,GAAG,KAAKF,UAAL,GAAkBE,QAAnC;MACA,IAAMC,QAAQ,GAAG,KAAKH,UAAL,GAAkBI,KAAnC;MACA,IAAIe,aAAa,GAAG,KAAKnB,UAAL,GAAkBM,UAAtC;MACA,IAAIO,CAAC,GAAG,CAAR;;MACA,OAAOA,CAAC,GAAGX,QAAQ,CAACQ,MAApB,EAA4B;QAC3B,IAAIH,QAAQ,GAAG,CAAf;QACA,IAAIC,SAAS,GAAG,CAAhB;;QACA,OAAOD,QAAQ,IAAIJ,QAAZ,IAAwBU,CAAC,GAAGX,QAAQ,CAACQ,MAA5C,EAAoD;UACnD,IAAIH,QAAQ,KAAK,CAAb,IAAkBM,CAAC,GAAG,CAA1B,EAA6B;YAC5B,IAAMO,eAAe,GAAGlB,QAAQ,CAACW,CAAD,CAAR,CAAYE,YAAZ,EAAxB;YACAI,aAAa,IAAIC,eAAjB;UACA;;UACDb,QAAQ,IAAIL,QAAQ,CAACW,CAAD,CAAR,CAAYC,QAAZ,EAAZ;UACAN,SAAS,GAAGS,IAAI,CAACC,GAAL,CAASV,SAAT,EAAoBN,QAAQ,CAACW,CAAD,CAAR,CAAYG,SAAZ,EAApB,CAAZ;UACAH,CAAC;QACD;;QACDM,aAAa,IAAIX,SAAjB;MACA;;MACDW,aAAa,IAAI,KAAKnB,UAAL,GAAkBqB,aAAnC;MACA,OAAOF,aAAP;IACA;IAED;AACD;AACA;;;;WACC,iBAAQ;MACP,KAAKnB,UAAL,GAAkBE,QAAlB,GAA6B,EAA7B;IACA"}
|