import { flexRender, getCoreRowModel, getSortedRowModel, useReactTable, type ColumnDef, type SortingState, } from '@tanstack/react-table' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { useState } from 'react' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from 'ui' import { describe, expect, it } from 'vitest' import { TanStackTableHeadSort } from './TanStackTableHeadSort' type Row = { name: string amount: number } const data: Row[] = [ { name: 'Bravo', amount: 200 }, { name: 'Alpha', amount: 100 }, ] const columns: ColumnDef[] = [ { accessorKey: 'name', header: ({ column }) => Name, cell: ({ row }) => row.getValue('name'), }, { accessorKey: 'amount', enableSorting: false, header: ({ column }) => Amount, cell: ({ row }) => row.getValue('amount'), }, ] const classNameColumns: ColumnDef[] = [ { accessorKey: 'name', header: ({ column }) => ( Name ), cell: ({ row }) => row.getValue('name'), }, ] const TestTable = ({ tableColumns = columns }: { tableColumns?: ColumnDef[] }) => { const [sorting, setSorting] = useState([]) const table = useReactTable({ data, columns: tableColumns, state: { sorting }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), }) return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} ))} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} ))}
) } describe('TanStackTableHeadSort', () => { it('cycles unsorted, ascending, descending, and cleared', async () => { const user = userEvent.setup() render() expect(screen.getAllByRole('row')[1]).toHaveTextContent('Bravo') await user.click(screen.getByRole('button', { name: 'Name' })) expect(screen.getAllByRole('row')[1]).toHaveTextContent('Alpha') await user.click(screen.getByRole('button', { name: 'Name' })) expect(screen.getAllByRole('row')[1]).toHaveTextContent('Bravo') await user.click(screen.getByRole('button', { name: 'Name' })) expect(screen.getAllByRole('row')[1]).toHaveTextContent('Bravo') }) it('renders non-sortable columns as plain content', () => { render() expect(screen.getByText('Amount')).toBeInTheDocument() expect(screen.queryByRole('button', { name: 'Amount' })).not.toBeInTheDocument() }) it('passes className through to the rendered sort control', () => { render() expect(screen.getByRole('button', { name: 'Name' })).toHaveClass('justify-end') }) })