import type { ReactNode } from 'react'; import { ArrowPathIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, } from '@heroicons/react/24/solid'; import { ArrowsUpDownIcon } from '@heroicons/react/24/outline'; import { Button } from './Button'; import { Dropdown } from './Dropdown'; import { Label } from './Label'; import type { SortState } from '../types/sort'; type HeaderValue = ReactNode | ((row: T) => ReactNode); export type TableHeader = { label: string; id: string; value: HeaderValue; sortable?: boolean; sortField?: string; headerClassName?: string; cellClassName?: string; }; type TableProps = { headers: TableHeader[]; data: T[]; rowKey: (row: T, index: number) => string; isLoading?: boolean; emptyMessage?: string; className?: string; sorting?: SortState | null; onSortChange?: (field: string) => void; pagination?: { page: number; pageSize: number; total: number; totalPages: number; onPageChange: (page: number) => void; onPageSizeChange?: (pageSize: number) => void; }; }; export function Table({ headers, data, rowKey, isLoading = false, emptyMessage = 'No data to show.', className = '', sorting = null, onSortChange, pagination, }: Readonly>) { const canGoPrev = pagination != null && pagination.page > 1; const canGoNext = pagination != null && pagination.page < pagination.totalPages; return (
{headers.map((header) => { const canSort = header.sortable === true && typeof onSortChange === 'function' && typeof header.sortField === 'string' && header.sortField.length > 0; const isActiveSort = canSort && sorting?.field === header.sortField; const sortDirection = isActiveSort ? sorting?.direction : null; return ( ); })} {isLoading ? ( ) : null} {!isLoading && data.length === 0 ? ( ) : null} {!isLoading && data.map((row, index) => ( {headers.map((header) => { const content = typeof header.value === 'function' ? (header.value as (item: T) => ReactNode)(row) : header.value; return ( ); })} ))}
{canSort ? ( ) : ( header.label )}
{content}
{pagination ? (
{pagination.onPageSizeChange ? ( ({ id: String(size), label: String(size), }))} size="sm" layout="inline" className="max-w-none" selectClassName="rounded-lg px-2" disabled={isLoading} onChange={(value) => pagination.onPageSizeChange?.(Number(value))} /> ) : null}
) : null}
); }