forked from VinokurovVE/tests
112 lines
4.4 KiB
TypeScript
112 lines
4.4 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: string | number | null, columnId: string | number | null }>({ 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] as DataType[keyof DataType]) = 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 as keyof DataType]}
|
|
onChange={(e) => handleEditCell(rowIndex, (cell.column.id as keyof DataType), 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;
|