Skip to content

Commit

Permalink
feat: support component.Row/Cell/TableBody
Browse files Browse the repository at this point in the history
  • Loading branch information
feichao93 committed Jul 1, 2021
1 parent 455e158 commit 08ee190
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 47 deletions.
100 changes: 57 additions & 43 deletions packages/ali-react-table/src/base-table/html-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { RenderInfo } from './interfaces'
import { Classes } from './styles'
import { BaseTableProps } from './table'

export interface HtmlTableProps extends Required<Pick<BaseTableProps, 'getRowProps' | 'primaryKey'>> {
export interface HtmlTableProps extends Required<Pick<BaseTableProps, 'getRowProps' | 'primaryKey' | 'components'>> {
tbodyHtmlTag: 'tbody' | 'tfoot'
data: any[]

Expand All @@ -32,6 +32,7 @@ export function HtmlTable({
data,
verticalRenderInfo: verInfo,
horizontalRenderInfo: hozInfo,
components: { Row, Cell, TableBody },
}: HtmlTableProps) {
const { flat, horizontalRenderRange: hoz } = hozInfo

Expand All @@ -40,18 +41,25 @@ export function HtmlTable({
const leftFlatCount = flat.left.length
const rightFlatCount = flat.right.length

const tbody =
TableBody != null && tbodyHtmlTag === 'tbody' ? (
<TableBody tbodyProps={{ children: data.map(renderRow) }} />
) : (
React.createElement(tbodyHtmlTag, null, data.map(renderRow))
)

return (
<table>
<Colgroup descriptors={hozInfo.visible} />
{React.createElement(tbodyHtmlTag, null, data.map(renderRow))}
{tbody}
</table>
)

function renderRow(record: any, i: number) {
function renderRow(row: any, i: number) {
const rowIndex = verInfo.offset + i
spanManager.stripUpwards(rowIndex)

const rowProps = getRowProps(record, rowIndex)
const rowProps = getRowProps(row, rowIndex)
const rowClass = cx(
Classes.tableRow,
{
Expand All @@ -63,40 +71,43 @@ export function HtmlTable({
rowProps?.className,
)

return (
<tr
{...rowProps}
className={rowClass}
key={internals.safeGetRowKey(primaryKey, record, rowIndex)}
data-rowindex={rowIndex}
>
{hozInfo.visible.map((descriptor) => {
if (descriptor.type === 'blank') {
return <td key={descriptor.blankSide} />
}
return renderBodyCell(record, rowIndex, descriptor.col, descriptor.colIndex)
})}
</tr>
)
const trProps = {
...rowProps,
className: rowClass,
'data-rowindex': rowIndex,
children: hozInfo.visible.map((descriptor) => {
if (descriptor.type === 'blank') {
return <td key={descriptor.blankSide} />
}
return renderBodyCell(row, rowIndex, descriptor.col, descriptor.colIndex)
}),
}

const key = internals.safeGetRowKey(primaryKey, row, rowIndex)
if (Row != null && tbodyHtmlTag === 'tbody') {
return React.createElement(Row, { key, row, rowIndex, trProps })
} else {
return <tr key={key} {...trProps} />
}
}

function renderBodyCell(record: any, rowIndex: number, column: ArtColumn, colIndex: number) {
function renderBodyCell(row: any, rowIndex: number, column: ArtColumn, colIndex: number) {
if (spanManager.testSkip(rowIndex, colIndex)) {
return null
}

const value = internals.safeGetValue(column, record, rowIndex)
const cellProps = column.getCellProps?.(value, record, rowIndex) ?? {}
const value = internals.safeGetValue(column, row, rowIndex)
const cellProps = column.getCellProps?.(value, row, rowIndex) ?? {}

let cellContent: ReactNode = value
if (column.render) {
cellContent = column.render(value, record, rowIndex)
cellContent = column.render(value, row, rowIndex)
}

let colSpan = 1
let rowSpan = 1
if (column.getSpanRect) {
const spanRect = column.getSpanRect(value, record, rowIndex)
const spanRect = column.getSpanRect(value, row, rowIndex)
colSpan = spanRect == null ? 1 : spanRect.right - colIndex
rowSpan = spanRect == null ? 1 : spanRect.bottom - rowIndex
} else {
Expand Down Expand Up @@ -127,25 +138,28 @@ export function HtmlTable({
positionStyle.right = hozInfo.stickyRightMap.get(colIndex)
}

return React.createElement(
'td',
{
key: colIndex,
...cellProps,
className: cx(Classes.tableCell, cellProps.className, {
first: colIndex === 0,
last: colIndex + colSpan === fullFlatCount,
'lock-left': colIndex < leftFlatCount,
'lock-right': colIndex >= fullFlatCount - rightFlatCount,
}),
...(hasSpan ? { colSpan, rowSpan } : null),
style: {
textAlign: column.align,
...cellProps.style,
...positionStyle,
},
let key = colIndex
const tdProps = {
...cellProps,
className: cx(Classes.tableCell, cellProps.className, {
first: colIndex === 0,
last: colIndex + colSpan === fullFlatCount,
'lock-left': colIndex < leftFlatCount,
'lock-right': colIndex >= fullFlatCount - rightFlatCount,
}),
...(hasSpan ? { colSpan, rowSpan } : null),
style: {
textAlign: column.align,
...cellProps.style,
...positionStyle,
},
cellContent,
)
children: cellContent,
}

if (Cell != null && tbodyHtmlTag === 'tbody') {
return <Cell key={key} tdProps={tdProps} row={row} rowIndex={rowIndex} column={column} colIndex={colIndex} />
} else {
return <td key={key} {...tdProps} />
}
}
}
18 changes: 14 additions & 4 deletions packages/ali-react-table/src/base-table/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function warnFlowRootIsDeprecated() {
}
}

export type PrimaryKey = string | ((record: any) => string)
export type PrimaryKey = string | ((row: any) => string)

export interface BaseTableProps {
/** 主键 */
Expand Down Expand Up @@ -96,6 +96,14 @@ export interface BaseTableProps {
LoadingIcon?: React.ComponentType
/** 数据为空时,表格的展示内容。*/
EmptyContent?: React.ComponentType
/** 覆盖内部渲染 tbody>tr 元素的组件,一般用于在 tr 上设置 context */
Row?: React.ComponentType<{ row: any; rowIndex: number; trProps: unknown }>
/** 覆盖内部渲染 tbody>td 元素的组件,一般用于在 td 上设置 context */
Cell?: React.ComponentType<{ row: any; rowIndex: number; colIndex: number; tdProps: unknown; column: ArtColumn }>
/** 覆盖内部渲染 tbody 元素的组件 */
TableBody?: React.ComponentType<{ tbodyProps: unknown }>

// todo TableHeader/HeaderRow/HeaderCell TableFooter/FooterRow/FooterCell
}

/** 列的默认宽度 */
Expand All @@ -110,7 +118,7 @@ export interface BaseTableProps {
/** 虚拟滚动调试标签,用于表格内部调试使用 */
virtualDebugLabel?: string

getRowProps?(record: any, rowIndex: number): React.HTMLAttributes<HTMLTableRowElement>
getRowProps?(row: any, rowIndex: number): React.HTMLAttributes<HTMLTableRowElement>
}

interface BaseTableState {
Expand Down Expand Up @@ -285,7 +293,7 @@ export class BaseTable extends React.Component<BaseTableProps, BaseTableState> {
}

private renderTableBody(info: RenderInfo) {
const { dataSource, getRowProps, primaryKey, isLoading, emptyCellHeight, footerDataSource } = this.props
const { dataSource, getRowProps, primaryKey, isLoading, emptyCellHeight, footerDataSource, components } = this.props
const tableBodyClassName = cx(Classes.tableBody, Classes.horizontalScrollContainer, {
'no-scrollbar': footerDataSource.length > 0,
})
Expand Down Expand Up @@ -318,6 +326,7 @@ export class BaseTable extends React.Component<BaseTableProps, BaseTableState> {
<div key="top-blank" className={cx(Classes.virtualBlank, 'top')} style={{ height: topBlank }} />
)}
<HtmlTable
components={components}
tbodyHtmlTag="tbody"
getRowProps={getRowProps}
primaryKey={primaryKey}
Expand All @@ -338,14 +347,15 @@ export class BaseTable extends React.Component<BaseTableProps, BaseTableState> {
}

private renderTableFooter(info: RenderInfo) {
const { footerDataSource = [], getRowProps, primaryKey, stickyBottom } = this.props
const { footerDataSource = [], getRowProps, primaryKey, stickyBottom, components } = this.props

return (
<div
className={cx(Classes.tableFooter, Classes.horizontalScrollContainer)}
style={{ bottom: stickyBottom === 0 ? undefined : stickyBottom }}
>
<HtmlTable
components={components}
tbodyHtmlTag="tfoot"
data={footerDataSource}
horizontalRenderInfo={info}
Expand Down

0 comments on commit 08ee190

Please sign in to comment.