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';