Files
tests/client/src/components/CustomTable.tsx
2024-12-10 10:51:29 +09:00

112 lines
4.3 KiB
TypeScript

import { Input, Table } from '@mantine/core';
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';
import { useMemo, useState } from 'react';
import styles from './CustomTable.module.scss'
// Sample data
type DataType = {
id: number,
name: string,
age: number
}
// Define columns
const columns: ColumnDef<DataType>[] = [
{
accessorKey: 'name',
header: 'Name',
cell: (info) => info.getValue(),
maxSize: Number.MAX_SAFE_INTEGER,
},
{
accessorKey: 'age',
header: 'Age',
cell: (info) => info.getValue(),
},
];
const CustomTable = () => {
const [data, setData] = useState<DataType[]>([
{ id: 1, name: 'John Doe', age: 25 },
{ id: 2, name: 'Jane Smith', age: 30 },
{ id: 3, name: 'Sam Green', age: 22 },
]);
const [editingCell, setEditingCell] = useState({ rowIndex: null, columnId: null });
const tableColumns = useMemo<ColumnDef<typeof data[0]>[]>(() => columns, []);
const table = useReactTable({
data,
columns: tableColumns,
getCoreRowModel: getCoreRowModel(),
columnResizeMode: "onChange",
});
// Function to handle cell edit
const handleEditCell = (
rowIndex: number,
columnId: keyof DataType,
value: DataType[keyof DataType]
) => {
const updatedData = [...data];
updatedData[rowIndex][columnId] = value;
setData(updatedData);
//setEditingCell({ rowIndex: null, columnId: null });
};
return (
<Table striped withColumnBorders highlightOnHover className={styles.table}>
<Table.Thead className={styles.thead}>
{table.getHeaderGroups().map(headerGroup => (
<Table.Tr key={headerGroup.id} className={styles.tr}>
{headerGroup.headers.map((header) => (
<Table.Th key={header.id} className={styles.th} w={header.getSize()}>
{flexRender(header.column.columnDef.header, header.getContext())}
<div
className={styles.resize_handler}
onMouseDown={header.getResizeHandler()} //for desktop
onTouchStart={header.getResizeHandler()}
>
</div>
</Table.Th>
))}
</Table.Tr>
))}
</Table.Thead>
<Table.Tbody className={styles.tbody}>
{table.getRowModel().rows.map((row, rowIndex) => (
<Table.Tr key={row.id} className={styles.tr}>
{row.getVisibleCells().map(cell => {
const isEditing = editingCell.rowIndex === rowIndex && editingCell.columnId === cell.column.id;
return (
<Table.Td
key={cell.id}
onDoubleClick={() => setEditingCell({ rowIndex, columnId: cell.column.id })}
style={{ width: cell.column.getSize() }}
className={styles.td}
>
{isEditing ? (
<Input
type='text'
value={data[rowIndex][cell.column.id]}
onChange={(e) => handleEditCell(rowIndex, cell.column.id, e.target.value)}
onBlur={() => setEditingCell({ rowIndex: null, columnId: null })}
autoFocus
/>
) : (
flexRender(cell.column.columnDef.cell, cell.getContext())
)}
</Table.Td>
);
})}
</Table.Tr>
))}
</Table.Tbody>
</Table>
);
};
export default CustomTable;