virtual-scroller 1.12.2 → 1.12.4
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 +7 -0
- package/CODE_OF_CONDUCT.md +78 -0
- package/README.md +1 -1
- package/bundle/index-bypass.html +2 -2
- package/bundle/index-grid.html +2 -2
- package/bundle/index-scrollableContainer.html +2 -2
- 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/Layout.js +10 -13
- package/commonjs/Layout.js.map +1 -1
- package/commonjs/Layout.test.js +20 -10
- package/commonjs/Layout.test.js.map +1 -1
- package/commonjs/Scroll.js +2 -1
- package/commonjs/Scroll.js.map +1 -1
- package/commonjs/{Resize.js → ScrollableContainerResizeHandler.js} +7 -7
- package/commonjs/ScrollableContainerResizeHandler.js.map +1 -0
- package/commonjs/VirtualScroller.constructor.js +5 -5
- package/commonjs/VirtualScroller.constructor.js.map +1 -1
- package/commonjs/VirtualScroller.items.js +1 -1
- package/commonjs/VirtualScroller.items.js.map +1 -1
- package/commonjs/VirtualScroller.js +67 -28
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +24 -22
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/{VirtualScroller.resize.js → VirtualScroller.onContainerResize.js} +2 -2
- package/commonjs/VirtualScroller.onContainerResize.js.map +1 -0
- package/commonjs/VirtualScroller.onRender.js +2 -2
- package/commonjs/VirtualScroller.onRender.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +3 -0
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/useEffectDontMountTwiceInStrictMode.js +83 -0
- package/commonjs/react/useEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/commonjs/react/useInsertionEffectDontMountTwiceInStrictMode.js +20 -0
- package/commonjs/react/useInsertionEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/commonjs/react/useLayoutEffectDontMountTwiceInStrictMode.js +20 -0
- package/commonjs/react/useLayoutEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/commonjs/react/useState.js +13 -7
- package/commonjs/react/useState.js.map +1 -1
- package/commonjs/react/useStateNoStaleBug.js +59 -0
- package/commonjs/react/useStateNoStaleBug.js.map +1 -0
- package/modules/Layout.js +10 -13
- package/modules/Layout.js.map +1 -1
- package/modules/Layout.test.js +20 -10
- package/modules/Layout.test.js.map +1 -1
- package/modules/Scroll.js +2 -1
- package/modules/Scroll.js.map +1 -1
- package/modules/{Resize.js → ScrollableContainerResizeHandler.js} +7 -7
- package/modules/ScrollableContainerResizeHandler.js.map +1 -0
- package/modules/VirtualScroller.constructor.js +5 -5
- package/modules/VirtualScroller.constructor.js.map +1 -1
- package/modules/VirtualScroller.items.js +1 -1
- package/modules/VirtualScroller.items.js.map +1 -1
- package/modules/VirtualScroller.js +67 -28
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +24 -22
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/{VirtualScroller.resize.js → VirtualScroller.onContainerResize.js} +2 -2
- package/modules/VirtualScroller.onContainerResize.js.map +1 -0
- package/modules/VirtualScroller.onRender.js +2 -2
- package/modules/VirtualScroller.onRender.js.map +1 -1
- package/modules/react/VirtualScroller.js +3 -1
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/useEffectDontMountTwiceInStrictMode.js +75 -0
- package/modules/react/useEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/modules/react/useInsertionEffectDontMountTwiceInStrictMode.js +9 -0
- package/modules/react/useInsertionEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/modules/react/useLayoutEffectDontMountTwiceInStrictMode.js +9 -0
- package/modules/react/useLayoutEffectDontMountTwiceInStrictMode.js.map +1 -0
- package/modules/react/useState.js +11 -8
- package/modules/react/useState.js.map +1 -1
- package/modules/react/useStateNoStaleBug.js +51 -0
- package/modules/react/useStateNoStaleBug.js.map +1 -0
- package/package.json +1 -1
- package/source/Layout.js +10 -13
- package/source/Layout.test.js +20 -10
- package/source/Scroll.js +1 -0
- package/source/{Resize.js → ScrollableContainerResizeHandler.js} +1 -1
- package/source/VirtualScroller.constructor.js +5 -5
- package/source/VirtualScroller.items.js +1 -1
- package/source/VirtualScroller.js +65 -25
- package/source/VirtualScroller.layout.js +22 -20
- package/source/{VirtualScroller.resize.js → VirtualScroller.onContainerResize.js} +1 -1
- package/source/VirtualScroller.onRender.js +2 -2
- package/source/react/VirtualScroller.js +3 -0
- package/source/react/useEffectDontMountTwiceInStrictMode.js +68 -0
- package/source/react/useInsertionEffectDontMountTwiceInStrictMode.js +10 -0
- package/source/react/useLayoutEffectDontMountTwiceInStrictMode.js +10 -0
- package/source/react/useState.js +8 -5
- package/source/react/useStateNoStaleBug.js +35 -0
- package/website/index-bypass.html +4 -14
- package/website/index-dom.html +1 -1
- package/website/index-grid.html +4 -4
- package/website/index-scrollableContainer.html +4 -4
- package/website/index-tbody-scrollableContainer.html +2 -0
- package/website/index-tbody.html +2 -0
- package/website/index.html +3 -3
- package/commonjs/Resize.js.map +0 -1
- package/commonjs/VirtualScroller.resize.js.map +0 -1
- package/modules/Resize.js.map +0 -1
- package/modules/VirtualScroller.resize.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","ref","AsComponent","as","itemsProperty","items","Component","itemComponent","itemComponentProps","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","bypass","tbody","preserveScrollPosition","preserveScrollPositionOnPrependItems","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","className","onMount","onItemFirstRender","onItemInitialRender","initialScrollPosition","onScrollPositionChange","onStateChange","initialState","getInitialItemState","rest","container","useRef","virtualScroller","useVirtualScroller","_initialState","useMemo","getInitialState","useState","onRender","getState","setState","stateToRender","useVirtualScrollerStartStop","useItemKeys","getItemKey","usesAutogeneratedItemKeys","updateItemKeysForNewItems","getSetItemState","useSetItemState","initialItemsCount","length","getOnItemHeightDidChange","useOnItemHeightDidChange","useSetNewItemsOnItemsPropertyChange","useUpdateItemKeysOnItemsChange","useInstanceMethods","useLayoutEffect","useClassName","style","useStyle","state","currentItems","itemStates","firstShownItemIndex","lastShownItemIndex","map","item","i","React","forwardRef","elementType","PropTypes","oneOfType","string","func","object","propTypes","arrayOf","any","isRequired","number","bool","shape","beforeItemsHeight","afterItemsHeight","itemHeights","columnsCount","verticalSpacing","defaultProps"],"sources":["../../source/react/VirtualScroller.js"],"sourcesContent":["import React, { useRef, useMemo, useLayoutEffect } from 'react'\r\nimport PropTypes from 'prop-types'\r\n\r\nimport useState from './useState.js'\r\nimport useVirtualScroller from './useVirtualScroller.js'\r\nimport useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js'\r\nimport useInstanceMethods from './useInstanceMethods.js'\r\nimport useItemKeys from './useItemKeys.js'\r\nimport useSetItemState from './useSetItemState.js'\r\nimport useOnItemHeightDidChange from './useOnItemHeightDidChange.js'\r\nimport useSetNewItemsOnItemsPropertyChange from './useSetNewItemsOnItemsPropertyChange.js'\r\nimport useUpdateItemKeysOnItemsChange from './useUpdateItemKeysOnItemsChange.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\nfunction VirtualScroller({\r\n\tas: AsComponent,\r\n\titems: itemsProperty,\r\n\titemComponent: Component,\r\n\titemComponentProps,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tbypass,\r\n\ttbody,\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\tclassName,\r\n\tonMount,\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\tonStateChange,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\t...rest\r\n}, ref) {\r\n\t// List items \"container\" DOM Element reference.\r\n\tconst container = useRef()\r\n\r\n\t// Create a `VirtualScroller` instance.\r\n\tconst virtualScroller = useVirtualScroller({\r\n\t\titems: itemsProperty,\r\n\t\t// `estimatedItemHeight` property name is deprecated,\r\n\t\t// use `getEstimatedItemHeight` property instead.\r\n\t\testimatedItemHeight,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tbypass,\r\n\t\t// bypassBatchSize,\r\n\t\ttbody,\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\tAsComponent,\r\n\t\tinitialState,\r\n\t\tgetInitialItemState,\r\n\t\tonStateChange\r\n\t}, {\r\n\t\tcontainer\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\titemsProperty\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\tuseVirtualScrollerStartStop(virtualScroller)\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\tconst {\r\n\t\tgetItemKey,\r\n\t\tusesAutogeneratedItemKeys,\r\n\t\tupdateItemKeysForNewItems\r\n\t} = useItemKeys({\r\n\t\tgetItemId\r\n\t})\r\n\r\n\t// Cache per-item `setItemState` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getSetItemState = useSetItemState({\r\n\t\tinitialItemsCount: itemsProperty.length,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\t// Cache per-item `onItemHeightDidChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemHeightDidChange = useOnItemHeightDidChange({\r\n\t\tinitialItemsCount: itemsProperty.length,\r\n\t\tvirtualScroller\r\n\t})\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// Updates `key`s if item indexes have changed.\r\n\tuseUpdateItemKeysOnItemsChange(stateToRender.items, {\r\n\t\tvirtualScroller,\r\n\t\tusesAutogeneratedItemKeys,\r\n\t\tupdateItemKeysForNewItems\r\n\t})\r\n\r\n\t// Add instance methods to the React component.\r\n\tuseInstanceMethods(ref, {\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\tuseLayoutEffect(() => {\r\n\t\t// (deprecated)\r\n\t\t// `onMount()` option is deprecated due to no longer being used.\r\n\t\t// If someone thinks there's a valid use case for it, create an issue.\r\n\t\tif (onMount) {\r\n\t\t\tonMount()\r\n\t\t}\r\n\t}, [])\r\n\r\n\t// `willRender()` function is no longer used.\r\n\t//\r\n\t// // `getSnapshotBeforeUpdate()` is called right before `componentDidUpdate()`.\r\n\t// // A hook equivalent/workaround for `getSnapshotBeforeUpdate()`:\r\n\t// // https://github.com/facebook/react/issues/15221#issuecomment-583448887\r\n\t// //\r\n\t// getSnapshotBeforeUpdate(prevProps, prevState) {\r\n\t// \tif (this.state !== prevState) {\r\n\t// \t\tthis.willRender(this.state, prevState)\r\n\t// \t}\r\n\t// \t// Returns `null` to avoid React warning:\r\n\t// \t// \"A snapshot value (or null) must be returned. You have returned undefined\".\r\n\t// \treturn null\r\n\t// }\r\n\r\n\tclassName = useClassName(className, {\r\n\t\ttbody\r\n\t})\r\n\r\n\tconst style = useStyle({\r\n\t\ttbody,\r\n\t\tstate: stateToRender\r\n\t})\r\n\r\n\tconst {\r\n\t\titems: currentItems,\r\n\t\titemStates,\r\n\t\tfirstShownItemIndex,\r\n\t\tlastShownItemIndex\r\n\t} = stateToRender\r\n\r\n\treturn (\r\n\t\t<AsComponent\r\n\t\t\t{...rest}\r\n\t\t\tref={container}\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={style}>\r\n\t\t\t{currentItems.map((item, i) => {\r\n\t\t\t\tif (i >= firstShownItemIndex && i <= lastShownItemIndex) {\r\n\t\t\t\t\t// * Passing `item` as `children` property is legacy and is deprecated.\r\n\t\t\t\t\t// If version `2.x` is published in some hypothetical future,\r\n\t\t\t\t\t// the `item` and `itemIndex` properties should be moved below\r\n\t\t\t\t\t// `{...itemComponentProps}`.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `itemIndex` property is legacy and is deprecated.\r\n\t\t\t\t\t// The rationale is that setting new `items` on a React component\r\n\t\t\t\t\t// is an asynchronous operation, so when a user obtains `itemIndex`,\r\n\t\t\t\t\t// they don't know which `items` list does that index correspond to,\r\n\t\t\t\t\t// therefore making it useless, or even buggy if used incorreclty.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `onStateChange` property for legacy reasons.\r\n\t\t\t\t\t// The new property name is `setState`.\r\n\t\t\t\t\t// The old property name `onStateChange` is deprecated.\r\n\t\t\t\t\t//\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<Component\r\n\t\t\t\t\t\t\titem={item}\r\n\t\t\t\t\t\t\titemIndex={i}\r\n\t\t\t\t\t\t\t{...itemComponentProps}\r\n\t\t\t\t\t\t\tkey={getItemKey(item, i)}\r\n\t\t\t\t\t\t\tstate={itemStates && itemStates[i]}\r\n\t\t\t\t\t\t\tsetState={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonStateChange={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonHeightChange={getOnItemHeightDidChange(i)}\r\n\t\t\t\t\t\t\tonHeightDidChange={getOnItemHeightDidChange(i)}>\r\n\t\t\t\t\t\t\t{item}\r\n\t\t\t\t\t\t</Component>\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\treturn null\r\n\t\t\t})}\r\n\t\t</AsComponent>\r\n\t)\r\n}\r\n\r\nVirtualScroller = React.forwardRef(VirtualScroller)\r\n\r\nexport default VirtualScroller\r\n\r\n// `PropTypes.elementType` is available in some version of `prop-types`.\r\n// https://github.com/facebook/prop-types/issues/200\r\nconst elementType = PropTypes.elementType || PropTypes.oneOfType([\r\n\tPropTypes.string,\r\n\tPropTypes.func,\r\n\tPropTypes.object\r\n])\r\n\r\nVirtualScroller.propTypes = {\r\n\tas: elementType,\r\n\titems: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\titemComponent: elementType.isRequired,\r\n\titemComponentProps: PropTypes.object,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight: PropTypes.number,\r\n\tgetEstimatedItemHeight: PropTypes.func,\r\n\tgetEstimatedVisibleItemRowsCount: PropTypes.func,\r\n\tbypass: PropTypes.bool,\r\n\t// bypassBatchSize: PropTypes.number,\r\n\ttbody: PropTypes.bool,\r\n\tpreserveScrollPositionOnPrependItems: PropTypes.bool,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` instead.\r\n\tpreserveScrollPosition: PropTypes.bool,\r\n\tmeasureItemsBatchSize: PropTypes.number,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer: PropTypes.any,\r\n\tgetScrollableContainer: PropTypes.func,\r\n\tgetColumnsCount: PropTypes.func,\r\n\tgetItemId: PropTypes.func,\r\n\tclassName: PropTypes.string,\r\n\tonMount: PropTypes.func,\r\n\tonItemInitialRender: PropTypes.func,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender: PropTypes.func,\r\n\tinitialScrollPosition: PropTypes.number,\r\n\tonScrollPositionChange: PropTypes.func,\r\n\tonStateChange: PropTypes.func,\r\n\tinitialState: PropTypes.shape({\r\n\t\titems: PropTypes.arrayOf(PropTypes.object).isRequired,\r\n\t\titemStates: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\t\tfirstShownItemIndex: PropTypes.number.isRequired,\r\n\t\tlastShownItemIndex: PropTypes.number.isRequired,\r\n\t\tbeforeItemsHeight: PropTypes.number.isRequired,\r\n\t\tafterItemsHeight: PropTypes.number.isRequired,\r\n\t\titemHeights: PropTypes.arrayOf(PropTypes.number).isRequired,\r\n\t\tcolumnsCount: PropTypes.number,\r\n\t\tverticalSpacing: PropTypes.number\r\n\t}),\r\n\tgetInitialItemState: PropTypes.func\r\n}\r\n\r\nVirtualScroller.defaultProps = {\r\n\tas: 'div'\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","ref","AsComponent","as","itemsProperty","items","Component","itemComponent","itemComponentProps","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","bypass","tbody","preserveScrollPosition","preserveScrollPositionOnPrependItems","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","className","onMount","onItemFirstRender","onItemInitialRender","initialScrollPosition","onScrollPositionChange","onStateChange","initialState","getInitialItemState","rest","container","useRef","virtualScroller","useVirtualScroller","_initialState","useMemo","getInitialState","useState","onRender","getState","setState","stateToRender","useVirtualScrollerStartStop","useItemKeys","getItemKey","usesAutogeneratedItemKeys","updateItemKeysForNewItems","getSetItemState","useSetItemState","initialItemsCount","length","getOnItemHeightDidChange","useOnItemHeightDidChange","useSetNewItemsOnItemsPropertyChange","useUpdateItemKeysOnItemsChange","useInstanceMethods","useLayoutEffect","warn","useClassName","style","useStyle","state","currentItems","itemStates","firstShownItemIndex","lastShownItemIndex","map","item","i","React","forwardRef","elementType","PropTypes","oneOfType","string","func","object","propTypes","arrayOf","any","isRequired","number","bool","shape","beforeItemsHeight","afterItemsHeight","itemHeights","columnsCount","verticalSpacing","defaultProps"],"sources":["../../source/react/VirtualScroller.js"],"sourcesContent":["import React, { useRef, useMemo, useLayoutEffect } from 'react'\r\nimport PropTypes from 'prop-types'\r\n\r\nimport useState from './useState.js'\r\nimport useVirtualScroller from './useVirtualScroller.js'\r\nimport useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js'\r\nimport useInstanceMethods from './useInstanceMethods.js'\r\nimport useItemKeys from './useItemKeys.js'\r\nimport useSetItemState from './useSetItemState.js'\r\nimport useOnItemHeightDidChange from './useOnItemHeightDidChange.js'\r\nimport useSetNewItemsOnItemsPropertyChange from './useSetNewItemsOnItemsPropertyChange.js'\r\nimport useUpdateItemKeysOnItemsChange from './useUpdateItemKeysOnItemsChange.js'\r\nimport useClassName from './useClassName.js'\r\nimport useStyle from './useStyle.js'\r\n\r\nimport { warn } from '../utility/debug.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\nfunction VirtualScroller({\r\n\tas: AsComponent,\r\n\titems: itemsProperty,\r\n\titemComponent: Component,\r\n\titemComponentProps,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tbypass,\r\n\ttbody,\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\tclassName,\r\n\tonMount,\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\tonStateChange,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\t...rest\r\n}, ref) {\r\n\t// List items \"container\" DOM Element reference.\r\n\tconst container = useRef()\r\n\r\n\t// Create a `VirtualScroller` instance.\r\n\tconst virtualScroller = useVirtualScroller({\r\n\t\titems: itemsProperty,\r\n\t\t// `estimatedItemHeight` property name is deprecated,\r\n\t\t// use `getEstimatedItemHeight` property instead.\r\n\t\testimatedItemHeight,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tbypass,\r\n\t\t// bypassBatchSize,\r\n\t\ttbody,\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\tAsComponent,\r\n\t\tinitialState,\r\n\t\tgetInitialItemState,\r\n\t\tonStateChange\r\n\t}, {\r\n\t\tcontainer\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\titemsProperty\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\tuseVirtualScrollerStartStop(virtualScroller)\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\tconst {\r\n\t\tgetItemKey,\r\n\t\tusesAutogeneratedItemKeys,\r\n\t\tupdateItemKeysForNewItems\r\n\t} = useItemKeys({\r\n\t\tgetItemId\r\n\t})\r\n\r\n\t// Cache per-item `setItemState` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getSetItemState = useSetItemState({\r\n\t\tinitialItemsCount: itemsProperty.length,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\t// Cache per-item `onItemHeightDidChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemHeightDidChange = useOnItemHeightDidChange({\r\n\t\tinitialItemsCount: itemsProperty.length,\r\n\t\tvirtualScroller\r\n\t})\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// Updates `key`s if item indexes have changed.\r\n\tuseUpdateItemKeysOnItemsChange(stateToRender.items, {\r\n\t\tvirtualScroller,\r\n\t\tusesAutogeneratedItemKeys,\r\n\t\tupdateItemKeysForNewItems\r\n\t})\r\n\r\n\t// Add instance methods to the React component.\r\n\tuseInstanceMethods(ref, {\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\tuseLayoutEffect(() => {\r\n\t\t// (deprecated)\r\n\t\t// `onMount()` option is deprecated due to no longer being used.\r\n\t\t// If someone thinks there's a valid use case for it, create an issue.\r\n\t\tif (onMount) {\r\n\t\t\twarn('`onMount` property is deprecated')\r\n\t\t\tonMount()\r\n\t\t}\r\n\t}, [])\r\n\r\n\t// `willRender()` function is no longer used.\r\n\t//\r\n\t// // `getSnapshotBeforeUpdate()` is called right before `componentDidUpdate()`.\r\n\t// // A hook equivalent/workaround for `getSnapshotBeforeUpdate()`:\r\n\t// // https://github.com/facebook/react/issues/15221#issuecomment-583448887\r\n\t// //\r\n\t// getSnapshotBeforeUpdate(prevProps, prevState) {\r\n\t// \tif (this.state !== prevState) {\r\n\t// \t\tthis.willRender(this.state, prevState)\r\n\t// \t}\r\n\t// \t// Returns `null` to avoid React warning:\r\n\t// \t// \"A snapshot value (or null) must be returned. You have returned undefined\".\r\n\t// \treturn null\r\n\t// }\r\n\r\n\tclassName = useClassName(className, {\r\n\t\ttbody\r\n\t})\r\n\r\n\tconst style = useStyle({\r\n\t\ttbody,\r\n\t\tstate: stateToRender\r\n\t})\r\n\r\n\tconst {\r\n\t\titems: currentItems,\r\n\t\titemStates,\r\n\t\tfirstShownItemIndex,\r\n\t\tlastShownItemIndex\r\n\t} = stateToRender\r\n\r\n\treturn (\r\n\t\t<AsComponent\r\n\t\t\t{...rest}\r\n\t\t\tref={container}\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={style}>\r\n\t\t\t{currentItems.map((item, i) => {\r\n\t\t\t\tif (i >= firstShownItemIndex && i <= lastShownItemIndex) {\r\n\t\t\t\t\t// * Passing `item` as `children` property is legacy and is deprecated.\r\n\t\t\t\t\t// If version `2.x` is published in some hypothetical future,\r\n\t\t\t\t\t// the `item` and `itemIndex` properties should be moved below\r\n\t\t\t\t\t// `{...itemComponentProps}`.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `itemIndex` property is legacy and is deprecated.\r\n\t\t\t\t\t// The rationale is that setting new `items` on a React component\r\n\t\t\t\t\t// is an asynchronous operation, so when a user obtains `itemIndex`,\r\n\t\t\t\t\t// they don't know which `items` list does that index correspond to,\r\n\t\t\t\t\t// therefore making it useless, or even buggy if used incorreclty.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `onStateChange` property for legacy reasons.\r\n\t\t\t\t\t// The new property name is `setState`.\r\n\t\t\t\t\t// The old property name `onStateChange` is deprecated.\r\n\t\t\t\t\t//\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<Component\r\n\t\t\t\t\t\t\titem={item}\r\n\t\t\t\t\t\t\titemIndex={i}\r\n\t\t\t\t\t\t\t{...itemComponentProps}\r\n\t\t\t\t\t\t\tkey={getItemKey(item, i)}\r\n\t\t\t\t\t\t\tstate={itemStates && itemStates[i]}\r\n\t\t\t\t\t\t\tsetState={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonStateChange={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonHeightChange={getOnItemHeightDidChange(i)}\r\n\t\t\t\t\t\t\tonHeightDidChange={getOnItemHeightDidChange(i)}>\r\n\t\t\t\t\t\t\t{item}\r\n\t\t\t\t\t\t</Component>\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\treturn null\r\n\t\t\t})}\r\n\t\t</AsComponent>\r\n\t)\r\n}\r\n\r\nVirtualScroller = React.forwardRef(VirtualScroller)\r\n\r\nexport default VirtualScroller\r\n\r\n// `PropTypes.elementType` is available in some version of `prop-types`.\r\n// https://github.com/facebook/prop-types/issues/200\r\nconst elementType = PropTypes.elementType || PropTypes.oneOfType([\r\n\tPropTypes.string,\r\n\tPropTypes.func,\r\n\tPropTypes.object\r\n])\r\n\r\nVirtualScroller.propTypes = {\r\n\tas: elementType,\r\n\titems: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\titemComponent: elementType.isRequired,\r\n\titemComponentProps: PropTypes.object,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight: PropTypes.number,\r\n\tgetEstimatedItemHeight: PropTypes.func,\r\n\tgetEstimatedVisibleItemRowsCount: PropTypes.func,\r\n\tbypass: PropTypes.bool,\r\n\t// bypassBatchSize: PropTypes.number,\r\n\ttbody: PropTypes.bool,\r\n\tpreserveScrollPositionOnPrependItems: PropTypes.bool,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` instead.\r\n\tpreserveScrollPosition: PropTypes.bool,\r\n\tmeasureItemsBatchSize: PropTypes.number,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer: PropTypes.any,\r\n\tgetScrollableContainer: PropTypes.func,\r\n\tgetColumnsCount: PropTypes.func,\r\n\tgetItemId: PropTypes.func,\r\n\tclassName: PropTypes.string,\r\n\tonMount: PropTypes.func,\r\n\tonItemInitialRender: PropTypes.func,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender: PropTypes.func,\r\n\tinitialScrollPosition: PropTypes.number,\r\n\tonScrollPositionChange: PropTypes.func,\r\n\tonStateChange: PropTypes.func,\r\n\tinitialState: PropTypes.shape({\r\n\t\titems: PropTypes.arrayOf(PropTypes.object).isRequired,\r\n\t\titemStates: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\t\tfirstShownItemIndex: PropTypes.number.isRequired,\r\n\t\tlastShownItemIndex: PropTypes.number.isRequired,\r\n\t\tbeforeItemsHeight: PropTypes.number.isRequired,\r\n\t\tafterItemsHeight: PropTypes.number.isRequired,\r\n\t\titemHeights: PropTypes.arrayOf(PropTypes.number).isRequired,\r\n\t\tcolumnsCount: PropTypes.number,\r\n\t\tverticalSpacing: PropTypes.number\r\n\t}),\r\n\tgetInitialItemState: PropTypes.func\r\n}\r\n\r\nVirtualScroller.defaultProps = {\r\n\tas: 'div'\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useEffectDontMountTwiceInStrictMode;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
// A workaround for a React bug when `useInsertionEffect()` doesn't run twice on mount
|
|
11
|
+
// in "strict" mode unlike `useEffect()` and `useLayoutEffect()` do.
|
|
12
|
+
// https://github.com/facebook/react/issues/26320
|
|
13
|
+
function useEffectDontMountTwiceInStrictMode(useEffect, handler, dependencies) {
|
|
14
|
+
if (!Array.isArray(dependencies)) {
|
|
15
|
+
throw new Error('Dependencies argument must be an array');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var _useEffectStatus = useEffectStatus(),
|
|
19
|
+
onEffect = _useEffectStatus.onEffect;
|
|
20
|
+
|
|
21
|
+
var _usePrevousValue = usePrevousValue(dependencies),
|
|
22
|
+
onChange = _usePrevousValue.onChange;
|
|
23
|
+
|
|
24
|
+
useEffect(function () {
|
|
25
|
+
var _onEffect = onEffect(),
|
|
26
|
+
isInitialRun = _onEffect.isInitialRun;
|
|
27
|
+
|
|
28
|
+
var previousDependencies = onChange(dependencies);
|
|
29
|
+
|
|
30
|
+
if (isInitialRun || !isShallowEqualArrays(previousDependencies, dependencies)) {
|
|
31
|
+
var cleanUpFunction = handler();
|
|
32
|
+
|
|
33
|
+
if (typeof cleanUpFunction === 'function') {
|
|
34
|
+
throw new Error('An effect can\'t return a clean-up function when used with `useEffectDontMountTwiceInStrictMode()` because the clean-up function won\'t behave correctly in that case');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}, dependencies);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function useEffectStatus() {
|
|
41
|
+
var hasMounted = (0, _react.useRef)(false);
|
|
42
|
+
var onEffect = (0, _react.useCallback)(function () {
|
|
43
|
+
var wasAlreadyMounted = hasMounted.current;
|
|
44
|
+
hasMounted.current = true;
|
|
45
|
+
return {
|
|
46
|
+
isInitialRun: !wasAlreadyMounted
|
|
47
|
+
};
|
|
48
|
+
}, []);
|
|
49
|
+
return {
|
|
50
|
+
onEffect: onEffect
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function usePrevousValue(value) {
|
|
55
|
+
var prevValue = (0, _react.useRef)(value);
|
|
56
|
+
var onChange = (0, _react.useCallback)(function (value) {
|
|
57
|
+
var previousValue = prevValue.current;
|
|
58
|
+
prevValue.current = value;
|
|
59
|
+
return previousValue;
|
|
60
|
+
}, []);
|
|
61
|
+
return {
|
|
62
|
+
onChange: onChange
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isShallowEqualArrays(a, b) {
|
|
67
|
+
if (a.length !== b.length) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
var i = 0;
|
|
72
|
+
|
|
73
|
+
while (i < a.length) {
|
|
74
|
+
if (a[i] !== b[i]) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
i++;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=useEffectDontMountTwiceInStrictMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEffectDontMountTwiceInStrictMode.js","names":["useEffectDontMountTwiceInStrictMode","useEffect","handler","dependencies","Array","isArray","Error","useEffectStatus","onEffect","usePrevousValue","onChange","isInitialRun","previousDependencies","isShallowEqualArrays","cleanUpFunction","hasMounted","useRef","useCallback","wasAlreadyMounted","current","value","prevValue","previousValue","a","b","length","i"],"sources":["../../source/react/useEffectDontMountTwiceInStrictMode.js"],"sourcesContent":["import { useRef, useCallback } from 'react'\r\n\r\n// A workaround for a React bug when `useInsertionEffect()` doesn't run twice on mount\r\n// in \"strict\" mode unlike `useEffect()` and `useLayoutEffect()` do.\r\n// https://github.com/facebook/react/issues/26320\r\nexport default function useEffectDontMountTwiceInStrictMode(useEffect, handler, dependencies) {\r\n if (!Array.isArray(dependencies)) {\r\n throw new Error('Dependencies argument must be an array')\r\n }\r\n\r\n const { onEffect } = useEffectStatus()\r\n const { onChange } = usePrevousValue(dependencies)\r\n\r\n useEffect(() => {\r\n const { isInitialRun } = onEffect()\r\n const previousDependencies = onChange(dependencies)\r\n if (isInitialRun || !isShallowEqualArrays(previousDependencies, dependencies)) {\r\n const cleanUpFunction = handler()\r\n if (typeof cleanUpFunction === 'function') {\r\n throw new Error('An effect can\\'t return a clean-up function when used with `useEffectDontMountTwiceInStrictMode()` because the clean-up function won\\'t behave correctly in that case')\r\n }\r\n }\r\n }, dependencies)\r\n}\r\n\r\nfunction useEffectStatus() {\r\n const hasMounted = useRef(false)\r\n\r\n const onEffect = useCallback(() => {\r\n const wasAlreadyMounted = hasMounted.current\r\n hasMounted.current = true\r\n return {\r\n isInitialRun: !wasAlreadyMounted\r\n }\r\n }, [])\r\n\r\n return {\r\n onEffect\r\n }\r\n}\r\n\r\nfunction usePrevousValue(value) {\r\n const prevValue = useRef(value)\r\n\r\n const onChange = useCallback((value) => {\r\n const previousValue = prevValue.current\r\n prevValue.current = value\r\n return previousValue\r\n }, [])\r\n\r\n return {\r\n onChange\r\n }\r\n}\r\n\r\nfunction isShallowEqualArrays(a, b) {\r\n if (a.length !== b.length) {\r\n return false\r\n }\r\n let i = 0\r\n while (i < a.length) {\r\n if (a[i] !== b[i]) {\r\n return false\r\n }\r\n i++\r\n }\r\n return true\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;AACA;AACA;AACe,SAASA,mCAAT,CAA6CC,SAA7C,EAAwDC,OAAxD,EAAiEC,YAAjE,EAA+E;EAC5F,IAAI,CAACC,KAAK,CAACC,OAAN,CAAcF,YAAd,CAAL,EAAkC;IAChC,MAAM,IAAIG,KAAJ,CAAU,wCAAV,CAAN;EACD;;EAED,uBAAqBC,eAAe,EAApC;EAAA,IAAQC,QAAR,oBAAQA,QAAR;;EACA,uBAAqBC,eAAe,CAACN,YAAD,CAApC;EAAA,IAAQO,QAAR,oBAAQA,QAAR;;EAEAT,SAAS,CAAC,YAAM;IACd,gBAAyBO,QAAQ,EAAjC;IAAA,IAAQG,YAAR,aAAQA,YAAR;;IACA,IAAMC,oBAAoB,GAAGF,QAAQ,CAACP,YAAD,CAArC;;IACA,IAAIQ,YAAY,IAAI,CAACE,oBAAoB,CAACD,oBAAD,EAAuBT,YAAvB,CAAzC,EAA+E;MAC7E,IAAMW,eAAe,GAAGZ,OAAO,EAA/B;;MACA,IAAI,OAAOY,eAAP,KAA2B,UAA/B,EAA2C;QACzC,MAAM,IAAIR,KAAJ,CAAU,uKAAV,CAAN;MACD;IACF;EACF,CATQ,EASNH,YATM,CAAT;AAUD;;AAED,SAASI,eAAT,GAA2B;EACzB,IAAMQ,UAAU,GAAG,IAAAC,aAAA,EAAO,KAAP,CAAnB;EAEA,IAAMR,QAAQ,GAAG,IAAAS,kBAAA,EAAY,YAAM;IACjC,IAAMC,iBAAiB,GAAGH,UAAU,CAACI,OAArC;IACAJ,UAAU,CAACI,OAAX,GAAqB,IAArB;IACA,OAAO;MACLR,YAAY,EAAE,CAACO;IADV,CAAP;EAGD,CANgB,EAMd,EANc,CAAjB;EAQA,OAAO;IACLV,QAAQ,EAARA;EADK,CAAP;AAGD;;AAED,SAASC,eAAT,CAAyBW,KAAzB,EAAgC;EAC9B,IAAMC,SAAS,GAAG,IAAAL,aAAA,EAAOI,KAAP,CAAlB;EAEA,IAAMV,QAAQ,GAAG,IAAAO,kBAAA,EAAY,UAACG,KAAD,EAAW;IACtC,IAAME,aAAa,GAAGD,SAAS,CAACF,OAAhC;IACAE,SAAS,CAACF,OAAV,GAAoBC,KAApB;IACA,OAAOE,aAAP;EACD,CAJgB,EAId,EAJc,CAAjB;EAMA,OAAO;IACLZ,QAAQ,EAARA;EADK,CAAP;AAGD;;AAED,SAASG,oBAAT,CAA8BU,CAA9B,EAAiCC,CAAjC,EAAoC;EAClC,IAAID,CAAC,CAACE,MAAF,KAAaD,CAAC,CAACC,MAAnB,EAA2B;IACzB,OAAO,KAAP;EACD;;EACD,IAAIC,CAAC,GAAG,CAAR;;EACA,OAAOA,CAAC,GAAGH,CAAC,CAACE,MAAb,EAAqB;IACnB,IAAIF,CAAC,CAACG,CAAD,CAAD,KAASF,CAAC,CAACE,CAAD,CAAd,EAAmB;MACjB,OAAO,KAAP;IACD;;IACDA,CAAC;EACF;;EACD,OAAO,IAAP;AACD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useInsertionEffectDontMountTwiceInStrictMode;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
var _useEffectDontMountTwiceInStrictMode = _interopRequireDefault(require("./useEffectDontMountTwiceInStrictMode.js"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
|
+
|
|
14
|
+
// A workaround for a React bug when `useInsertionEffect()` doesn't run twice on mount
|
|
15
|
+
// in "strict" mode unlike `useEffect()` and `useLayoutEffect()` do.
|
|
16
|
+
// https://github.com/facebook/react/issues/26320
|
|
17
|
+
function useInsertionEffectDontMountTwiceInStrictMode(handler, dependencies) {
|
|
18
|
+
return (0, _useEffectDontMountTwiceInStrictMode["default"])(_react.useInsertionEffect, handler, dependencies);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=useInsertionEffectDontMountTwiceInStrictMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInsertionEffectDontMountTwiceInStrictMode.js","names":["useInsertionEffectDontMountTwiceInStrictMode","handler","dependencies","useEffectDontMountTwiceInStrictMode","useInsertionEffect"],"sources":["../../source/react/useInsertionEffectDontMountTwiceInStrictMode.js"],"sourcesContent":["import { useInsertionEffect } from 'react'\r\n\r\nimport useEffectDontMountTwiceInStrictMode from './useEffectDontMountTwiceInStrictMode.js'\r\n\r\n// A workaround for a React bug when `useInsertionEffect()` doesn't run twice on mount\r\n// in \"strict\" mode unlike `useEffect()` and `useLayoutEffect()` do.\r\n// https://github.com/facebook/react/issues/26320\r\nexport default function useInsertionEffectDontMountTwiceInStrictMode(handler, dependencies) {\r\n return useEffectDontMountTwiceInStrictMode(useInsertionEffect, handler, dependencies)\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;;;;AAEA;AACA;AACA;AACe,SAASA,4CAAT,CAAsDC,OAAtD,EAA+DC,YAA/D,EAA6E;EAC1F,OAAO,IAAAC,+CAAA,EAAoCC,yBAApC,EAAwDH,OAAxD,EAAiEC,YAAjE,CAAP;AACD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useLayoutEffectDontMountTwiceInStrictMode;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
var _useEffectDontMountTwiceInStrictMode = _interopRequireDefault(require("./useEffectDontMountTwiceInStrictMode.js"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
13
|
+
|
|
14
|
+
// A workaround for a React bug when `useInsertionEffect()` doesn't run twice on mount
|
|
15
|
+
// in "strict" mode unlike `useEffect()` and `useLayoutEffect()` do.
|
|
16
|
+
// https://github.com/facebook/react/issues/26320
|
|
17
|
+
function useLayoutEffectDontMountTwiceInStrictMode(handler, dependencies) {
|
|
18
|
+
return (0, _useEffectDontMountTwiceInStrictMode["default"])(_react.useLayoutEffect, handler, dependencies);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=useLayoutEffectDontMountTwiceInStrictMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLayoutEffectDontMountTwiceInStrictMode.js","names":["useLayoutEffectDontMountTwiceInStrictMode","handler","dependencies","useEffectDontMountTwiceInStrictMode","useLayoutEffect"],"sources":["../../source/react/useLayoutEffectDontMountTwiceInStrictMode.js"],"sourcesContent":["import { useLayoutEffect } from 'react'\r\n\r\nimport useEffectDontMountTwiceInStrictMode from './useEffectDontMountTwiceInStrictMode.js'\r\n\r\n// A workaround for a React bug when `useInsertionEffect()` doesn't run twice on mount\r\n// in \"strict\" mode unlike `useEffect()` and `useLayoutEffect()` do.\r\n// https://github.com/facebook/react/issues/26320\r\nexport default function useLayoutEffectDontMountTwiceInStrictMode(handler, dependencies) {\r\n return useEffectDontMountTwiceInStrictMode(useLayoutEffect, handler, dependencies)\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;;;;AAEA;AACA;AACA;AACe,SAASA,yCAAT,CAAmDC,OAAnD,EAA4DC,YAA5D,EAA0E;EACvF,OAAO,IAAAC,+CAAA,EAAoCC,sBAApC,EAAqDH,OAArD,EAA8DC,YAA9D,CAAP;AACD"}
|
|
@@ -13,6 +13,12 @@ var _getStateSnapshot = _interopRequireDefault(require("../utility/getStateSnaps
|
|
|
13
13
|
|
|
14
14
|
var _react = require("react");
|
|
15
15
|
|
|
16
|
+
var _useStateNoStaleBug3 = _interopRequireDefault(require("./useStateNoStaleBug.js"));
|
|
17
|
+
|
|
18
|
+
var _useInsertionEffectDontMountTwiceInStrictMode = _interopRequireDefault(require("./useInsertionEffectDontMountTwiceInStrictMode.js"));
|
|
19
|
+
|
|
20
|
+
var _useLayoutEffectDontMountTwiceInStrictMode = _interopRequireDefault(require("./useLayoutEffectDontMountTwiceInStrictMode.js"));
|
|
21
|
+
|
|
16
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
17
23
|
|
|
18
24
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -42,10 +48,10 @@ function _useState(_ref) {
|
|
|
42
48
|
// `VirtualScroller` state gets updated from this variable.
|
|
43
49
|
// The reason for that is that `VirtualScroller` state must always
|
|
44
50
|
// correspond exactly to what's currently rendered on the screen.
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
_newState =
|
|
48
|
-
_setNewState =
|
|
51
|
+
var _useStateNoStaleBug = (0, _useStateNoStaleBug3["default"])(initialState),
|
|
52
|
+
_useStateNoStaleBug2 = _slicedToArray(_useStateNoStaleBug, 2),
|
|
53
|
+
_newState = _useStateNoStaleBug2[0],
|
|
54
|
+
_setNewState = _useStateNoStaleBug2[1]; // This `state` reference is what `VirtualScroller` uses internally.
|
|
49
55
|
// It's the "source of truth" on the actual `VirtualScroller` state.
|
|
50
56
|
|
|
51
57
|
|
|
@@ -163,7 +169,7 @@ function _useState(_ref) {
|
|
|
163
169
|
// it could be replaced with using `ref`s on `ItemComponent`s to measure the DOM element heights.
|
|
164
170
|
//
|
|
165
171
|
|
|
166
|
-
(0,
|
|
172
|
+
(0, _useInsertionEffectDontMountTwiceInStrictMode["default"])(function () {
|
|
167
173
|
// Update the actual `VirtualScroller` state right before the DOM changes
|
|
168
174
|
// are going to be applied for the requested state update.
|
|
169
175
|
//
|
|
@@ -186,13 +192,13 @@ function _useState(_ref) {
|
|
|
186
192
|
// This hook doesn't do anything at the initial render.
|
|
187
193
|
//
|
|
188
194
|
if ((0, _debug.isDebug)()) {
|
|
189
|
-
(0, _debug["default"])('React: ~ The requested state is about to be applied in DOM.
|
|
195
|
+
(0, _debug["default"])('React: ~ The requested state is about to be applied in DOM. Setting it as the `VirtualScroller` state. ~');
|
|
190
196
|
(0, _debug["default"])((0, _getStateSnapshot["default"])(_newState));
|
|
191
197
|
}
|
|
192
198
|
|
|
193
199
|
setState(_newState);
|
|
194
200
|
}, [_newState]);
|
|
195
|
-
(0,
|
|
201
|
+
(0, _useLayoutEffectDontMountTwiceInStrictMode["default"])(function () {
|
|
196
202
|
// Call `onRender()` right after a requested state update has been applied,
|
|
197
203
|
// and also right after the initial render.
|
|
198
204
|
onRender();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useState.js","names":["_useState","initialState","onRender","itemsProperty","useState","_newState","_setNewState","state","useRef","getState","useCallback","current","setState","newState","useInsertionEffect","isDebug","log","getStateSnapshot","useLayoutEffect","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 { useState, useRef, useCallback, useLayoutEffect, useInsertionEffect } from 'react'\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] = useState(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\tuseInsertionEffect(() => {\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. Set 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\tuseLayoutEffect(() => {\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;;;;;;;;;;;;;;;;;;;;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,iBAAkC,IAAAC,eAAA,EAASH,YAAT,CAAlC;EAAA;EAAA,IAAOI,SAAP;EAAA,IAAkBC,YAAlB,iBANE,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,yBAAA,EAAmB,YAAM;IACxB;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,sGAAJ;MACA,IAAAA,iBAAA,EAAI,IAAAC,4BAAA,EAAiBZ,SAAjB,CAAJ;IACA;;IACDO,QAAQ,CAACP,SAAD,CAAR;EACA,CA3BD,EA2BG,CAACA,SAAD,CA3BH;EA6BA,IAAAa,sBAAA,EAAgB,YAAM;IACrB;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","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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useStateNoStaleBug;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
11
|
+
|
|
12
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
|
+
|
|
14
|
+
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); }
|
|
15
|
+
|
|
16
|
+
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; }
|
|
17
|
+
|
|
18
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
19
|
+
|
|
20
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
21
|
+
|
|
22
|
+
// This hook fixes any weird intermediate inconsistent/invalid/stale state values.
|
|
23
|
+
// https://github.com/facebook/react/issues/25023#issuecomment-1480463544
|
|
24
|
+
function useStateNoStaleBug(initialState) {
|
|
25
|
+
// const latestValidState = useRef(initialState)
|
|
26
|
+
var latestWrittenState = (0, _react.useRef)(initialState);
|
|
27
|
+
|
|
28
|
+
var _useState = (0, _react.useState)(initialState),
|
|
29
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
30
|
+
_state = _useState2[0],
|
|
31
|
+
_setState = _useState2[1]; // Instead of dealing with a potentially out-of-sync (stale) state value,
|
|
32
|
+
// simply use the correct latest one.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
var state = latestWrittenState.current;
|
|
36
|
+
/*
|
|
37
|
+
let state
|
|
38
|
+
if (_state === latestWrittenState.current) {
|
|
39
|
+
state = _state
|
|
40
|
+
latestValidState.current = _state
|
|
41
|
+
} else {
|
|
42
|
+
// React bug detected: an out-of-sync (stale) state value received.
|
|
43
|
+
// Ignore the out-of-sync (stale) state value.
|
|
44
|
+
state = latestValidState.current
|
|
45
|
+
}
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
var setState = (0, _react.useCallback)(function (newState) {
|
|
49
|
+
if (typeof newState === 'function') {
|
|
50
|
+
throw new Error('Function argument of `setState()` function is not supported by this hook');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
latestWrittenState.current = newState;
|
|
54
|
+
|
|
55
|
+
_setState(newState);
|
|
56
|
+
}, []);
|
|
57
|
+
return [state, setState];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=useStateNoStaleBug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStateNoStaleBug.js","names":["useStateNoStaleBug","initialState","latestWrittenState","useRef","useState","_state","_setState","state","current","setState","useCallback","newState","Error"],"sources":["../../source/react/useStateNoStaleBug.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 useStateNoStaleBug(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,kBAAT,CAA4BC,YAA5B,EAA0C;EACvD;EACA,IAAMC,kBAAkB,GAAG,IAAAC,aAAA,EAAOF,YAAP,CAA3B;;EACA,gBAA4B,IAAAG,eAAA,EAASH,YAAT,CAA5B;EAAA;EAAA,IAAOI,MAAP;EAAA,IAAeC,SAAf,iBAHuD,CAKvD;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"}
|
package/modules/Layout.js
CHANGED
|
@@ -70,7 +70,7 @@ var Layout = /*#__PURE__*/function () {
|
|
|
70
70
|
return getValue();
|
|
71
71
|
} catch (error) {
|
|
72
72
|
if (error instanceof ScrollableContainerNotReadyError) {
|
|
73
|
-
log(
|
|
73
|
+
log("Scrollable container size is not known at this point, so \"".concat(name, "\" can't be calculated yet. Default to"), defaultValue);
|
|
74
74
|
return defaultValue;
|
|
75
75
|
} else {
|
|
76
76
|
throw error;
|
|
@@ -357,14 +357,12 @@ var Layout = /*#__PURE__*/function () {
|
|
|
357
357
|
key: "getShownItemIndexes",
|
|
358
358
|
value: function getShownItemIndexes(_ref8) {
|
|
359
359
|
var itemsCount = _ref8.itemsCount,
|
|
360
|
-
|
|
361
|
-
visibleAreaBottom = _ref8.visibleAreaBottom;
|
|
360
|
+
visibleAreaInsideTheList = _ref8.visibleAreaInsideTheList;
|
|
362
361
|
|
|
363
362
|
var indexes = this._getShownItemIndex({
|
|
364
363
|
itemsCount: itemsCount,
|
|
365
364
|
fromIndex: 0,
|
|
366
|
-
|
|
367
|
-
visibleAreaBottom: visibleAreaBottom,
|
|
365
|
+
visibleAreaInsideTheList: visibleAreaInsideTheList,
|
|
368
366
|
findFirstShownItemIndex: true
|
|
369
367
|
});
|
|
370
368
|
|
|
@@ -383,8 +381,7 @@ var Layout = /*#__PURE__*/function () {
|
|
|
383
381
|
itemsCount: itemsCount,
|
|
384
382
|
fromIndex: firstShownItemIndex,
|
|
385
383
|
beforeItemsHeight: beforeItemsHeight,
|
|
386
|
-
|
|
387
|
-
visibleAreaBottom: visibleAreaBottom,
|
|
384
|
+
visibleAreaInsideTheList: visibleAreaInsideTheList,
|
|
388
385
|
findLastShownItemIndex: true
|
|
389
386
|
});
|
|
390
387
|
|
|
@@ -408,8 +405,7 @@ var Layout = /*#__PURE__*/function () {
|
|
|
408
405
|
value: function _getShownItemIndex(parameters) {
|
|
409
406
|
var beforeResize = parameters.beforeResize,
|
|
410
407
|
itemsCount = parameters.itemsCount,
|
|
411
|
-
|
|
412
|
-
visibleAreaBottom = parameters.visibleAreaBottom,
|
|
408
|
+
visibleAreaInsideTheList = parameters.visibleAreaInsideTheList,
|
|
413
409
|
findFirstShownItemIndex = parameters.findFirstShownItemIndex,
|
|
414
410
|
findLastShownItemIndex = parameters.findLastShownItemIndex;
|
|
415
411
|
var fromIndex = parameters.fromIndex,
|
|
@@ -436,7 +432,8 @@ var Layout = /*#__PURE__*/function () {
|
|
|
436
432
|
// If "previously calculated layout" would be used then it would first find
|
|
437
433
|
// `firstShownItemIndex` and then find `lastShownItemIndex` as part of two
|
|
438
434
|
// separate calls of this function, each with or without `backwards` flag,
|
|
439
|
-
// depending on whether `
|
|
435
|
+
// depending on whether `visibleAreaInsideTheList.top` and `visibleAreaInsideTheList.top`
|
|
436
|
+
// have shifted up or down.
|
|
440
437
|
|
|
441
438
|
var firstShownItemIndex;
|
|
442
439
|
var lastShownItemIndex; // It's not always required to pass `beforeItemsHeight` parameter:
|
|
@@ -511,7 +508,7 @@ var Layout = /*#__PURE__*/function () {
|
|
|
511
508
|
itemsCount: itemsCount,
|
|
512
509
|
firstShownItemIndex: findLastShownItemIndex ? fromIndex : undefined,
|
|
513
510
|
indexOfTheFirstItemInTheRow: currentRowFirstItemIndex,
|
|
514
|
-
nonMeasuredAreaHeight:
|
|
511
|
+
nonMeasuredAreaHeight: visibleAreaInsideTheList.bottom + this.getPrerenderMargin() - beforeItemsHeight
|
|
515
512
|
});
|
|
516
513
|
}
|
|
517
514
|
|
|
@@ -521,8 +518,8 @@ var Layout = /*#__PURE__*/function () {
|
|
|
521
518
|
}
|
|
522
519
|
|
|
523
520
|
var itemsHeightFromFirstRowToThisRow = beforeItemsHeight + currentRowHeight;
|
|
524
|
-
var rowStepsIntoVisibleAreaTop = itemsHeightFromFirstRowToThisRow >
|
|
525
|
-
var rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder = itemsHeightFromFirstRowToThisRow + verticalSpacingAfterCurrentRow >=
|
|
521
|
+
var rowStepsIntoVisibleAreaTop = itemsHeightFromFirstRowToThisRow > visibleAreaInsideTheList.top - this.getPrerenderMargin();
|
|
522
|
+
var rowStepsOutOfVisibleAreaBottomOrIsAtTheBorder = itemsHeightFromFirstRowToThisRow + verticalSpacingAfterCurrentRow >= visibleAreaInsideTheList.bottom + this.getPrerenderMargin(); // if (backwards) {
|
|
526
523
|
// if (findFirstShownItemIndex) {
|
|
527
524
|
// if (rowStepsOutOfVisibleAreaTop) {
|
|
528
525
|
// return {
|