import * as ReactDom from 'react-dom'; import { createRef, PureComponent } from 'react'; import classnames from 'classnames'; import isEqual from '../utils/isEqual'; import noop from '../utils/noop'; import measureScrollbar from '../utils/dom/measureScrollbar'; import { runOnceInNextFrame } from '../utils/nextFrame'; import { WindowResizeHandler } from '../utils/component/WindowResizeHandler'; import { WindowScrollHandler } from '../utils/component/WindowScrollHandler'; import BatchComponents from './BatchComponents'; import { groupedColumns, getLeafColumns, needFixBatchComps, isElementInView, mapDOMNodes, getCompatSelectionPropsFn, getSelectAllCheckboxState, } from './utils'; import { I18nReceiver as Receiver, II18nLocaleGrid } from '../i18n'; import BlockLoading from '../loading/BlockLoading'; import Store from './Store'; import ColGroup from './ColGroup'; import Header from './Header'; import Body from './Body'; import Footer from './Footer'; import SelectionCheckbox from './SelectionCheckbox'; import SelectionRadio from './SelectionRadio'; import Affix from '../affix'; import SelectionCheckboxAll, { IGridSelectionAllCheckboxProps, } from './SelectionCheckboxAll'; import { IGridColumn, IGridOnChangeConfig, GridScrollPosition, GridSortType, GridRowClassNameType, GridPaginationType, IGridPageInfo, IGridScrollDelta, IGridSelection, IGridExpandation, IGridRowClickHandler, IGridOnExpandHandler, IGridInnerFixedType, IGridColumnBodyRenderFunc, IGridBatchRender, } from './types'; import { ICheckboxEvent } from '../checkbox'; import { IRadioEvent } from '../radio'; import isBrowser from '../utils/isBrowser'; import { IBlockLoadingProps } from '../loading/props'; import { hasOwnProperty } from '../utils/hasOwn'; import isNil from '../utils/isNil'; import { Icon } from '../icon'; function stopPropagation(e: React.MouseEvent) { e.stopPropagation(); if (e.nativeEvent.stopImmediatePropagation) { e.nativeEvent.stopImmediatePropagation(); } } const prefix = 'zent'; const BTN_WIDTH = 28; const DEFAULT_SIZE = 'large'; // eslint-disable-next-line @typescript-eslint/ban-types export interface IGridProps { size?: 'medium' | 'large' | 'small'; columns: IGridColumn[]; datasets: ReadonlyArray; rowKey?: string; tableLayout?: 'auto' | 'fixed'; onChange?: (conf: IGridOnChangeConfig) => any; scroll?: IGridScrollDelta; sortBy?: string; sortType?: GridSortType; defaultSortType?: GridSortType; emptyLabel?: React.ReactNode; selection?: IGridSelection; expandation?: IGridExpandation; loading?: boolean; bordered?: boolean; className?: string; rowClassName?: GridRowClassNameType; pageInfo?: IGridPageInfo; paginationType?: GridPaginationType; onRowClick?: IGridRowClickHandler; ellipsis?: boolean; onExpand?: IGridOnExpandHandler; components?: { row?: React.ComponentType; }; rowProps?: (data: Data, index: number) => RowProps; batchRender?: IGridBatchRender; stickyBatch?: boolean; autoStick?: boolean; autoStickOffsetTop?: number; disableHoverHighlight?: boolean; // scroll时hover每次都会重绘,提供属性去禁用,这时hover就没有样式了 loadingProps?: Omit; } export interface IGridState { mouseOverRowIndex: number; fixedColumnsBodyRowsHeight: Array; fixedColumnsHeadRowsHeight: Array; fixedColumnsBodyExpandRowsHeight: Array; expandRowKeys: boolean[]; showStickHead: boolean; tableWidth?: number; marginLeft?: string; } export interface IGridInnerColumn extends IGridColumn { key?: string; } // eslint-disable-next-line @typescript-eslint/ban-types export class Grid< Data = any, RowProps = Record, Key = string > extends PureComponent, IGridState> { static defaultProps: Partial = { className: '', bordered: false, datasets: [], columns: [], loading: false, paginationType: 'default', onChange: noop, rowKey: 'id', emptyLabel: '', scroll: {}, onRowClick: noop, ellipsis: false, onExpand: noop, stickyBatch: false, autoStick: false, autoStickOffsetTop: 0, disableHoverHighlight: false, }; mounted = false; selectionPropsCache: { [key: string]: { disabled?: boolean; reason?: React.ReactNode; }; } = {}; store: Store = new Store(); gridNode = createRef(); footNode = createRef