/**
* 此插件用于开启行选择
*/
import React, { useCallback, useMemo, useRef } from 'react'
import { ColumnInstance, Hooks, TableToggleAllRowsSelectedProps } from 'react-table'
import cns from 'classnames'
import { InternalCheckbox as Checkbox } from '../../Checkbox/InternalCheckbox'
import { Radio } from '../../Radio'
import { concat } from '../../utils'
import { useReportWidth } from '../hooks'
import { useColumnWidths } from '../providers/ColumnWidthsProvider'
import { useHorizontalScroll } from '../providers/HorizontalScrollProvider'
import { useTable } from '../providers/TableProvider'
import { TableProps } from '../types'
import { getFixedStyle } from '../utils'
type Props = TableToggleAllRowsSelectedProps & {
position: 'header' | 'cell'
}
// 这里只作为事件的触发器,不负责状态的加工处理
function SelectBox(props: Props) {
const { indeterminate, onChange, position, ...rest } = props
const { selectionType } = useTable()
function handleChange(value: boolean) {
onChange?.({ target: { checked: value } } as any)
}
if (selectionType === 'single') {
if (position === 'header') {
return null
}
return
}
return (
)
}
export default function withSelectionColumn(tableProps: TableProps) {
return function _withSelectionColumn(hooks: Hooks) {
hooks.columns.push(columns => [
{
id: 'selection',
// ColumnWidthsProvider 需要根据实际宽度生成 col,也就是被 react-table 修改过后的 columns
// 而不是用户最开始传入的 columns,所以这里需要给一个宽度让 table 知道行选择列也是有宽度的
// 54: 14 宽度 + 20 左右 padding
width: '54px',
// eslint-disable-next-line react/display-name, @typescript-eslint/naming-convention
Header: ({ column, getToggleAllRowsSelectedProps, columns: _columns, index: columnIndex }) => {
const { prefix: tablePrefix } = useTable()
const bodyPrefix = concat(tablePrefix, 'body')
const tdPrefix = concat(bodyPrefix, 'td')
const { reportHeadCellWidth } = useColumnWidths()
const ref = useRef(null)
const { colWidths } = useColumnWidths()
const { pinnedLeft } = useHorizontalScroll()
const fixed = tableProps.selection?.fixed
const fixedStyle = useMemo(
() => getFixedStyle(colWidths, columnIndex, _columns, fixed),
[colWidths, columnIndex, _columns, fixed]
)
const isLeftLast = fixed === 'left' && pinnedLeft === columnIndex
useReportWidth(ref, useCallback(nextWidth => {
reportHeadCellWidth(column.id, nextWidth)
}, [column.id, reportHeadCellWidth]))
return (
|
|
)
},
// eslint-disable-next-line react/display-name, @typescript-eslint/naming-convention
Cell: ({ column, columns: _columns, row, index: columnIndex }) => {
const { prefix: tablePrefix } = useTable()
const bodyPrefix = concat(tablePrefix, 'body')
const tdPrefix = concat(bodyPrefix, 'td')
const { reportBodyCellWidth } = useColumnWidths()
const ref = useRef(null)
const { colWidths } = useColumnWidths()
const { pinnedLeft } = useHorizontalScroll()
const fixed = tableProps.selection?.fixed
const fixedStyle = useMemo(
() => getFixedStyle(colWidths, columnIndex, _columns, fixed),
[colWidths, columnIndex, _columns, fixed]
)
const isLeftLast = fixed === 'left' && pinnedLeft === columnIndex
useReportWidth(ref, useCallback(nextWidth => {
reportBodyCellWidth(column.id, nextWidth)
}, [column.id, reportBodyCellWidth]))
return (
|
)
},
meta: tableProps.selection?.fixed ? { fixed: tableProps.selection?.fixed } : {}
} as ColumnInstance,
...columns
])
}
}