import { getStatic, typeCheck } from '@/utils'; import clsx from 'clsx'; import { useMemo, useCallback } from '@wordpress/element'; import type { CSSProperties, ReactNode } from 'react'; import { Pagination, PaginationProps } from '../pagination'; import { CheckboxControl } from '@wordpress/components'; import uniqBy from 'lodash.uniqby'; export interface TableColumnItem< T extends Record = Record, > { title: string; key: Extract | (string & {}); align?: 'left' | 'right' | 'center'; width?: string; render?: (record: T, index: number, dataSource: T[]) => ReactNode; } interface TableProps> { rowKey: string; dataSource: T[]; columns: TableColumnItem[]; pagination?: PaginationProps | false; style?: CSSProperties; className?: string; selectable?: boolean; selectedList?: T[]; onSelectedList?: (list: T[]) => void; } const PREFIX = 'lks-table'; const TableEmpty = () => (

No Data

); export const Table = = Record>({ rowKey, dataSource = [], columns, className, pagination, selectable, selectedList = [], onSelectedList, style = {}, }: TableProps) => { const isEmptyTable = useMemo( () => !Array.isArray(dataSource) || !dataSource.length, [dataSource], ); const isAllChecked = useMemo(() => { if (!dataSource.length || !selectedList.length) return false; return !dataSource.find( item => !selectedList.find( selectedItem => selectedItem[rowKey] === item[rowKey], ), ); }, [selectedList, dataSource]); const getIsChecked = useCallback( (item: T) => { return !!selectedList.find( selectedItem => selectedItem[rowKey] == item[rowKey], ); }, [selectedList], ); const handleCheckAll = useCallback( (checked: boolean) => { if (checked) { onSelectedList?.(uniqBy([...selectedList, ...dataSource], rowKey)); } else { onSelectedList?.( selectedList.filter( selectedItem => !dataSource.find(item => item[rowKey] === selectedItem[rowKey]), ), ); } }, [selectedList, dataSource], ); const handleCheckItem = useCallback( (checked: boolean, item: T) => { if (checked) { onSelectedList?.(uniqBy([...selectedList, item], rowKey)); } else { onSelectedList?.( selectedList.filter( selectedItem => selectedItem[rowKey] !== item[rowKey], ), ); } }, [selectedList], ); return (
{selectable && ( )} {columns.map(column => ( ))} {!isEmptyTable ? ( dataSource.map((dataItem, dataIndex) => ( {selectable && ( )} {columns.map(column => { const dataValue = dataItem[column.key]; const renderNode = column.render ? column.render(dataItem, dataIndex, dataSource) : dataValue; const columnRender = typeCheck(renderNode, ['string', 'undefined', 'object']) && !renderNode ? '-' : renderNode; const mapKey = typeCheck(dataValue, ['string', 'number']) ? dataValue : `${column.title}-${column.key}`; return ( ); })} )) ) : ( )}
{column.title}
handleCheckItem(checked, dataItem)} /> {columnRender}
{pagination && (
Total {pagination.total} items
)}
); };