/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict-local * @format */ import typeof VirtualizedList from './VirtualizedList'; import * as React from 'react'; import {useContext, useMemo} from 'react'; type Context = $ReadOnly<{ cellKey: ?string, getScrollMetrics: () => { contentLength: number, dOffset: number, dt: number, offset: number, timestamp: number, velocity: number, visibleLength: number, zoomScale: number, }, horizontal: ?boolean, getOutermostParentListRef: () => React.ElementRef, registerAsNestedChild: ({ cellKey: string, ref: React.ElementRef, }) => void, unregisterAsNestedChild: ({ ref: React.ElementRef, }) => void, }>; export const VirtualizedListContext: React.Context = React.createContext(null); if (__DEV__) { VirtualizedListContext.displayName = 'VirtualizedListContext'; } /** * Resets the context. Intended for use by portal-like components (e.g. Modal). */ export function VirtualizedListContextResetter({ children, }: { children: React.Node, }): React.Node { return ( {children} ); } /** * Sets the context with memoization. Intended to be used by `VirtualizedList`. */ export function VirtualizedListContextProvider({ children, value, }: { children: React.Node, value: Context, }): React.Node { // Avoid setting a newly created context object if the values are identical. const context = useMemo( () => ({ cellKey: null, getScrollMetrics: value.getScrollMetrics, horizontal: value.horizontal, getOutermostParentListRef: value.getOutermostParentListRef, registerAsNestedChild: value.registerAsNestedChild, unregisterAsNestedChild: value.unregisterAsNestedChild, }), [ value.getScrollMetrics, value.horizontal, value.getOutermostParentListRef, value.registerAsNestedChild, value.unregisterAsNestedChild, ], ); return ( {children} ); } /** * Sets the `cellKey`. Intended to be used by `VirtualizedList` for each cell. */ export function VirtualizedListCellContextProvider({ cellKey, children, }: { cellKey: string, children: React.Node, }): React.Node { // Avoid setting a newly created context object if the values are identical. const currContext = useContext(VirtualizedListContext); const context = useMemo( () => (currContext == null ? null : {...currContext, cellKey}), [currContext, cellKey], ); return ( {children} ); }