/** * 对应表体的一格 */ import React, { PropsWithChildren, ReactNode, useMemo } from 'react' import { CellProps } from 'react-table' import cns from 'classnames' import { concat } from '../utils' import { useTable } from './providers/TableProvider' import { getFixedStyle } from './utils' import { useHorizontalScroll } from './providers/HorizontalScrollProvider' import { useColumnWidths } from './providers/ColumnWidthsProvider' export type Props = PropsWithChildren< CellProps & { index: number className?: string } > export type CellRender = (value: K extends keyof R ? R[K] : void, record: R, index: number) => ReactNode export type CellRowSpan = (value: K extends keyof R ? R[K] : void, record: R, index: number) => number | undefined export default function Cell( { cell, data, value, index: columnIndex, columns, className }: Props ) { const { prefix: tablePrefix } = useTable() const { colWidths } = useColumnWidths() const { pinnedLeft, pinnedRight } = useHorizontalScroll() const bodyPrefix = concat(tablePrefix, 'body') const tdPrefix = concat(bodyPrefix, 'td') const indexInRow = cell.row.index const cellData: R = data[indexInRow] const render = cell.column.meta.render const getRowSpan = cell.column.meta.getRowSpan // TODO 这里违背了 meta 的初衷,即 meta 对应原始数据(原始列)且是不可修改的,有空把这里挪出去 const rowSpans = cell.column.meta.rowSpans const fixedStyle = useMemo( () => getFixedStyle(colWidths, columnIndex, columns, cell.column.meta.fixed), [cell.column.meta.fixed, colWidths, columnIndex, columns] ) const isLeftLast = cell.column.meta.fixed === 'left' && pinnedLeft === columnIndex const isRightFirst = cell.column.meta.fixed === 'right' && pinnedRight === columnIndex let rowSpan = getRowSpan?.(value, cellData, indexInRow) if (rowSpan == null) { rowSpan = rowSpans[indexInRow] ?? 1 } if (rowSpan === 0) { return null } if (rowSpan === 1) { rowSpans[indexInRow] = 1 } if (rowSpan > 1) { rowSpans.push(...new Array(rowSpan).fill(0)) rowSpans[indexInRow] = rowSpan } const cellProps = cell.getCellProps({ className: tdPrefix }) return ( {render != null ? render(value, cellData, indexInRow) : value} ) }