office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
145 lines (144 loc) • 6.92 kB
TypeScript
/// <reference types="react" />
import * as React from 'react';
import { BaseComponent } from '../../Utilities';
import { IList, IListProps, IPage, ScrollToMode } from './List.types';
export interface IListState {
pages?: IPage[];
/** The last versionstamp for */
measureVersion?: number;
isScrolling?: boolean;
}
/**
* The List renders virtualized pages of items. Each page's item count is determined by the getItemCountForPage callback if
* provided by the caller, or 10 as default. Each page's height is determined by the getPageHeight callback if provided by
* the caller, or by cached measurements if available, or by a running average, or a default fallback.
*
* The algorithm for rendering pages works like this:
*
* 1. Predict visible pages based on "current measure data" (page heights, surface position, visible window)
* 2. If changes are necessary, apply changes (add/remove pages)
* 3. For pages that are added, measure the page heights if we need to using getBoundingClientRect
* 4. If measurements don't match predictions, update measure data and goto step 1 asynchronously
*
* Measuring too frequently can pull performance down significantly. To compensate, we cache measured values so that
* we can avoid re-measuring during operations that should not alter heights, like scrolling.
*
* To optimize glass rendering performance, onShouldVirtualize can be set. When onShouldVirtualize return false,
* List will run in fast mode (not virtualized) to render all items without any measurements to improve page load time. And we
* start doing measurements and rendering in virtualized mode when items grows larger than this threshold.
*
* However, certain operations can make measure data stale. For example, resizing the list, or passing in new props,
* or forcing an update change cause pages to shrink/grow. When these operations occur, we increment a measureVersion
* number, which we associate with cached measurements and use to determine if a remeasure should occur.
*/
export declare class List extends BaseComponent<IListProps, IListState> implements IList {
static defaultProps: {
startIndex: number;
onRenderCell: (item: any, index: number, containsFocus: boolean) => JSX.Element;
renderedWindowsAhead: number;
renderedWindowsBehind: number;
};
refs: {
[key: string]: React.ReactInstance;
};
private _root;
private _surface;
private _estimatedPageHeight;
private _totalEstimates;
private _cachedPageHeights;
private _focusedIndex;
private _scrollElement;
private _hasCompletedFirstRender;
private _surfaceRect;
private _requiredRect;
private _allowedRect;
private _materializedRect;
private _requiredWindowsAhead;
private _requiredWindowsBehind;
private _measureVersion;
private _scrollHeight;
private _scrollTop;
private _pageCache;
constructor(props: IListProps);
/**
* Scroll to the given index. By default will bring the page the specified item is on into the view. If a callback
* to measure the height of an individual item is specified, will only scroll to bring the specific item into view.
*
* Note: with items of variable height and no passed in `getPageHeight` method, the list might jump after scrolling
* when windows before/ahead are being rendered, and the estimated height is replaced using actual elements.
*
* @param index Index of item to scroll to
* @param measureItem Optional callback to measure the height of an individual item
* @param scrollToMode Optional defines where in the window the item should be positioned to when scrolling
*/
scrollToIndex(index: number, measureItem?: (itemIndex: number) => number, scrollToMode?: ScrollToMode): void;
getStartItemIndexInView(measureItem?: (itemIndex: number) => number): number;
componentDidMount(): void;
componentWillReceiveProps(newProps: IListProps): void;
shouldComponentUpdate(newProps: IListProps, newState: IListState): boolean;
forceUpdate(): void;
render(): JSX.Element;
private _shouldVirtualize(props?);
/**
* when props.items change or forceUpdate called, throw away cached pages
*/
private _invalidatePageCache();
private _renderPage(page);
/** Generate the style object for the page. */
private _getPageStyle(page);
private _onRenderPage;
/** Track the last item index focused so that we ensure we keep it rendered. */
private _onFocus(ev);
/**
* Called synchronously to reset the required render range to 0 on scrolling. After async scroll has executed,
* we will call onAsyncIdle which will reset it back to it's correct value.
*/
private _onScroll();
private _resetRequiredWindows();
/**
* Debounced method to asynchronously update the visible region on a scroll event.
*/
private _onAsyncScroll();
/**
* This is an async debounced method that will try and increment the windows we render. If we can increment
* either, we increase the amount we render and re-evaluate.
*/
private _onAsyncIdle();
/**
* Function to call when the list is done scrolling.
* This function is debounced.
*/
private _onScrollingDone();
private _onAsyncResize();
private _updatePages(props?);
/**
* Notify consumers that the rendered pages have changed
* @param oldPages The old pages
* @param newPages The new pages
* @param props The props to use
*/
private _notifyPageChanges(oldPages, newPages, props?);
private _updatePageMeasurements(pages);
/**
* Given a page, measure its dimensions, update cache.
* @returns True if the height has changed.
*/
private _measurePage(page);
/** Called when a page has been added to the DOM. */
private _onPageAdded(page);
/** Called when a page has been removed from the DOM. */
private _onPageRemoved(page);
/** Build up the pages that should be rendered. */
private _buildPages(props);
private _getPageSpecification(itemIndex, visibleRect);
/**
* Get the pixel height of a give page. Will use the props getPageHeight first, and if not provided, fallback to
* cached height, or estimated page height, or default page height.
*/
private _getPageHeight(itemIndex, itemsPerPage, visibleRect);
private _getItemCountForPage(itemIndex, visibileRect);
private _createPage(pageKey, items, startIndex?, count?, style?, data?, isSpacer?);
private _getRenderCount(props?);
/** Calculate the visible rect within the list where top: 0 and left: 0 is the top/left of the list. */
private _updateRenderRects(props?, forceUpdate?);
}