UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

746 lines (745 loc) 22.3 kB
import React, { MouseEventHandler, ReactElement, ReactNode } from 'react'; import ResizeObserver from 'resize-observer-polyfill'; import { DragDropContextProps, DraggableProps, DraggableProvided, DraggableRubric, DraggableStateSnapshot, DragStart, DroppableProps, DroppableStateSnapshot, DropResult, ResponderProvided } from 'react-beautiful-dnd'; import { ColumnProps } from './Column'; import { TableRowProps } from './TableRow'; import DataSet, { ValidationErrors, ValidationSelfErrors } from '../data-set/DataSet'; import Record from '../data-set/Record'; import Field from '../data-set/Field'; import { TransportProps } from '../data-set/Transport'; import TableStore from './TableStore'; import { PaginationProps } from '../pagination/Pagination'; import { SpinProps } from '../spin'; import DataSetComponent, { DataSetComponentProps } from '../data-set/DataSetComponent'; import { ColumnLock, DragColumnAlign, GroupType, HighLightRowType, RowBoxPlacement, ScrollPosition, SelectionMode, TableAutoHeightType, TableButtonType, TableCommandType, TableEditMode, TableHeightType, TableMode, TablePaginationPosition, TableQueryBarType } from './enum'; import ToolBar from './query-bar/TableToolBar'; import FilterBar from './query-bar/TableFilterBar'; import AdvancedQueryBar from './query-bar/TableAdvancedQueryBar'; import ProfessionalBar, { TableProfessionalBarProps } from './query-bar/TableProfessionalBar'; import ComboBar, { ComboBarProps } from './query-bar/TableComboBar'; import DynamicFilterBar, { TableDynamicFilterBarProps } from './query-bar/TableDynamicFilterBar'; import FilterSelect from './query-bar/FilterSelect'; import { ButtonProps } from '../button/Button'; import { Size } from '../core/enum'; import { HighlightRenderer } from '../field/FormField'; import ColumnGroups from './ColumnGroups'; export declare type TableGroup = { name: string; type: GroupType; hidden?: boolean; parentField?: string; columnProps?: ColumnProps; }; export declare type TableButtonProps = ButtonProps & { afterClick?: MouseEventHandler<any>; children?: ReactNode; }; /** * 表头汇总栏hook */ export declare type SummaryBarHook = (props: SummaryBarProps) => { label: ReactNode | string; value: ReactNode | string; }; export declare type Buttons = TableButtonType | [TableButtonType, TableButtonProps] | ReactElement<TableButtonProps>; export declare type Suffixes = 'filter' | ReactElement | ((props: { queryDataSet?: DataSet; dataSet: DataSet; }) => ReactElement); export declare type SummaryBar = Field | SummaryBarHook; export interface SummaryBarProps { dataSet: DataSet; summaryFieldsLimit: number; summaryBarFieldWidth?: number; } export interface TableQueryBarBaseProps { dataSet: DataSet; queryDataSet?: DataSet; buttons: ReactElement<ButtonProps>[]; queryFields: ReactElement<any>[]; } export interface TableQueryBarCustomProps { queryFieldsLimit: number; buttonsLimit?: number; summaryFieldsLimit: number; pagination?: ReactElement<PaginationProps>; summaryBar?: ReactElement<any>; onQuery?: () => void; onReset?: () => void; autoQueryAfterReset?: boolean; } export interface TableQueryBarHookProps extends TableQueryBarBaseProps, TableQueryBarCustomProps { } export interface expandedRowRendererProps { dataSet: DataSet; record: Record; } export interface expandIconProps { prefixCls?: string; expanded: boolean; onExpand: Function; record: Record; expandable?: boolean; needIndentSpaced: boolean; } export interface onRowProps { dataSet: DataSet; record: Record; index: number; expandedRow: boolean; } export interface onColumnResizeProps { column: ColumnProps; width: number; index: number; } export declare type TableQueryBarHookCustomProps = Omit<object, keyof TableQueryBarBaseProps> & TableQueryBarCustomProps & ComboBarProps & TableProfessionalBarProps & TableDynamicFilterBarProps; export declare type TableQueryBarHook = (props: TableQueryBarHookProps & TableQueryBarHookCustomProps) => ReactNode; export declare type Commands = TableCommandType | [TableCommandType, TableButtonProps] | ReactElement<TableButtonProps>; export interface TablePaginationConfig extends PaginationProps { position?: TablePaginationPosition; } export declare type SpinIndicator = ReactElement<any>; export interface TableSpinConfig extends SpinProps { spinning?: boolean; indicator?: SpinIndicator; } export interface DynamicFilterBarConfig { searchCode?: string; searchText?: string; suffixes?: Suffixes[]; prefixes?: React.ReactElement<any>[]; tableFilterAdapter?: TransportProps; } export interface Instance { tbody: React.ReactElement | HTMLElement; headtr: React.ReactElement | HTMLElement; } /** * DraggableRubric 可以获取拖动起来item的index和id从列表获取信息 */ export interface DragTableHeaderCellProps { rubric: DraggableRubric; snapshot: DraggableStateSnapshot; provided: DraggableProvided; } export interface DragTableRowProps extends TableRowProps { rubric: DraggableRubric; } export interface RowRenderIcon { record: Record; } export interface ColumnRenderIcon { column: ColumnProps; dataSet: DataSet; snapshot?: DraggableStateSnapshot; } export interface DragRender { droppableProps?: DroppableProps; draggableProps?: DraggableProps; renderClone?: ((dragRenderProps: DragTableRowProps | DragTableHeaderCellProps) => ReactElement<any>); renderIcon?: ((rowRenderIcon: RowRenderIcon | ColumnRenderIcon) => ReactElement<any>); } export interface TableCustomized { columns: { [key: string]: ColumnProps; }; heightType?: TableHeightType; height?: number; heightDiff?: number; aggregation?: boolean; size?: Size; parityRow?: boolean; aggregationExpandType?: 'cell' | 'row' | 'column'; } export declare const instance: (wrapperClassName: string | undefined, prefixCls?: string | undefined) => Instance; export interface TableProps extends DataSetComponentProps { columns?: ColumnProps[] | undefined; children?: ReactNode; /** * 表头 */ header?: ReactNode | ((records: Record[]) => ReactNode); /** * 是否显示表头 */ showHeader?: boolean; /** * 表脚 */ footer?: ReactNode | ((records: Record[]) => ReactNode); /** * 是否显示边框 * @default true */ border?: boolean; /** * 单元格编辑器边框 */ columnEditorBorder?: boolean; /** * 数据源 */ dataSet: DataSet; /** * 选择记录的模式 */ selectionMode?: SelectionMode; /** * 行选择框位置 */ rowBoxPlacement?: RowBoxPlacement | number; /** * 在其他模式下是不是要是要rowbox */ alwaysShowRowBox?: boolean; /** * 显示选择提示 */ showSelectionTips?: boolean; /** * 显示缓存选中记录的按钮 */ showSelectionCachedButton?: boolean; /** * 显示缓存选中记录 */ showCachedSelection?: boolean; /** * 显示缓存选中记录变化 */ onShowCachedSelectionChange?: (showCachedSelection: boolean) => void; /** * 显示切换跨页全选按钮 */ showAllPageSelectionButton?: boolean; /** * 设置行属性 * @param {onRowProps} props * @return {Object} 行属性 */ onRow?: (props: onRowProps) => object; /** * @deprecated * 请使用 onRow */ rowRenderer?: (record: Record, index: number) => object; /** * 功能按钮 * 可选值:`add` `delete` `remove` `save` `query` `reset` `expandAll` `collapseAll` `export` 或 自定义按钮 * 给内置按钮加属性:buttons={[['add', { color: 'red' }], ...]} */ buttons?: Buttons[]; /** * 头部显示的功能按钮数量,超出限制的查询字段放入更多 */ buttonsLimit?: number; /** * 自定义查询字段组件 * @example * { age: <NumberField /> } * * 默认会根据queryDataSet中定义的field类型自动匹配组件, 匹配类型如下 * lovCode => Lov * lookupCode => Select * type:number => NumberField * type:date => DatePicker * type:dateTime => DatePicker[mode=dateTime] * type:week => DatePicker[mode=week] * default => TextField */ queryFields?: { [key: string]: ReactElement<any>; }; /** * 头部显示的查询字段的数量,超出限制的查询字段放入弹出窗口 * @default 1 */ queryFieldsLimit?: number | undefined; /** * 显示查询条 * 可选值: `advancedBar` `normal` `bar` `none` `professionalBar` `filterBar` `comboBar` * @default 'normal' */ queryBar?: TableQueryBarType | TableQueryBarHook | undefined; /** * 查询条自定义参数 */ queryBarProps?: Partial<TableQueryBarHookCustomProps>; /** * 显示汇总条 * @default 'normal' */ summaryBar?: SummaryBar[]; /** * 头部显示的汇总字段的数量,超出限制的查询字段放入弹出窗口 * @default 3 */ summaryFieldsLimit?: number; /** * 头部显示的汇总字段单个宽度 * @default 170 */ summaryBarFieldWidth?: number; /** * 是否使用拖拽选择 * @default false */ useMouseBatchChoose?: boolean; /** * @deprecated * 请使用 queryBar="none" */ showQueryBar?: boolean; /** * 行高 * @default 30 */ rowHeight?: number | 'auto' | ((props: { size: Size; }) => 'auto' | number); /** * 头行高 * @default rowHeight */ headerRowHeight?: number | 'auto' | ((props: { size: Size; }) => 'auto' | number); /** * 脚行高 * @default rowHeight */ footerRowHeight?: number | 'auto' | ((props: { size: Size; }) => 'auto' | number); /** * 默认行是否展开,当dataSet没有设置expandField时才有效 * @default false; */ defaultRowExpanded?: boolean; /** * 通过点击行来展开子行 */ expandRowByClick?: boolean; /** * 展开行渲染器 */ expandedRowRenderer?: (props: expandedRowRendererProps) => ReactNode; /** * 自定义展开图标 */ expandIcon?: (props: expandIconProps) => ReactNode; /** * 展开图标是否单独单元格展示 */ expandIconAsCell?: boolean; /** * 展开图标所在列索引 */ expandIconColumnIndex?: number; /** * 展示树形数据时,每层缩进的宽度 */ indentSize?: number; /** * 数据过滤 * 返回值 true - 显示 false - 不显示 * @param {Record} record 记录 * @return {boolean} */ filter?: (record: Record) => boolean; /** * 表格展示的模式 * tree需要配合dataSet的`idField`和`parentField`来展示 * 可选值: `list` `tree` */ mode?: TableMode; /** * 表格编辑的模式 * 可选值: `cell` `inline` * @default cell */ editMode?: TableEditMode; /** * queryBar为bar时,直接输入的过滤条件的字段名 */ filterBarFieldName?: string; /** * queryBar为bar时输入框的占位符 */ filterBarPlaceholder?: string; /** * 分页导航条属性 */ pagination?: TablePaginationConfig | false; /** * 高亮行 */ highLightRow?: boolean | HighLightRowType; /** * 勾选高亮行 */ selectedHighLightRow?: boolean; /** * 奇偶行 */ parityRow?: boolean; /** * 可调整列宽 */ columnResizable?: boolean; /** * 可调整列显示 */ columnHideable?: boolean; /** * 可编辑列标题 */ columnTitleEditable?: boolean; /** * 可设置高度 */ heightChangeable?: boolean; /** * 显示原始值 */ pristine?: boolean; /** * 点击展开图标时触发 */ onExpand?: (expanded: boolean, record: Record) => void; /** * 列宽改变时触发 */ onColumnResize?: (props: onColumnResizeProps) => void; /** * 加载条属性 */ spin?: TableSpinConfig | false; /** * 虚拟滚动 */ virtual?: boolean; /** * 虚拟单元格 */ virtualCell?: boolean; /** * 虚拟滚动是否显示加载 */ virtualSpin?: boolean; /** * 是否开启自适应高度 */ autoHeight?: boolean | { type: TableAutoHeightType; diff: number; }; /** * 是否开启自适应宽度 */ autoWidth?: boolean; /** * @deprecated */ autoMaxWidth?: boolean; /** * 是否单独处理column footer */ autoFootHeight?: boolean; /** * 设置drag框体位置 */ dragColumnAlign?: DragColumnAlign; /** * 开启列拖拽 */ columnDraggable?: boolean; /** * 开启行拖拽 */ rowDraggable?: boolean; /** * 拖拽触发事件 */ onDragEnd?: (dataSet: DataSet, columns: ColumnProps[], resultDrag: DropResult, provided: ResponderProvided) => void; /** * 拖拽触发事件位置切换前回调 */ onDragEndBefore?: (dataSet: DataSet, columns: ColumnProps[], resultDrag: DropResult, provided: ResponderProvided) => DropResult | boolean | void; /** * DragDropContext */ dragDropContextProps?: DragDropContextProps; /** * 渲染列拖拽 */ columnsDragRender?: DragRender; /** * 渲染行拖拽 */ rowDragRender?: DragRender; /** * 是否开启回车跳转下一行编辑 */ editorNextKeyEnterDown?: boolean; /** * 是否开启关闭快捷键(只关闭新加组合快捷键) */ keyboard?: boolean; /** * @deprecated * 筛选条属性配置 使用 queryBarProps.dynamicFilterBar */ dynamicFilterBar?: DynamicFilterBarConfig; /** * 异步树 */ treeAsync?: boolean; /** * 树节点展开时,加载数据钩子 */ treeLoadData?: ({ record, dataSet }: { record: any; dataSet: any; }) => Promise<any>; /** * 树形结构下queryBar触发查询,自动展开树形结构 */ treeQueryExpanded?: boolean; /** * 显示行号 */ rowNumber?: boolean | ((props: { record?: Record | null; dataSet?: DataSet | null; text: string; pathNumbers: number[]; }) => ReactNode); /** * 个性化编码 */ customizedCode?: string; /** * 是否显示个性化设置入口按钮 */ customizable?: boolean | undefined; /** * @deprecated * 同 columnDraggable */ dragColumn?: boolean; /** * @deprecated * 同 rowDraggable */ dragRow?: boolean; /** * 客户端导出一次查询数量配置 */ clientExportQuantity?: number; /** * @deprecated * 可以修改由于样式导致的虚拟高度和rowHeight不一致 */ virtualRowHeight?: number; /** * 摘要 */ summary?: string; /** * 聚合视图 */ aggregation?: boolean; /** * 聚合视图切换钩子 */ onAggregationChange?: (aggregation: boolean) => void; /** * 高亮渲染器 */ cellHighlightRenderer?: HighlightRenderer; /** * 是否显示临时移除的行 */ showRemovedRow?: boolean; /** * 动态筛选条编码 */ searchCode?: string; /** * 分组 */ groups?: TableGroup[]; /** * 横向滚动事件 */ onScrollLeft?: (left: number) => void; /** * 纵向滚动事件 */ onScrollTop?: (top: number) => void; /** * 表格体是否可展开 */ bodyExpandable?: boolean; /** * 默认表格体是否展开 */ defaultBodyExpanded?: boolean; /** * 表格体是否展开 */ bodyExpanded?: boolean; /** * 表格体展开变更事件 */ onBodyExpand?: (expanded: boolean) => void; /** * 自定义渲染数据为空的状态 */ renderEmpty?: () => ReactNode; /** * 校验失败自动定位 */ autoValidationLocate?: boolean; } export default class Table extends DataSetComponent<TableProps> { static displayName: string; static Column: import("./Column").IColumn; static FilterBar: typeof FilterBar; static AdvancedQueryBar: typeof AdvancedQueryBar; static ProfessionalBar: typeof ProfessionalBar; static ComboBar: typeof ComboBar; static DynamicFilterBar: typeof DynamicFilterBar; static FilterSelect: typeof FilterSelect; static ToolBar: typeof ToolBar; static TableRow: React.FunctionComponent<TableRowProps>; static TableHeaderCell: React.FunctionComponent<import("./TableHeaderCell").TableHeaderCellProps>; static defaultProps: { suffixCls: string; tabIndex: number; selectionMode: SelectionMode; rowBoxPlacement: RowBoxPlacement; queryFields: {}; defaultRowExpanded: boolean; expandRowByClick: boolean; indentSize: number; summaryFieldsLimit: number; summaryBarFieldWidth: number; filterBarFieldName: string; virtualSpin: boolean; autoHeight: boolean; autoMaxWidth: boolean; autoFootHeight: boolean; clientExportQuantity: number; showSelectionCachedButton: boolean; showHeader: boolean; }; tableStore: TableStore; nextFrameActionId?: number; scrollId?: number; resizeLine: HTMLDivElement | null; tableHeadWrap: HTMLDivElement | null; tableBodyWrap: HTMLDivElement | null; tableFootWrap: HTMLDivElement | null; tableContentWrap: HTMLDivElement | null; fixedColumnsBodyLeft: HTMLDivElement | null; fixedColumnsBodyRight: HTMLDivElement | null; lastScrollLeft: number; lastScrollTop: number; wrapperWidth: number[]; wrapperWidthTimer?: number; resizeObserver?: ResizeObserver; get currentRow(): HTMLTableRowElement | null; get firstRow(): HTMLTableRowElement | null; get lastRow(): HTMLTableRowElement | null; saveResizeRef(node: HTMLDivElement | null): void; saveContentRef(node: any): void; useFocusedClassName(): boolean; setCode(props: any): void; handleResize(width?: number): void; handleWindowResize(): void; handleDataSetLoad(): void; handleDataSetCreate({ record, dataSet }: { record: any; dataSet: any; }): void; handleDataSetValidateSelf(props: { valid: boolean; dataSet: DataSet; errors: ValidationSelfErrors[]; noLocate?: boolean; }): void; handleDataSetValidate(props: { valid: boolean; dataSet: DataSet; errors: ValidationErrors[]; noLocate?: boolean; }): void; handleKeyDown(e: any): void; focusRow(row: HTMLTableRowElement | null): Record | void; handleKeyDownHome(e: any): Promise<void>; handleKeyDownEnd(e: any): Promise<void>; handleKeyDownCTRLS(e: any): Promise<void>; handleKeyDownCTRLN(e: any): Promise<void>; handleKeyDownCTRLD(e: any): Promise<void>; handleKeyDownCTRLDELETE(e: any): Promise<void>; handleKeyDownUp(e: any): Promise<void | Record>; handleKeyDownDown(e: any): Promise<void | Record>; handleKeyDownDownShift(e: any): Promise<void>; handleKeyDownUpShift(e: any): Promise<void>; handleKeyDownRight(e: any): void; handleKeyDownLeft(e: any): void; getOmitPropsKeys(): string[]; getWrapperProps(props?: any): any; getOtherProps(): any; getClassName(): string | undefined; /** * 获取传入的 Spin props */ getSpinProps(): SpinProps; componentWillMount(): void; componentDidMount(): void; private columnsSize?; componentDidUpdate(): void; componentWillReceiveProps(nextProps: any, nextContext: any): void; componentWillUnmount(): void; syncParentSize(entries: ResizeObserverEntry[]): void; connect(): void; disconnect(): void; processDataSetListener(flag: boolean): void; render(): JSX.Element; reorderDataSet(startIndex: number, endIndex: number): void; /** * 触发组合或拖拽排序, 移除原纪录 * @param currentRecord */ removeSourceRecord(currentRecord: Record): void; handleDragStart(initial: DragStart, provided: ResponderProvided): void; handleDragEnd(resultDrag: DropResult, provided: ResponderProvided): void; handleBodyScroll(e: React.SyntheticEvent): void; handleBodyScrollTop(e: any, currentTarget: any): void; handleBodyScrollLeft(e: any, currentTarget: any): void; setScrollPositionClassName(target?: any): void; setScrollPosition(position: ScrollPosition): void; renderTable(hasHeader: boolean, hasBody: boolean, hasFooter: boolean, lock?: ColumnLock, virtual?: boolean): ReactNode; getHeader(): ReactNode; getFooter(): ReactNode | undefined; getPagination(position: TablePaginationPosition): ReactElement<PaginationProps> | undefined; getTable(lock?: ColumnLock): ReactNode; getLeftFixedTable(): ReactNode; getRightFixedTable(): ReactNode; getTableBody(columnGroups: ColumnGroups, lock?: ColumnLock, snapshot?: DroppableStateSnapshot, dragRowHeight?: number): ReactNode; getTableHeader(lock?: ColumnLock): ReactNode; getTableFooter(columnGroups: ColumnGroups, lock?: ColumnLock): ReactNode; getStyleHeight(): number | undefined; syncSizeInFrame(width?: number): void; syncSize(width?: number): void; initDefaultExpandedRows(): void; handleHeightTypeChange(immediate?: boolean): void; getWidth(): number; setColumnWidth(width: number, indexOrKeyOrName: number | string): void; setScrollTop(scrollTop: number, target?: HTMLElement): void; setScrollLeft(scrollLeft: number, target?: HTMLElement): void; }