/* eslint-disable react-hooks/exhaustive-deps */ import React, { memo, forwardRef, useImperativeHandle, useRef, useMemo } from 'react' import { Table as AntdTable, TableProps, Empty } from 'antd' import { run, classnames, isObject, isArray } from '@fexd/tools' import { useMemoizedFn, useLatest } from 'ahooks' import { useProps, createPlugin } from '../../utils' import useQueryFieldPlugin from '../queryField' import useModalPlugin from '../modal' import useConfigPlugin from '../config' import useStickyScrollBar from './useStickyScrollBar' import useResizableColumns, { ResizableTitle } from './useResizableColumns' import useToolbar from './useToolbar' import usePagination from './usePagination' import useColumns from './useColumns' import useSelectable from './useSelectable' import useExpandable from './useExpandable' import useItem from './useItem' const TdCell = memo(function TdCell(props: any) { // https://juejin.cn/post/7063332320339099678 // onMouseEnter, onMouseLeave在数据量多的时候,会严重阻塞表格单元格渲染,严重影响性能 const { onMouseEnter, onMouseLeave, children, style, ...restProps } = props const cell = useMemo( () => ( {children} ), [children, style], ) return cell }) const PluginTable = memo( forwardRef(function PluginTable({}, ref) { const { pure, rowKey, dataSource: propDataSource, mainStyle, mainClassName, loading: propLoading, sticky, components: propComponents, resizableHeader, noTableHeaderEllipsis, __EXTRA_PROPS__, ...restProps } = useProps() const { size, t } = useConfigPlugin(({ size, t }) => [size, t]) const queryField = useQueryFieldPlugin(({ loading, paginationParams, selectedItems, dataSource, isSearched }) => [ loading, paginationParams, selectedItems, dataSource, isSearched, ]) const { loading: queryFieldLoading, setExtraParams, dataSource: tableDataSource } = queryField const loading = queryFieldLoading || propLoading const dataSource = propDataSource ?? tableDataSource const tableWrapperDomRef = useRef(null) const tableContentDomRef = useRef(null) const tableToolbarDomRef = useRef(null) const antdTableRef = useRef(null) const { renderStation } = useModalPlugin(() => []) const { hasToolbar, renderToolbar } = useToolbar({ ref: tableToolbarDomRef, }) const columns = useColumns() const expandableConfig = useExpandable() const { rowSelection, renderBatchToolbar, handleRowSelectionByClick, toggleRowSelectionByClick } = useSelectable(expandableConfig) const antdTablePaginationConfig = usePagination() const resizableColumns = useResizableColumns(columns) useStickyScrollBar(antdTableRef, antdTablePaginationConfig) const tableColumns = resizableHeader ? resizableColumns : columns const tableColumnsRef = useLatest(tableColumns) useImperativeHandle(ref, () => ({ tableWrapperDomRef, tableToolbarDomRef, tableContentDomRef, antdTableRef, tableColumnsRef, })) return (
{run(renderStation)} {run(renderToolbar)} {run(renderBatchToolbar)}
({ x: 'max-content' }), [])} size={size as any} onChange={useMemoizedFn(async (pagination, filters, sorters, extra) => { switch (extra?.action) { case 'paginate': { // do nothing break } default: { setExtraParams({ filters, sorters }) queryField.search() } } })} {...(restProps as Omit, 'title'>)} locale={{ emptyText: ( ), ...(isObject(restProps?.locale) ? restProps?.locale : {}), }} onRow={useMemoizedFn((item, ...args: any[]) => { const customerConfig = run(restProps, 'onRow', item, ...args) ?? {} return { ...customerConfig, className: classnames(customerConfig?.className, { 'f-pro-table-row-clickable': toggleRowSelectionByClick || expandableConfig?.expandRowByClick, }), onClick(...args: any[]) { handleRowSelectionByClick(item) run(customerConfig, 'onClick', ...args) }, } })} loading={loading} pagination={antdTablePaginationConfig} title={undefined} rowSelection={rowSelection} expandable={expandableConfig} components={useMemo( () => ({ ...(propComponents ?? {}), header: { ...(resizableHeader ? { cell: ResizableTitle } : {}), ...(propComponents?.header ?? {}), }, body: { cell: TdCell, ...(propComponents?.body ?? {}), }, }), [propComponents, resizableHeader], )} className={classnames('f-pro-table-ant-table', restProps?.className, { 'f-pro-table-header-no-ellipsis': noTableHeaderEllipsis, })} sticky={sticky as boolean} rowKey={rowKey} // dataSource={dataSource} dataSource={isArray(dataSource) ? dataSource : isObject(dataSource) ? Object.values(dataSource) : []} columns={tableColumns} />
) }), ) export const useTablePlugin = createPlugin(() => { const tableRef = useRef<{ tableWrapperDomRef: HTMLDivElement tableToolbarDomRef: HTMLDivElement tableContentDomRef: HTMLDivElement antdTableRef: any tableColumnsRef: any[] }>(null) return { tableRef, render: () => , } }, 'table') export default useTablePlugin export { useItem }