import { Children, CSSProperties, isValidElement, ReactNode } from 'react' import { ColumnInstance, IdType } from 'react-table' import { TableColumn } from '.' import { ComponentSize } from '../ConfigProvider' import { isDev } from '../utils' import { TableColumnFixType, TableColumnWidths, TableInternalColumnOptions } from './types' // returns { 1: true, 2: true } export function getSelectedRowIds(ids: string[]): Record, boolean> { const result: Record, boolean> = {} ids.forEach((id: number | string) => { result[id] = true }) return result } // 将 children( 组)转为 InternalColumnOptions 列表 export function children2ColumnOptions(children: ReactNode): Array> { const columns: Array> = [] Children.toArray(children).filter(isValidElement).forEach( ({ type, props }) => { if (type !== TableColumn) { if (isDev) { // eslint-disable-next-line no-console console.warn('Unknown element type, expected ``, while got', type) } return } columns.push(props as TableInternalColumnOptions) } ) return columns } export function areIdsEquals(idsA: Record, boolean>, idsB: Record, boolean>) { if (idsA === idsB) return true const idsAKeys = Object.keys(idsA).filter(id => idsA[id]) const idsBKeys = Object.keys(idsB).filter(id => idsB[id]) // 过滤掉值为 false 的 id 再对比长度 if (idsAKeys.length !== idsBKeys.length) return false for (const item of idsBKeys) { if (idsA[item] === undefined) { return false } } return true } export function getRowId(record: R, recordIdAccessor?: keyof R): string | null { if (recordIdAccessor == null) { return null } const id = record[recordIdAccessor] if (typeof id !== 'string') { throw Error('Unsupported record id type.') } return id } export function areColumnWidthsEquals(widthsA: TableColumnWidths, widthsB: TableColumnWidths) { if (widthsA === widthsB) return true if (Object.keys(widthsA).length !== Object.keys(widthsB).length) return false const keysB = Object.keys(widthsB) for (const item of keysB) { const widthA = widthsA[item] const widthB = widthsB[item] if (widthA !== widthB) { // FIXME: 临时解决 https://github.com/qbox/horn/issues/529 if (typeof widthA === 'number' && typeof widthB === 'number' && Math.abs(widthA - widthB) < 0.01) { continue } return false } } return true } // 这边需要和样式保持同步 export function getPaddingBySize(size: ComponentSize) { if (size === 'small') { return [12, 20] } return [16, 20] } export function getNumberWidthByPx(stringWidth: string) { return +stringWidth.substring(0, stringWidth.indexOf('px')) } export function getFixedStyle( colWidths: TableColumnWidths, columnIndex: number, columns: Array>, fixed?: TableColumnFixType ): CSSProperties { const style: CSSProperties = {} if (fixed) { style.background = 'inherit' style.zIndex = 1 style.position = 'sticky' // 计算 position: sticky 的最终位置 const columnWidthList = Object.values(colWidths) if (fixed === 'left') { const leftWidths = columnWidthList.slice(0, columnIndex) if (!leftWidths.some(col => col === 'auto')) { const leftWidthList = leftWidths .filter((_, index) => columns[index].meta.fixed === 'left') .map(width => (typeof width === 'string' ? Number.parseFloat(width.replace('px', '')) : width)) style.left = leftWidthList.reduce((prev, cur) => cur + prev, 0) + 'px' } } else if (fixed === 'right') { const rightWidths = columnWidthList.slice(columnIndex + 1, columnWidthList.length) if (!rightWidths.some(col => col === 'auto')) { const rightWidthList = rightWidths .filter((_, index) => columns[index].meta.fixed === 'right') .map(width => (typeof width === 'string' ? Number.parseFloat(width.replace('px', '')) : width)) style.right = rightWidthList.reduce((prev, cur) => cur + prev, 0) + 'px' } } } return style }