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' ;
2022-05-21 10:56:28 +08:00
import type { CSSProperties , PropType } from 'vue' ;
2021-12-16 16:01:58 +08:00
import { nextTick , reactive , ref , computed , defineComponent , toRef , watchEffect , watch } from 'vue' ;
2023-05-18 21:22:58 +08:00
import type { DefaultRecordType , RenderExpandIconProps } from '../vc-table/interface' ;
2021-09-25 16:51:32 +08:00
import useBreakpoint from '../_util/hooks/useBreakpoint' ;
import useConfigInject from '../_util/hooks/useConfigInject' ;
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-05-18 21:22:58 +08:00
import type { CustomSlotsType } from '../_util/type' ;
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 ;
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 {
2021-09-25 16:51:32 +08:00
prefixCls : { type : String as PropType < string > , default : undefined } ,
columns : { type : Array as PropType < ColumnsType > , default : undefined } ,
rowKey : { type : [ String , Function ] as PropType < TableProps [ ' rowKey ' ] > , default : undefined } ,
tableLayout : { type : String as PropType < TableProps [ ' tableLayout ' ] > , default : undefined } ,
rowClassName : {
type : [ String , Function ] as PropType < TableProps [ ' rowClassName ' ] > ,
default : undefined ,
} ,
title : { type : Function as PropType < TableProps [ ' title ' ] > , default : undefined } ,
footer : { type : Function as PropType < TableProps [ ' footer ' ] > , default : undefined } ,
id : { type : String as PropType < TableProps [ ' id ' ] > , default : undefined } ,
showHeader : { type : Boolean as PropType < TableProps [ ' showHeader ' ] > , default : undefined } ,
components : { type : Object as PropType < TableProps [ ' components ' ] > , default : undefined } ,
customRow : { type : Function as PropType < TableProps [ ' customRow ' ] > , default : undefined } ,
customHeaderRow : {
type : Function as PropType < TableProps [ ' customHeaderRow ' ] > ,
default : undefined ,
} ,
direction : { type : String as PropType < TableProps [ ' direction ' ] > , default : undefined } ,
2022-04-23 09:44:15 +08:00
expandFixed : {
type : [ Boolean , String ] as PropType < TableProps [ ' expandFixed ' ] > ,
default : undefined ,
} ,
2021-09-25 16:51:32 +08:00
expandColumnWidth : {
type : Number as PropType < TableProps [ ' expandColumnWidth ' ] > ,
default : undefined ,
} ,
expandedRowKeys : {
type : Array as PropType < TableProps [ ' expandedRowKeys ' ] > ,
default : undefined as TableProps [ 'expandedRowKeys' ] ,
} ,
defaultExpandedRowKeys : {
type : Array as PropType < TableProps [ ' defaultExpandedRowKeys ' ] > ,
default : undefined as TableProps [ 'defaultExpandedRowKeys' ] ,
} ,
expandedRowRender : {
type : Function as PropType < TableProps [ ' expandedRowRender ' ] > ,
default : undefined ,
} ,
expandRowByClick : {
type : Boolean as PropType < TableProps [ ' expandRowByClick ' ] > ,
default : undefined ,
} ,
expandIcon : { type : Function as PropType < TableProps [ ' expandIcon ' ] > , default : undefined } ,
onExpand : { type : Function as PropType < TableProps [ ' onExpand ' ] > , default : undefined } ,
onExpandedRowsChange : {
type : Function as PropType < TableProps [ ' onExpandedRowsChange ' ] > ,
default : undefined ,
} ,
2022-06-13 09:35:03 +08:00
'onUpdate:expandedRowKeys' : {
type : Function as PropType < TableProps [ ' onExpandedRowsChange ' ] > ,
default : undefined ,
} ,
2021-09-25 16:51:32 +08:00
defaultExpandAllRows : {
type : Boolean as PropType < TableProps [ ' defaultExpandAllRows ' ] > ,
default : undefined ,
} ,
indentSize : { type : Number as PropType < TableProps [ ' indentSize ' ] > , default : undefined } ,
2022-03-12 09:56:32 +08:00
/** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */
2021-09-25 16:51:32 +08:00
expandIconColumnIndex : {
type : Number as PropType < TableProps [ ' expandIconColumnIndex ' ] > ,
default : undefined ,
} ,
2022-03-12 09:56:32 +08:00
showExpandColumn : { type : Boolean , default : undefined } ,
2021-09-25 16:51:32 +08:00
expandedRowClassName : {
type : Function as PropType < TableProps [ ' expandedRowClassName ' ] > ,
default : undefined ,
} ,
childrenColumnName : {
type : String as PropType < TableProps [ ' childrenColumnName ' ] > ,
default : undefined ,
} ,
rowExpandable : { type : Function as PropType < TableProps [ ' rowExpandable ' ] > , default : undefined } ,
2021-10-26 16:46:32 +08:00
sticky : { type : [ Boolean , Object ] as PropType < TableProps [ ' sticky ' ] > , default : undefined } ,
2021-09-25 16:51:32 +08:00
dropdownPrefixCls : String ,
dataSource : { type : Array as PropType < RcTableProps [ ' data ' ] > , default : undefined } ,
pagination : {
type : [ Boolean , Object ] as PropType < false | TablePaginationConfig > ,
default : undefined ,
} ,
2022-09-26 21:34:34 +08:00
loading : { type : [ Boolean , Object ] as PropType < boolean | SpinProps > , default : undefined } ,
2021-09-25 16:51:32 +08:00
size : { type : String as PropType < SizeType > , default : undefined } ,
bordered : Boolean ,
locale : { type : Object as PropType < TableLocale > , default : undefined } ,
onChange : {
type : Function as PropType <
(
pagination : TablePaginationConfig ,
filters : Record < string , FilterValue | null > ,
sorter : SorterResult | SorterResult [ ] ,
extra : TableCurrentDataSource ,
) => void
> ,
default : undefined ,
} ,
2021-10-27 14:58:55 +08:00
onResizeColumn : {
2021-11-04 22:00:07 +08:00
type : Function as PropType < ( w : number , col : ColumnType ) => void > ,
2021-10-27 14:58:55 +08:00
default : undefined ,
} ,
2021-09-25 16:51:32 +08:00
rowSelection : { type : Object as PropType < TableRowSelection > , default : undefined } ,
getPopupContainer : { type : Function as PropType < GetPopupContainer > , default : undefined } ,
scroll : {
type : Object as PropType <
RcTableProps [ 'scroll' ] & {
scrollToFirstRowOnChange ? : boolean ;
}
> ,
default : undefined ,
} ,
sortDirections : { type : Array as PropType < SortOrder [ ] > , default : undefined } ,
showSorterTooltip : {
type : [ Boolean , Object ] as PropType < boolean | TooltipProps > ,
2021-10-10 10:37:59 +08:00
default : true ,
2021-09-25 16:51:32 +08:00
} ,
2023-05-18 22:53:21 +08:00
2021-09-25 16:51:32 +08:00
transformCellText : {
type : Function as PropType < TableProps [ ' transformCellText ' ] > ,
2020-03-07 19:45:13 +08:00
} ,
} ;
} ;
2023-05-18 22:53:21 +08:00
const InteralTable = defineComponent ( {
2021-09-25 16:51:32 +08:00
name : 'InteralTable' ,
inheritAttrs : false ,
2023-05-18 22:53:21 +08:00
props : initDefaultProps (
{
... tableProps ( ) ,
contextSlots : {
type : Object as PropType < ContextSlots > ,
} ,
} ,
{
rowKey : 'key' ,
} ,
) ,
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 ) ;
const transformCellText = computed (
( ) => props . transformCellText || configProvider . transformCellText ,
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' ) ) ;
const columnTitleProps = computed ( ( ) => ( {
... sorterTitleProps . value ,
} ) ) ;
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
? { }
: getPaginationParam ( props . pagination , mergedPagination . value ) ;
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 ) ) {
const topPos = position . find ( p => p . indexOf ( 'top' ) !== - 1 ) ;
const bottomPos = position . find ( p => p . indexOf ( 'bottom' ) !== - 1 ) ;
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 ,
) ;
const tableProps = omit ( props , [ 'columns' ] ) ;
return (
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 : ( ) =>
2021-10-26 16:44:10 +08:00
slots . emptyText ? . ( ) || props . locale ? . emptyText || renderEmpty . value ( 'Table' ) ,
2021-09-25 16:51:32 +08:00
} }
/ >
{ bottomPaginationNode }
< / Spin >
< / div >
) ;
} ;
2018-03-31 17:46:35 +08:00
} ,
2021-09-25 16:51:32 +08:00
} ) ;
2018-03-31 17:46:35 +08:00
2023-05-18 22:53:21 +08:00
const Table = defineComponent ( {
2021-09-25 16:51:32 +08:00
name : 'ATable' ,
inheritAttrs : false ,
2023-05-18 22:53:21 +08:00
props : initDefaultProps ( tableProps ( ) , {
rowKey : 'key' ,
} ) ,
slots : Object as CustomSlotsType < {
emptyText ? : any ;
expandIcon ? : RenderExpandIconProps < any > ;
title ? : any ;
footer ? : any ;
summary ? : any ;
expandedRowRender ? : any ;
bodyCell ? : {
text : any ;
value : any ;
record : Record < string , any > ;
index : number ;
column : ColumnType ;
} ;
headerCell ? : {
title : any ;
column : ColumnType ;
} ;
customFilterIcon ? : any ;
customFilterDropdown ? : any ;
default : any ;
} > ,
2021-09-25 16:51:32 +08:00
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 ;