Private
Public Access
1
0
Files
power-apps-codeapps-blog-part2/node_modules/@fluentui/react-virtualizer/lib/components/VirtualizerScrollViewDynamic/useVirtualizerScrollViewDynamic.js

156 lines
8.0 KiB
JavaScript

'use client';
import * as React from 'react';
import { slot, useMergedRefs } from '@fluentui/react-utilities';
import { useVirtualizer_unstable } from '../Virtualizer/useVirtualizer';
import { useDynamicVirtualizerMeasure } from '../../Hooks';
import { useVirtualizerContextState_unstable, scrollToItemDynamic } from '../../Utilities';
import { useMeasureList } from '../../hooks/useMeasureList';
import { useDynamicVirtualizerPagination } from '../../hooks/useDynamicPagination';
/**
* @deprecated migrated to \@fluentui\-contrib/react\-virtualizer for stable release.
*/ export function useVirtualizerScrollViewDynamic_unstable(props) {
'use no memo';
var _imperativeVirtualizerRef_current;
const contextState = useVirtualizerContextState_unstable(props.virtualizerContext);
const { imperativeRef, axis = 'vertical', reversed, imperativeVirtualizerRef, enablePagination = false, bufferItems: _bufferItems, bufferSize: _bufferSize } = props;
let sizeTrackingArray = React.useRef(new Array(props.numItems).fill(props.itemSize));
// This lets us trigger updates when a size change occurs.
const [sizeUpdateCount, setSizeUpdateCount] = React.useState(0);
const getChildSizeAuto = React.useCallback((index)=>{
if (sizeTrackingArray.current.length <= index || sizeTrackingArray.current[index] <= 0) {
// Default size for initial state or untracked
return props.itemSize;
}
/* Required to be defined prior to our measure function
* we use a sizing array ref that we will update post-render
*/ return sizeTrackingArray.current[index];
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[
sizeTrackingArray,
props.itemSize,
sizeUpdateCount
]);
var _props_axis, _props_getItemSize;
const { virtualizerLength, bufferItems, bufferSize, scrollRef, containerSizeRef, updateScrollPosition } = useDynamicVirtualizerMeasure({
defaultItemSize: props.itemSize,
direction: (_props_axis = props.axis) !== null && _props_axis !== void 0 ? _props_axis : 'vertical',
getItemSize: (_props_getItemSize = props.getItemSize) !== null && _props_getItemSize !== void 0 ? _props_getItemSize : getChildSizeAuto,
virtualizerContext: contextState,
numItems: props.numItems,
bufferItems: _bufferItems,
bufferSize: _bufferSize
});
const _imperativeVirtualizerRef = useMergedRefs(React.useRef(null), imperativeVirtualizerRef);
var _contextState_contextIndex;
const paginationRef = useDynamicVirtualizerPagination({
axis,
progressiveItemSizes: (_imperativeVirtualizerRef_current = _imperativeVirtualizerRef.current) === null || _imperativeVirtualizerRef_current === void 0 ? void 0 : _imperativeVirtualizerRef_current.progressiveSizes,
virtualizerLength,
currentIndex: (_contextState_contextIndex = contextState === null || contextState === void 0 ? void 0 : contextState.contextIndex) !== null && _contextState_contextIndex !== void 0 ? _contextState_contextIndex : 0
}, enablePagination);
// Store the virtualizer length as a ref for imperative ref access
const virtualizerLengthRef = React.useRef(virtualizerLength);
if (virtualizerLengthRef.current !== virtualizerLength) {
virtualizerLengthRef.current = virtualizerLength;
}
const scrollViewRef = useMergedRefs(props.scrollViewRef, scrollRef, paginationRef);
const scrollCallbackRef = React.useRef(null);
React.useImperativeHandle(imperativeRef, ()=>{
var _imperativeVirtualizerRef_current;
return {
scrollTo (index, behavior = 'auto', callback) {
scrollCallbackRef.current = callback !== null && callback !== void 0 ? callback : null;
if (_imperativeVirtualizerRef.current) {
var _imperativeVirtualizerRef_current;
const progressiveSizes = _imperativeVirtualizerRef.current.progressiveSizes.current;
const totalSize = progressiveSizes && (progressiveSizes === null || progressiveSizes === void 0 ? void 0 : progressiveSizes.length) > 0 ? progressiveSizes[Math.max(progressiveSizes.length - 1, 0)] : 0;
_imperativeVirtualizerRef.current.setFlaggedIndex(index);
scrollToItemDynamic({
index,
itemSizes: (_imperativeVirtualizerRef_current = _imperativeVirtualizerRef.current) === null || _imperativeVirtualizerRef_current === void 0 ? void 0 : _imperativeVirtualizerRef_current.nodeSizes,
totalSize,
scrollViewRef: scrollViewRef,
axis,
reversed,
behavior
});
}
},
currentIndex: (_imperativeVirtualizerRef_current = _imperativeVirtualizerRef.current) === null || _imperativeVirtualizerRef_current === void 0 ? void 0 : _imperativeVirtualizerRef_current.currentIndex,
virtualizerLength: virtualizerLengthRef
};
}, [
axis,
scrollViewRef,
reversed,
_imperativeVirtualizerRef
]);
const handleRenderedIndex = (index)=>{
if (scrollCallbackRef.current) {
scrollCallbackRef.current(index);
}
};
var _props_getItemSize1;
const virtualizerState = useVirtualizer_unstable({
...props,
getItemSize: (_props_getItemSize1 = props.getItemSize) !== null && _props_getItemSize1 !== void 0 ? _props_getItemSize1 : getChildSizeAuto,
virtualizerLength,
bufferItems,
bufferSize,
virtualizerContext: contextState,
imperativeVirtualizerRef: _imperativeVirtualizerRef,
onRenderedFlaggedIndex: handleRenderedIndex,
containerSizeRef,
scrollViewRef,
updateScrollPosition
});
const measureObject = useMeasureList(virtualizerState.virtualizerStartIndex, virtualizerLength, props.numItems, props.itemSize);
if (enablePagination && measureObject.sizeUpdateCount !== sizeUpdateCount) {
/* This enables us to let callback know that the sizes have been updated
triggers a re-render but is only required on pagination (else index change handles) */ setSizeUpdateCount(measureObject.sizeUpdateCount);
}
if (axis === 'horizontal') {
sizeTrackingArray = measureObject.widthArray;
} else {
sizeTrackingArray = measureObject.heightArray;
}
if (!props.getItemSize) {
// Auto-measuring is required
React.Children.map(virtualizerState.virtualizedChildren, (child, index)=>{
if (/*#__PURE__*/ React.isValidElement(child)) {
virtualizerState.virtualizedChildren[index] = /*#__PURE__*/ React.createElement(child.type, {
...child.props,
key: child.key,
ref: (element)=>{
if (child.hasOwnProperty('ref')) {
// We must access this from the child directly, not props (forward ref).
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const localRef = child === null || child === void 0 ? void 0 : child.ref;
if (typeof localRef === 'function') {
localRef(element);
} else if (localRef) {
localRef.current = element;
}
}
// Call the auto-measure ref attachment.
measureObject.createIndexedRef(index)(element);
}
});
}
});
}
return {
...virtualizerState,
components: {
...virtualizerState.components,
container: 'div'
},
container: slot.always(props.container, {
defaultProps: {
ref: scrollViewRef
},
elementType: 'div'
})
};
}