UNPKG

17.2 kBTypeScriptView Raw
1import { Validator, ReactNode, Requireable, PureComponent, Component } from 'react';
2import { CellMeasurerCache } from './CellMeasurer';
3import { Index, Alignment, ScrollEventData, IndexRange, OverscanIndexRange } from '../../index';
4import { Grid, GridCoreProps } from './Grid';
5
6export type SortParams = {
7 defaultSortDirection: SortDirectionType;
8 event: MouseEvent;
9 sortBy: string;
10};
11
12export type SortDirectionMap = { [key: string]: SortDirectionType };
13
14export type MultiSortOptions = {
15 defaultSortBy?: string[] | undefined;
16 defaultSortDirection?: SortDirectionMap | undefined;
17};
18
19export type MultiSortReturn = {
20 /**
21 * Sort property to be passed to the `Table` component.
22 * This function updates `sortBy` and `sortDirection` values.
23 */
24 sort: (params: SortParams) => void;
25
26 /**
27 * Specifies the fields currently responsible for sorting data,
28 * In order of importance.
29 */
30 sortBy: string[];
31
32 /**
33 * Specifies the direction a specific field is being sorted in.
34 */
35 sortDirection: SortDirectionMap;
36};
37
38export function createMultiSort(
39 sortCallback: (params: { sortBy: string; sortDirection: SortDirectionType }) => void,
40 options?: MultiSortOptions
41): MultiSortReturn;
42
43export type TableCellDataGetterParams = {
44 columnData?: any;
45 dataKey: string;
46 rowData: any;
47};
48export type TableCellProps = {
49 cellData?: any;
50 columnData?: any;
51 columnIndex: number;
52 dataKey: string;
53 isScrolling: boolean;
54 parent?: any;
55 rowData: any;
56 rowIndex: number;
57};
58export type TableHeaderProps = {
59 columnData?: any;
60 dataKey: string;
61 disableSort?: boolean | undefined;
62 label?: ReactNode | undefined;
63 sortBy?: string | undefined;
64 sortDirection?: SortDirectionType | undefined;
65};
66export type TableHeaderRowProps = {
67 className: string;
68 columns: React.ReactNode[];
69 style: React.CSSProperties;
70 scrollbarWidth: number;
71 height: number;
72 width: number;
73};
74export type TableRowProps = {
75 className: string;
76 columns: any[];
77 index: number;
78 isScrolling: boolean;
79 key: string;
80 onRowClick?: ((params: RowMouseEventHandlerParams) => void) | undefined;
81 onRowDoubleClick?: ((params: RowMouseEventHandlerParams) => void) | undefined;
82 onRowMouseOver?: ((params: RowMouseEventHandlerParams) => void) | undefined;
83 onRowMouseOut?: ((params: RowMouseEventHandlerParams) => void) | undefined;
84 onRowRightClick?: ((params: RowMouseEventHandlerParams) => void) | undefined;
85 rowData: any;
86 style: any;
87};
88
89export type TableCellDataGetter = (params: TableCellDataGetterParams) => any;
90export type TableCellRenderer = (props: TableCellProps) => React.ReactNode;
91export type TableHeaderRenderer = (props: TableHeaderProps) => React.ReactNode;
92export type TableHeaderRowRenderer = (props: TableHeaderRowProps) => React.ReactNode;
93export type TableRowRenderer = (props: TableRowProps) => React.ReactNode;
94
95// https://github.com/bvaughn/react-virtualized/blob/master/docs/Column.md
96export type ColumnProps = {
97 /** Optional aria-label value to set on the column header */
98 'aria-label'?: string | undefined;
99 /**
100 * Callback responsible for returning a cell's data, given its :dataKey
101 * ({ columnData: any, dataKey: string, rowData: any }): any
102 */
103 cellDataGetter?: TableCellDataGetter | undefined;
104 /**
105 * Callback responsible for rendering a cell's contents.
106 * ({ cellData: any, columnData: any, dataKey: string, rowData: any, rowIndex: number }): node
107 */
108 cellRenderer?: TableCellRenderer | undefined;
109 /** Optional CSS class to apply to cell */
110 className?: string | undefined;
111 /** Optional additional data passed to this column's :cellDataGetter */
112 columnData?: any;
113 /** Uniquely identifies the row-data attribute correspnding to this cell */
114 dataKey: any;
115 /** Default sort order when clicked for the first time. Valid options include "ASC" and "DESC". Defaults to "ASC" */
116 defaultSortDirection?: SortDirectionType | undefined;
117 /** If sort is enabled for the table at large, disable it for this column */
118 disableSort?: boolean | undefined;
119 /** Flex grow style; defaults to 0 */
120 flexGrow?: number | undefined;
121 /** Flex shrink style; defaults to 1 */
122 flexShrink?: number | undefined;
123 /** Optional CSS class to apply to this column's header */
124 headerClassName?: string | undefined;
125 /**
126 * Optional callback responsible for rendering a column header contents.
127 * ({ columnData: object, dataKey: string, disableSort: boolean, label: string, sortBy: string, sortDirection: string }): PropTypes.node
128 */
129 headerRenderer?: TableHeaderRenderer | undefined;
130 /** Optional inline style to apply to this column's header */
131 headerStyle?: React.CSSProperties | undefined;
132 /** Optional id to set on the column header; used for aria-describedby */
133 id?: string | undefined;
134 /** Header label for this column */
135 label?: ReactNode | undefined;
136 /** Maximum width of column; this property will only be used if :flexGrow is > 0. */
137 maxWidth?: number | undefined;
138 /** Minimum width of column. */
139 minWidth?: number | undefined;
140 /** Optional inline style to apply to cell */
141 style?: React.CSSProperties | undefined;
142 /** Flex basis (width) for this column; This value can grow or shrink based on :flexGrow and :flexShrink properties. */
143 width: number;
144};
145export class Column extends Component<ColumnProps> {
146 static propTypes: {
147 'aria-label': Requireable<string>;
148 cellDataGetter: Requireable<TableCellDataGetter>;
149 cellRenderer: Requireable<TableCellRenderer>;
150 className: Requireable<string>;
151 columnData: Requireable<object>;
152 dataKey: Validator<string>;
153 disableSort: Requireable<boolean>;
154 flexGrow: Requireable<number>;
155 flexShrink: Requireable<number>;
156 headerClassName: Requireable<string>;
157 headerRenderer: Validator<TableHeaderRowRenderer>;
158 label: Requireable<string>;
159 maxWidth: Requireable<number>;
160 minWidth: Requireable<number>;
161 style: Requireable<React.CSSProperties>;
162 width: Validator<number>;
163 id: Requireable<string>;
164 };
165
166 static defaultProps: {
167 cellDataGetter: TableCellDataGetter;
168 cellRenderer: TableCellRenderer;
169 flexGrow: 0;
170 flexShrink: 1;
171 headerRenderer: TableHeaderRenderer;
172 style: {};
173 };
174}
175
176export type RowMouseEventHandlerParams = {
177 rowData: any;
178 index: number;
179 event: React.MouseEvent<any>;
180};
181
182export type HeaderMouseEventHandlerParams = {
183 dataKey: string;
184 columnData: any;
185 event: React.MouseEvent<any>;
186};
187
188// ref: https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md
189export type TableProps = GridCoreProps & {
190 'aria-label'?: string | undefined;
191 deferredMeasurementCache?: CellMeasurerCache | undefined;
192 /**
193 * Removes fixed height from the scrollingContainer so that the total height
194 * of rows can stretch the window. Intended for use with WindowScroller
195 */
196 autoHeight?: boolean | undefined;
197 /** One or more Columns describing the data displayed in this row */
198 children?: React.ReactNode | undefined;
199 /** Optional CSS class name */
200 className?: string | undefined;
201 /** Disable rendering the header at all */
202 disableHeader?: boolean | undefined;
203 /**
204 * Used to estimate the total height of a Table before all of its rows have actually been measured.
205 * The estimated total height is adjusted as rows are rendered.
206 */
207 estimatedRowSize?: number | undefined;
208 /** Optional custom CSS class name to attach to inner Grid element. */
209 gridClassName?: string | undefined;
210 /** Optional inline style to attach to inner Grid element. */
211 gridStyle?: any;
212 /** Optional CSS class to apply to all column headers */
213 headerClassName?: string | undefined;
214 /** Fixed height of header row */
215 headerHeight: number;
216 /**
217 * Responsible for rendering a table row given an array of columns:
218 * Should implement the following interface: ({
219 * className: string,
220 * columns: any[],
221 * style: any
222 * }): PropTypes.node
223 */
224 headerRowRenderer?: TableHeaderRowRenderer | undefined;
225 /** Optional custom inline style to attach to table header columns. */
226 headerStyle?: any;
227 /** Fixed/available height for out DOM element */
228 height?: number | undefined;
229 /** Optional id */
230 id?: string | undefined;
231 /** Optional renderer to be used in place of table body rows when rowCount is 0 */
232 noRowsRenderer?: (() => JSX.Element | null) | undefined;
233 /**
234 * Optional callback when a column's header is clicked.
235 * ({ columnData: any, dataKey: string }): void
236 */
237 onHeaderClick?: ((params: HeaderMouseEventHandlerParams) => void) | undefined;
238 /**
239 * Callback invoked when a user clicks on a table row.
240 * ({ index: number }): void
241 */
242 onRowClick?: ((info: RowMouseEventHandlerParams) => void) | undefined;
243 /**
244 * Callback invoked when a user double-clicks on a table row.
245 * ({ index: number }): void
246 */
247 onRowDoubleClick?: ((info: RowMouseEventHandlerParams) => void) | undefined;
248 /**
249 * Callback invoked when the mouse leaves a table row.
250 * ({ index: number }): void
251 */
252 onRowMouseOut?: ((info: RowMouseEventHandlerParams) => void) | undefined;
253 /**
254 * Callback invoked when a user moves the mouse over a table row.
255 * ({ index: number }): void
256 */
257 onRowMouseOver?: ((info: RowMouseEventHandlerParams) => void) | undefined;
258 /**
259 * Callback invoked with information about the slice of rows that were just rendered.
260 * ({ startIndex, stopIndex }): void
261 */
262 onRowsRendered?: ((info: IndexRange & OverscanIndexRange) => void) | undefined;
263 /**
264 * Callback invoked whenever the scroll offset changes within the inner scrollable region.
265 * This callback can be used to sync scrolling between lists, tables, or grids.
266 * ({ clientHeight, scrollHeight, scrollTop }): void
267 */
268 onScroll?: ((info: ScrollEventData) => void) | undefined;
269 /**
270 * Number of rows to render above/below the visible bounds of the list.
271 * These rows can help for smoother scrolling on touch devices.
272 */
273 overscanRowCount?: number | undefined;
274 /**
275 * Optional CSS class to apply to all table rows (including the header row).
276 * This property can be a CSS class name (string) or a function that returns a class name.
277 * If a function is provided its signature should be: ({ index: number }): string
278 */
279 rowClassName?: string | ((info: Index) => string) | undefined;
280 /**
281 * Callback responsible for returning a data row given an index.
282 * ({ index: number }): any
283 */
284 rowGetter?: ((info: Index) => any) | undefined;
285 /**
286 * Either a fixed row height (number) or a function that returns the height of a row given its index.
287 * ({ index: number }): number
288 */
289 rowHeight: number | ((info: Index) => number);
290 /** Number of rows in table. */
291 rowCount: number;
292 /**
293 * Responsible for rendering a table row given an array of columns:
294 * Should implement the following interface: ({
295 * className: string,
296 * columns: Array,
297 * index: number,
298 * isScrolling: boolean,
299 * onRowClick: ?Function,
300 * onRowDoubleClick: ?Function,
301 * onRowMouseOver: ?Function,
302 * onRowMouseOut: ?Function,
303 * rowData: any,
304 * style: any
305 * }): PropTypes.node
306 */
307 rowRenderer?: TableRowRenderer | undefined;
308 /** Optional custom inline style to attach to table rows. */
309 rowStyle?: React.CSSProperties | ((info: Index) => React.CSSProperties) | undefined;
310 /** See Grid#scrollToAlignment */
311 scrollToAlignment?: string | undefined;
312 /** Row index to ensure visible (by forcefully scrolling if necessary) */
313 scrollToIndex?: number | undefined;
314 /** Vertical offset. */
315 scrollTop?: number | undefined;
316 /**
317 * Sort function to be called if a sortable header is clicked.
318 * ({ sortBy: string, sortDirection: SortDirection }): void
319 */
320 sort?: ((info: { sortBy: string; sortDirection: SortDirectionType }) => void) | undefined;
321 /** Table data is currently sorted by this :dataKey (if it is sorted at all) */
322 sortBy?: string | undefined;
323 /** Table data is currently sorted in this direction (if it is sorted at all) */
324 sortDirection?: SortDirectionType | undefined;
325 /** Optional inline style */
326 style?: React.CSSProperties | undefined;
327 /** Tab index for focus */
328 tabIndex?: number | null | undefined;
329 /** Width of list */
330 width?: number | undefined;
331};
332
333export const defaultCellDataGetter: TableCellDataGetter;
334export const defaultCellRenderer: TableCellRenderer;
335export const defaultHeaderRenderer: () => React.ReactElement<TableHeaderProps>[];
336export const defaultHeaderRowRenderer: TableHeaderRowRenderer;
337export const defaultRowRenderer: TableRowRenderer;
338
339export type SortDirectionStatic = {
340 /**
341 * Sort items in ascending order.
342 * This means arranging from the lowest value to the highest (e.g. a-z, 0-9).
343 */
344 ASC: 'ASC';
345
346 /**
347 * Sort items in descending order.
348 * This means arranging from the highest value to the lowest (e.g. z-a, 9-0).
349 */
350 DESC: 'DESC';
351};
352
353export const SortDirection: SortDirectionStatic;
354
355export type SortDirectionType = 'ASC' | 'DESC';
356
357export const SortIndicator: React.StatelessComponent<{
358 sortDirection?: SortDirectionType | undefined;
359}>;
360
361/**
362 * Table component with fixed headers and virtualized rows for improved performance with large data sets.
363 * This component expects explicit width, height, and padding parameters.
364 */
365export class Table extends PureComponent<TableProps> {
366 static propTypes: {
367 'aria-label': Requireable<string>;
368 autoHeight: Requireable<boolean>;
369 children: Validator<Column>;
370 className: Requireable<string>;
371 disableHeader: Requireable<boolean>;
372 estimatedRowSize: Validator<number>;
373 gridClassName: Requireable<string>;
374 gridStyle: Requireable<React.CSSProperties>;
375 headerClassName: Requireable<string>;
376 headerHeight: Validator<number>;
377 headerRowRenderer: Requireable<TableHeaderRowRenderer>;
378 headerStyle: Requireable<React.CSSProperties>;
379 height: Validator<number>;
380 id: Requireable<string>;
381 noRowsRenderer: Requireable<() => JSX.Element>;
382 onHeaderClick: Requireable<(params: HeaderMouseEventHandlerParams) => void>;
383 onRowClick: Requireable<(params: RowMouseEventHandlerParams) => void>;
384 onRowDoubleClick: Requireable<(params: RowMouseEventHandlerParams) => void>;
385 onRowMouseOut: Requireable<(params: RowMouseEventHandlerParams) => void>;
386 onRowMouseOver: Requireable<(params: RowMouseEventHandlerParams) => void>;
387 onRowsRendered: Requireable<(params: IndexRange & OverscanIndexRange) => void>;
388 onScroll: Requireable<(params: ScrollEventData) => void>;
389 overscanRowCount: Validator<number>;
390 rowClassName: Requireable<string | ((params: Index) => string)>;
391 rowGetter: Validator<(params: Index) => any>;
392 rowHeight: Validator<number | ((params: Index) => number)>;
393 rowCount: Validator<number>;
394 rowRenderer: Requireable<(props: TableRowProps) => React.ReactNode>;
395 rowStyle: Validator<React.CSSProperties | ((params: Index) => React.CSSProperties)>;
396 scrollToAlignment: Validator<Alignment>;
397 scrollToIndex: Validator<number>;
398 scrollTop: Requireable<number>;
399 sort: Requireable<(params: { sortBy: string; sortDirection: SortDirectionType }) => void>;
400 sortBy: Requireable<string>;
401 sortDirection: Validator<SortDirectionType>;
402 style: Requireable<React.CSSProperties>;
403 tabIndex: Requireable<number>;
404 width: Validator<number>;
405 };
406
407 static defaultProps: {
408 disableHeader: false;
409 estimatedRowSize: 30;
410 headerHeight: 0;
411 headerStyle: {};
412 noRowsRenderer: () => null;
413 onRowsRendered: () => null;
414 onScroll: () => null;
415 overscanRowCount: 10;
416 rowRenderer: TableRowRenderer;
417 headerRowRenderer: TableHeaderRowRenderer;
418 rowStyle: {};
419 scrollToAlignment: 'auto';
420 scrollToIndex: -1;
421 style: {};
422 };
423
424 Grid: Grid;
425
426 forceUpdateGrid(): void;
427
428 getScrollbarWidth(): number;
429
430 /** See Grid#getOffsetForCell */
431 getOffsetForRow(params: { alignment?: Alignment | undefined; index?: number | undefined }): number;
432
433 /** See Grid#scrollToPosition */
434 scrollToPosition(scrollTop?: number): void;
435
436 /** See Grid#measureAllCells */
437 measureAllRows(): void;
438
439 /** See Grid#recomputeGridSize */
440 recomputeRowHeights(index?: number): void;
441
442 /** See Grid#scrollToCell */
443 scrollToRow(index?: number): void;
444}
445
446export default Table;