UNPKG

5.03 kBTypeScriptView Raw
1import { PureComponent, Validator, Requireable } from 'react';
2import { CellMeasurerCacheInterface, KeyMapper, MeasuredCellParent } from './CellMeasurer';
3import { GridCellRenderer } from './Grid';
4import { IndexRange } from '../../index';
5/**
6 * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress.
7 * This improves performance and makes scrolling smoother.
8 */
9export const DEFAULT_SCROLLING_RESET_TIME_INTERVAL = 150;
10
11export type OnCellsRenderedCallback = (params: IndexRange) => void;
12
13export type OnScrollCallback = (params: { clientHeight: number; scrollHeight: number; scrollTop: number }) => void;
14
15export type MasonryCellProps = {
16 index: number;
17 isScrolling: boolean;
18 key: React.Key;
19 parent: MeasuredCellParent;
20 style?: React.CSSProperties;
21};
22
23export type CellRenderer = (props: MasonryCellProps) => React.ReactNode;
24
25export type MasonryProps = {
26 autoHeight: boolean;
27 cellCount: number;
28 cellMeasurerCache: CellMeasurerCacheInterface;
29 cellPositioner: Positioner;
30 cellRenderer: CellRenderer;
31 className?: string;
32 height: number;
33 id?: string;
34 keyMapper?: KeyMapper;
35 onCellsRendered?: OnCellsRenderedCallback;
36 onScroll?: OnScrollCallback;
37 overscanByPixels?: number;
38 role?: string;
39 scrollingResetTimeInterval?: number;
40 style?: React.CSSProperties;
41 tabIndex?: number | null;
42 width: number;
43 /**
44 * PLEASE NOTE
45 * The [key: string]: any; line is here on purpose
46 * This is due to the need of force re-render of PureComponent
47 * Check the following link if you want to know more
48 * https://github.com/bvaughn/react-virtualized#pass-thru-props
49 */
50 [key: string]: any;
51};
52
53export type MasonryState = {
54 isScrolling: boolean;
55 scrollTop: number;
56};
57
58/**
59 * This component efficiently displays arbitrarily positioned cells using windowing techniques.
60 * Cell position is determined by an injected `cellPositioner` property.
61 * Windowing is vertical; this component does not support horizontal scrolling.
62 *
63 * Rendering occurs in two phases:
64 * 1) First pass uses estimated cell sizes (provided by the cache) to determine how many cells to measure in a batch.
65 * Batch size is chosen using a fast, naive layout algorithm that stacks images in order until the viewport has been filled.
66 * After measurement is complete (componentDidMount or componentDidUpdate) this component evaluates positioned cells
67 * in order to determine if another measurement pass is required (eg if actual cell sizes were less than estimated sizes).
68 * All measurements are permanently cached (keyed by `keyMapper`) for performance purposes.
69 * 2) Second pass uses the external `cellPositioner` to layout cells.
70 * At this time the positioner has access to cached size measurements for all cells.
71 * The positions it returns are cached by Masonry for fast access later.
72 * Phase one is repeated if the user scrolls beyond the current layout's bounds.
73 * If the layout is invalidated due to eg a resize, cached positions can be cleared using `recomputeCellPositions()`.
74 *
75 * Animation constraints:
76 * Simple animations are supported (eg translate/slide into place on initial reveal).
77 * More complex animations are not (eg flying from one position to another on resize).
78 *
79 * Layout constraints:
80 * This component supports multi-column layout.
81 * The height of each item may vary.
82 * The width of each item must not exceed the width of the column it is "in".
83 * The left position of all items within a column must align.
84 * (Items may not span multiple columns.)
85 */
86export class Masonry extends PureComponent<MasonryProps, MasonryState> {
87 static defaultProps: {
88 autoHeight: false;
89 keyMapper: identity;
90 onCellsRendered: noop;
91 onScroll: noop;
92 overscanByPixels: 20;
93 role: 'grid';
94 scrollingResetTimeInterval: typeof DEFAULT_SCROLLING_RESET_TIME_INTERVAL;
95 style: emptyObject;
96 tabIndex: 0;
97 };
98
99 clearCellPositions(): void;
100
101 // HACK This method signature was intended for Grid
102 invalidateCellSizeAfterRender(params: { rowIndex: number }): void;
103
104 recomputeCellPositions(): void;
105
106 static getDerivedStateFromProps(nextProps: MasonryProps, prevState: MasonryState): MasonryState | null;
107}
108
109export default Masonry;
110
111export type emptyObject = {};
112
113export type identity = <T>(value: T) => T;
114
115export type noop = () => void;
116
117export type Position = {
118 left: number;
119 top: number;
120};
121
122export type createCellPositionerParams = {
123 cellMeasurerCache: CellMeasurerCacheInterface;
124 columnCount: number;
125 columnWidth: number;
126 spacer?: number;
127};
128
129export type resetParams = {
130 columnCount: number;
131 columnWidth: number;
132 spacer?: number;
133};
134
135export type Positioner = ((index: number) => Position) & {
136 reset: (params: resetParams) => void;
137};
138
139export const createCellPositioner: (params: createCellPositionerParams) => Positioner;