UNPKG

@ackplus/react-tanstack-data-table

Version:

A powerful React data table component built with MUI and TanStack Table

273 lines (272 loc) 11.3 kB
import { TableProps, TableContainerProps, BoxProps } from '@mui/material'; import { Table, Row, Column } from '@tanstack/react-table'; import { ComponentType, ReactNode } from 'react'; import { DataTableColumn, TableFilters, ExportProgress, ExportResult, ExportError, ServerExportColumn } from './index'; import { DataTableSize } from '../utils/table-helpers'; import { DataTablePaginationProps } from "../components/pagination"; export interface DataTableSlots<T = any> { root?: ComponentType<DataTableSlotProps<T>['root']>; tableContainer?: ComponentType<DataTableSlotProps<T>['tableContainer']>; table?: ComponentType<DataTableSlotProps<T>['table']>; toolbar?: ComponentType<DataTableSlotProps<T>['toolbar']>; header?: ComponentType<DataTableSlotProps<T>['header']>; headerRow?: ComponentType<DataTableSlotProps<T>['headerRow']>; headerCell?: ComponentType<DataTableSlotProps<T>['headerCell']>; sortIconAsc?: ComponentType<DataTableSlotProps<T>['sortIconAsc']>; sortIconDesc?: ComponentType<DataTableSlotProps<T>['sortIconDesc']>; body?: ComponentType<DataTableSlotProps<T>['body']>; row?: ComponentType<DataTableSlotProps<T>['row']>; cell?: ComponentType<DataTableSlotProps<T>['cell']>; loadingRow?: ComponentType<DataTableSlotProps<T>['loadingRow']>; emptyRow?: ComponentType<DataTableSlotProps<T>['emptyRow']>; expandedRow?: ComponentType<DataTableSlotProps<T>['expandedRow']>; footer?: ComponentType<DataTableSlotProps<T>['footer']>; pagination?: ComponentType<DataTableSlotProps<T>['pagination']>; searchInput?: ComponentType<DataTableSlotProps<T>['searchInput']>; columnVisibilityControl?: ComponentType<DataTableSlotProps<T>['columnVisibilityControl']>; columnCustomFilterControl?: ComponentType<DataTableSlotProps<T>['columnCustomFilterControl']>; columnPinningControl?: ComponentType<DataTableSlotProps<T>['columnPinningControl']>; exportButton?: ComponentType<DataTableSlotProps<T>['exportButton']>; resetButton?: ComponentType<DataTableSlotProps<T>['resetButton']>; tableSizeControl?: ComponentType<DataTableSlotProps<T>['tableSizeControl']>; bulkActionsToolbar?: ComponentType<DataTableSlotProps<T>['bulkActionsToolbar']>; searchIcon?: ComponentType<DataTableSlotProps<T>['searchIcon']>; clearIcon?: ComponentType<DataTableSlotProps<T>['clearIcon']>; exportIcon?: ComponentType<DataTableSlotProps<T>['exportIcon']>; columnIcon?: ComponentType<DataTableSlotProps<T>['columnIcon']>; resetIcon?: ComponentType<DataTableSlotProps<T>['resetIcon']>; moreIcon?: ComponentType<DataTableSlotProps<T>['moreIcon']>; filterIcon?: ComponentType<DataTableSlotProps<T>['filterIcon']>; pinIcon?: ComponentType<DataTableSlotProps<T>['pinIcon']>; unpinIcon?: ComponentType<DataTableSlotProps<T>['unpinIcon']>; leftIcon?: ComponentType<DataTableSlotProps<T>['leftIcon']>; rightIcon?: ComponentType<DataTableSlotProps<T>['rightIcon']>; csvIcon?: ComponentType<DataTableSlotProps<T>['csvIcon']>; excelIcon?: ComponentType<DataTableSlotProps<T>['excelIcon']>; selectAllIcon?: ComponentType<DataTableSlotProps<T>['selectAllIcon']>; deselectIcon?: ComponentType<DataTableSlotProps<T>['deselectIcon']>; tableSizeIcon?: ComponentType<DataTableSlotProps<T>['tableSizeIcon']>; tableSizeSmallIcon?: ComponentType<DataTableSlotProps<T>['tableSizeSmallIcon']>; tableSizeMediumIcon?: ComponentType<DataTableSlotProps<T>['tableSizeMediumIcon']>; checkboxSelection?: ComponentType<DataTableSlotProps<T>['checkboxSelection']>; expandIcon?: ComponentType<DataTableSlotProps<T>['expandIcon']>; collapseIcon?: ComponentType<DataTableSlotProps<T>['collapseIcon']>; loadingSkeleton?: ComponentType<DataTableSlotProps<T>['loadingSkeleton']>; noDataOverlay?: ComponentType<DataTableSlotProps<T>['noDataOverlay']>; exportProgressDialog?: ComponentType<DataTableSlotProps<T>['exportProgressDialog']>; } export interface BaseSlotProps<T = any> { table: Table<T>; data: T[]; columns: DataTableColumn<T>[]; } export interface DataTableSlotProps<T = any> { root: BaseSlotProps<T> & BoxProps & { children: ReactNode; }; tableContainer: BaseSlotProps<T> & TableContainerProps & { children: ReactNode; enableStickyHeader?: boolean; maxHeight?: string | number; enableVirtualization?: boolean; }; table: BaseSlotProps<T> & TableProps & { children: ReactNode; tableSize?: DataTableSize; enableStickyHeader?: boolean; fitToScreen?: boolean; tableStyle?: React.CSSProperties; }; toolbar: BaseSlotProps<T> & { title?: string; subtitle?: string; enableGlobalFilter?: boolean; enableColumnVisibility?: boolean; enableColumnFilter?: boolean; enableExport?: boolean; enableReset?: boolean; enableTableSizeControl?: boolean; enableColumnPinning?: boolean; extraFilter?: ReactNode; serverExport?: { fetchData: (page: number, pageSize: number, filters: TableFilters) => Promise<{ data: T[]; total: number; }>; columns: ServerExportColumn<T>[]; pageSize?: number; }; currentFilters?: TableFilters; onExportStart?: (format: 'csv' | 'excel', summary: { mode: 'client' | 'server'; totalRows: number; estimatedMemoryMB?: number; }) => void; onExportProgress?: (progress: ExportProgress) => void; onExportComplete?: (result: ExportResult) => void; onExportError?: (error: ExportError) => void; onExportCancel?: () => void; }; header: BaseSlotProps<T> & { enableSorting?: boolean; draggable?: boolean; enableColumnResizing?: boolean; enableStickyHeader?: boolean; fitToScreen?: boolean; onColumnReorder?: (draggedColumnId: string, targetColumnId: string) => void; }; headerRow: BaseSlotProps<T> & { headerGroups: any[]; }; headerCell: BaseSlotProps<T> & { header: any; column: Column<T>; enableSorting?: boolean; draggable?: boolean; enableColumnResizing?: boolean; onColumnReorder?: (draggedColumnId: string, targetColumnId: string) => void; isPinned?: boolean | 'left' | 'right'; pinnedPosition?: number; pinnedRightPosition?: number; }; sortIconAsc: Record<string, any>; sortIconDesc: Record<string, any>; body: BaseSlotProps<T> & { children: ReactNode; rows: Row<T>[]; loading?: boolean; emptyMessage?: string; enableVirtualization?: boolean; enablePagination?: boolean; }; row: BaseSlotProps<T> & { row: Row<T>; index: number; enableHover?: boolean; enableStripes?: boolean; isOdd?: boolean; renderSubComponent?: (row: Row<T>) => ReactNode; disableStickyHeader?: boolean; }; cell: BaseSlotProps<T> & { row: Row<T>; cell: any; column: Column<T>; value: any; isPinned?: boolean | 'left' | 'right'; pinnedPosition?: number; pinnedRightPosition?: number; alignment?: 'left' | 'center' | 'right'; }; loadingRow: BaseSlotProps<T> & { rowCount: number; colSpan: number; }; emptyRow: BaseSlotProps<T> & { colSpan: number; message: string; }; expandedRow: BaseSlotProps<T> & { row: Row<T>; colSpan: number; children: ReactNode; }; footer: BaseSlotProps<T> & { children: ReactNode; enableStickyFooter?: boolean; }; pagination: BaseSlotProps<T> & DataTablePaginationProps; searchInput: BaseSlotProps<T> & { value: string; onChange: (value: string) => void; placeholder?: string; autoFocus?: boolean; }; columnsPanel: BaseSlotProps<T> & { getTogglableColumns: (columns: DataTableColumn<T>[]) => DataTableColumn<T>[]; getPinnableColumns: (columns: DataTableColumn<T>[]) => DataTableColumn<T>[]; }; columnVisibilityControl: BaseSlotProps<T>; columnCustomFilterControl: BaseSlotProps<T>; columnPinningControl: BaseSlotProps<T>; resetButton: BaseSlotProps<T>; tableSizeControl: BaseSlotProps<T>; bulkActionsToolbar: BaseSlotProps<T> & { selectionState: any; selectedRowCount: number; bulkActions?: (selectionState: any) => ReactNode; onBulkAction?: (action: string, selectionState: T[]) => void; enableSelectAll?: boolean; onSelectAll?: () => void; onDeselectAll?: () => void; }; exportButton: BaseSlotProps<T> & { filename?: string; dataMode?: 'client' | 'server'; serverExport?: { fetchData: (page: number, pageSize: number, filters: TableFilters) => Promise<{ data: T[]; total: number; }>; columns: ServerExportColumn<T>[]; pageSize?: number; }; currentFilters?: TableFilters; onExportStart?: (format: 'csv' | 'excel', summary: { mode: 'client' | 'server'; totalRows: number; estimatedMemoryMB?: number; }) => void; onExportProgress?: (progress: ExportProgress) => void; onExportComplete?: (result: ExportResult) => void; onExportError?: (error: ExportError) => void; onExportCancel?: () => void; }; searchIcon: Record<string, any>; clearIcon: Record<string, any>; exportIcon: Record<string, any>; columnIcon: Record<string, any>; resetIcon: Record<string, any>; moreIcon: Record<string, any>; filterIcon: Record<string, any>; pinIcon: Record<string, any>; unpinIcon: Record<string, any>; leftIcon: Record<string, any>; rightIcon: Record<string, any>; expandIcon: Record<string, any>; collapseIcon: Record<string, any>; csvIcon: Record<string, any>; excelIcon: Record<string, any>; selectAllIcon: Record<string, any>; deselectIcon: Record<string, any>; tableSizeIcon: Record<string, any>; tableSizeSmallIcon: Record<string, any>; tableSizeMediumIcon: Record<string, any>; checkboxSelection: BaseSlotProps<T> & { row?: Row<T>; checked: boolean; indeterminate?: boolean; onChange: (checked: boolean) => void; disabled?: boolean; }; selectionColumn: DataTableColumn<T>; expandColumn: DataTableColumn<T>; loadingSkeleton: BaseSlotProps<T> & { rows: number; columns: number; }; noDataOverlay: BaseSlotProps<T> & { message: string; }; exportProgressDialog: BaseSlotProps<T> & { open: boolean; progress: ExportProgress; onCancel: () => void; }; } export interface DefaultSlots<T = any> extends DataTableSlots<T> { } export type PartialSlotProps<T = any> = { [K in keyof DataTableSlotProps<T>]?: Partial<DataTableSlotProps<T>[K]>; }; export type SlotComponentProps<TSlot extends keyof DataTableSlots<T>, T = any> = DataTableSlotProps<T>[TSlot];