2021-09-25 16:51:32 +08:00
import RcTable from '../vc-table' ;
import type { TableProps as RcTableProps } from '../vc-table/Table' ;
import { INTERNAL _HOOKS } from '../vc-table/Table' ;
import type { SpinProps } from '../spin' ;
import Spin from '../spin' ;
import Pagination from '../pagination' ;
import type { TooltipProps } from '../tooltip' ;
import usePagination , { DEFAULT _PAGE _SIZE , getPaginationParam } from './hooks/usePagination' ;
import useLazyKVMap from './hooks/useLazyKVMap' ;
import type { Breakpoint } from '../_util/responsiveObserve' ;
2021-06-26 09:35:40 +08:00
import type {
2021-09-25 16:51:32 +08:00
TableRowSelection ,
GetRowKey ,
ColumnType ,
ColumnsType ,
TableCurrentDataSource ,
SorterResult ,
GetPopupContainer ,
ExpandType ,
TablePaginationConfig ,
SortOrder ,
TableLocale ,
TableAction ,
FilterValue ,
2020-10-23 14:29:39 +08:00
} from './interface' ;
2021-09-25 16:51:32 +08:00
import useSelection from './hooks/useSelection' ;
import type { SortState } from './hooks/useSorter' ;
import useSorter , { getSortData } from './hooks/useSorter' ;
import type { FilterState } from './hooks/useFilter' ;
import useFilter , { getFilterData } from './hooks/useFilter' ;
import useTitleColumns from './hooks/useTitleColumns' ;
import renderExpandIcon from './ExpandIcon' ;
2020-03-07 19:45:13 +08:00
import scrollTo from '../_util/scrollTo' ;
2021-09-25 16:51:32 +08:00
import defaultLocale from '../locale/en_US' ;
import type { SizeType } from '../config-provider' ;
import devWarning from '../vc-util/devWarning' ;
2023-02-16 07:44:48 +08:00
import type { CSSProperties } from 'vue' ;
2021-12-16 16:01:58 +08:00
import { nextTick , reactive , ref , computed , defineComponent , toRef , watchEffect , watch } from 'vue' ;
2021-09-25 16:51:32 +08:00
import type { DefaultRecordType } from '../vc-table/interface' ;
import useBreakpoint from '../_util/hooks/useBreakpoint' ;
2023-01-27 16:00:17 +08:00
import useConfigInject from '../config-provider/hooks/useConfigInject' ;
2021-09-25 16:51:32 +08:00
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver' ;
import classNames from '../_util/classNames' ;
import omit from '../_util/omit' ;
import { initDefaultProps } from '../_util/props-util' ;
2021-10-27 14:58:55 +08:00
import { useProvideSlots , useProvideTableContext } from './context' ;
2021-09-25 16:51:32 +08:00
import type { ContextSlots } from './context' ;
import useColumns from './hooks/useColumns' ;
import { convertChildrenToColumns } from './util' ;
2023-02-16 07:44:48 +08:00
import {
stringType ,
booleanType ,
arrayType ,
someType ,
functionType ,
objectType ,
} from '../_util/type' ;
// CSSINJS
import useStyle from './style' ;
2021-09-25 16:51:32 +08:00
export type { ColumnsType , TablePaginationConfig } ;
const EMPTY _LIST : any [ ] = [ ] ;
interface ChangeEventInfo < RecordType = DefaultRecordType > {
pagination : {
current ? : number ;
pageSize ? : number ;
total ? : number ;
} ;
filters : Record < string , FilterValue | null > ;
sorter : SorterResult < RecordType > | SorterResult < RecordType > [ ] ;
2019-01-12 11:33:27 +08:00
2021-09-25 16:51:32 +08:00
filterStates : FilterState < RecordType > [ ] ;
sorterStates : SortState < RecordType > [ ] ;
2019-01-12 11:33:27 +08:00
2021-09-25 16:51:32 +08:00
resetPagination : Function ;
2018-03-31 17:46:35 +08:00
}
2021-09-25 16:51:32 +08:00
export interface TableProps < RecordType = DefaultRecordType >
extends Omit <
RcTableProps < RecordType > ,
| 'transformColumns'
| 'internalHooks'
| 'internalRefs'
| 'data'
| 'columns'
| 'scroll'
| 'emptyText'
| 'canExpandable'
| 'onUpdateInternalRefs'
> {
dropdownPrefixCls ? : string ;
dataSource ? : RcTableProps < RecordType > [ 'data' ] ;
columns ? : ColumnsType < RecordType > ;
pagination ? : false | TablePaginationConfig ;
loading ? : boolean | SpinProps ;
size ? : SizeType ;
bordered ? : boolean ;
locale ? : TableLocale ;
onChange ? : (
pagination : TablePaginationConfig ,
filters : Record < string , FilterValue | null > ,
sorter : SorterResult < RecordType > | SorterResult < RecordType > [ ] ,
extra : TableCurrentDataSource < RecordType > ,
) => void ;
2023-04-27 21:04:29 +08:00
onResizeColumn ? : ( w : number , col : ColumnType ) => void ;
2021-09-25 16:51:32 +08:00
rowSelection ? : TableRowSelection < RecordType > ;
getPopupContainer ? : GetPopupContainer ;
scroll ? : RcTableProps < RecordType > [ 'scroll' ] & {
scrollToFirstRowOnChange ? : boolean ;
} ;
sortDirections ? : SortOrder [ ] ;
showSorterTooltip ? : boolean | TooltipProps ;
2020-03-07 19:45:13 +08:00
}
2021-09-25 16:51:32 +08:00
export const tableProps = ( ) => {
2020-03-07 19:45:13 +08:00
return {
2023-02-16 07:44:48 +08:00
prefixCls : stringType < string > ( ) ,
columns : arrayType < ColumnsType > ( ) ,
rowKey : someType < TableProps [ ' rowKey ' ] > ( [ String , Function ] ) ,
tableLayout : stringType < TableProps [ ' tableLayout ' ] > ( ) ,
rowClassName : someType < TableProps [ ' rowClassName ' ] > ( [ String , Function ] ) ,
title : functionType < TableProps [ ' title ' ] > ( ) ,
footer : functionType < TableProps [ ' footer ' ] > ( ) ,
id : stringType < TableProps [ ' id ' ] > ( ) ,
showHeader : booleanType ( ) ,
components : objectType < TableProps [ ' components ' ] > ( ) ,
customRow : functionType < TableProps [ ' customRow ' ] > ( ) ,
customHeaderRow : functionType < TableProps [ ' customHeaderRow ' ] > ( ) ,
direction : stringType < TableProps [ ' direction ' ] > ( ) ,
expandFixed : someType < TableProps [ ' expandFixed ' ] > ( [ Boolean , String ] ) ,
expandColumnWidth : Number ,
expandedRowKeys : arrayType < TableProps [ ' expandedRowKeys ' ] > ( ) ,
defaultExpandedRowKeys : arrayType < TableProps [ ' defaultExpandedRowKeys ' ] > ( ) ,
expandedRowRender : functionType < TableProps [ ' expandedRowRender ' ] > ( ) ,
expandRowByClick : booleanType ( ) ,
expandIcon : functionType < TableProps [ ' expandIcon ' ] > ( ) ,
onExpand : functionType < TableProps [ ' onExpand ' ] > ( ) ,
onExpandedRowsChange : functionType < TableProps [ ' onExpandedRowsChange ' ] > ( ) ,
'onUpdate:expandedRowKeys' : functionType < TableProps [ ' onExpandedRowsChange ' ] > ( ) ,
defaultExpandAllRows : booleanType ( ) ,
indentSize : Number ,
2022-03-12 09:56:32 +08:00
/** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */
2023-02-16 07:44:48 +08:00
expandIconColumnIndex : Number ,
showExpandColumn : booleanType ( ) ,
expandedRowClassName : functionType < TableProps [ ' expandedRowClassName ' ] > ( ) ,
childrenColumnName : stringType < TableProps [ ' childrenColumnName ' ] > ( ) ,
rowExpandable : functionType < TableProps [ ' rowExpandable ' ] > ( ) ,
sticky : someType < TableProps [ ' sticky ' ] > ( [ Boolean , Object ] ) ,
2021-09-25 16:51:32 +08:00
dropdownPrefixCls : String ,
2023-02-16 07:44:48 +08:00
dataSource : arrayType < RcTableProps [ ' data ' ] > ( ) ,
pagination : someType < false | TablePaginationConfig > ( [ Boolean , Object ] ) ,
loading : someType < boolean | SpinProps > ( [ Boolean , Object ] ) ,
size : stringType < SizeType > ( ) ,
bordered : booleanType ( ) ,
locale : objectType < TableLocale > ( ) ,
onChange :
functionType <
2021-09-25 16:51:32 +08:00
(
pagination : TablePaginationConfig ,
filters : Record < string , FilterValue | null > ,
sorter : SorterResult | SorterResult [ ] ,
extra : TableCurrentDataSource ,
) => void
2023-02-16 07:44:48 +08:00
> ( ) ,
onResizeColumn : functionType < ( w : number , col : ColumnType ) => void > ( ) ,
rowSelection : objectType < TableRowSelection > ( ) ,
getPopupContainer : functionType < GetPopupContainer > ( ) ,
scroll : objectType <
RcTableProps [ 'scroll' ] & {
scrollToFirstRowOnChange ? : boolean ;
}
> ( ) ,
sortDirections : arrayType < SortOrder [ ] > ( ) ,
showSorterTooltip : someType < boolean | TooltipProps > ( [ Boolean , Object ] , true ) ,
contextSlots : objectType < ContextSlots > ( ) ,
transformCellText : functionType < TableProps [ ' transformCellText ' ] > ( ) ,
2020-03-07 19:45:13 +08:00
} ;
} ;
2021-09-25 16:51:32 +08:00
const InteralTable = defineComponent <
TableProps & {
contextSlots : ContextSlots ;
2020-03-07 19:45:13 +08:00
}
2021-09-25 16:51:32 +08:00
> ( {
name : 'InteralTable' ,
inheritAttrs : false ,
props : initDefaultProps ( tableProps ( ) , {
rowKey : 'key' ,
} ) as any ,
// emits: ['expandedRowsChange', 'change', 'expand'],
slots : [
'emptyText' ,
'expandIcon' ,
'title' ,
'footer' ,
'summary' ,
'expandedRowRender' ,
'bodyCell' ,
'headerCell' ,
'customFilterIcon' ,
'customFilterDropdown' ,
2023-02-17 09:49:21 +08:00
'expandColumnTitle' ,
2021-09-25 16:51:32 +08:00
] ,
2021-10-27 14:58:55 +08:00
setup ( props , { attrs , slots , expose , emit } ) {
2021-09-25 16:51:32 +08:00
devWarning (
! ( typeof props . rowKey === 'function' && props . rowKey . length > 1 ) ,
'Table' ,
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.' ,
) ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
useProvideSlots ( computed ( ( ) => props . contextSlots ) ) ;
2021-10-27 14:58:55 +08:00
useProvideTableContext ( {
onResizeColumn : ( w , col ) => {
emit ( 'resizeColumn' , w , col ) ;
} ,
} ) ;
2021-09-25 16:51:32 +08:00
const screens = useBreakpoint ( ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const mergedColumns = computed ( ( ) => {
2022-01-17 10:47:04 +08:00
const matched = new Set (
Object . keys ( screens . value ) . filter ( ( m : Breakpoint ) => screens . value [ m ] ) ,
) ;
2021-09-25 16:51:32 +08:00
return props . columns . filter (
( c : ColumnType < DefaultRecordType > ) =>
! c . responsive || c . responsive . some ( ( r : Breakpoint ) => matched . has ( r ) ) ,
) ;
2021-02-27 22:50:21 +08:00
} ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const {
size : mergedSize ,
renderEmpty ,
direction ,
prefixCls ,
configProvider ,
} = useConfigInject ( 'table' , props ) ;
2023-02-16 07:44:48 +08:00
// Style
const [ wrapSSR , hashId ] = useStyle ( prefixCls ) ;
2021-09-25 16:51:32 +08:00
const transformCellText = computed (
2023-01-27 16:00:17 +08:00
( ) => props . transformCellText || configProvider . transformCellText ? . value ,
2019-09-23 08:38:54 +08:00
) ;
2021-09-25 16:51:32 +08:00
const [ tableLocale ] = useLocaleReceiver ( 'Table' , defaultLocale . Table , toRef ( props , 'locale' ) ) ;
const rawData = computed ( ( ) => props . dataSource || EMPTY _LIST ) ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
const dropdownPrefixCls = computed ( ( ) =>
configProvider . getPrefixCls ( 'dropdown' , props . dropdownPrefixCls ) ,
) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const childrenColumnName = computed ( ( ) => props . childrenColumnName || 'children' ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const expandType = computed < ExpandType > ( ( ) => {
if ( rawData . value . some ( item => ( item as any ) ? . [ childrenColumnName . value ] ) ) {
return 'nest' ;
2018-03-31 21:11:02 +08:00
}
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
if ( props . expandedRowRender ) {
return 'row' ;
2019-04-30 16:59:53 +08:00
}
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
return null ;
} ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const internalRefs = reactive ( {
body : null ,
} ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const updateInternalRefs = refs => {
Object . assign ( internalRefs , refs ) ;
} ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
// ============================ RowKey ============================
const getRowKey = computed < GetRowKey < DefaultRecordType > > ( ( ) => {
if ( typeof props . rowKey === 'function' ) {
return props . rowKey ;
2018-03-31 21:11:02 +08:00
}
2021-09-25 16:51:32 +08:00
return record => ( record as any ) ? . [ props . rowKey as string ] ;
} ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const [ getRecordByKey ] = useLazyKVMap ( rawData , childrenColumnName , getRowKey ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
// ============================ Events =============================
const changeEventInfo : Partial < ChangeEventInfo > = { } ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const triggerOnChange = (
info : Partial < ChangeEventInfo > ,
action : TableAction ,
reset = false ,
) => {
const { pagination , scroll , onChange } = props ;
const changeInfo = {
... changeEventInfo ,
... info ,
2019-01-12 11:33:27 +08:00
} ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
if ( reset ) {
changeEventInfo . resetPagination ! ( ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
// Reset event param
if ( changeInfo . pagination ! . current ) {
changeInfo . pagination ! . current = 1 ;
2018-03-31 21:11:02 +08:00
}
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
// Trigger pagination events
if ( pagination && pagination . onChange ) {
pagination . onChange ( 1 , changeInfo . pagination ! . pageSize ) ;
}
2020-03-07 19:45:13 +08:00
}
2021-09-25 16:51:32 +08:00
if ( scroll && scroll . scrollToFirstRowOnChange !== false && internalRefs . body ) {
2020-03-07 19:45:13 +08:00
scrollTo ( 0 , {
2021-09-25 16:51:32 +08:00
getContainer : ( ) => internalRefs . body ,
2020-03-07 19:45:13 +08:00
} ) ;
}
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
onChange ? . ( changeInfo . pagination ! , changeInfo . filters ! , changeInfo . sorter ! , {
currentDataSource : getFilterData (
getSortData ( rawData . value , changeInfo . sorterStates ! , childrenColumnName . value ) ,
changeInfo . filterStates ! ,
) ,
action ,
2019-01-12 11:33:27 +08:00
} ) ;
2021-09-25 16:51:32 +08:00
} ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +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
* complex . We should provides Table props like ` sorter ` & ` filter ` to handle control in next big version .
* /
// ============================ Sorter =============================
const onSorterChange = ( sorter : SorterResult | SorterResult [ ] , sorterStates : SortState [ ] ) => {
triggerOnChange (
{
sorter ,
sorterStates ,
} ,
'sort' ,
false ,
) ;
} ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const [ transformSorterColumns , sortStates , sorterTitleProps , sorters ] = useSorter ( {
prefixCls ,
mergedColumns ,
onSorterChange ,
sortDirections : computed ( ( ) => props . sortDirections || [ 'ascend' , 'descend' ] ) ,
tableLocale ,
showSorterTooltip : toRef ( props , 'showSorterTooltip' ) ,
} ) ;
const sortedData = computed ( ( ) =>
getSortData ( rawData . value , sortStates . value , childrenColumnName . value ) ,
) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
// ============================ Filter ============================
const onFilterChange = ( filters : Record < string , FilterValue > , filterStates : FilterState [ ] ) => {
triggerOnChange (
{
filters ,
filterStates ,
} ,
'filter' ,
true ,
) ;
} ;
2018-03-31 21:11:02 +08:00
2021-09-25 16:51:32 +08:00
const [ transformFilterColumns , filterStates , filters ] = useFilter ( {
prefixCls ,
locale : tableLocale ,
dropdownPrefixCls ,
mergedColumns ,
onFilterChange ,
getPopupContainer : toRef ( props , 'getPopupContainer' ) ,
} ) ;
const mergedData = computed ( ( ) => getFilterData ( sortedData . value , filterStates . value ) ) ;
// ============================ Column ============================
const [ transformBasicColumns ] = useColumns ( toRef ( props , 'contextSlots' ) ) ;
2023-02-16 19:23:44 +08:00
const columnTitleProps = computed ( ( ) => {
const mergedFilters : Record < string , FilterValue > = { } ;
const filtersValue = filters . value ;
Object . keys ( filtersValue ) . forEach ( filterKey => {
if ( filtersValue [ filterKey ] !== null ) {
mergedFilters [ filterKey ] = filtersValue [ filterKey ] ! ;
}
} ) ;
return {
... sorterTitleProps . value ,
filters : mergedFilters ,
} ;
} ) ;
2021-09-25 16:51:32 +08:00
const [ transformTitleColumns ] = useTitleColumns ( columnTitleProps ) ;
// ========================== Pagination ==========================
const onPaginationChange = ( current : number , pageSize : number ) => {
triggerOnChange (
{
pagination : { ... changeEventInfo . pagination , current , pageSize } ,
} ,
'paginate' ,
) ;
} ;
2018-03-31 21:11:02 +08:00
2021-09-25 16:51:32 +08:00
const [ mergedPagination , resetPagination ] = usePagination (
computed ( ( ) => mergedData . value . length ) ,
toRef ( props , 'pagination' ) ,
onPaginationChange ,
) ;
2018-09-05 21:28:54 +08:00
2021-09-25 16:51:32 +08:00
watchEffect ( ( ) => {
changeEventInfo . sorter = sorters . value ;
changeEventInfo . sorterStates = sortStates . value ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
changeEventInfo . filters = filters . value ;
changeEventInfo . filterStates = filterStates . value ;
changeEventInfo . pagination =
props . pagination === false
? { }
2023-02-16 19:23:44 +08:00
: getPaginationParam ( mergedPagination . value , props . pagination ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
changeEventInfo . resetPagination = resetPagination ;
} ) ;
2018-03-31 21:11:02 +08:00
2021-09-25 16:51:32 +08:00
// ============================= Data =============================
const pageData = computed ( ( ) => {
if ( props . pagination === false || ! mergedPagination . value . pageSize ) {
return mergedData . value ;
2018-03-31 21:11:02 +08:00
}
2021-09-25 16:51:32 +08:00
const { current = 1 , total , pageSize = DEFAULT _PAGE _SIZE } = mergedPagination . value ;
devWarning ( current > 0 , 'Table' , '`current` should be positive number.' ) ;
2018-03-31 21:11:02 +08:00
2021-09-25 16:51:32 +08:00
// Dynamic table data
if ( mergedData . value . length < total ! ) {
if ( mergedData . value . length > pageSize ) {
return mergedData . value . slice ( ( current - 1 ) * pageSize , current * pageSize ) ;
}
return mergedData . value ;
2018-03-31 21:11:02 +08:00
}
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
return mergedData . value . slice ( ( current - 1 ) * pageSize , current * pageSize ) ;
} ) ;
2018-03-31 17:46:35 +08:00
2021-12-16 16:01:58 +08:00
watchEffect (
( ) => {
nextTick ( ( ) => {
const { total , pageSize = DEFAULT _PAGE _SIZE } = mergedPagination . value ;
// Dynamic table data
if ( mergedData . value . length < total ! ) {
if ( mergedData . value . length > pageSize ) {
devWarning (
false ,
'Table' ,
'`dataSource` length is less than `pagination.total` but large than `pagination.pageSize`. Please make sure your config correct data with async mode.' ,
) ;
}
}
} ) ;
} ,
{ flush : 'post' } ,
) ;
2021-10-14 10:42:35 +08:00
const expandIconColumnIndex = computed ( ( ) => {
2022-03-12 09:56:32 +08:00
if ( props . showExpandColumn === false ) return - 1 ;
2021-10-14 10:42:35 +08:00
// Adjust expand icon index, no overwrite expandIconColumnIndex if set.
if ( expandType . value === 'nest' && props . expandIconColumnIndex === undefined ) {
return props . rowSelection ? 1 : 0 ;
} else if ( props . expandIconColumnIndex ! > 0 && props . rowSelection ) {
return props . expandIconColumnIndex - 1 ;
}
return props . expandIconColumnIndex ;
} ) ;
2021-11-20 16:29:27 +08:00
const rowSelection = ref ( ) ;
watch (
( ) => props . rowSelection ,
( ) => {
2021-11-20 22:08:30 +08:00
rowSelection . value = props . rowSelection ? { ... props . rowSelection } : props . rowSelection ;
2021-09-25 16:51:32 +08:00
} ,
2021-11-20 16:49:25 +08:00
{ deep : true , immediate : true } ,
2021-09-25 16:51:32 +08:00
) ;
2021-11-20 16:29:27 +08:00
// ========================== Selections ==========================
const [ transformSelectionColumns , selectedKeySet ] = useSelection ( rowSelection , {
prefixCls ,
data : mergedData ,
pageData ,
getRowKey ,
getRecordByKey ,
expandType ,
childrenColumnName ,
locale : tableLocale ,
getPopupContainer : computed ( ( ) => props . getPopupContainer ) ,
} ) ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
const internalRowClassName = ( record : any , index : number , indent : number ) => {
let mergedRowClassName ;
const { rowClassName } = props ;
if ( typeof rowClassName === 'function' ) {
mergedRowClassName = classNames ( rowClassName ( record , index , indent ) ) ;
2020-03-07 19:45:13 +08:00
} else {
2021-09-25 16:51:32 +08:00
mergedRowClassName = classNames ( rowClassName ) ;
2020-03-07 19:45:13 +08:00
}
2021-09-25 16:51:32 +08:00
return classNames (
{
[ ` ${ prefixCls . value } -row-selected ` ] : selectedKeySet . value . has (
getRowKey . value ( record , index ) ,
) ,
} ,
mergedRowClassName ,
2020-03-07 19:45:13 +08:00
) ;
2021-09-25 16:51:32 +08:00
} ;
expose ( {
selectedKeySet ,
} ) ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
const indentSize = computed ( ( ) => {
// Indent size
return typeof props . indentSize === 'number' ? props . indentSize : 15 ;
} ) ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
const transformColumns = ( innerColumns : ColumnsType < any > ) : ColumnsType < any > => {
const res = transformTitleColumns (
transformSelectionColumns (
transformFilterColumns ( transformSorterColumns ( transformBasicColumns ( innerColumns ) ) ) ,
) ,
2020-03-07 19:45:13 +08:00
) ;
2021-09-25 16:51:32 +08:00
return res ;
} ;
2020-03-07 19:45:13 +08:00
2021-09-25 16:51:32 +08:00
return ( ) => {
const {
expandIcon = slots . expandIcon || renderExpandIcon ( tableLocale . value ) ,
pagination ,
loading ,
bordered ,
} = props ;
let topPaginationNode ;
let bottomPaginationNode ;
if ( pagination !== false && mergedPagination . value ? . total ) {
let paginationSize : TablePaginationConfig [ 'size' ] ;
if ( mergedPagination . value . size ) {
paginationSize = mergedPagination . value . size ;
} else {
paginationSize =
mergedSize . value === 'small' || mergedSize . value === 'middle' ? 'small' : undefined ;
2020-03-07 19:45:13 +08:00
}
2021-09-25 16:51:32 +08:00
const renderPagination = ( position : string ) => (
< Pagination
{ ... mergedPagination . value }
2022-03-12 09:56:32 +08:00
class = { [
` ${ prefixCls . value } -pagination ${ prefixCls . value } -pagination- ${ position } ` ,
mergedPagination . value . class ,
] }
2021-09-25 16:51:32 +08:00
size = { paginationSize }
/ >
2019-01-12 11:33:27 +08:00
) ;
2021-09-25 16:51:32 +08:00
const defaultPosition = direction . value === 'rtl' ? 'left' : 'right' ;
const { position } = mergedPagination . value ;
if ( position !== null && Array . isArray ( position ) ) {
2023-02-16 19:23:44 +08:00
const topPos = position . find ( p => p . includes ( 'top' ) ) ;
const bottomPos = position . find ( p => p . includes ( 'bottom' ) ) ;
2021-09-25 16:51:32 +08:00
const isDisable = position . every ( p => ` ${ p } ` === 'none' ) ;
if ( ! topPos && ! bottomPos && ! isDisable ) {
bottomPaginationNode = renderPagination ( defaultPosition ) ;
}
if ( topPos ) {
topPaginationNode = renderPagination ( topPos ! . toLowerCase ( ) . replace ( 'top' , '' ) ) ;
}
if ( bottomPos ) {
bottomPaginationNode = renderPagination ( bottomPos ! . toLowerCase ( ) . replace ( 'bottom' , '' ) ) ;
2018-03-31 17:46:35 +08:00
}
2018-03-31 21:11:02 +08:00
} else {
2021-09-25 16:51:32 +08:00
bottomPaginationNode = renderPagination ( defaultPosition ) ;
2018-03-31 21:11:02 +08:00
}
}
2019-04-30 16:59:53 +08:00
2021-09-25 16:51:32 +08:00
// >>>>>>>>> Spinning
let spinProps : SpinProps | undefined ;
if ( typeof loading === 'boolean' ) {
spinProps = {
spinning : loading ,
} ;
} else if ( typeof loading === 'object' ) {
spinProps = {
spinning : true ,
... loading ,
2019-01-12 11:33:27 +08:00
} ;
2019-04-30 16:59:53 +08:00
}
2021-09-25 16:51:32 +08:00
const wrapperClassNames = classNames (
` ${ prefixCls . value } -wrapper ` ,
{
[ ` ${ prefixCls . value } -wrapper-rtl ` ] : direction . value === 'rtl' ,
} ,
attrs . class ,
2023-02-16 07:44:48 +08:00
hashId . value ,
2021-09-25 16:51:32 +08:00
) ;
const tableProps = omit ( props , [ 'columns' ] ) ;
2023-02-16 07:44:48 +08:00
return wrapSSR (
2022-05-21 10:56:28 +08:00
< div class = { wrapperClassNames } style = { attrs . style as CSSProperties } >
2021-09-25 16:51:32 +08:00
< Spin spinning = { false } { ...spinProps } >
{ topPaginationNode }
< RcTable
{ ... attrs }
{ ... tableProps }
expandedRowKeys = { props . expandedRowKeys as any }
defaultExpandedRowKeys = { props . defaultExpandedRowKeys as any }
expandIconColumnIndex = { expandIconColumnIndex . value }
indentSize = { indentSize . value }
expandIcon = { expandIcon }
columns = { mergedColumns . value }
direction = { direction . value }
prefixCls = { prefixCls . value }
class = { classNames ( {
[ ` ${ prefixCls . value } -middle ` ] : mergedSize . value === 'middle' ,
[ ` ${ prefixCls . value } -small ` ] : mergedSize . value === 'small' ,
[ ` ${ prefixCls . value } -bordered ` ] : bordered ,
[ ` ${ prefixCls . value } -empty ` ] : rawData . value . length === 0 ,
} ) }
data = { pageData . value }
rowKey = { getRowKey . value }
rowClassName = { internalRowClassName }
// Internal
internalHooks = { INTERNAL _HOOKS }
internalRefs = { internalRefs }
onUpdateInternalRefs = { updateInternalRefs }
transformColumns = { transformColumns }
transformCellText = { transformCellText . value }
v - slots = { {
... slots ,
emptyText : ( ) =>
2023-01-27 16:00:17 +08:00
slots . emptyText ? . ( ) || props . locale ? . emptyText || renderEmpty ( 'Table' ) ,
2021-09-25 16:51:32 +08:00
} }
/ >
{ bottomPaginationNode }
< / Spin >
2023-02-16 07:44:48 +08:00
< / div > ,
2021-09-25 16:51:32 +08:00
) ;
} ;
2018-03-31 17:46:35 +08:00
} ,
2021-09-25 16:51:32 +08:00
} ) ;
2018-03-31 17:46:35 +08:00
2021-09-25 16:51:32 +08:00
const Table = defineComponent < TableProps > ( {
name : 'ATable' ,
inheritAttrs : false ,
setup ( _props , { attrs , slots , expose } ) {
const table = ref ( ) ;
expose ( {
table ,
} ) ;
return ( ) => {
const props = attrs as TableProps ;
const columns = props . columns || convertChildrenToColumns ( slots . default ? . ( ) ) ;
return (
< InteralTable
ref = { table }
{ ... attrs }
columns = { columns || [ ] }
expandedRowRender = { slots . expandedRowRender }
contextSlots = { { ... slots } } // use new object, 否则slot热更新失效, 原因需进一步探究
v - slots = { slots }
/ >
) ;
2019-01-12 11:33:27 +08:00
} ;
2018-03-31 17:46:35 +08:00
} ,
2020-10-23 14:29:39 +08:00
} ) ;
2021-09-25 16:51:32 +08:00
export default Table ;