2016-06-19 10:56:42 +08:00
import classNames from 'classnames' ;
2020-04-27 15:08:54 +08:00
import RcTable , { Summary } from 'rc-table' ;
2022-06-22 14:57:09 +08:00
import { convertChildrenToColumns } from 'rc-table/lib/hooks/useColumns' ;
2022-05-07 14:31:54 +08:00
import type { TableProps as RcTableProps } from 'rc-table/lib/Table' ;
import { INTERNAL_HOOKS } from 'rc-table/lib/Table' ;
2022-06-22 14:57:09 +08:00
import omit from 'rc-util/lib/omit' ;
import * as React from 'react' ;
import { ConfigContext } from '../config-provider/context' ;
import defaultRenderEmpty from '../config-provider/defaultRenderEmpty' ;
import type { SizeType } from '../config-provider/SizeContext' ;
import SizeContext from '../config-provider/SizeContext' ;
import useBreakpoint from '../grid/hooks/useBreakpoint' ;
import defaultLocale from '../locale/en_US' ;
import Pagination from '../pagination' ;
2022-05-07 14:31:54 +08:00
import type { SpinProps } from '../spin' ;
import Spin from '../spin' ;
import type { TooltipProps } from '../tooltip' ;
import type { Breakpoint } from '../_util/responsiveObserve' ;
2022-06-22 14:57:09 +08:00
import scrollTo from '../_util/scrollTo' ;
import warning from '../_util/warning' ;
import Column from './Column' ;
import ColumnGroup from './ColumnGroup' ;
import renderExpandIcon from './ExpandIcon' ;
import type { FilterState } from './hooks/useFilter' ;
import useFilter , { getFilterData } from './hooks/useFilter' ;
import useLazyKVMap from './hooks/useLazyKVMap' ;
import usePagination , { DEFAULT_PAGE_SIZE , getPaginationParam } from './hooks/usePagination' ;
2020-12-29 10:38:43 +08:00
import useSelection , {
SELECTION_ALL ,
2021-11-26 17:50:41 +08:00
SELECTION_COLUMN ,
2020-12-29 10:38:43 +08:00
SELECTION_INVERT ,
SELECTION_NONE ,
} from './hooks/useSelection' ;
2022-05-07 14:31:54 +08:00
import type { SortState } from './hooks/useSorter' ;
import useSorter , { getSortData } from './hooks/useSorter' ;
2019-11-15 14:35:25 +08:00
import useTitleColumns from './hooks/useTitleColumns' ;
2022-06-22 14:57:09 +08:00
import type {
2022-09-30 17:44:24 +08:00
ColumnTitleProps ,
2022-06-22 14:57:09 +08:00
ColumnType ,
ExpandableConfig ,
ExpandType ,
FilterValue ,
GetPopupContainer ,
GetRowKey ,
SorterResult ,
SortOrder ,
TableAction ,
TableCurrentDataSource ,
TableLocale ,
TableRowSelection ,
} from './interface' ;
import { ColumnsType , TablePaginationConfig } from './interface' ;
2016-06-19 10:56:42 +08:00
2019-11-17 17:57:35 +08:00
export { ColumnsType , TablePaginationConfig } ;
2019-11-15 14:35:25 +08:00
const EMPTY_LIST : any [ ] = [ ] ;
2017-03-14 19:51:28 +08:00
2019-11-15 14:35:25 +08:00
interface ChangeEventInfo < RecordType > {
pagination : {
current? : number ;
pageSize? : number ;
total? : number ;
2019-08-14 19:17:23 +08:00
} ;
2021-02-20 16:32:59 +08:00
filters : Record < string , FilterValue | null > ;
2022-08-17 10:13:25 +08:00
sorter : SorterResult < RecordType > | SorterResult < RecordType > [ ] ;
2019-09-28 14:14:44 +08:00
2019-11-15 14:35:25 +08:00
filterStates : FilterState < RecordType > [ ] ;
sorterStates : SortState < RecordType > [ ] ;
2019-08-05 18:38:10 +08:00
2019-11-15 14:35:25 +08:00
resetPagination : Function ;
2019-08-28 17:39:38 +08:00
}
2016-11-22 10:11:12 +08:00
2019-11-15 14:35:25 +08:00
export interface TableProps < RecordType >
extends Omit <
RcTableProps < RecordType > ,
2020-06-13 02:29:20 +08:00
| 'transformColumns'
| 'internalHooks'
| 'internalRefs'
| 'data'
| 'columns'
| 'scroll'
| 'emptyText'
2019-11-15 14:35:25 +08:00
> {
dropdownPrefixCls? : string ;
dataSource? : RcTableProps < RecordType > [ 'data' ] ;
2019-11-19 10:03:03 +08:00
columns? : ColumnsType < RecordType > ;
2019-11-15 14:35:25 +08:00
pagination? : false | TablePaginationConfig ;
loading? : boolean | SpinProps ;
2020-01-03 13:38:16 +08:00
size? : SizeType ;
2019-11-15 14:35:25 +08:00
bordered? : boolean ;
locale? : TableLocale ;
onChange ? : (
2020-05-13 16:03:07 +08:00
pagination : TablePaginationConfig ,
2021-02-20 16:32:59 +08:00
filters : Record < string , FilterValue | null > ,
2022-08-17 10:13:25 +08:00
sorter : SorterResult < RecordType > | SorterResult < RecordType > [ ] ,
2019-11-15 14:35:25 +08:00
extra : TableCurrentDataSource < RecordType > ,
) = > void ;
rowSelection? : TableRowSelection < RecordType > ;
getPopupContainer? : GetPopupContainer ;
scroll? : RcTableProps < RecordType > [ 'scroll' ] & {
scrollToFirstRowOnChange? : boolean ;
2016-07-13 11:14:24 +08:00
} ;
2019-11-15 14:35:25 +08:00
sortDirections? : SortOrder [ ] ;
2021-02-01 10:15:39 +08:00
showSorterTooltip? : boolean | TooltipProps ;
2019-11-15 14:35:25 +08:00
}
2016-06-19 10:56:42 +08:00
2021-09-17 11:17:29 +08:00
function InternalTable < RecordType extends object = any > (
props : TableProps < RecordType > ,
ref : React.MutableRefObject < HTMLDivElement > ,
) {
2019-11-15 14:35:25 +08:00
const {
prefixCls : customizePrefixCls ,
className ,
2020-03-07 23:17:28 +08:00
style ,
2020-01-03 13:38:16 +08:00
size : customizeSize ,
2019-11-15 14:35:25 +08:00
bordered ,
2020-03-11 23:58:32 +08:00
dropdownPrefixCls : customizeDropdownPrefixCls ,
2019-11-15 14:35:25 +08:00
dataSource ,
pagination ,
rowSelection ,
2022-09-30 17:44:24 +08:00
rowKey = 'key' ,
2019-11-15 14:35:25 +08:00
rowClassName ,
columns ,
2020-03-01 13:11:28 +08:00
children ,
2020-04-13 22:56:26 +08:00
childrenColumnName : legacyChildrenColumnName ,
2019-11-15 14:35:25 +08:00
onChange ,
getPopupContainer ,
loading ,
expandIcon ,
expandable ,
expandedRowRender ,
2020-03-06 00:58:26 +08:00
expandIconColumnIndex ,
2019-11-15 14:35:25 +08:00
indentSize ,
scroll ,
sortDirections ,
locale ,
2020-02-29 22:01:13 +08:00
showSorterTooltip = true ,
2019-11-15 14:35:25 +08:00
} = props ;
2020-03-07 23:17:28 +08:00
2022-05-10 15:43:29 +08:00
warning (
2020-06-28 22:41:59 +08:00
! ( typeof rowKey === 'function' && rowKey . length > 1 ) ,
'Table' ,
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.' ,
) ;
2022-08-22 11:19:53 +08:00
[
[ 'filterDropdownVisible' , 'filterDropdownOpen' ] ,
[ 'onFilterDropdownVisibleChange' , 'onFilterDropdownOpenChange' ] ,
] . forEach ( ( [ deprecatedName , newName ] ) = > {
warning (
! ( deprecatedName in props ) ,
'Table' ,
` \` ${ deprecatedName } \` is deprecated which will be removed in next major version.Please use \` ${ newName } \` instead. ` ,
) ;
} ) ;
2022-02-17 18:11:33 +08:00
const baseColumns = React . useMemo (
2022-04-08 22:55:42 +08:00
( ) = > columns || ( convertChildrenToColumns ( children ) as ColumnsType < RecordType > ) ,
2022-02-17 18:11:33 +08:00
[ columns , children ] ,
) ;
const needResponsive = React . useMemo (
( ) = > baseColumns . some ( ( col : ColumnType < RecordType > ) = > col . responsive ) ,
[ baseColumns ] ,
) ;
const screens = useBreakpoint ( needResponsive ) ;
2020-04-24 12:17:42 +08:00
const mergedColumns = React . useMemo ( ( ) = > {
const matched = new Set ( Object . keys ( screens ) . filter ( ( m : Breakpoint ) = > screens [ m ] ) ) ;
2022-02-17 18:11:33 +08:00
return baseColumns . filter (
2022-04-08 22:55:42 +08:00
c = > ! c . responsive || c . responsive . some ( ( r : Breakpoint ) = > matched . has ( r ) ) ,
2020-04-24 12:17:42 +08:00
) ;
2022-02-17 18:11:33 +08:00
} , [ baseColumns , screens ] ) ;
2020-04-24 12:17:42 +08:00
const tableProps = omit ( props , [ 'className' , 'style' , 'columns' ] ) as TableProps < RecordType > ;
2020-03-07 23:17:28 +08:00
2020-01-03 13:38:16 +08:00
const size = React . useContext ( SizeContext ) ;
2021-09-11 21:44:03 +08:00
const {
locale : contextLocale = defaultLocale ,
renderEmpty ,
direction ,
} = React . useContext ( ConfigContext ) ;
2020-01-03 13:38:16 +08:00
const mergedSize = customizeSize || size ;
2020-03-02 17:15:39 +08:00
const tableLocale = { . . . contextLocale . Table , . . . locale } as TableLocale ;
2021-01-28 01:21:58 +08:00
const rawData : readonly RecordType [ ] = dataSource || EMPTY_LIST ;
2016-06-19 10:56:42 +08:00
2019-11-15 14:35:25 +08:00
const { getPrefixCls } = React . useContext ( ConfigContext ) ;
const prefixCls = getPrefixCls ( 'table' , customizePrefixCls ) ;
2020-03-11 23:58:32 +08:00
const dropdownPrefixCls = getPrefixCls ( 'dropdown' , customizeDropdownPrefixCls ) ;
2019-04-17 17:31:39 +08:00
2020-03-06 00:58:26 +08:00
const mergedExpandable : ExpandableConfig < RecordType > = {
2020-04-13 22:56:26 +08:00
childrenColumnName : legacyChildrenColumnName ,
2020-03-06 00:58:26 +08:00
expandIconColumnIndex ,
. . . expandable ,
} ;
2020-04-13 22:56:26 +08:00
const { childrenColumnName = 'children' } = mergedExpandable ;
2020-03-06 00:58:26 +08:00
2022-09-30 17:44:24 +08:00
const expandType = React . useMemo < ExpandType > ( ( ) = > {
2020-08-05 22:29:38 +08:00
if ( rawData . some ( item = > ( item as any ) ? . [ childrenColumnName ] ) ) {
2019-11-15 14:35:25 +08:00
return 'nest' ;
2019-04-17 17:31:39 +08:00
}
2019-01-08 20:52:31 +08:00
2019-11-15 14:35:25 +08:00
if ( expandedRowRender || ( expandable && expandable . expandedRowRender ) ) {
return 'row' ;
2016-06-19 10:56:42 +08:00
}
2017-11-18 00:03:30 +08:00
2019-11-15 14:35:25 +08:00
return null ;
} , [ rawData ] ) ;
2019-10-17 16:01:46 +08:00
2019-11-15 14:35:25 +08:00
const internalRefs = {
body : React.useRef < HTMLDivElement > ( ) ,
2019-08-05 18:38:10 +08:00
} ;
2016-06-19 10:56:42 +08:00
2019-11-15 14:35:25 +08:00
// ============================ RowKey ============================
const getRowKey = React . useMemo < GetRowKey < RecordType > > ( ( ) = > {
if ( typeof rowKey === 'function' ) {
return rowKey ;
2017-11-09 19:30:24 +08:00
}
2020-08-05 22:29:38 +08:00
return ( record : RecordType ) = > ( record as any ) ? . [ rowKey as string ] ;
2019-11-15 14:35:25 +08:00
} , [ rowKey ] ) ;
2017-11-09 19:30:24 +08:00
2019-11-15 14:35:25 +08:00
const [ getRecordByKey ] = useLazyKVMap ( rawData , childrenColumnName , getRowKey ) ;
2017-11-09 19:30:24 +08:00
2019-11-15 14:35:25 +08:00
// ============================ Events =============================
const changeEventInfo : Partial < ChangeEventInfo < RecordType > > = { } ;
2017-11-09 19:30:24 +08:00
2020-06-28 22:41:59 +08:00
const triggerOnChange = (
info : Partial < ChangeEventInfo < RecordType > > ,
action : TableAction ,
reset : boolean = false ,
) = > {
2019-11-15 14:35:25 +08:00
const changeInfo = {
. . . changeEventInfo ,
. . . info ,
2016-06-19 10:56:42 +08:00
} ;
2019-08-05 18:38:10 +08:00
2019-11-15 14:35:25 +08:00
if ( reset ) {
changeEventInfo . resetPagination ! ( ) ;
2017-11-21 13:48:37 +08:00
2019-11-15 14:35:25 +08:00
// Reset event param
if ( changeInfo . pagination ! . current ) {
changeInfo . pagination ! . current = 1 ;
2016-06-19 10:56:42 +08:00
}
2019-11-15 14:35:25 +08:00
// Trigger pagination events
if ( pagination && pagination . onChange ) {
2021-09-13 12:15:18 +08:00
pagination . onChange ( 1 , changeInfo . pagination ! . pageSize ! ) ;
2019-11-15 14:35:25 +08:00
}
2018-11-01 13:42:53 +08:00
}
2019-11-15 14:35:25 +08:00
if ( scroll && scroll . scrollToFirstRowOnChange !== false && internalRefs . body . current ) {
scrollTo ( 0 , {
getContainer : ( ) = > internalRefs . body . current ! ,
} ) ;
2018-10-06 18:20:43 +08:00
}
2019-06-10 11:59:46 +08:00
2021-02-19 18:26:53 +08:00
onChange ? . ( changeInfo . pagination ! , changeInfo . filters ! , changeInfo . sorter ! , {
currentDataSource : getFilterData (
getSortData ( rawData , changeInfo . sorterStates ! , childrenColumnName ) ,
changeInfo . filterStates ! ,
) ,
action ,
} ) ;
2019-08-05 18:38:10 +08:00
} ;
2016-06-19 10:56:42 +08:00
2021-01-28 01:21:58 +08:00
/ * *
2021-02-23 10:45:11 +08:00
* Controlled state in ` columns ` is not a good idea that makes too many code ( 1000 + line ? ) to read
* state out and then put it back to title render . Move these code into ` hooks ` but still too
2022-09-19 15:29:26 +08:00
* complex . We should provides Table props like ` sorter ` & ` filter ` to handle control in next big
* version .
2021-01-28 01:21:58 +08:00
* /
2019-11-15 14:35:25 +08:00
// ============================ Sorter =============================
const onSorterChange = (
2022-08-17 10:13:25 +08:00
sorter : SorterResult < RecordType > | SorterResult < RecordType > [ ] ,
2019-11-15 14:35:25 +08:00
sorterStates : SortState < RecordType > [ ] ,
) = > {
triggerOnChange (
{
sorter ,
sorterStates ,
} ,
2020-06-28 22:41:59 +08:00
'sort' ,
2019-12-30 16:43:34 +08:00
false ,
2019-08-05 18:38:10 +08:00
) ;
} ;
2019-11-15 14:35:25 +08:00
const [ transformSorterColumns , sortStates , sorterTitleProps , getSorters ] = useSorter < RecordType > ( {
prefixCls ,
2020-04-24 12:17:42 +08:00
mergedColumns ,
2019-11-15 14:35:25 +08:00
onSorterChange ,
sortDirections : sortDirections || [ 'ascend' , 'descend' ] ,
2020-02-29 22:01:13 +08:00
tableLocale ,
showSorterTooltip ,
2019-11-15 14:35:25 +08:00
} ) ;
2021-09-11 21:44:03 +08:00
const sortedData = React . useMemo (
( ) = > getSortData ( rawData , sortStates , childrenColumnName ) ,
[ rawData , sortStates ] ,
) ;
2019-11-15 14:35:25 +08:00
changeEventInfo . sorter = getSorters ( ) ;
changeEventInfo . sorterStates = sortStates ;
// ============================ Filter ============================
const onFilterChange = (
2021-02-20 16:32:59 +08:00
filters : Record < string , FilterValue > ,
2019-11-15 14:35:25 +08:00
filterStates : FilterState < RecordType > [ ] ,
) = > {
triggerOnChange (
{
filters ,
filterStates ,
} ,
2020-06-28 22:41:59 +08:00
'filter' ,
2019-11-15 14:35:25 +08:00
true ,
) ;
2018-12-07 20:02:01 +08:00
} ;
2016-06-19 10:56:42 +08:00
2022-09-19 15:29:26 +08:00
const [ transformFilterColumns , filterStates , filters ] = useFilter < RecordType > ( {
2019-11-15 14:35:25 +08:00
prefixCls ,
2020-03-02 17:15:39 +08:00
locale : tableLocale ,
2019-11-15 14:35:25 +08:00
dropdownPrefixCls ,
2020-04-24 12:17:42 +08:00
mergedColumns ,
2019-11-15 14:35:25 +08:00
onFilterChange ,
getPopupContainer ,
} ) ;
const mergedData = getFilterData ( sortedData , filterStates ) ;
2018-07-24 14:49:23 +08:00
2022-09-19 15:29:26 +08:00
changeEventInfo . filters = filters ;
2019-11-15 14:35:25 +08:00
changeEventInfo . filterStates = filterStates ;
2018-07-24 14:49:23 +08:00
2019-11-15 14:35:25 +08:00
// ============================ Column ============================
2022-09-30 17:44:24 +08:00
const columnTitleProps = React . useMemo < ColumnTitleProps < RecordType > > ( ( ) = > {
2022-09-19 15:29:26 +08:00
const mergedFilters : Record < string , FilterValue > = { } ;
Object . keys ( filters ) . forEach ( filterKey = > {
if ( filters [ filterKey ] !== null ) {
mergedFilters [ filterKey ] = filters [ filterKey ] ! ;
}
} ) ;
return {
2019-11-15 14:35:25 +08:00
. . . sorterTitleProps ,
2022-09-19 15:29:26 +08:00
filters : mergedFilters ,
} ;
} , [ sorterTitleProps , filters ] ) ;
2019-11-15 14:35:25 +08:00
const [ transformTitleColumns ] = useTitleColumns ( columnTitleProps ) ;
2016-06-19 10:56:42 +08:00
2019-11-15 14:35:25 +08:00
// ========================== Pagination ==========================
const onPaginationChange = ( current : number , pageSize : number ) = > {
2020-06-28 22:41:59 +08:00
triggerOnChange (
{
pagination : { . . . changeEventInfo . pagination , current , pageSize } ,
} ,
'paginate' ,
) ;
2018-12-07 20:02:01 +08:00
} ;
2016-06-19 10:56:42 +08:00
2019-11-15 14:35:25 +08:00
const [ mergedPagination , resetPagination ] = usePagination (
mergedData . length ,
pagination ,
onPaginationChange ,
) ;
2017-02-23 19:29:47 +08:00
2019-11-15 14:35:25 +08:00
changeEventInfo . pagination =
pagination === false ? { } : getPaginationParam ( pagination , mergedPagination ) ;
changeEventInfo . resetPagination = resetPagination ;
// ============================= Data =============================
const pageData = React . useMemo < RecordType [ ] > ( ( ) = > {
2020-04-10 14:13:14 +08:00
if ( pagination === false || ! mergedPagination . pageSize ) {
return mergedData ;
}
const { current = 1 , total , pageSize = DEFAULT_PAGE_SIZE } = mergedPagination ;
2022-05-10 15:43:29 +08:00
warning ( current > 0 , 'Table' , '`current` should be positive number.' ) ;
2020-04-10 14:13:14 +08:00
// Dynamic table data
if ( mergedData . length < total ! ) {
if ( mergedData . length > pageSize ) {
2022-05-10 15:43:29 +08:00
warning (
2020-04-10 14:13:14 +08:00
false ,
'Table' ,
'`dataSource` length is less than `pagination.total` but large than `pagination.pageSize`. Please make sure your config correct data with async mode.' ,
) ;
return mergedData . slice ( ( current - 1 ) * pageSize , current * pageSize ) ;
}
2019-11-15 14:35:25 +08:00
return mergedData ;
}
2020-04-24 12:17:42 +08:00
return mergedData . slice ( ( current - 1 ) * pageSize , current * pageSize ) ;
2019-11-15 14:35:25 +08:00
} , [
! ! pagination ,
mergedData ,
mergedPagination && mergedPagination . current ,
mergedPagination && mergedPagination . pageSize ,
mergedPagination && mergedPagination . total ,
] ) ;
// ========================== Selections ==========================
const [ transformSelectionColumns , selectedKeySet ] = useSelection < RecordType > ( rowSelection , {
prefixCls ,
data : mergedData ,
pageData ,
getRowKey ,
getRecordByKey ,
expandType ,
childrenColumnName ,
2020-03-02 17:15:39 +08:00
locale : tableLocale ,
2020-04-01 17:14:53 +08:00
getPopupContainer ,
2019-11-15 14:35:25 +08:00
} ) ;
2016-06-19 10:56:42 +08:00
2019-11-15 14:35:25 +08:00
const internalRowClassName = ( record : RecordType , index : number , indent : number ) = > {
2022-09-30 17:44:24 +08:00
let mergedRowClassName : string ;
2019-11-15 14:35:25 +08:00
if ( typeof rowClassName === 'function' ) {
mergedRowClassName = classNames ( rowClassName ( record , index , indent ) ) ;
2016-06-19 10:56:42 +08:00
} else {
2019-11-15 14:35:25 +08:00
mergedRowClassName = classNames ( rowClassName ) ;
2016-06-19 10:56:42 +08:00
}
2016-11-11 15:26:51 +08:00
2019-11-15 14:35:25 +08:00
return classNames (
{
[ ` ${ prefixCls } -row-selected ` ] : selectedKeySet . has ( getRowKey ( record , index ) ) ,
} ,
mergedRowClassName ,
) ;
2018-12-07 20:02:01 +08:00
} ;
2016-06-19 10:56:42 +08:00
2019-11-15 14:35:25 +08:00
// ========================== Expandable ==========================
2016-06-19 10:56:42 +08:00
2020-02-01 22:50:58 +08:00
// Pass origin render status into `rc-table`, this can be removed when refactor with `rc-table`
( mergedExpandable as any ) . __PARENT_RENDER_ICON__ = mergedExpandable . expandIcon ;
2019-11-15 14:35:25 +08:00
// Customize expandable icon
mergedExpandable . expandIcon =
mergedExpandable . expandIcon || expandIcon || renderExpandIcon ( tableLocale ! ) ;
2019-08-05 18:38:10 +08:00
2020-02-10 15:04:22 +08:00
// Adjust expand icon index, no overwrite expandIconColumnIndex if set.
2020-03-06 00:58:26 +08:00
if ( expandType === 'nest' && mergedExpandable . expandIconColumnIndex === undefined ) {
2019-11-15 14:35:25 +08:00
mergedExpandable . expandIconColumnIndex = rowSelection ? 1 : 0 ;
2020-03-06 00:58:26 +08:00
} else if ( mergedExpandable . expandIconColumnIndex ! > 0 && rowSelection ) {
mergedExpandable . expandIconColumnIndex ! -= 1 ;
2019-08-05 18:38:10 +08:00
}
2019-11-15 14:35:25 +08:00
// Indent size
2020-07-30 10:16:44 +08:00
if ( typeof mergedExpandable . indentSize !== 'number' ) {
mergedExpandable . indentSize = typeof indentSize === 'number' ? indentSize : 15 ;
}
2019-08-05 18:38:10 +08:00
2019-11-15 14:35:25 +08:00
// ============================ Render ============================
const transformColumns = React . useCallback (
2020-12-09 17:12:32 +08:00
( innerColumns : ColumnsType < RecordType > ) : ColumnsType < RecordType > = >
transformTitleColumns (
2019-11-15 14:35:25 +08:00
transformSelectionColumns ( transformFilterColumns ( transformSorterColumns ( innerColumns ) ) ) ,
2020-12-09 17:12:32 +08:00
) ,
2019-11-15 14:35:25 +08:00
[ transformSorterColumns , transformFilterColumns , transformSelectionColumns ] ,
) ;
2019-08-05 18:38:10 +08:00
2019-11-15 14:35:25 +08:00
let topPaginationNode : React.ReactNode ;
let bottomPaginationNode : React.ReactNode ;
2020-08-28 15:48:19 +08:00
if ( pagination !== false && mergedPagination ? . total ) {
2020-05-13 16:03:07 +08:00
let paginationSize : TablePaginationConfig [ 'size' ] ;
2019-11-15 14:35:25 +08:00
if ( mergedPagination . size ) {
paginationSize = mergedPagination . size ;
} else {
2020-01-03 13:38:16 +08:00
paginationSize = mergedSize === 'small' || mergedSize === 'middle' ? 'small' : undefined ;
2019-08-05 18:38:10 +08:00
}
2020-04-29 12:12:54 +08:00
const renderPagination = ( position : string ) = > (
2019-08-05 18:38:10 +08:00
< Pagination
2019-11-15 14:35:25 +08:00
{ . . . mergedPagination }
2021-09-11 21:44:03 +08:00
className = { classNames (
` ${ prefixCls } -pagination ${ prefixCls } -pagination- ${ position } ` ,
mergedPagination . className ,
) }
2019-11-15 14:35:25 +08:00
size = { paginationSize }
2019-08-05 18:38:10 +08:00
/ >
2019-11-15 14:35:25 +08:00
) ;
2020-04-29 12:12:54 +08:00
const defaultPosition = direction === 'rtl' ? 'left' : 'right' ;
2021-02-07 20:23:40 +08:00
const { position } = mergedPagination ;
if ( position !== null && Array . isArray ( position ) ) {
2022-10-21 11:45:55 +08:00
const topPos = position . find ( p = > p . includes ( 'top' ) ) ;
const bottomPos = position . find ( p = > p . includes ( 'bottom' ) ) ;
2021-02-07 20:23:40 +08:00
const isDisable = position . every ( p = > ` ${ p } ` === 'none' ) ;
if ( ! topPos && ! bottomPos && ! isDisable ) {
2020-04-29 12:12:54 +08:00
bottomPaginationNode = renderPagination ( defaultPosition ) ;
2021-02-07 20:23:40 +08:00
}
if ( topPos ) {
topPaginationNode = renderPagination ( topPos ! . toLowerCase ( ) . replace ( 'top' , '' ) ) ;
}
if ( bottomPos ) {
bottomPaginationNode = renderPagination ( bottomPos ! . toLowerCase ( ) . replace ( 'bottom' , '' ) ) ;
2020-03-27 15:48:42 +08:00
}
} else {
2020-04-29 12:12:54 +08:00
bottomPaginationNode = renderPagination ( defaultPosition ) ;
2016-06-19 10:56:42 +08:00
}
}
2019-11-15 14:35:25 +08:00
// >>>>>>>>> Spinning
let spinProps : SpinProps | undefined ;
if ( typeof loading === 'boolean' ) {
spinProps = {
spinning : loading ,
} ;
2020-03-30 15:45:14 +08:00
} else if ( typeof loading === 'object' ) {
spinProps = {
spinning : true ,
. . . loading ,
} ;
2018-09-17 19:52:24 +08:00
}
2020-09-06 13:07:39 +08:00
const wrapperClassNames = classNames (
` ${ prefixCls } -wrapper ` ,
{
[ ` ${ prefixCls } -wrapper-rtl ` ] : direction === 'rtl' ,
} ,
className ,
) ;
2019-11-15 14:35:25 +08:00
return (
2021-09-17 11:17:29 +08:00
< div ref = { ref } className = { wrapperClassNames } style = { style } >
2019-11-15 14:35:25 +08:00
< Spin spinning = { false } { ...spinProps } >
{ topPaginationNode }
< RcTable < RecordType >
2020-03-07 23:17:28 +08:00
{ . . . tableProps }
2022-04-08 22:55:42 +08:00
columns = { mergedColumns as RcTableProps < RecordType > [ 'columns' ] }
2020-03-10 20:30:31 +08:00
direction = { direction }
2019-11-15 14:35:25 +08:00
expandable = { mergedExpandable }
prefixCls = { prefixCls }
2020-03-07 23:17:28 +08:00
className = { classNames ( {
2020-01-03 13:38:16 +08:00
[ ` ${ prefixCls } -middle ` ] : mergedSize === 'middle' ,
[ ` ${ prefixCls } -small ` ] : mergedSize === 'small' ,
2019-11-15 14:35:25 +08:00
[ ` ${ prefixCls } -bordered ` ] : bordered ,
2020-05-19 14:45:57 +08:00
[ ` ${ prefixCls } -empty ` ] : rawData . length === 0 ,
2019-11-15 14:35:25 +08:00
} ) }
data = { pageData }
rowKey = { getRowKey }
rowClassName = { internalRowClassName }
2022-05-16 16:34:42 +08:00
emptyText = { ( locale && locale . emptyText ) || ( renderEmpty || defaultRenderEmpty ) ( 'Table' ) }
2019-11-15 14:35:25 +08:00
// Internal
internalHooks = { INTERNAL_HOOKS }
internalRefs = { internalRefs as any }
2022-04-08 22:55:42 +08:00
transformColumns = { transformColumns as RcTableProps < RecordType > [ 'transformColumns' ] }
2019-11-15 14:35:25 +08:00
/ >
2020-08-28 15:48:19 +08:00
{ bottomPaginationNode }
2019-11-15 14:35:25 +08:00
< / Spin >
< / div >
) ;
2016-06-19 10:56:42 +08:00
}
2019-08-28 02:35:39 +08:00
2021-09-30 11:43:42 +08:00
const ForwardTable = React . forwardRef ( InternalTable ) as < RecordType extends object = any > (
props : React.PropsWithChildren < TableProps < RecordType > > & { ref? : React.Ref < HTMLDivElement > } ,
) = > React . ReactElement ;
2021-09-17 11:17:29 +08:00
2021-09-30 11:43:42 +08:00
type InternalTableType = typeof ForwardTable ;
2021-09-17 11:17:29 +08:00
2023-01-03 11:46:48 +08:00
type CompoundedComponent = InternalTableType & {
2021-11-26 17:50:41 +08:00
SELECTION_COLUMN : typeof SELECTION_COLUMN ;
EXPAND_COLUMN : typeof RcTable . EXPAND_COLUMN ;
2021-09-17 11:17:29 +08:00
SELECTION_ALL : 'SELECT_ALL' ;
SELECTION_INVERT : 'SELECT_INVERT' ;
SELECTION_NONE : 'SELECT_NONE' ;
Column : typeof Column ;
ColumnGroup : typeof ColumnGroup ;
Summary : typeof Summary ;
2023-01-03 11:46:48 +08:00
} ;
2021-09-17 11:17:29 +08:00
2023-01-03 11:46:48 +08:00
const Table = ForwardTable as CompoundedComponent ;
2021-09-17 11:17:29 +08:00
2021-11-26 17:50:41 +08:00
Table . SELECTION_COLUMN = SELECTION_COLUMN ;
Table . EXPAND_COLUMN = RcTable . EXPAND_COLUMN ;
2019-11-15 14:35:25 +08:00
Table . SELECTION_ALL = SELECTION_ALL ;
Table . SELECTION_INVERT = SELECTION_INVERT ;
2020-12-29 10:38:43 +08:00
Table . SELECTION_NONE = SELECTION_NONE ;
2019-11-15 14:35:25 +08:00
Table . Column = Column ;
Table . ColumnGroup = ColumnGroup ;
2020-04-27 15:08:54 +08:00
Table . Summary = Summary ;
2019-08-28 02:35:39 +08:00
2019-11-15 14:35:25 +08:00
export default Table ;