table
Summary: _typescript_ Reviewed By: priteshrnandgaonkar Differential Revision: D16807180 fbshipit-source-id: dcba794351eee69c0574dc224cf7bd2732bea447
This commit is contained in:
committed by
Facebook Github Bot
parent
62a204bdbe
commit
4c4169063d
@@ -58,6 +58,8 @@
|
|||||||
"@types/react": "^16.8.24",
|
"@types/react": "^16.8.24",
|
||||||
"@types/react-dom": "^16.8.5",
|
"@types/react-dom": "^16.8.5",
|
||||||
"@types/react-redux": "^7.1.1",
|
"@types/react-redux": "^7.1.1",
|
||||||
|
"@types/react-virtualized-auto-sizer": "^1.0.0",
|
||||||
|
"@types/react-window": "^1.8.1",
|
||||||
"@types/redux-persist": "^4.3.1",
|
"@types/redux-persist": "^4.3.1",
|
||||||
"@types/rsocket-core": "^0.0.2",
|
"@types/rsocket-core": "^0.0.2",
|
||||||
"@types/uuid": "^3.4.5",
|
"@types/uuid": "^3.4.5",
|
||||||
|
|||||||
16
src/index.js
16
src/index.js
@@ -73,17 +73,17 @@ export {
|
|||||||
TableColumnOrder,
|
TableColumnOrder,
|
||||||
TableColumnOrderVal,
|
TableColumnOrderVal,
|
||||||
TableColumnSizes,
|
TableColumnSizes,
|
||||||
} from './ui/components/table/types.js';
|
} from './ui/components/table/types.tsx';
|
||||||
export {default as ManagedTable} from './ui/components/table/ManagedTable.js';
|
export {default as ManagedTable} from './ui/components/table/ManagedTable.tsx';
|
||||||
export {ManagedTableProps} from './ui/components/table/ManagedTable.js';
|
export {ManagedTableProps} from './ui/components/table/ManagedTable.tsx';
|
||||||
export {
|
export {
|
||||||
default as ManagedTable_immutable,
|
default as ManagedTable_immutable,
|
||||||
} from './ui/components/table/ManagedTable_immutable.js';
|
|
||||||
export {
|
|
||||||
ManagedTableProps_immutable,
|
ManagedTableProps_immutable,
|
||||||
} from './ui/components/table/ManagedTable_immutable.js';
|
} from './ui/components/table/ManagedTable_immutable.tsx';
|
||||||
export {Value} from './ui/components/table/TypeBasedValueRenderer.js';
|
export {
|
||||||
export {renderValue} from './ui/components/table/TypeBasedValueRenderer.js';
|
Value,
|
||||||
|
renderValue,
|
||||||
|
} from './ui/components/table/TypeBasedValueRenderer.tsx';
|
||||||
export {
|
export {
|
||||||
DataValueExtractor,
|
DataValueExtractor,
|
||||||
DataInspectorExpanded,
|
DataInspectorExpanded,
|
||||||
|
|||||||
@@ -17,12 +17,14 @@ import Select from '../ui/components/Select';
|
|||||||
import ErrorBlock from '../ui/components/ErrorBlock';
|
import ErrorBlock from '../ui/components/ErrorBlock';
|
||||||
import FlexColumn from '../ui/components/FlexColumn';
|
import FlexColumn from '../ui/components/FlexColumn';
|
||||||
import SearchableTable from '../ui/components/searchable/SearchableTable';
|
import SearchableTable from '../ui/components/searchable/SearchableTable';
|
||||||
import TableHighlightedRows from '../ui/components/table/types';
|
import {
|
||||||
import TableRows from '../ui/components/table/types';
|
TableHighlightedRows,
|
||||||
import TableColumnSizes from '../ui/components/table/types';
|
TableRows,
|
||||||
import TableColumns from '../ui/components/table/types';
|
TableColumnSizes,
|
||||||
import TableColumnOrderVal from '../ui/components/table/types';
|
TableColumns,
|
||||||
import TableBodyRow from '../ui/components/table/types';
|
TableColumnOrderVal,
|
||||||
|
TableBodyRow,
|
||||||
|
} from '../ui/components/table/types';
|
||||||
import DetailSidebar from '../chrome/DetailSidebar';
|
import DetailSidebar from '../chrome/DetailSidebar';
|
||||||
import {FlipperPlugin} from '../plugin';
|
import {FlipperPlugin} from '../plugin';
|
||||||
import textContent from '../utils/textContent';
|
import textContent from '../utils/textContent';
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {PluginClient} from '../../plugin.tsx';
|
import type {PluginClient, Value} from 'flipper';
|
||||||
import type {Value} from '../../ui/components/table/TypeBasedValueRenderer';
|
|
||||||
|
|
||||||
type ClientCall<Params, Response> = Params => Promise<Response>;
|
type ClientCall<Params, Response> = Params => Promise<Response>;
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,7 @@ import {
|
|||||||
ManagedDataInspector,
|
ManagedDataInspector,
|
||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
import {Component} from 'react';
|
import {Component} from 'react';
|
||||||
import type {
|
import type {TableBodyRow, TableRowSortOrder} from 'flipper';
|
||||||
TableBodyRow,
|
|
||||||
TableRowSortOrder,
|
|
||||||
} from '../../ui/components/table/types';
|
|
||||||
import {FlipperPlugin} from 'flipper';
|
import {FlipperPlugin} from 'flipper';
|
||||||
import {DatabaseClient} from './ClientProtocol';
|
import {DatabaseClient} from './ClientProtocol';
|
||||||
import {renderValue} from 'flipper';
|
import {renderValue} from 'flipper';
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ type Props = {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
/** The component that is used to wrap the children. Defaults to `FlexColumn`. */
|
/** The component that is used to wrap the children. Defaults to `FlexColumn`. */
|
||||||
component: React.ComponentType<any> | string;
|
component: React.ComponentType<any> | string;
|
||||||
onMouseDown: (e: React.MouseEvent) => any;
|
onMouseDown?: (e: React.MouseEvent) => any;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ type InteractiveProps = {
|
|||||||
minLeft?: number;
|
minLeft?: number;
|
||||||
width?: number | string;
|
width?: number | string;
|
||||||
height?: number | string;
|
height?: number | string;
|
||||||
minWidth: number;
|
minWidth?: number;
|
||||||
minHeight: number;
|
minHeight?: number;
|
||||||
maxWidth?: number;
|
maxWidth?: number;
|
||||||
maxHeight?: number;
|
maxHeight?: number;
|
||||||
onCanResize?: (sides: ResizingSides) => void;
|
onCanResize?: (sides: ResizingSides) => void;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import Glyph from './Glyph';
|
|||||||
import styled from 'react-emotion';
|
import styled from 'react-emotion';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {BackgroundColorProperty} from 'csstype';
|
import {BackgroundColorProperty} from 'csstype';
|
||||||
|
import {TableBodyRow} from './table/types';
|
||||||
|
|
||||||
const Padder = styled('div')(
|
const Padder = styled('div')(
|
||||||
({
|
({
|
||||||
@@ -132,8 +133,8 @@ export default class StackTrace extends Component<{
|
|||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const rows = children.map((l, i) => ({
|
const rows: TableBodyRow[] = children.map((l, i) => ({
|
||||||
key: i,
|
key: String(i),
|
||||||
columns: Object.keys(columns).reduce((acc, cv) => {
|
columns: Object.keys(columns).reduce((acc, cv) => {
|
||||||
acc[cv] = {
|
acc[cv] = {
|
||||||
align: cv === 'lineNumber' ? 'right' : 'left',
|
align: cv === 'lineNumber' ? 'right' : 'left',
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Filter} from '../filter/types';
|
import {Filter} from '../filter/types';
|
||||||
import ManagedTable, {ManagedTableProps} from '../table/ManagedTable.js';
|
import ManagedTable, {ManagedTableProps} from '../table/ManagedTable';
|
||||||
import {TableBodyRow} from '../table/types.js';
|
import {TableBodyRow} from '../table/types';
|
||||||
import Searchable, {SearchableProps} from './Searchable';
|
import Searchable, {SearchableProps} from './Searchable';
|
||||||
import React, {PureComponent} from 'react';
|
import React, {PureComponent} from 'react';
|
||||||
import textContent from '../../../utils/textContent';
|
import textContent from '../../../utils/textContent';
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Filter} from '../filter/types';
|
import {Filter} from '../filter/types';
|
||||||
import {ManagedTableProps_immutable} from '../table/ManagedTable_immutable.js';
|
import {ManagedTableProps_immutable} from '../table/ManagedTable_immutable';
|
||||||
import {TableBodyRow} from '../table/types.js';
|
import {TableBodyRow} from '../table/types';
|
||||||
import Searchable, {SearchableProps} from './Searchable';
|
import Searchable, {SearchableProps} from './Searchable';
|
||||||
import {PureComponent} from 'react';
|
import {PureComponent} from 'react';
|
||||||
import ManagedTable_immutable from '../table/ManagedTable_immutable.js';
|
import ManagedTable_immutable from '../table/ManagedTable_immutable';
|
||||||
import textContent from '../../../utils/textContent';
|
import textContent from '../../../utils/textContent';
|
||||||
import deepEqual from 'deep-equal';
|
import deepEqual from 'deep-equal';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import {
|
||||||
TableColumnOrder,
|
TableColumnOrder,
|
||||||
TableColumnSizes,
|
TableColumnSizes,
|
||||||
TableColumns,
|
TableColumns,
|
||||||
@@ -14,146 +14,143 @@ import type {
|
|||||||
TableRows,
|
TableRows,
|
||||||
TableBodyRow,
|
TableBodyRow,
|
||||||
TableOnAddFilter,
|
TableOnAddFilter,
|
||||||
} from './types.js';
|
} from './types';
|
||||||
|
import {MenuTemplate} from '../ContextMenu';
|
||||||
import type {MenuTemplate} from '../ContextMenu.tsx';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from '../../styled/index.js';
|
import styled from 'react-emotion';
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||||
import {VariableSizeList as List} from 'react-window';
|
import {VariableSizeList as List} from 'react-window';
|
||||||
import {clipboard} from 'electron';
|
import {clipboard, MenuItemConstructorOptions} from 'electron';
|
||||||
import TableHead from './TableHead.js';
|
import TableHead from './TableHead';
|
||||||
import TableRow from './TableRow.js';
|
import TableRow from './TableRow';
|
||||||
import ContextMenu from '../ContextMenu.tsx';
|
import ContextMenu from '../ContextMenu';
|
||||||
import FlexColumn from '../FlexColumn.tsx';
|
import FlexColumn from '../FlexColumn';
|
||||||
import createPaste from '../../../fb-stubs/createPaste.tsx';
|
import createPaste from '../../../fb-stubs/createPaste';
|
||||||
import debounceRender from 'react-debounce-render';
|
import debounceRender from 'react-debounce-render';
|
||||||
import debounce from 'lodash.debounce';
|
import debounce from 'lodash.debounce';
|
||||||
import {DEFAULT_ROW_HEIGHT} from './types';
|
import {DEFAULT_ROW_HEIGHT} from './types';
|
||||||
import textContent from '../../../utils/textContent.tsx';
|
import textContent from '../../../utils/textContent';
|
||||||
|
|
||||||
export type ManagedTableProps = {|
|
export type ManagedTableProps = {
|
||||||
/**
|
/**
|
||||||
* Column definitions.
|
* Column definitions.
|
||||||
*/
|
*/
|
||||||
columns: TableColumns,
|
columns: TableColumns;
|
||||||
/**
|
/**
|
||||||
* Row definitions.
|
* Row definitions.
|
||||||
*/
|
*/
|
||||||
rows: TableRows,
|
rows: TableRows;
|
||||||
/*
|
/*
|
||||||
* Globally unique key for persisting data between uses of a table such as column sizes.
|
* Globally unique key for persisting data between uses of a table such as column sizes.
|
||||||
*/
|
*/
|
||||||
tableKey?: string,
|
tableKey?: string;
|
||||||
/**
|
/**
|
||||||
* Whether the table has a border.
|
* Whether the table has a border.
|
||||||
*/
|
*/
|
||||||
floating?: boolean,
|
floating?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether a row can span over multiple lines. Otherwise lines cannot wrap and
|
* Whether a row can span over multiple lines. Otherwise lines cannot wrap and
|
||||||
* are truncated.
|
* are truncated.
|
||||||
*/
|
*/
|
||||||
multiline?: boolean,
|
multiline?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether the body is scrollable. When this is set to `true` then the table
|
* Whether the body is scrollable. When this is set to `true` then the table
|
||||||
* is not scrollable.
|
* is not scrollable.
|
||||||
*/
|
*/
|
||||||
autoHeight?: boolean,
|
autoHeight?: boolean;
|
||||||
/**
|
/**
|
||||||
* Order of columns.
|
* Order of columns.
|
||||||
*/
|
*/
|
||||||
columnOrder?: TableColumnOrder,
|
columnOrder?: TableColumnOrder;
|
||||||
/**
|
/**
|
||||||
* Initial size of the columns.
|
* Initial size of the columns.
|
||||||
*/
|
*/
|
||||||
columnSizes?: TableColumnSizes,
|
columnSizes?: TableColumnSizes;
|
||||||
/**
|
/**
|
||||||
* Value to filter rows on. Alternative to the `filter` prop.
|
* Value to filter rows on. Alternative to the `filter` prop.
|
||||||
*/
|
*/
|
||||||
filterValue?: string,
|
filterValue?: string;
|
||||||
/**
|
/**
|
||||||
* Callback to filter rows.
|
* Callback to filter rows.
|
||||||
*/
|
*/
|
||||||
filter?: (row: TableBodyRow) => boolean,
|
filter?: (row: TableBodyRow) => boolean;
|
||||||
/**
|
/**
|
||||||
* Callback when the highlighted rows change.
|
* Callback when the highlighted rows change.
|
||||||
*/
|
*/
|
||||||
onRowHighlighted?: (keys: TableHighlightedRows) => void,
|
onRowHighlighted?: (keys: TableHighlightedRows) => void;
|
||||||
/**
|
/**
|
||||||
* Whether rows can be highlighted or not.
|
* Whether rows can be highlighted or not.
|
||||||
*/
|
*/
|
||||||
highlightableRows?: boolean,
|
highlightableRows?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether multiple rows can be highlighted or not.
|
* Whether multiple rows can be highlighted or not.
|
||||||
*/
|
*/
|
||||||
multiHighlight?: boolean,
|
multiHighlight?: boolean;
|
||||||
/**
|
/**
|
||||||
* Height of each row.
|
* Height of each row.
|
||||||
*/
|
*/
|
||||||
rowLineHeight?: number,
|
rowLineHeight?: number;
|
||||||
/**
|
/**
|
||||||
* This makes it so the scroll position sticks to the bottom of the window.
|
* This makes it so the scroll position sticks to the bottom of the window.
|
||||||
* Useful for streaming data like requests, logs etc.
|
* Useful for streaming data like requests, logs etc.
|
||||||
*/
|
*/
|
||||||
stickyBottom?: boolean,
|
stickyBottom?: boolean;
|
||||||
/**
|
/**
|
||||||
* Used by SearchableTable to add filters for rows.
|
* Used by SearchableTable to add filters for rows.
|
||||||
*/
|
*/
|
||||||
onAddFilter?: TableOnAddFilter,
|
onAddFilter?: TableOnAddFilter;
|
||||||
/**
|
/**
|
||||||
* Enable or disable zebra striping.
|
* Enable or disable zebra striping.
|
||||||
*/
|
*/
|
||||||
zebra?: boolean,
|
zebra?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether to hide the column names at the top of the table.
|
* Whether to hide the column names at the top of the table.
|
||||||
*/
|
*/
|
||||||
hideHeader?: boolean,
|
hideHeader?: boolean;
|
||||||
/**
|
/**
|
||||||
* Rows that are highlighted initially.
|
* Rows that are highlighted initially.
|
||||||
*/
|
*/
|
||||||
highlightedRows?: Set<string>,
|
highlightedRows?: Set<string>;
|
||||||
/**
|
/**
|
||||||
* Allows to create context menu items for rows.
|
* Allows to create context menu items for rows.
|
||||||
*/
|
*/
|
||||||
buildContextMenuItems?: () => MenuTemplate,
|
buildContextMenuItems?: () => MenuTemplate;
|
||||||
initialSortOrder?: ?TableRowSortOrder,
|
|
||||||
/**
|
/**
|
||||||
* Callback when sorting changes.
|
* Callback when sorting changes.
|
||||||
*/
|
*/
|
||||||
onSort?: (order: TableRowSortOrder) => void,
|
onSort?: (order: TableRowSortOrder) => void;
|
||||||
/**
|
/**
|
||||||
* Initial sort order of the table.
|
* Initial sort order of the table.
|
||||||
*/
|
*/
|
||||||
initialSortOrder?: ?TableRowSortOrder,
|
initialSortOrder?: TableRowSortOrder;
|
||||||
/**
|
/**
|
||||||
* Table scroll horizontally, if needed
|
* Table scroll horizontally, if needed
|
||||||
*/
|
*/
|
||||||
horizontallyScrollable?: boolean,
|
horizontallyScrollable?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether to allow navigation via arrow keys. Default: true
|
* Whether to allow navigation via arrow keys. Default: true
|
||||||
*/
|
*/
|
||||||
enableKeyboardNavigation?: boolean,
|
enableKeyboardNavigation?: boolean;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type ManagedTableState = {|
|
type ManagedTableState = {
|
||||||
highlightedRows: Set<string>,
|
highlightedRows: Set<string>;
|
||||||
sortOrder: ?TableRowSortOrder,
|
sortOrder?: TableRowSortOrder;
|
||||||
columnOrder: TableColumnOrder,
|
columnOrder: TableColumnOrder;
|
||||||
columnSizes: TableColumnSizes,
|
columnSizes: TableColumnSizes;
|
||||||
shouldScrollToBottom: boolean,
|
shouldScrollToBottom: boolean;
|
||||||
|};
|
};
|
||||||
|
|
||||||
const Container = styled(FlexColumn)(props => ({
|
const Container = styled(FlexColumn)((props: {canOverflow?: boolean}) => ({
|
||||||
overflow: props.canOverflow ? 'scroll' : 'visible',
|
overflow: props.canOverflow ? 'scroll' : 'visible',
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const globalTableState: {[string]: TableColumnSizes} = {};
|
const globalTableState: {[key: string]: TableColumnSizes} = {};
|
||||||
|
|
||||||
class ManagedTable extends React.Component<
|
class ManagedTable extends React.Component<
|
||||||
ManagedTableProps,
|
ManagedTableProps,
|
||||||
ManagedTableState,
|
ManagedTableState
|
||||||
> {
|
> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
highlightableRows: true,
|
highlightableRows: true,
|
||||||
@@ -188,10 +185,10 @@ class ManagedTable extends React.Component<
|
|||||||
tableRef = React.createRef<List>();
|
tableRef = React.createRef<List>();
|
||||||
|
|
||||||
scrollRef: {
|
scrollRef: {
|
||||||
current: null | HTMLDivElement,
|
current: null | HTMLDivElement;
|
||||||
} = React.createRef();
|
} = React.createRef();
|
||||||
|
|
||||||
dragStartIndex: ?number = null;
|
dragStartIndex: number | null = null;
|
||||||
|
|
||||||
// We want to call scrollToHighlightedRows on componentDidMount. However, at
|
// We want to call scrollToHighlightedRows on componentDidMount. However, at
|
||||||
// this time, tableRef is still null, because AutoSizer needs one render to
|
// this time, tableRef is still null, because AutoSizer needs one render to
|
||||||
@@ -225,7 +222,7 @@ class ManagedTable extends React.Component<
|
|||||||
// if columnOrder has changed
|
// if columnOrder has changed
|
||||||
if (nextProps.columnOrder !== this.props.columnOrder) {
|
if (nextProps.columnOrder !== this.props.columnOrder) {
|
||||||
if (this.tableRef && this.tableRef.current) {
|
if (this.tableRef && this.tableRef.current) {
|
||||||
this.tableRef.current.resetAfterIndex(0);
|
this.tableRef.current.resetAfterIndex(0, true);
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
columnOrder: nextProps.columnOrder,
|
columnOrder: nextProps.columnOrder,
|
||||||
@@ -238,7 +235,7 @@ class ManagedTable extends React.Component<
|
|||||||
this.tableRef.current
|
this.tableRef.current
|
||||||
) {
|
) {
|
||||||
// rows were filtered, we need to recalculate heights
|
// rows were filtered, we need to recalculate heights
|
||||||
this.tableRef.current.resetAfterIndex(0);
|
this.tableRef.current.resetAfterIndex(0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +333,7 @@ class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onRowHighlighted = (highlightedRows: Set<string>, cb?: Function) => {
|
onRowHighlighted = (highlightedRows: Set<string>, cb?: () => void) => {
|
||||||
if (!this.props.highlightableRows) {
|
if (!this.props.highlightableRows) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -385,11 +382,7 @@ class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onHighlight = (
|
onHighlight = (e: React.MouseEvent, row: TableBodyRow, index: number) => {
|
||||||
e: SyntheticMouseEvent<>,
|
|
||||||
row: TableBodyRow,
|
|
||||||
index: number,
|
|
||||||
) => {
|
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
// prevents text selection
|
// prevents text selection
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -468,11 +461,7 @@ class ManagedTable extends React.Component<
|
|||||||
return selected;
|
return selected;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMouseEnterRow = (
|
onMouseEnterRow = (e: React.MouseEvent, row: TableBodyRow, index: number) => {
|
||||||
e: SyntheticMouseEvent<>,
|
|
||||||
row: TableBodyRow,
|
|
||||||
index: number,
|
|
||||||
) => {
|
|
||||||
const {dragStartIndex} = this;
|
const {dragStartIndex} = this;
|
||||||
const {current} = this.tableRef;
|
const {current} = this.tableRef;
|
||||||
if (
|
if (
|
||||||
@@ -585,9 +574,9 @@ class ManagedTable extends React.Component<
|
|||||||
scrollDirection,
|
scrollDirection,
|
||||||
scrollOffset,
|
scrollOffset,
|
||||||
}: {
|
}: {
|
||||||
scrollDirection: 'forward' | 'backward',
|
scrollDirection: 'forward' | 'backward';
|
||||||
scrollOffset: number,
|
scrollOffset: number;
|
||||||
scrollUpdateWasRequested: boolean,
|
scrollUpdateWasRequested: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const {current} = this.scrollRef;
|
const {current} = this.scrollRef;
|
||||||
const parent = current ? current.parentElement : null;
|
const parent = current ? current.parentElement : null;
|
||||||
@@ -612,13 +601,7 @@ class ManagedTable extends React.Component<
|
|||||||
);
|
);
|
||||||
|
|
||||||
getRow = ({index, style}) => {
|
getRow = ({index, style}) => {
|
||||||
const {
|
const {onAddFilter, multiline, zebra, rows} = this.props;
|
||||||
onAddFilter,
|
|
||||||
multiline,
|
|
||||||
zebra,
|
|
||||||
rows,
|
|
||||||
horizontallyScrollable,
|
|
||||||
} = this.props;
|
|
||||||
const {columnOrder, columnSizes, highlightedRows} = this.state;
|
const {columnOrder, columnSizes, highlightedRows} = this.state;
|
||||||
const columnKeys = columnOrder
|
const columnKeys = columnOrder
|
||||||
.map(k => (k.visible ? k.key : null))
|
.map(k => (k.visible ? k.key : null))
|
||||||
@@ -639,7 +622,6 @@ class ManagedTable extends React.Component<
|
|||||||
style={style}
|
style={style}
|
||||||
onAddFilter={onAddFilter}
|
onAddFilter={onAddFilter}
|
||||||
zebra={zebra}
|
zebra={zebra}
|
||||||
horizontallyScrollable={horizontallyScrollable}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -664,12 +646,12 @@ class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const width = columnSizes[col.key];
|
const width = columnSizes[col.key];
|
||||||
if (isNaN(width)) {
|
if (typeof width === 'number' && isNaN(width)) {
|
||||||
// non-numeric columns with, can't caluclate
|
// non-numeric columns with, can't caluclate
|
||||||
computedWidth = 0;
|
computedWidth = 0;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
computedWidth += parseInt(width, 10);
|
computedWidth += parseInt(String(width), 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import {
|
||||||
TableColumnOrder,
|
TableColumnOrder,
|
||||||
TableColumnSizes,
|
TableColumnSizes,
|
||||||
TableColumns,
|
TableColumns,
|
||||||
@@ -14,142 +14,140 @@ import type {
|
|||||||
TableRows_immutable,
|
TableRows_immutable,
|
||||||
TableBodyRow,
|
TableBodyRow,
|
||||||
TableOnAddFilter,
|
TableOnAddFilter,
|
||||||
} from './types.js';
|
} from './types';
|
||||||
|
import {MenuTemplate} from '../ContextMenu';
|
||||||
import type {MenuTemplate} from '../ContextMenu.tsx';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from '../../styled/index.js';
|
import styled from 'react-emotion';
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||||
import {VariableSizeList as List} from 'react-window';
|
import {VariableSizeList as List} from 'react-window';
|
||||||
import {clipboard} from 'electron';
|
import {clipboard, MenuItemConstructorOptions} from 'electron';
|
||||||
import TableHead from './TableHead.js';
|
import TableHead from './TableHead';
|
||||||
import TableRow from './TableRow.js';
|
import TableRow from './TableRow';
|
||||||
import ContextMenu from '../ContextMenu.tsx';
|
import ContextMenu from '../ContextMenu';
|
||||||
import FlexColumn from '../FlexColumn.tsx';
|
import FlexColumn from '../FlexColumn';
|
||||||
import createPaste from '../../../fb-stubs/createPaste.tsx';
|
import createPaste from '../../../fb-stubs/createPaste';
|
||||||
import debounceRender from 'react-debounce-render';
|
import debounceRender from 'react-debounce-render';
|
||||||
import debounce from 'lodash.debounce';
|
import debounce from 'lodash.debounce';
|
||||||
import {DEFAULT_ROW_HEIGHT} from './types';
|
import {DEFAULT_ROW_HEIGHT} from './types';
|
||||||
import textContent from '../../../utils/textContent.tsx';
|
import textContent from '../../../utils/textContent';
|
||||||
|
|
||||||
export type ManagedTableProps_immutable = {|
|
export type ManagedTableProps_immutable = {
|
||||||
/**
|
/**
|
||||||
* Column definitions.
|
* Column definitions.
|
||||||
*/
|
*/
|
||||||
columns: TableColumns,
|
columns: TableColumns;
|
||||||
/**
|
/**
|
||||||
* Row definitions.
|
* Row definitions.
|
||||||
*/
|
*/
|
||||||
rows: TableRows_immutable,
|
rows: TableRows_immutable;
|
||||||
/*
|
/*
|
||||||
* Globally unique key for persisting data between uses of a table such as column sizes.
|
* Globally unique key for persisting data between uses of a table such as column sizes.
|
||||||
*/
|
*/
|
||||||
tableKey?: string,
|
tableKey?: string;
|
||||||
/**
|
/**
|
||||||
* Whether the table has a border.
|
* Whether the table has a border.
|
||||||
*/
|
*/
|
||||||
floating?: boolean,
|
floating?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether a row can span over multiple lines. Otherwise lines cannot wrap and
|
* Whether a row can span over multiple lines. Otherwise lines cannot wrap and
|
||||||
* are truncated.
|
* are truncated.
|
||||||
*/
|
*/
|
||||||
multiline?: boolean,
|
multiline?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether the body is scrollable. When this is set to `true` then the table
|
* Whether the body is scrollable. When this is set to `true` then the table
|
||||||
* is not scrollable.
|
* is not scrollable.
|
||||||
*/
|
*/
|
||||||
autoHeight?: boolean,
|
autoHeight?: boolean;
|
||||||
/**
|
/**
|
||||||
* Order of columns.
|
* Order of columns.
|
||||||
*/
|
*/
|
||||||
columnOrder?: TableColumnOrder,
|
columnOrder?: TableColumnOrder;
|
||||||
/**
|
/**
|
||||||
* Initial size of the columns.
|
* Initial size of the columns.
|
||||||
*/
|
*/
|
||||||
columnSizes?: TableColumnSizes,
|
columnSizes?: TableColumnSizes;
|
||||||
/**
|
/**
|
||||||
* Value to filter rows on. Alternative to the `filter` prop.
|
* Value to filter rows on. Alternative to the `filter` prop.
|
||||||
*/
|
*/
|
||||||
filterValue?: string,
|
filterValue?: string;
|
||||||
/**
|
/**
|
||||||
* Callback to filter rows.
|
* Callback to filter rows.
|
||||||
*/
|
*/
|
||||||
filter?: (row: TableBodyRow) => boolean,
|
filter?: (row: TableBodyRow) => boolean;
|
||||||
/**
|
/**
|
||||||
* Callback when the highlighted rows change.
|
* Callback when the highlighted rows change.
|
||||||
*/
|
*/
|
||||||
onRowHighlighted?: (keys: TableHighlightedRows) => void,
|
onRowHighlighted?: (keys: TableHighlightedRows) => void;
|
||||||
/**
|
/**
|
||||||
* Whether rows can be highlighted or not.
|
* Whether rows can be highlighted or not.
|
||||||
*/
|
*/
|
||||||
highlightableRows?: boolean,
|
highlightableRows?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether multiple rows can be highlighted or not.
|
* Whether multiple rows can be highlighted or not.
|
||||||
*/
|
*/
|
||||||
multiHighlight?: boolean,
|
multiHighlight?: boolean;
|
||||||
/**
|
/**
|
||||||
* Height of each row.
|
* Height of each row.
|
||||||
*/
|
*/
|
||||||
rowLineHeight?: number,
|
rowLineHeight?: number;
|
||||||
/**
|
/**
|
||||||
* This makes it so the scroll position sticks to the bottom of the window.
|
* This makes it so the scroll position sticks to the bottom of the window.
|
||||||
* Useful for streaming data like requests, logs etc.
|
* Useful for streaming data like requests, logs etc.
|
||||||
*/
|
*/
|
||||||
stickyBottom?: boolean,
|
stickyBottom?: boolean;
|
||||||
/**
|
/**
|
||||||
* Used by SearchableTable to add filters for rows.
|
* Used by SearchableTable to add filters for rows.
|
||||||
*/
|
*/
|
||||||
onAddFilter?: TableOnAddFilter,
|
onAddFilter?: TableOnAddFilter;
|
||||||
/**
|
/**
|
||||||
* Enable or disable zebra striping.
|
* Enable or disable zebra striping.
|
||||||
*/
|
*/
|
||||||
zebra?: boolean,
|
zebra?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether to hide the column names at the top of the table.
|
* Whether to hide the column names at the top of the table.
|
||||||
*/
|
*/
|
||||||
hideHeader?: boolean,
|
hideHeader?: boolean;
|
||||||
/**
|
/**
|
||||||
* Rows that are highlighted initially.
|
* Rows that are highlighted initially.
|
||||||
*/
|
*/
|
||||||
highlightedRows?: Set<string>,
|
highlightedRows?: Set<string>;
|
||||||
/**
|
/**
|
||||||
* Allows to create context menu items for rows.
|
* Allows to create context menu items for rows.
|
||||||
*/
|
*/
|
||||||
buildContextMenuItems?: () => MenuTemplate,
|
buildContextMenuItems?: () => MenuTemplate;
|
||||||
initialSortOrder?: ?TableRowSortOrder,
|
|
||||||
/**
|
/**
|
||||||
* Callback when sorting changes.
|
* Callback when sorting changes.
|
||||||
*/
|
*/
|
||||||
onSort?: (order: TableRowSortOrder) => void,
|
onSort?: (order: TableRowSortOrder) => void;
|
||||||
/**
|
/**
|
||||||
* Initial sort order of the table.
|
* Initial sort order of the table.
|
||||||
*/
|
*/
|
||||||
initialSortOrder?: ?TableRowSortOrder,
|
initialSortOrder?: TableRowSortOrder;
|
||||||
/**
|
/**
|
||||||
* Table scroll horizontally, if needed
|
* Table scroll horizontally, if needed
|
||||||
*/
|
*/
|
||||||
horizontallyScrollable?: boolean,
|
horizontallyScrollable?: boolean;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type ManagedTableState = {|
|
type ManagedTableState = {
|
||||||
highlightedRows: Set<string>,
|
highlightedRows: Set<string>;
|
||||||
sortOrder: ?TableRowSortOrder,
|
sortOrder?: TableRowSortOrder;
|
||||||
columnOrder: TableColumnOrder,
|
columnOrder: TableColumnOrder;
|
||||||
columnSizes: TableColumnSizes,
|
columnSizes: TableColumnSizes;
|
||||||
shouldScrollToBottom: boolean,
|
shouldScrollToBottom: boolean;
|
||||||
|};
|
};
|
||||||
|
|
||||||
const Container = styled(FlexColumn)(props => ({
|
const Container = styled(FlexColumn)((props: {canOverflow?: boolean}) => ({
|
||||||
overflow: props.canOverflow ? 'scroll' : 'visible',
|
overflow: props.canOverflow ? 'scroll' : 'visible',
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const globalTableState: {[string]: TableColumnSizes} = {};
|
const globalTableState: {[key: string]: TableColumnSizes} = {};
|
||||||
|
|
||||||
class ManagedTable extends React.Component<
|
class ManagedTable extends React.Component<
|
||||||
ManagedTableProps_immutable,
|
ManagedTableProps_immutable,
|
||||||
ManagedTableState,
|
ManagedTableState
|
||||||
> {
|
> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
highlightableRows: true,
|
highlightableRows: true,
|
||||||
@@ -183,10 +181,10 @@ class ManagedTable extends React.Component<
|
|||||||
tableRef = React.createRef<List>();
|
tableRef = React.createRef<List>();
|
||||||
|
|
||||||
scrollRef: {
|
scrollRef: {
|
||||||
current: null | HTMLDivElement,
|
current: null | HTMLDivElement;
|
||||||
} = React.createRef();
|
} = React.createRef();
|
||||||
|
|
||||||
dragStartIndex: ?number = null;
|
dragStartIndex: number | null = null;
|
||||||
|
|
||||||
// We want to call scrollToHighlightedRows on componentDidMount. However, at
|
// We want to call scrollToHighlightedRows on componentDidMount. However, at
|
||||||
// this time, tableRef is still null, because AutoSizer needs one render to
|
// this time, tableRef is still null, because AutoSizer needs one render to
|
||||||
@@ -220,7 +218,7 @@ class ManagedTable extends React.Component<
|
|||||||
// if columnOrder has changed
|
// if columnOrder has changed
|
||||||
if (nextProps.columnOrder !== this.props.columnOrder) {
|
if (nextProps.columnOrder !== this.props.columnOrder) {
|
||||||
if (this.tableRef && this.tableRef.current) {
|
if (this.tableRef && this.tableRef.current) {
|
||||||
this.tableRef.current.resetAfterIndex(0);
|
this.tableRef.current.resetAfterIndex(0, true);
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
columnOrder: nextProps.columnOrder,
|
columnOrder: nextProps.columnOrder,
|
||||||
@@ -233,7 +231,7 @@ class ManagedTable extends React.Component<
|
|||||||
this.tableRef.current
|
this.tableRef.current
|
||||||
) {
|
) {
|
||||||
// rows were filtered, we need to recalculate heights
|
// rows were filtered, we need to recalculate heights
|
||||||
this.tableRef.current.resetAfterIndex(0);
|
this.tableRef.current.resetAfterIndex(0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +329,7 @@ class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onRowHighlighted = (highlightedRows: Set<string>, cb?: Function) => {
|
onRowHighlighted = (highlightedRows: Set<string>, cb?: () => void) => {
|
||||||
if (!this.props.highlightableRows) {
|
if (!this.props.highlightableRows) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -380,11 +378,7 @@ class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onHighlight = (
|
onHighlight = (e: React.MouseEvent, row: TableBodyRow, index: number) => {
|
||||||
e: SyntheticMouseEvent<>,
|
|
||||||
row: TableBodyRow,
|
|
||||||
index: number,
|
|
||||||
) => {
|
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
// prevents text selection
|
// prevents text selection
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -466,11 +460,7 @@ class ManagedTable extends React.Component<
|
|||||||
return selected;
|
return selected;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMouseEnterRow = (
|
onMouseEnterRow = (e: React.MouseEvent, row: TableBodyRow, index: number) => {
|
||||||
e: SyntheticMouseEvent<>,
|
|
||||||
row: TableBodyRow,
|
|
||||||
index: number,
|
|
||||||
) => {
|
|
||||||
const {dragStartIndex} = this;
|
const {dragStartIndex} = this;
|
||||||
const {current} = this.tableRef;
|
const {current} = this.tableRef;
|
||||||
if (
|
if (
|
||||||
@@ -493,7 +483,7 @@ class ManagedTable extends React.Component<
|
|||||||
clipboard.writeText(cellText);
|
clipboard.writeText(cellText);
|
||||||
};
|
};
|
||||||
|
|
||||||
buildContextMenuItems: () => Array<MenuItemConstructorOptions> = () => {
|
buildContextMenuItems: () => MenuItemConstructorOptions[] = () => {
|
||||||
const {highlightedRows} = this.state;
|
const {highlightedRows} = this.state;
|
||||||
if (highlightedRows.size === 0) {
|
if (highlightedRows.size === 0) {
|
||||||
return [];
|
return [];
|
||||||
@@ -584,9 +574,9 @@ class ManagedTable extends React.Component<
|
|||||||
scrollDirection,
|
scrollDirection,
|
||||||
scrollOffset,
|
scrollOffset,
|
||||||
}: {
|
}: {
|
||||||
scrollDirection: 'forward' | 'backward',
|
scrollDirection: 'forward' | 'backward';
|
||||||
scrollOffset: number,
|
scrollOffset: number;
|
||||||
scrollUpdateWasRequested: boolean,
|
scrollUpdateWasRequested: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const {current} = this.scrollRef;
|
const {current} = this.scrollRef;
|
||||||
const parent = current ? current.parentElement : null;
|
const parent = current ? current.parentElement : null;
|
||||||
@@ -611,13 +601,7 @@ class ManagedTable extends React.Component<
|
|||||||
);
|
);
|
||||||
|
|
||||||
getRow = ({index, style}) => {
|
getRow = ({index, style}) => {
|
||||||
const {
|
const {onAddFilter, multiline, zebra, rows} = this.props;
|
||||||
onAddFilter,
|
|
||||||
multiline,
|
|
||||||
zebra,
|
|
||||||
rows,
|
|
||||||
horizontallyScrollable,
|
|
||||||
} = this.props;
|
|
||||||
const {columnOrder, columnSizes, highlightedRows} = this.state;
|
const {columnOrder, columnSizes, highlightedRows} = this.state;
|
||||||
const columnKeys = columnOrder
|
const columnKeys = columnOrder
|
||||||
.map(k => (k.visible ? k.key : null))
|
.map(k => (k.visible ? k.key : null))
|
||||||
@@ -643,7 +627,6 @@ class ManagedTable extends React.Component<
|
|||||||
style={style}
|
style={style}
|
||||||
onAddFilter={onAddFilter}
|
onAddFilter={onAddFilter}
|
||||||
zebra={zebra}
|
zebra={zebra}
|
||||||
horizontallyScrollable={horizontallyScrollable}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -668,12 +651,12 @@ class ManagedTable extends React.Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const width = columnSizes[col.key];
|
const width = columnSizes[col.key];
|
||||||
if (isNaN(width)) {
|
if (typeof width === 'number' && isNaN(width)) {
|
||||||
// non-numeric columns with, can't caluclate
|
// non-numeric columns with, can't caluclate
|
||||||
computedWidth = 0;
|
computedWidth = 0;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
computedWidth += parseInt(width, 10);
|
computedWidth += parseInt(String(width), 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,27 +5,24 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import {
|
||||||
TableColumnOrder,
|
TableColumnOrder,
|
||||||
TableColumnSizes,
|
TableColumnSizes,
|
||||||
TableColumns,
|
TableColumns,
|
||||||
TableOnColumnResize,
|
TableOnColumnResize,
|
||||||
TableOnSort,
|
TableOnSort,
|
||||||
TableRowSortOrder,
|
TableRowSortOrder,
|
||||||
} from './types.js';
|
} from './types';
|
||||||
|
import {normaliseColumnWidth, isPercentage} from './utils';
|
||||||
import {normaliseColumnWidth, isPercentage} from './utils.js';
|
|
||||||
import {PureComponent} from 'react';
|
import {PureComponent} from 'react';
|
||||||
import ContextMenu from '../ContextMenu.tsx';
|
import ContextMenu from '../ContextMenu';
|
||||||
import Interactive from '../Interactive.tsx';
|
import Interactive from '../Interactive';
|
||||||
import styled from '../../styled/index.js';
|
import styled from 'react-emotion';
|
||||||
import {colors} from '../colors.tsx';
|
import {colors} from '../colors';
|
||||||
|
import FlexRow from '../FlexRow';
|
||||||
import FlexRow from '../FlexRow.tsx';
|
|
||||||
|
|
||||||
import invariant from 'invariant';
|
import invariant from 'invariant';
|
||||||
|
import {MenuItemConstructorOptions} from 'electron';
|
||||||
type MenuTemplate = Array<MenuItemConstructorOptions>;
|
import React from 'react';
|
||||||
|
|
||||||
const TableHeaderArrow = styled('span')({
|
const TableHeaderArrow = styled('span')({
|
||||||
float: 'right',
|
float: 'right',
|
||||||
@@ -43,41 +40,45 @@ const TableHeaderColumnContainer = styled('div')({
|
|||||||
padding: '0 8px',
|
padding: '0 8px',
|
||||||
});
|
});
|
||||||
|
|
||||||
const TableHeadContainer = styled(FlexRow)(props => ({
|
const TableHeadContainer = styled(FlexRow)(
|
||||||
borderBottom: `1px solid ${colors.sectionHeaderBorder}`,
|
(props: {horizontallyScrollable?: boolean}) => ({
|
||||||
color: colors.light50,
|
borderBottom: `1px solid ${colors.sectionHeaderBorder}`,
|
||||||
flexShrink: 0,
|
color: colors.light50,
|
||||||
left: 0,
|
flexShrink: 0,
|
||||||
overflow: 'hidden',
|
left: 0,
|
||||||
right: 0,
|
overflow: 'hidden',
|
||||||
textAlign: 'left',
|
|
||||||
top: 0,
|
|
||||||
zIndex: 2,
|
|
||||||
minWidth: props.horizontallyScrollable ? 'min-content' : 0,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const TableHeadColumnContainer = styled('div')(props => ({
|
|
||||||
position: 'relative',
|
|
||||||
backgroundColor: colors.white,
|
|
||||||
flexShrink: props.width === 'flex' ? 1 : 0,
|
|
||||||
height: 23,
|
|
||||||
lineHeight: '23px',
|
|
||||||
fontSize: '0.85em',
|
|
||||||
fontWeight: 500,
|
|
||||||
width: props.width === 'flex' ? '100%' : props.width,
|
|
||||||
'&::after': {
|
|
||||||
position: 'absolute',
|
|
||||||
content: '""',
|
|
||||||
right: 0,
|
right: 0,
|
||||||
top: 5,
|
textAlign: 'left',
|
||||||
height: 13,
|
top: 0,
|
||||||
width: 1,
|
zIndex: 2,
|
||||||
background: colors.light15,
|
minWidth: props.horizontallyScrollable ? 'min-content' : 0,
|
||||||
},
|
}),
|
||||||
'&:last-child::after': {
|
);
|
||||||
display: 'none',
|
|
||||||
},
|
const TableHeadColumnContainer = styled('div')(
|
||||||
}));
|
(props: {width: string | number}) => ({
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: colors.white,
|
||||||
|
flexShrink: props.width === 'flex' ? 1 : 0,
|
||||||
|
height: 23,
|
||||||
|
lineHeight: '23px',
|
||||||
|
fontSize: '0.85em',
|
||||||
|
fontWeight: 500,
|
||||||
|
width: props.width === 'flex' ? '100%' : props.width,
|
||||||
|
'&::after': {
|
||||||
|
position: 'absolute',
|
||||||
|
content: '""',
|
||||||
|
right: 0,
|
||||||
|
top: 5,
|
||||||
|
height: 13,
|
||||||
|
width: 1,
|
||||||
|
background: colors.light15,
|
||||||
|
},
|
||||||
|
'&:last-child::after': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const RIGHT_RESIZABLE = {right: true};
|
const RIGHT_RESIZABLE = {right: true};
|
||||||
|
|
||||||
@@ -86,19 +87,19 @@ function calculatePercentage(parentWidth: number, selfWidth: number): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TableHeadColumn extends PureComponent<{
|
class TableHeadColumn extends PureComponent<{
|
||||||
id: string,
|
id: string;
|
||||||
width: string | number,
|
width: string | number;
|
||||||
sortable: ?boolean,
|
sortable?: boolean;
|
||||||
isResizable: boolean,
|
isResizable: boolean;
|
||||||
leftHasResizer: boolean,
|
leftHasResizer: boolean;
|
||||||
hasFlex: boolean,
|
hasFlex: boolean;
|
||||||
sortOrder: ?TableRowSortOrder,
|
sortOrder?: TableRowSortOrder;
|
||||||
onSort: ?TableOnSort,
|
onSort?: TableOnSort;
|
||||||
columnSizes: TableColumnSizes,
|
columnSizes: TableColumnSizes;
|
||||||
onColumnResize: ?TableOnColumnResize,
|
onColumnResize?: TableOnColumnResize;
|
||||||
children?: React$Node,
|
children?: React.ReactNode;
|
||||||
title?: string,
|
title?: string;
|
||||||
horizontallyScrollable?: boolean,
|
horizontallyScrollable?: boolean;
|
||||||
}> {
|
}> {
|
||||||
ref: HTMLElement;
|
ref: HTMLElement;
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ class TableHeadColumn extends PureComponent<{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let normalizedWidth = newWidth;
|
let normalizedWidth: number | string = newWidth;
|
||||||
|
|
||||||
// normalise number to a percentage if we were originally passed a percentage
|
// normalise number to a percentage if we were originally passed a percentage
|
||||||
if (isPercentage(width)) {
|
if (isPercentage(width)) {
|
||||||
@@ -191,16 +192,16 @@ class TableHeadColumn extends PureComponent<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class TableHead extends PureComponent<{
|
export default class TableHead extends PureComponent<{
|
||||||
columnOrder: TableColumnOrder,
|
columnOrder: TableColumnOrder;
|
||||||
onColumnOrder: ?(order: TableColumnOrder) => void,
|
onColumnOrder?: (order: TableColumnOrder) => void;
|
||||||
columns: TableColumns,
|
columns: TableColumns;
|
||||||
sortOrder: ?TableRowSortOrder,
|
sortOrder?: TableRowSortOrder;
|
||||||
onSort: ?TableOnSort,
|
onSort?: TableOnSort;
|
||||||
columnSizes: TableColumnSizes,
|
columnSizes: TableColumnSizes;
|
||||||
onColumnResize: ?TableOnColumnResize,
|
onColumnResize?: TableOnColumnResize;
|
||||||
horizontallyScrollable?: boolean,
|
horizontallyScrollable?: boolean;
|
||||||
}> {
|
}> {
|
||||||
buildContextMenu = (): MenuTemplate => {
|
buildContextMenu = (): MenuItemConstructorOptions[] => {
|
||||||
const visibles = this.props.columnOrder
|
const visibles = this.props.columnOrder
|
||||||
.map(c => (c.visible ? c.key : null))
|
.map(c => (c.visible ? c.key : null))
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
@@ -231,7 +232,7 @@ export default class TableHead extends PureComponent<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
type: 'checkbox',
|
type: 'checkbox' as 'checkbox',
|
||||||
checked: visible,
|
checked: visible,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2018-present Facebook.
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type {
|
|
||||||
TableColumnKeys,
|
|
||||||
TableColumnSizes,
|
|
||||||
TableOnAddFilter,
|
|
||||||
TableBodyRow,
|
|
||||||
} from './types.js';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import FilterRow from '../filter/FilterRow.tsx';
|
|
||||||
import styled from 'react-emotion';
|
|
||||||
import FlexRow from '../FlexRow.tsx';
|
|
||||||
import {colors} from '../colors.tsx';
|
|
||||||
import {normaliseColumnWidth} from './utils.js';
|
|
||||||
import {DEFAULT_ROW_HEIGHT} from './types';
|
|
||||||
|
|
||||||
const backgroundColor = props => {
|
|
||||||
if (props.highlighted) {
|
|
||||||
if (props.highlightedBackgroundColor) {
|
|
||||||
return props.highlightedBackgroundColor;
|
|
||||||
} else {
|
|
||||||
return colors.macOSTitleBarIconSelected;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (props.backgroundColor) {
|
|
||||||
return props.backgroundColor;
|
|
||||||
} else if (props.even && props.zebra) {
|
|
||||||
return colors.light02;
|
|
||||||
} else {
|
|
||||||
return 'transparent';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const TableBodyRowContainer = styled(FlexRow)(props => ({
|
|
||||||
backgroundColor: backgroundColor(props),
|
|
||||||
boxShadow: props.zebra ? 'none' : 'inset 0 -1px #E9EBEE',
|
|
||||||
color: props.highlighted ? colors.white : props.color || 'inherit',
|
|
||||||
'& *': {
|
|
||||||
color: props.highlighted ? `${colors.white} !important` : null,
|
|
||||||
},
|
|
||||||
'& img': {
|
|
||||||
backgroundColor: props.highlighted ? `${colors.white} !important` : 'none',
|
|
||||||
},
|
|
||||||
height: props.multiline ? 'auto' : props.rowLineHeight,
|
|
||||||
lineHeight: `${String(props.rowLineHeight || DEFAULT_ROW_HEIGHT)}px`,
|
|
||||||
fontWeight: props.fontWeight || 'inherit',
|
|
||||||
overflow: 'hidden',
|
|
||||||
width: '100%',
|
|
||||||
userSelect: 'none',
|
|
||||||
flexShrink: 0,
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor:
|
|
||||||
!props.highlighted && props.highlightOnHover ? colors.light02 : 'none',
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const TableBodyColumnContainer = styled('div')(props => ({
|
|
||||||
display: 'flex',
|
|
||||||
flexShrink: props.width === 'flex' ? 1 : 0,
|
|
||||||
overflow: 'hidden',
|
|
||||||
padding: '0 8px',
|
|
||||||
userSelect: 'none',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
verticalAlign: 'top',
|
|
||||||
whiteSpace: props.multiline ? 'normal' : 'nowrap',
|
|
||||||
wordWrap: props.multiline ? 'break-word' : 'normal',
|
|
||||||
width: props.width === 'flex' ? '100%' : props.width,
|
|
||||||
maxWidth: '100%',
|
|
||||||
justifyContent: props.justifyContent,
|
|
||||||
}));
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
columnSizes: TableColumnSizes,
|
|
||||||
columnKeys: TableColumnKeys,
|
|
||||||
onMouseDown: (e: SyntheticMouseEvent<>) => mixed,
|
|
||||||
onMouseEnter?: (e: SyntheticMouseEvent<>) => void,
|
|
||||||
multiline: ?boolean,
|
|
||||||
rowLineHeight: number,
|
|
||||||
highlighted: boolean,
|
|
||||||
row: TableBodyRow,
|
|
||||||
index: number,
|
|
||||||
style: ?Object,
|
|
||||||
onAddFilter?: TableOnAddFilter,
|
|
||||||
zebra: ?boolean,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class TableRow extends React.PureComponent<Props> {
|
|
||||||
static defaultProps = {
|
|
||||||
zebra: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
index,
|
|
||||||
highlighted,
|
|
||||||
rowLineHeight,
|
|
||||||
row,
|
|
||||||
style,
|
|
||||||
multiline,
|
|
||||||
columnKeys,
|
|
||||||
columnSizes,
|
|
||||||
onMouseEnter,
|
|
||||||
onMouseDown,
|
|
||||||
zebra,
|
|
||||||
onAddFilter,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableBodyRowContainer
|
|
||||||
rowLineHeight={rowLineHeight}
|
|
||||||
highlightedBackgroundColor={row.highlightedBackgroundColor}
|
|
||||||
backgroundColor={row.backgroundColor}
|
|
||||||
highlighted={highlighted}
|
|
||||||
multiline={multiline}
|
|
||||||
even={index % 2 === 0}
|
|
||||||
zebra={zebra}
|
|
||||||
onMouseDown={onMouseDown}
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
style={style}
|
|
||||||
highlightOnHover={row.highlightOnHover}
|
|
||||||
data-key={row.key}
|
|
||||||
{...row.style}>
|
|
||||||
{columnKeys.map(key => {
|
|
||||||
const col = row.columns[key];
|
|
||||||
|
|
||||||
const isFilterable = col?.isFilterable || false;
|
|
||||||
const value = col?.value;
|
|
||||||
const title = col?.title;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableBodyColumnContainer
|
|
||||||
key={key}
|
|
||||||
title={title}
|
|
||||||
multiline={multiline}
|
|
||||||
justifyContent={col?.align || 'flex-start'}
|
|
||||||
width={normaliseColumnWidth(columnSizes[key])}>
|
|
||||||
{isFilterable && onAddFilter != null ? (
|
|
||||||
<FilterRow addFilter={onAddFilter} filterKey={key}>
|
|
||||||
{value}
|
|
||||||
</FilterRow>
|
|
||||||
) : (
|
|
||||||
value
|
|
||||||
)}
|
|
||||||
</TableBodyColumnContainer>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</TableBodyRowContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
185
src/ui/components/table/TableRow.tsx
Normal file
185
src/ui/components/table/TableRow.tsx
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
TableColumnKeys,
|
||||||
|
TableColumnSizes,
|
||||||
|
TableOnAddFilter,
|
||||||
|
TableBodyRow,
|
||||||
|
} from './types';
|
||||||
|
import React from 'react';
|
||||||
|
import FilterRow from '../filter/FilterRow';
|
||||||
|
import styled from 'react-emotion';
|
||||||
|
import FlexRow from '../FlexRow';
|
||||||
|
import {colors} from '../colors';
|
||||||
|
import {normaliseColumnWidth} from './utils';
|
||||||
|
import {DEFAULT_ROW_HEIGHT} from './types';
|
||||||
|
import {
|
||||||
|
FontWeightProperty,
|
||||||
|
ColorProperty,
|
||||||
|
JustifyContentProperty,
|
||||||
|
BackgroundColorProperty,
|
||||||
|
} from 'csstype';
|
||||||
|
|
||||||
|
type TableBodyRowContainerProps = {
|
||||||
|
even?: boolean;
|
||||||
|
zebra?: boolean;
|
||||||
|
highlighted?: boolean;
|
||||||
|
rowLineHeight?: number;
|
||||||
|
multiline?: boolean;
|
||||||
|
fontWeight?: FontWeightProperty;
|
||||||
|
color?: ColorProperty;
|
||||||
|
highlightOnHover?: boolean;
|
||||||
|
backgroundColor?: BackgroundColorProperty;
|
||||||
|
highlightedBackgroundColor?: BackgroundColorProperty;
|
||||||
|
};
|
||||||
|
|
||||||
|
const backgroundColor = (props: TableBodyRowContainerProps) => {
|
||||||
|
if (props.highlighted) {
|
||||||
|
if (props.highlightedBackgroundColor) {
|
||||||
|
return props.highlightedBackgroundColor;
|
||||||
|
} else {
|
||||||
|
return colors.macOSTitleBarIconSelected;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (props.backgroundColor) {
|
||||||
|
return props.backgroundColor;
|
||||||
|
} else if (props.even && props.zebra) {
|
||||||
|
return colors.light02;
|
||||||
|
} else {
|
||||||
|
return 'transparent';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const TableBodyRowContainer = styled(FlexRow)(
|
||||||
|
(props: TableBodyRowContainerProps) => ({
|
||||||
|
backgroundColor: backgroundColor(props),
|
||||||
|
boxShadow: props.zebra ? 'none' : 'inset 0 -1px #E9EBEE',
|
||||||
|
color: props.highlighted ? colors.white : props.color || 'inherit',
|
||||||
|
'& *': {
|
||||||
|
color: props.highlighted ? `${colors.white} !important` : null,
|
||||||
|
},
|
||||||
|
'& img': {
|
||||||
|
backgroundColor: props.highlighted
|
||||||
|
? `${colors.white} !important`
|
||||||
|
: 'none',
|
||||||
|
},
|
||||||
|
height: props.multiline ? 'auto' : props.rowLineHeight,
|
||||||
|
lineHeight: `${String(props.rowLineHeight || DEFAULT_ROW_HEIGHT)}px`,
|
||||||
|
fontWeight: props.fontWeight || 'inherit',
|
||||||
|
overflow: 'hidden',
|
||||||
|
width: '100%',
|
||||||
|
userSelect: 'none',
|
||||||
|
flexShrink: 0,
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor:
|
||||||
|
!props.highlighted && props.highlightOnHover ? colors.light02 : 'none',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const TableBodyColumnContainer = styled('div')(
|
||||||
|
(props: {
|
||||||
|
width?: any;
|
||||||
|
multiline?: boolean;
|
||||||
|
justifyContent: JustifyContentProperty;
|
||||||
|
}) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexShrink: props.width === 'flex' ? 1 : 0,
|
||||||
|
overflow: 'hidden',
|
||||||
|
padding: '0 8px',
|
||||||
|
userSelect: 'none',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
verticalAlign: 'top',
|
||||||
|
whiteSpace: props.multiline ? 'normal' : 'nowrap',
|
||||||
|
wordWrap: props.multiline ? 'break-word' : 'normal',
|
||||||
|
width: props.width === 'flex' ? '100%' : props.width,
|
||||||
|
maxWidth: '100%',
|
||||||
|
justifyContent: props.justifyContent,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
columnSizes: TableColumnSizes;
|
||||||
|
columnKeys: TableColumnKeys;
|
||||||
|
onMouseDown: (e: React.MouseEvent) => any;
|
||||||
|
onMouseEnter?: (e: React.MouseEvent) => void;
|
||||||
|
multiline?: boolean;
|
||||||
|
rowLineHeight: number;
|
||||||
|
highlighted: boolean;
|
||||||
|
row: TableBodyRow;
|
||||||
|
index: number;
|
||||||
|
style?: React.CSSProperties | null;
|
||||||
|
onAddFilter?: TableOnAddFilter;
|
||||||
|
zebra?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class TableRow extends React.PureComponent<Props> {
|
||||||
|
static defaultProps = {
|
||||||
|
zebra: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
index,
|
||||||
|
highlighted,
|
||||||
|
rowLineHeight,
|
||||||
|
row,
|
||||||
|
style,
|
||||||
|
multiline,
|
||||||
|
columnKeys,
|
||||||
|
columnSizes,
|
||||||
|
onMouseEnter,
|
||||||
|
onMouseDown,
|
||||||
|
zebra,
|
||||||
|
onAddFilter,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableBodyRowContainer
|
||||||
|
rowLineHeight={rowLineHeight}
|
||||||
|
highlightedBackgroundColor={row.highlightedBackgroundColor}
|
||||||
|
backgroundColor={row.backgroundColor}
|
||||||
|
highlighted={highlighted}
|
||||||
|
multiline={multiline}
|
||||||
|
even={index % 2 === 0}
|
||||||
|
zebra={zebra}
|
||||||
|
onMouseDown={onMouseDown}
|
||||||
|
onMouseEnter={onMouseEnter}
|
||||||
|
style={style}
|
||||||
|
highlightOnHover={row.highlightOnHover}
|
||||||
|
data-key={row.key}
|
||||||
|
{...row.style}>
|
||||||
|
{columnKeys.map(key => {
|
||||||
|
const col = row.columns[key];
|
||||||
|
|
||||||
|
const isFilterable = Boolean(col && col.isFilterable);
|
||||||
|
const value = col && col.value ? col.value : null;
|
||||||
|
const title = col && col.title ? col.title : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableBodyColumnContainer
|
||||||
|
key={key}
|
||||||
|
title={title}
|
||||||
|
multiline={multiline}
|
||||||
|
justifyContent={col && col.align ? col.align : 'flex-start'}
|
||||||
|
width={normaliseColumnWidth(columnSizes[key])}>
|
||||||
|
{isFilterable && onAddFilter != null ? (
|
||||||
|
<FilterRow addFilter={onAddFilter} filterKey={key}>
|
||||||
|
{value}
|
||||||
|
</FilterRow>
|
||||||
|
) : (
|
||||||
|
value
|
||||||
|
)}
|
||||||
|
</TableBodyColumnContainer>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</TableBodyRowContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,24 +5,25 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
import {default as styled} from 'react-emotion';
|
import {default as styled} from 'react-emotion';
|
||||||
import {colors} from '../colors.tsx';
|
import {colors} from '../colors';
|
||||||
import {default as Text} from '../Text.tsx';
|
import {default as Text} from '../Text';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
export type Value =
|
export type Value =
|
||||||
| {
|
| {
|
||||||
type: 'string',
|
type: 'string';
|
||||||
value: string,
|
value: string;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'boolean',
|
type: 'boolean';
|
||||||
value: boolean,
|
value: boolean;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'integer' | 'float' | 'double' | 'number',
|
type: 'integer' | 'float' | 'double' | 'number';
|
||||||
value: number,
|
value: number;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'null',
|
type: 'null';
|
||||||
};
|
};
|
||||||
|
|
||||||
const NonWrappingText = styled(Text)({
|
const NonWrappingText = styled(Text)({
|
||||||
@@ -32,7 +33,7 @@ const NonWrappingText = styled(Text)({
|
|||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
});
|
});
|
||||||
|
|
||||||
const BooleanValue = styled(NonWrappingText)(props => ({
|
const BooleanValue = styled(NonWrappingText)((props: {active?: boolean}) => ({
|
||||||
'&::before': {
|
'&::before': {
|
||||||
content: '""',
|
content: '""',
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -63,6 +64,6 @@ export function renderValue(val: Value) {
|
|||||||
case 'null':
|
case 'null':
|
||||||
return <NonWrappingText>NULL</NonWrappingText>;
|
return <NonWrappingText>NULL</NonWrappingText>;
|
||||||
default:
|
default:
|
||||||
return <NonWrappingText>{val.value}</NonWrappingText>;
|
return <NonWrappingText />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,23 +5,23 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {Filter} from '../filter/types.tsx';
|
import {Filter} from '../filter/types';
|
||||||
|
|
||||||
import {List} from 'immutable';
|
import {List} from 'immutable';
|
||||||
|
import {BackgroundColorProperty} from 'csstype';
|
||||||
|
|
||||||
export const MINIMUM_COLUMN_WIDTH = 100;
|
export const MINIMUM_COLUMN_WIDTH = 100;
|
||||||
export const DEFAULT_COLUMN_WIDTH = 200;
|
export const DEFAULT_COLUMN_WIDTH = 200;
|
||||||
export const DEFAULT_ROW_HEIGHT = 23;
|
export const DEFAULT_ROW_HEIGHT = 23;
|
||||||
|
|
||||||
export type TableColumnOrderVal = {
|
export type TableColumnOrderVal = {
|
||||||
key: string,
|
key: string;
|
||||||
visible: boolean,
|
visible: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableColumnOrder = Array<TableColumnOrderVal>;
|
export type TableColumnOrder = Array<TableColumnOrderVal>;
|
||||||
|
|
||||||
export type TableColumnSizes = {
|
export type TableColumnSizes = {
|
||||||
[key: string]: string | number,
|
[key: string]: string | number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableHighlightedRows = Array<string>;
|
export type TableHighlightedRows = Array<string>;
|
||||||
@@ -33,55 +33,55 @@ export type TableOnColumnOrder = (order: TableColumnOrder) => void;
|
|||||||
export type TableOnSort = (order: TableRowSortOrder) => void;
|
export type TableOnSort = (order: TableRowSortOrder) => void;
|
||||||
export type TableOnHighlight = (
|
export type TableOnHighlight = (
|
||||||
highlightedRows: TableHighlightedRows,
|
highlightedRows: TableHighlightedRows,
|
||||||
e: SyntheticUIEvent<>,
|
e: React.UIEvent,
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
export type TableHeaderColumn = {|
|
export type TableHeaderColumn = {
|
||||||
value: string,
|
value: string;
|
||||||
sortable?: boolean,
|
sortable?: boolean;
|
||||||
resizable?: boolean,
|
resizable?: boolean;
|
||||||
|};
|
};
|
||||||
|
|
||||||
export type TableBodyRow = {|
|
export type TableBodyRow = {
|
||||||
key: string,
|
key: string;
|
||||||
height?: ?number,
|
height?: number | null | undefined;
|
||||||
filterValue?: ?string,
|
filterValue?: string | null | undefined;
|
||||||
backgroundColor?: ?string,
|
backgroundColor?: string | null | undefined;
|
||||||
sortKey?: string | number,
|
sortKey?: string | number;
|
||||||
style?: Object,
|
style?: Object;
|
||||||
type?: ?string,
|
type?: string | null | undefined;
|
||||||
highlightedBackgroundColor?: ?string,
|
highlightedBackgroundColor?: BackgroundColorProperty | null | undefined;
|
||||||
onDoubleClick?: (e: SyntheticMouseEvent<>) => void,
|
onDoubleClick?: (e: React.MouseEvent) => void;
|
||||||
copyText?: string,
|
copyText?: string;
|
||||||
highlightOnHover?: boolean,
|
highlightOnHover?: boolean;
|
||||||
columns: {
|
columns: {
|
||||||
[key: string]: TableBodyColumn,
|
[key: string]: TableBodyColumn;
|
||||||
},
|
};
|
||||||
|};
|
};
|
||||||
|
|
||||||
export type TableBodyColumn = {|
|
export type TableBodyColumn = {
|
||||||
sortValue?: string | number,
|
sortValue?: string | number;
|
||||||
isFilterable?: boolean,
|
isFilterable?: boolean;
|
||||||
value: any,
|
value: any;
|
||||||
align?: 'left' | 'center' | 'right' | 'flex-start' | 'flex-end',
|
align?: 'left' | 'center' | 'right' | 'flex-start' | 'flex-end';
|
||||||
title?: string,
|
title?: string;
|
||||||
|};
|
};
|
||||||
|
|
||||||
export type TableColumns = {
|
export type TableColumns = {
|
||||||
[key: string]: TableHeaderColumn,
|
[key: string]: TableHeaderColumn;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableRows = Array<TableBodyRow>;
|
export type TableRows = Array<TableBodyRow>;
|
||||||
|
|
||||||
export type TableRows_immutable = List<TableBodyRow>;
|
export type TableRows_immutable = List<TableBodyRow>;
|
||||||
|
|
||||||
export type TableRowSortOrder = {|
|
export type TableRowSortOrder = {
|
||||||
key: string,
|
key: string;
|
||||||
direction: 'up' | 'down',
|
direction: 'up' | 'down';
|
||||||
|};
|
};
|
||||||
|
|
||||||
export type TableOnDragSelect = (
|
export type TableOnDragSelect = (
|
||||||
e: SyntheticMouseEvent<>,
|
e: React.MouseEvent,
|
||||||
key: string,
|
key: string,
|
||||||
index: number,
|
index: number,
|
||||||
) => void;
|
) => void;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function normaliseColumnWidth(
|
export function normaliseColumnWidth(
|
||||||
width: void | string | number,
|
width: string | number | null | undefined,
|
||||||
): number | string {
|
): number | string {
|
||||||
if (width == null || width === 'flex') {
|
if (width == null || width === 'flex') {
|
||||||
// default
|
// default
|
||||||
@@ -26,6 +26,6 @@ export function normaliseColumnWidth(
|
|||||||
throw new TypeError(`Unknown value ${width} for table column width`);
|
throw new TypeError(`Unknown value ${width} for table column width`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPercentage(width: mixed): boolean {
|
export function isPercentage(width: any): boolean {
|
||||||
return typeof width === 'string' && width[width.length - 1] === '%';
|
return typeof width === 'string' && width[width.length - 1] === '%';
|
||||||
}
|
}
|
||||||
@@ -38,18 +38,18 @@ export type {
|
|||||||
TableColumnOrder,
|
TableColumnOrder,
|
||||||
TableColumnOrderVal,
|
TableColumnOrderVal,
|
||||||
TableColumnSizes,
|
TableColumnSizes,
|
||||||
} from './components/table/types.js';
|
} from './components/table/types.tsx';
|
||||||
export {default as ManagedTable} from './components/table/ManagedTable.js';
|
export {default as ManagedTable} from './components/table/ManagedTable.tsx';
|
||||||
export type {ManagedTableProps} from './components/table/ManagedTable.js';
|
export type {ManagedTableProps} from './components/table/ManagedTable.tsx';
|
||||||
export {
|
export {
|
||||||
default as ManagedTable_immutable,
|
default as ManagedTable_immutable,
|
||||||
} from './components/table/ManagedTable_immutable.js';
|
} from './components/table/ManagedTable_immutable.tsx';
|
||||||
export type {
|
export type {
|
||||||
ManagedTableProps_immutable,
|
ManagedTableProps_immutable,
|
||||||
} from './components/table/ManagedTable_immutable.js';
|
} from './components/table/ManagedTable_immutable.tsx';
|
||||||
|
|
||||||
export type {Value} from './components/table/TypeBasedValueRenderer.js';
|
export type {Value} from './components/table/TypeBasedValueRenderer.tsx';
|
||||||
export {renderValue} from './components/table/TypeBasedValueRenderer.js';
|
export {renderValue} from './components/table/TypeBasedValueRenderer.tsx';
|
||||||
|
|
||||||
//
|
//
|
||||||
export type {
|
export type {
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
"flipper": ["./src/index.js"]
|
"flipper": ["./src/index.js"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src/**/*", "types/globals.tsx", "types/nodejs.tsx"],
|
"include": ["src/**/*", "types/*"],
|
||||||
"exclude": ["node_modules", "**/*.spec.ts"]
|
"exclude": ["node_modules", "**/*.spec.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
18
types/ReactDebounceRender.d.tsx
Normal file
18
types/ReactDebounceRender.d.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare module 'react-debounce-render' {
|
||||||
|
export default function<P>(
|
||||||
|
component: React.ComponentType<P>,
|
||||||
|
maxWait: number,
|
||||||
|
options: {
|
||||||
|
maxWait?: number;
|
||||||
|
leading?: boolean;
|
||||||
|
trailing?: boolean;
|
||||||
|
},
|
||||||
|
): React.ComponentType<P & {ref?: (ref: React.RefObject<any>) => void}>;
|
||||||
|
}
|
||||||
14
yarn.lock
14
yarn.lock
@@ -1185,6 +1185,20 @@
|
|||||||
hoist-non-react-statics "^3.3.0"
|
hoist-non-react-statics "^3.3.0"
|
||||||
redux "^4.0.0"
|
redux "^4.0.0"
|
||||||
|
|
||||||
|
"@types/react-virtualized-auto-sizer@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.0.tgz#fc32f30a8dab527b5816f3a757e1e1d040c8f272"
|
||||||
|
integrity sha512-NMErdIdSnm2j/7IqMteRiRvRulpjoELnXWUwdbucYCz84xG9PHcoOrr7QfXwB/ku7wd6egiKFrzt/+QK4Imeeg==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-window@^1.8.1":
|
||||||
|
version "1.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.1.tgz#6e1ceab2e6f2f78dbf1f774ee0e00f1bb0364bb3"
|
||||||
|
integrity sha512-V3k1O5cbfZIRa0VVbQ81Ekq/7w42CK1SuiB9U1oPMTxv270D9qUn7rHb3sZoqMkIJFfB1NZxaH7NRDlk+ToDsg==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@^16.8.24":
|
"@types/react@*", "@types/react@^16.8.24":
|
||||||
version "16.8.24"
|
version "16.8.24"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.24.tgz#8d1ea1fcbfa214220da3d3c04e506f1077b0deac"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.24.tgz#8d1ea1fcbfa214220da3d3c04e506f1077b0deac"
|
||||||
|
|||||||
Reference in New Issue
Block a user