import React, { memo, forwardRef } from 'react'; import { flexRender } from '@tanstack/react-table'; import type { TableColumn } from './DataTable.types'; import type { Row } from '@tanstack/react-table'; import { TableCell, TableRow } from '../Table'; import { Checkbox } from '../Checkbox'; import { Skeleton } from '../Skeleton'; import { cn } from '~/utils'; export const SelectionCheckbox = memo( ({ checked, onChange, ariaLabel, }: { checked: boolean; onChange: (value: boolean) => void; ariaLabel: string; }) => (
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onChange(!checked); } e.stopPropagation(); }} className="flex h-full w-8 items-center justify-center" onClick={(e) => { e.stopPropagation(); onChange(!checked); }} >
), ); SelectionCheckbox.displayName = 'SelectionCheckbox'; interface TableRowComponentProps> { row: Row; virtualIndex?: number; style?: React.CSSProperties; selected: boolean; } const TableRowComponent = >( { row, virtualIndex, style, selected }: TableRowComponentProps, ref: React.Ref, ) => ( {row.getVisibleCells().map((cell) => { const meta = cell.column.columnDef.meta as | { className?: string; desktopOnly?: boolean; width?: number } | undefined; const isDesktopOnly = meta?.desktopOnly; const percent = meta?.width; const widthStyle = cell.column.id === 'select' ? { width: '32px', maxWidth: '32px' } : percent && percent >= 1 && percent <= 100 ? { width: `${percent}%`, maxWidth: `${percent}%` } : undefined; return ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ); })} ); type ForwardTableRowComponentType = >( props: TableRowComponentProps & React.RefAttributes, ) => JSX.Element; const ForwardTableRowComponent = forwardRef(TableRowComponent) as ForwardTableRowComponentType; interface GenericRowProps { row: Row>; virtualIndex?: number; style?: React.CSSProperties; selected: boolean; } export const MemoizedTableRow = memo( ForwardTableRowComponent as (props: GenericRowProps) => JSX.Element, (prev: GenericRowProps, next: GenericRowProps) => prev.row.original === next.row.original && prev.selected === next.selected, ); export const SkeletonRows = memo( , TValue>({ count = 10, columns, }: { count?: number; columns: TableColumn[]; }) => ( <> {Array.from({ length: count }, (_, index) => ( {columns.map((column) => { const columnKey = String( column.id ?? ('accessorKey' in column && column.accessorKey) ?? '', ); const meta = column.meta as { className?: string; desktopOnly?: boolean } | undefined; return ( ); })} ))} ), ); SkeletonRows.displayName = 'SkeletonRows';