Skip to content

Commit

Permalink
Expose virtualize index/length for casual use (microsoft#28450)
Browse files Browse the repository at this point in the history
* Update index setting to be imperative ref accessible

* Change file

* API Changelogs

* Update index as soon as possible - doesnt depend on render to measure
  • Loading branch information
Mitch-At-Work authored Jul 13, 2023
1 parent 3d52b1b commit 2971c4f
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Feat: Add imperative ref access to both virtualizer length and current index",
"packageName": "@fluentui/react-virtualizer",
"email": "mifraser@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export interface ResizeCallbackWithRef {
// @public (undocumented)
export type ScrollToInterface = {
scrollTo: (index: number, behavior?: ScrollBehavior, callback?: (index: number) => void) => void;
virtualizerLength: RefObject<number>;
currentIndex: RefObject<number> | undefined;
};

// @public (undocumented)
Expand Down Expand Up @@ -133,6 +135,7 @@ export type VirtualizerDataRef = {
progressiveSizes: RefObject<number[]>;
nodeSizes: RefObject<number[]>;
setFlaggedIndex: (index: number | null) => void;
currentIndex: RefObject<number>;
};

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export type VirtualizerDataRef = {
progressiveSizes: RefObject<number[]>;
nodeSizes: RefObject<number[]>;
setFlaggedIndex: (index: number | null) => void;
currentIndex: RefObject<number>;
};

export type VirtualizerConfigProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta
/* The context is optional, it's useful for injecting additional index logic, or performing uniform state updates*/
const _virtualizerContext = useVirtualizerContextState_unstable(virtualizerContext);

// We use this ref as a constant source to access the virtualizer's state imperatively
const actualIndexRef = useRef<number>(_virtualizerContext.contextIndex);
if (actualIndexRef.current !== _virtualizerContext.contextIndex) {
actualIndexRef.current = _virtualizerContext.contextIndex;
}
const flaggedIndex = useRef<number | null>(null);

const actualIndex = _virtualizerContext.contextIndex;
Expand Down Expand Up @@ -113,6 +118,11 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta
// Local updates
updateChildRows(index);
updateCurrentItemSizes(index);

// Set before 'setActualIndex' call
// If it changes before render, or injected via context, re-render will update ref.
actualIndexRef.current = index;

// State setters
setActualIndex(index);
};
Expand Down Expand Up @@ -412,6 +422,7 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta
progressiveSizes: childProgressiveSizes,
nodeSizes: childSizes,
setFlaggedIndex: (index: number | null) => (flaggedIndex.current = index),
currentIndex: actualIndexRef,
};
},
[childProgressiveSizes, childSizes],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export function useVirtualizerScrollView_unstable(props: VirtualizerScrollViewPr
direction: props.axis ?? 'vertical',
});

// Store the virtualizer length as a ref for imperative ref access
const virtualizerLengthRef = React.useRef<number>(virtualizerLength);
if (virtualizerLengthRef.current !== virtualizerLength) {
virtualizerLengthRef.current = virtualizerLength;
}
const scrollViewRef = useMergedRefs(React.useRef<HTMLDivElement>(null), scrollRef) as React.RefObject<HTMLDivElement>;
const imperativeVirtualizerRef = React.useRef<VirtualizerDataRef | null>(null);
const scrollCallbackRef = React.useRef<null | ((index: number) => void)>(null);
Expand All @@ -35,6 +40,8 @@ export function useVirtualizerScrollView_unstable(props: VirtualizerScrollViewPr
behavior,
});
},
currentIndex: imperativeVirtualizerRef.current?.currentIndex,
virtualizerLength: virtualizerLengthRef,
};
},
[axis, scrollViewRef, itemSize, numItems, reversed],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export function useVirtualizerScrollViewDynamic_unstable(
numItems: props.numItems,
});

// Store the virtualizer length as a ref for imperative ref access
const virtualizerLengthRef = React.useRef<number>(virtualizerLength);
if (virtualizerLengthRef.current !== virtualizerLength) {
virtualizerLengthRef.current = virtualizerLength;
}
const scrollViewRef = useMergedRefs(React.useRef<HTMLDivElement>(null), scrollRef) as React.RefObject<HTMLDivElement>;
const scrollCallbackRef = React.useRef<null | ((index: number) => void)>(null);

Expand Down Expand Up @@ -54,6 +59,8 @@ export function useVirtualizerScrollViewDynamic_unstable(
});
}
},
currentIndex: _imperativeVirtualizerRef.current?.currentIndex,
virtualizerLength: virtualizerLengthRef,
};
},
[axis, scrollViewRef, reversed, _imperativeVirtualizerRef],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ export type ScrollToItemDynamicParams = {

export type ScrollToInterface = {
scrollTo: (index: number, behavior?: ScrollBehavior, callback?: (index: number) => void) => void;
virtualizerLength: RefObject<number>;
currentIndex: RefObject<number> | undefined;
};

0 comments on commit 2971c4f

Please sign in to comment.