import React, { useEffect, useMemo, useRef, useState } from 'react' import TableHead from './table-head' import TableBody from './table-body' import useRealShape from '../utils/use-real-shape' import useResize from '../utils/use-resize' import { TableContext, TableConfig } from './table-context' import { TableAbstractColumn, TableDataItemBase, TableOnCellClick, TableOnChange, TableOnRowClick, TableRowClassNameHandler, } from './table-types' import useScaleable, { ScaleableProps, withScaleable } from '../use-scaleable' import TableColumn from './table-column' interface Props { data?: Array initialData?: Array emptyText?: string hover?: boolean onRow?: TableOnRowClick onCell?: TableOnCellClick onChange?: TableOnChange className?: string rowClassName?: TableRowClassNameHandler } const defaultProps = { hover: true, initialData: [], emptyText: '', className: '', rowClassName: () => '', } type NativeAttrs = Omit, keyof Props> export type TableProps = Props & NativeAttrs function TableComponent( tableProps: React.PropsWithChildren>, ) { /* eslint-disable @typescript-eslint/no-unused-vars */ const { children, data: customData, initialData, hover, emptyText, onRow, onCell, onChange, className, rowClassName, ...props } = tableProps as React.PropsWithChildren> & typeof defaultProps /* eslint-enable @typescript-eslint/no-unused-vars */ const { SCALES } = useScaleable() const ref = useRef(null) const [{ width }, updateShape] = useRealShape(ref) const [columns, setColumns] = useState>>([]) const [data, setData] = useState>(initialData) const updateColumn = (column: TableAbstractColumn) => { setColumns(last => { const hasColumn = last.find(item => item.prop === column.prop) if (!hasColumn) return [...last, column] return last.map(item => { if (item.prop !== column.prop) return item return column }) }) } const contextValue = useMemo>( () => ({ columns, updateColumn, }), [columns], ) useEffect(() => { if (typeof customData === 'undefined') return setData(customData) }, [customData]) useResize(() => updateShape()) return ( data={data} hover={hover} emptyText={emptyText} onRow={onRow} onCell={onCell} rowClassName={rowClassName} /> {children}
) } TableComponent.defaultProps = defaultProps TableComponent.displayName = 'GeistTable' TableComponent.Column = TableColumn let Table = withScaleable(TableComponent) as any Table.Column = TableColumn export default Table as typeof TableComponent & ScaleableProps