import type { CSSProperties , VNode } from 'vue' ; import { TableCell , TableColumn , TableOperationColumn } from './interface' ; import { isArray , isNull , isUndefined } from '../_utils/is' ; import { resolveProps , isNamedComponent , isSlotsChildren , } from '../_utils/vue-utils' ; const getDataColumnsNumber = ( columns ) : number => { let count = 0 ; const travelColumns = ( columns ) => { if ( isArray ( columns ) && columns . length > 0 ) { for ( const item of columns ) { if ( ! item . children ) { count += 1 ; } else { travelColumns ( item . children ) ; } } } } ; travelColumns ( columns ) ; return count ; } ; const getTotalHeaderRows = ( columns ) : number => { let count = 0 ; if ( isArray ( columns ) && columns . length > 0 ) { count = 1 ; for ( const item of columns ) { if ( item . children ) { const depth = getTotalHeaderRows ( item . children ) ; if ( depth > 0 ) { count = Math . max ( count , depth + 1 ) ; } } } } return count ; } ; export const getGroupColumns = ( columns ) : { dataColumns : TableColumn [ ] ; groupColumns : TableColumn [ ] [ ] ; } => { const totalHeaderRows = getTotalHeaderRows ( columns ) ; const dataColumns = [ ] ; const groupColumns = [ ... Array ( totalHeaderRows ) ] . map ( ( ) => [ ] ) ; let lastLeftFixedIndex ; let firstRightFixedIndex ; const travelColumns = ( columns , level = 0 , fixed ? ) => { for ( const item of columns ) { const cell = { ... item } ; if ( isArray ( cell . children ) ) { const colSpan = getDataColumnsNumber ( cell . children ) ; if ( colSpan > 1 ) { cell . colSpan = colSpan ; } groupColumns [ level ] . push ( cell ) ; travelColumns ( cell . children , level + 1 , cell . fixed ) ; } else { const rowSpan = totalHeaderRows - level ; if ( rowSpan > 1 ) { cell . rowSpan = rowSpan ; } if ( fixed || cell . fixed ) { cell . fixed = cell . fixed ?? fixed ; if ( cell . fixed === 'left' ) { lastLeftFixedIndex = dataColumns . length ; } else if ( isUndefined ( firstRightFixedIndex ) ) { firstRightFixedIndex = dataColumns . length ; } } if ( isUndefined ( cell . dataIndex ) || isNull ( cell . dataIndex ) ) { cell . dataIndex = `__arco_data_index_${ dataColumns . length }` ; } dataColumns . push ( cell ) ; groupColumns [ level ] . push ( cell ) ; } } } ; travelColumns ( columns ) ; if ( ! isUndefined ( lastLeftFixedIndex ) ) { dataColumns [ lastLeftFixedIndex ] . isLastLeftFixed = true ; } if ( ! isUndefined ( firstRightFixedIndex ) ) { dataColumns [ firstRightFixedIndex ] . isFirstRightFixed = true ; } return { dataColumns , groupColumns } ; } ; const getOperationColumnIndex = ( operations , name ) => { for ( let i = 0 ; i < operations . length ; i ++ ) { if ( operations [ i ] . name === name ) { return i ; } } return - 1 ; } ; export const getOperationFixedNumber = ( column , operations ) => { const index = getOperationColumnIndex ( operations , column . name ) ; if ( index <= 0 ) { return 0 ; } let count = 0 ; const _operations = operations . slice ( 0 , index ) ; for ( const item of _operations ) { count += item . width ?? 0 ; } return count ; } ; export const getFixedNumber = ( column , { dataColumns , operations , } ) => { let count = 0 ; if ( column . fixed === 'left' ) { for ( const item of operations ) { count += item . width ?? 40 ; } for ( const item of dataColumns ) { if ( column . dataIndex === item . dataIndex ) { break ; } count += item . width as number ; } return count ; } for ( let i = dataColumns . length - 1 ; i > 0 ; i -- ) { const item = dataColumns [ i ] ; if ( column . dataIndex === item . dataIndex ) { break ; } if ( item . fixed === 'right' ) { count += item . width as number ; } } return count ; } ; export const getOperationFixedCls = ( prefixCls , column ) : any [ ] => { if ( column . fixed ) { return [ `${ prefixCls }-col-fixed-left` , { [ `${ prefixCls }-col-fixed-left-last` ] : column . isLastLeftFixed } , ] ; } return [ ] ; } ; export const getFixedCls = ( prefixCls , column ) : any [ ] => { if ( column . fixed === 'left' ) { return [ `${ prefixCls }-col-fixed-left` , { [ `${ prefixCls }-col-fixed-left-last` ] : column . isLastLeftFixed } , ] ; } if ( column . fixed === 'right' ) { return [ `${ prefixCls }-col-fixed-right` , { [ `${ prefixCls }-col-fixed-right-first` ] : column . isFirstRightFixed } , ] ; } return [ ] ; } ; export const getFiltersAndSorter = ( columns ) => { const filters = { } ; const sorter = { } ; for ( const item of columns ) { if ( item . filterable ) { filters [ item . dataIndex ] = item . filterable . filteredValue ?? item . filterable . defaultFilteredValue ; } if ( item . sortable && ! sorter . field ) { sorter . field = item . dataIndex ; sorter . direction = item . sortable . sortOrder ?? item . sortable . defaultSortOrder ; } } return { filters , sorter } ; } ; export const getStyle = ( column , { dataColumns , operations , } ) : CSSProperties => { if ( column . fixed ) { const offset = `${ getFixedNumber ( column , { dataColumns , operations } ) }px` ; if ( column . fixed === 'left' ) { return { left : offset } ; } return { right : offset } ; } return { } ; } ; export const getOperationStyle = ( column , operations ) => { if ( column . fixed ) { return { left : `${ getOperationFixedNumber ( column , operations ) }px` } ; } return { } ; } ; param { VNode [ ] } vns export const getColumnsFromSlot = ( vns ) => { const columns = [ ] ; for ( const vn of vns ) { if ( isNamedComponent ( vn , 'TableColumn' ) ) { const column = resolveProps ( vn ) as TableColumn ; if ( isSlotsChildren ( vn , vn . children ) ) { if ( vn . children . default ) { column . children = getColumnsFromSlot ( vn . children . default ( ) ) ; } if ( vn . children . cell ) { column . render = vn . children . cell ; } if ( vn . children . title ) { column . title = vn . children . title ; } } columns . push ( column ) ; } } return columns ; } ;