choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
480 lines (479 loc) • 18.1 kB
TypeScript
import * as React from 'react';
import { DraggableChildrenFn, DraggableProps, DraggableProvided, DraggableStateSnapshot, DragStart, DroppableProps, DropResult, ResponderProvided } from 'react-beautiful-dnd';
import ConfigContext, { ConfigContextValue } from '../../../lib/config-provider/ConfigContext';
import { PerformanceTable as PerformanceTableLocal } from '../../../lib/locale-provider';
import { RadioChangeEvent } from '../../../lib/radio';
import { CheckboxChangeEvent } from '../../../lib/checkbox';
import { RowProps } from './Row';
import { RowDataType, SortType, StandardProps } from './common';
import Column, { ColumnProps } from './Column';
import Cell from './Cell';
import HeaderCell from './HeaderCell';
import ProfessionalBar from './query-bar/TableProfessionalBar';
import DynamicFilterBar from './query-bar/TableDynamicFilterBar';
import TableStore from './TableStore';
import { ToolBarProps } from './tool-bar';
import { TableHeightType } from '../table/enum';
import DataSet from '../data-set';
import { TransportProps } from '../data-set/Transport';
import { FormProps } from '../form/Form';
export interface TableLocale {
emptyMessage?: string;
loading?: string;
}
export interface TableScrollLength {
horizontal?: number;
vertical?: number;
}
export declare enum TableQueryBarType {
professionalBar = "professionalBar",
filterBar = "filterBar"
}
export interface TableQueryBarProps {
type?: TableQueryBarType;
renderer?: (props: TableQueryBarHookProps) => React.ReactNode;
dataSet?: DataSet;
queryFormProps?: FormProps;
defaultExpanded?: Boolean;
queryDataSet?: DataSet;
queryFields?: React.ReactElement<any>[];
queryFieldsLimit?: number;
onQuery?: (props: object) => void;
onReset?: () => void;
}
export interface TableQueryBarHookProps {
dataSet: DataSet;
queryDataSet?: DataSet;
queryFields: React.ReactElement<any>[];
queryFieldsLimit?: number;
onQuery?: (props: object) => void;
onReset?: () => void;
}
export interface DynamicFilterBarConfig {
searchCode: string;
searchText?: string;
quickSearch?: boolean;
suffixes?: React.ReactElement<any>[];
prefixes?: React.ReactElement<any>[];
tableFilterAdapter?: TransportProps;
}
export interface PerformanceTableCustomized {
columns: object;
heightType?: TableHeightType;
height?: number;
heightDiff?: number;
}
export declare type RowSelectionType = 'checkbox' | 'radio';
export declare type SelectionSelectFn = (record: object, selected: boolean, selectedRows: Object[], nativeEvent: Event) => void;
export declare type TableSelectWay = 'onSelect' | 'onSelectMultiple' | 'onSelectAll' | 'onSelectInvert';
export declare type SelectionItemSelectFn = (key: string[]) => void;
export interface SelectionItem {
key: string;
text: React.ReactNode;
onSelect?: SelectionItemSelectFn;
}
export interface TableRowSelection {
type?: RowSelectionType;
selectedRowKeys?: string[] | number[];
onChange?: (selectedRowKeys: string[] | number[], selectedRows: object[]) => void;
getCheckboxProps?: (record: object) => Object;
onSelect?: SelectionSelectFn;
onSelectMultiple?: (selected: boolean, selectedRows: object[], changeRows: object[]) => void;
onSelectAll?: (selected: boolean, selectedRows: object[], changeRows: object[]) => void;
onSelectInvert?: (selectedRowKeys: string[] | number[]) => void;
selections?: SelectionItem[] | boolean;
hideDefaultSelections?: boolean;
fixed?: boolean | string;
columnWidth?: number;
selectWay?: TableSelectWay;
columnTitle?: string | React.ReactNode;
columnIndex?: number;
}
export interface SelectionCheckboxAllProps {
store: any;
disabled: boolean;
getCheckboxPropsByItem: (item: object, index: number) => {
defaultChecked: boolean;
};
getRecordKey: (record: object, index?: number) => string;
data: object[];
prefixCls: string | undefined;
onSelect: (key: string, index: number, selectFunc: any) => void;
hideDefaultSelections?: boolean;
selections?: SelectionItem[] | boolean;
}
export interface SelectionCheckboxAllState {
checked?: boolean;
indeterminate?: boolean;
}
export interface SelectionBoxProps {
store: any;
type?: RowSelectionType;
defaultSelection: string[];
rowIndex: string;
name?: string;
disabled?: boolean;
onChange: (e: RadioChangeEvent | CheckboxChangeEvent) => void;
}
export interface SelectionBoxState {
checked?: boolean;
}
export interface SelectionInfo {
selectWay: TableSelectWay;
record?: object;
checked?: boolean;
changeRowKeys?: React.Key[];
nativeEvent?: Event;
}
export interface ColumnRenderIcon {
column: ColumnProps;
dataSet?: DataSet | undefined;
snapshot?: DraggableStateSnapshot;
}
export interface DragRender {
droppableProps?: DroppableProps;
draggableProps?: DraggableProps;
renderClone?: DraggableChildrenFn;
renderIcon?: ((rowRenderIcon: ColumnRenderIcon) => React.ReactElement<any>);
}
export interface TableProps extends StandardProps {
/** 左上角的 title */
headerTitle?: React.ReactNode;
rowSelection?: TableRowSelection;
queryBar?: false | TableQueryBarProps;
toolbar?: ToolBarProps;
/** 渲染操作栏 */
toolBarRender?: ToolBarProps['toolBarRender'] | false;
columns?: ColumnProps[];
autoHeight?: boolean;
affixHeader?: boolean | number;
affixHorizontalScrollbar?: boolean | number;
bodyRef?: (ref: HTMLElement) => void;
bordered?: boolean;
className?: string;
classPrefix?: string;
children?: React.ReactNode;
cellBordered?: boolean;
defaultSortType?: SortType;
disabledScroll?: boolean;
defaultExpandAllRows?: boolean;
defaultExpandedRowKeys?: string[] | number[];
data: object[];
expandedRowKeys?: string[] | number[];
height?: number;
hover?: boolean;
headerHeight?: number;
locale?: TableLocale;
clickScrollLength?: TableScrollLength;
loading?: boolean;
loadAnimation?: boolean;
minHeight?: number;
rowHeight?: number | ((rowData: object) => number);
rowKey?: string;
isTree?: boolean;
rowExpandedHeight?: number;
rowClassName?: string | ((rowData: object) => string);
showHeader?: boolean;
showScrollArrow?: boolean;
style?: React.CSSProperties;
sortColumn?: string;
sortType?: SortType;
shouldUpdateScroll?: boolean;
translate3d?: boolean;
rtl?: boolean;
width?: number;
wordWrap?: boolean;
virtualized?: boolean;
renderTreeToggle?: (expandButton: React.ReactNode, rowData?: RowDataType, expanded?: boolean) => React.ReactNode;
renderRowExpanded?: (rowDate?: object) => React.ReactNode;
renderEmpty?: (info: React.ReactNode) => React.ReactNode;
renderLoading?: (loading: React.ReactNode) => React.ReactNode;
onRowClick?: (rowData: object, event: React.MouseEvent) => void;
onRowContextMenu?: (rowData: object, event: React.MouseEvent) => void;
onScroll?: (scrollX: number, scrollY: number) => void;
onSortColumn?: (dataKey: string, sortType?: SortType) => void;
onExpandChange?: (expanded: boolean, rowData: object) => void;
onTouchStart?: (event: React.TouchEvent) => void;
onTouchMove?: (event: React.TouchEvent) => void;
onDataUpdated?: (nextData: object[], scrollTo: (coord: {
x: number;
y: number;
}) => void) => void;
customizedCode?: string;
customizable?: boolean;
columnDraggable?: boolean;
columnTitleEditable?: boolean;
columnsDragRender?: DragRender;
rowDraggable?: boolean;
onDragStart?: (initial: DragStart, provided: ResponderProvided) => void;
onDragEnd?: (result: DropResult, provided: ResponderProvided, data: object) => void;
onDragEndBefore?: (result: DropResult, provided: ResponderProvided) => boolean;
}
interface TableRowProps extends RowProps {
key?: string | number;
depth?: number;
}
declare type Offset = {
top?: number;
left?: number;
width?: number;
height?: number;
};
/**
* 记录rowSpan的坐标
* @property rowIndex 行坐标
* @property columnIndex 列坐标
* @property start rowSpan起始行
* @property end rowSpan结束行
* @property zIndex 当前行的zIndex
*/
declare type TableRowSpanIndex = {
rowIndex: number;
columnIndex: number;
start: number;
end: number;
zIndex: number;
};
declare type StartRowSpan = {
rowIndex: number;
rowSpan: number;
height: number;
};
interface ColumnCellProps extends ColumnProps {
parent?: React.ReactElement;
}
interface TableState {
headerOffset?: Offset;
tableOffset?: Offset;
width: number;
columnWidth: number;
dataKey: number;
shouldFixedColumn: boolean;
contentHeight: number;
contentWidth: number;
tableRowsMaxHeight: number[];
isColumnResizing?: boolean;
expandedRowKeys: string[] | number[];
searchText: string;
sortType?: SortType;
scrollY: number;
isScrolling?: boolean;
data: object[];
cacheData: object[];
fixedHeader: boolean;
fixedHorizontalScrollbar?: boolean;
isTree?: boolean;
selectedRowKeys: string[] | number[];
selectionDirty?: boolean;
[key: string]: any;
}
export declare const CUSTOMIZED_KEY = "__customized-column__";
export default class PerformanceTable extends React.Component<TableProps, TableState> {
static displayName: string;
static Column: typeof Column;
static Cell: typeof Cell;
static ColumnGroup: import("./ColumnGroup").IColumnGroup;
static HeaderCell: typeof HeaderCell;
static ProfessionalBar: typeof ProfessionalBar;
static DynamicFilterBar: typeof DynamicFilterBar;
static defaultProps: {
classPrefix: string;
data: never[];
defaultSortType: string;
height: number;
rowHeight: number;
headerHeight: number;
minHeight: number;
rowExpandedHeight: number;
hover: boolean;
highLightRow: boolean;
showHeader: boolean;
showScrollArrow: boolean;
bordered: boolean;
rowKey: string;
translate3d: boolean;
shouldUpdateScroll: boolean;
locale: {
emptyMessage: string;
loading: string;
};
clickScrollLength: {
horizontal: number;
vertical: number;
};
};
static getDerivedStateFromProps(props: TableProps, state: TableState): {
cacheData: object[];
isTree: boolean | undefined;
data: object[];
} | null;
static get contextType(): typeof ConfigContext;
context: ConfigContextValue;
translateDOMPositionXY: null;
scrollListener: any;
bscroll: any;
tableRef: React.RefObject<any>;
scrollbarYRef: React.RefObject<any>;
scrollbarXRef: React.RefObject<any>;
tableBodyRef: React.RefObject<any>;
affixHeaderWrapperRef: React.RefObject<any>;
mouseAreaRef: React.RefObject<any>;
headerWrapperRef: React.RefObject<any>;
tableHeaderRef: React.RefObject<any>;
wheelWrapperRef: React.RefObject<any>;
tableRows: {
[key: string]: [HTMLElement, any];
};
mounted: boolean;
disableEventsTimeoutId: null;
scrollY: number;
scrollX: number;
wheelHandler: any;
minScrollY: any;
minScrollX: any;
mouseArea: any;
touchX: any;
touchY: any;
wheelListener: any;
touchStartListener: any;
touchMoveListener: any;
rowSpanList: Array<TableRowSpanIndex>;
nextRowZIndex: Array<number>;
calcStartRowSpan: StartRowSpan;
_cacheCalcStartRowSpan: Array<StartRowSpan>;
_cacheCells: any;
_cacheScrollX: number;
_cacheRenderCols: any;
_cacheChildrenSize: number;
_visibleRows: any;
_lastRowIndex: string | number;
tableStore: TableStore;
constructor(props: TableProps, context: ConfigContextValue);
setSelectionColumn: (props: any) => void;
listenWheel: (deltaX: number, deltaY: number) => void;
componentDidMount(): void;
shouldComponentUpdate(nextProps: TableProps, nextState: TableState): boolean;
componentDidUpdate(prevProps: TableProps, prevState: TableState): void;
componentWillUnmount(): void;
getExpandedRowKeys(): string[] | number[];
getSortType(): "desc" | "asc" | undefined;
getScrollCellGroups(): any;
getFixedLeftCellGroups(): any;
getFixedRightCellGroups(): any;
isRTL(): boolean;
getRowHeight(rowData?: {}): number;
/**
* 获取表头高度
*/
getTableHeaderHeight(): number;
/**
* Table 个性化高度变更
*/
handleHeightTypeChange(): void;
/**
* 获取 Table 需要渲染的高度
*/
getTableHeight(): number;
/**
* 处理 column props
* @param column
*/
getColumnProps(column: any): Pick<any, string | number | symbol>;
/**
* 处理columns json -> reactNode
* @param columns
*/
processTableColumns(columns: any[]): (JSX.Element | undefined)[];
getFlattenColumn(column: React.ReactElement, cellProps: ColumnCellProps, array: Array<React.ReactElement>): React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)>[];
/**
* 获取 columns ReactElement 数组
* - 处理 children 中存在 <Column> 数组的情况
* - 过滤 children 中的空项
*/
getTableColumns(): React.ReactNodeArray;
getRecordKey: (record: object, index: number) => any;
getCheckboxPropsByItem: (item: object, index: number) => any;
getDefaultSelection(): any[];
handleSelect: (record: object, rowIndex: number, e: CheckboxChangeEvent) => void;
handleSelectRow: (selectionKey: string, index: number, onSelectFunc: SelectionItemSelectFn) => void;
handleRadioSelect: (record: object, rowIndex: number, e: RadioChangeEvent) => void;
renderSelectionBox: (type: "checkbox" | "radio" | undefined, rowData: object, rowIndex: number) => JSX.Element;
renderRowSelection(fixed: any): JSX.Element | undefined;
getCellDescriptor(): any;
setOffsetByAffix: () => void;
handleWindowScroll: () => void;
affixHorizontalScrollbar: () => void;
affixTableHeader: () => void;
handleSortColumn: (dataKey: string) => void;
handleShowMouseArea: (width: number, left: number, fixed: string | boolean | undefined) => void;
handleHideMouseArea: () => void;
handleColumnResizeEnd: (columnWidth: number, _cursorDelta: number, dataKey: any, index: number) => void;
handleColumnResizeStart: (width: number, left: number, fixed: boolean) => void;
handleColumnResizeMove: (width: number, left: number, fixed: boolean) => void;
handleTreeToggle: (rowKey: any, _rowIndex: number, rowData: any) => void;
setSelectedRowKeys(selectedRowKeys: string[], selectionInfo: SelectionInfo): void;
handleScrollX: (delta: number) => void;
handleScrollY: (delta: number) => void;
handleWheel: (deltaX: number, deltaY: number) => void;
debounceScrollEndedCallback: () => void;
handleTouchStart: (event: React.TouchEvent<Element>) => void;
handleTouchMove: ({ e }: {
e: any;
}) => void;
/**
* 当用户在 Table 内使用 tab 键,触发了 onScroll 事件,这个时候应该更新滚动条位置
* https://github.com/rsuite/rsuite/issues/234
*/
handleBodyScroll: (event: React.UIEvent<HTMLDivElement>) => void;
handleDragStart: (initial: DragStart, provided: ResponderProvided) => void;
handleDragEnd: (resultDrag: DropResult, provided: ResponderProvided) => Promise<void>;
initPosition(): void;
initBScroll(tableBody: any): void;
updatePosition(): void;
updatePositionByFixedCell(): void;
shouldHandleWheelX: (delta: number) => boolean;
shouldHandleWheelY: (delta: number) => boolean;
shouldRenderExpandedRow(rowData: object): boolean;
addPrefix: (name: string) => string;
calculateRowMaxHeight(): void;
calculateTableWidth: () => void;
calculateTableContentWidth(prevProps: TableProps): void;
calculateTableContextHeight(prevProps?: TableProps): void;
getControlledScrollTopValue(value: any): number[];
getControlledScrollLeftValue(value: any): number[];
/**
* public method
*/
scrollTop: (top?: number) => void;
scrollLeft: (left?: number) => void;
scrollTo: (coord: {
x: number;
y: number;
}) => void;
bindTableRowsRef: (index: string | number, rowData: any, provided?: DraggableProvided | undefined) => (ref: HTMLElement) => void;
bindRowClick: (rowIndex: string | number, index: string | number, rowData: object) => (event: React.MouseEvent<Element, MouseEvent>) => void;
onRowClick(rowData: any, event: any, rowIndex: any, index: any): void;
bindRowContextMenu: (rowData: object) => (event: React.MouseEvent<Element, MouseEvent>) => void;
renderRowData(bodyCells: any[], rowData: any, props: TableRowProps, shouldRenderExpandedRow?: boolean): JSX.Element;
calculateFixedAndScrollColumn(cells: any[]): {
fixedLeftCells: any[];
fixedRightCells: any[];
scrollCells: any[];
fixedLeftCellGroupWidth: number;
fixedRightCellGroupWidth: number;
};
renderRow(props: TableRowProps, cells: any[], shouldRenderExpandedRow?: boolean, rowData?: any): JSX.Element;
renderRowExpanded(rowData?: object): JSX.Element | null;
renderMouseArea(): JSX.Element;
renderTableHeader(headerCells: any[], rowWidth: number): JSX.Element;
renderTableBody(bodyCells: any[], rowWidth: number): JSX.Element;
renderInfo(locale: PerformanceTableLocal): {} | null | undefined;
renderScrollbar(): JSX.Element | null;
/**
* show loading
*/
renderLoading(): {} | null | undefined;
renderTableToolbar(): JSX.Element | null;
render(): JSX.Element;
}
export {};