Untitled
import { Table as ShadTable, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@components/shadcn/ui/table' import SortArrow from '@public/icons/sort-arrow.svg' import { Table as ReactTable, flexRender } from '@tanstack/react-table' import { classnames, classnames as cn } from '@tools/common' import Text from './typography/Text' interface TableProps<T> { table: ReactTable<T> rowRef?: React.Ref<HTMLTableRowElement> onClickRow?: (row: T) => void } const Table = <T extends object>({ table, rowRef, onClickRow, }: TableProps<T>) => { const headers = table.getFlatHeaders() const rows = table.getRowModel().rows return ( <ShadTable> <TableHeader className="sticky top-0 z-10 bg-main-300"> <TableRow> {headers.map((header, index) => { const isSorted = header.column.getIsSorted() const noSorting = header.column.columnDef.enableSorting === false const sortDirection = noSorting ? ( '' ) : isSorted === 'desc' ? ( <SortArrow className="w-6 h-6 fill-primary transition-transform" /> ) : isSorted === 'asc' ? ( <SortArrow className="w-6 h-6 rotate-180 fill-primary transition-transform" /> ) : ( <SortArrow className="w-6 h-6 fill-main-500 group-hover:fill-main-700 transition-transform" /> ) return ( <TableHead key={header.id + index} className={cn( 'relative group bg-main-300 md:hover:bg-main-500 transition-colors border-r border-white', { 'sticky z-10': typeof header.column.getIsPinned() === 'string', 'left-0': header.column.getIsPinned() === 'left', 'right-0': header.column.getIsPinned() === 'right', }, )} style={{ minWidth: header.getSize(), width: header.getSize(), }} > <div onClick={() => !noSorting && header.column.toggleSorting( header.column.getIsSorted() === 'asc', ) } className="h-full items-center w-full cursor-pointer flex justify-between select-none" > {header.isPlaceholder ? null : ( <> <Text size="caption-default" as="span" className="uppercase" > {flexRender( header.column.columnDef.header, header.getContext(), )} </Text> <span className="duration-300">{sortDirection}</span> </> )} </div> {header.column.getCanResize() && ( <div onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={classnames( `absolute opacity-0 top-0 right-0 h-full w-[5px] bg-primary cursor-col-resize select-none touch-none rounded-[6px] group-hover:opacity-100`, { 'bg-main-500': header.column.getIsResizing(), }, )} /> )} </TableHead> ) })} </TableRow> </TableHeader> <TableBody> {rows.map((row, index) => ( <TableRow key={row.id + index} ref={rowRef} className={classnames( 'hover bg-white group/row transition-colors', { 'cursor-pointer': onClickRow, }, )} onClick={() => { if (onClickRow) { onClickRow(row.original) } }} > {row.getVisibleCells().map((cell, index) => { const CellComponent = index === 0 ? TableHead : TableCell return ( <CellComponent key={cell.id + index} className={cn({ 'sticky z-10': typeof cell.column.getIsPinned() === 'string', 'left-0': cell.column.getIsPinned() === 'left', 'right-0': cell.column.getIsPinned() === 'right', })} style={{ width: cell.column.getSize() }} > {flexRender(cell.column.columnDef.cell, cell.getContext())} </CellComponent> ) })} </TableRow> ))} </TableBody> </ShadTable> ) } export default Table
Leave a Comment