Im am using react table v7 and have built out a table with a couple of features already. When trying to implement the useResizeColumns hook I can see the column.width value updating, but the rendered column is not changing. As suggested by other users I am using BlockLayout however this doesnt seem to solve the issue. After testing I think the issue may be in the table cell portion of the code, but I haven't been able to implement a working solution that doesn't break the rest of my already implemented features such as filtering and pagination.
This is the code for the setup of the data, columns, and table itself.
// Table setup.
// Get table data.
const series = data.series;
const tableData = React.useMemo(() => {
if (series.length === 0) {
return [];
}
const firstSeries = series[0];
const rows: Array<Record<string, any>> = firstSeries.fields[0].values.map(() => ({}));
firstSeries.fields.forEach((field, i) => {
field.values.forEach((value, index) => {
const fieldName = field.name;
const cellValue = series[0].fields[i].type === 'time' ? new Date(value).toLocaleString() : value;
rows[index][fieldName] = cellValue; // Store the raw cell value
});
});
return rows;
}, [series]);
// Set columns.
const columns = React.useMemo(() => {
if (series.length === 0) {
return [];
}
const firstSeries = series[0];
return firstSeries.fields.map((field) => ({
Header: field.name,
accessor: field.name,
minWidth: 30, // set the minWidth
width: 150, // set the width
maxWidth: 500, // set the maxWidth
Filter: DefaultColumnFilter,
filter: (rows: any[], id: string | number, filterValue: string) => {
return rows.filter(row => {
return Object.keys(filterValues).every(columnName => {
const columnFilterValue = filterValues[columnName];
if (!columnFilterValue) {
return true;
}
const rowValue = row.values[columnName];
if (columnFilterValue.startsWith('!')) {
const excludeValue = columnFilterValue.slice(1).toLowerCase();
return !String(rowValue).toLowerCase().includes(excludeValue);
} else {
return String(rowValue).toLowerCase().includes(columnFilterValue.toLowerCase());
}
});
});
},
}));
}, [filterValues, series]);
console.log('Columns:', columns);
// Construct table.
const {
getTableProps,
getTableBodyProps,
headerGroups,
page,
rows,
prepareRow,
gotoPage,
nextPage,
previousPage,
canNextPage,
canPreviousPage,
pageCount,
state: { pageIndex },
setPageSize,
} = useTable({
columns, data: tableData,
initialState: {
pageIndex: 0, pageSize: options.showPagination ? rowCount : undefined
}
},
useFilters, usePagination, useBlockLayout, useResizeColumns);
and this is the code for the render method
<tbody {...getTableBodyProps()}>
{(options.showPagination ? page : rows).map((row: { getRowProps: () => React.JSX.IntrinsicAttributes & React.ClassAttributes<HTMLTableRowElement> & React.HTMLAttributes<HTMLTableRowElement>; index: number; cells: any[]; }) => {
prepareRow(row);
return (
<tr
{...row.getRowProps()}
style={{
borderBottom: '1px solid #ddd',
backgroundColor: options.showSelectedRow && row.index === selectedRow ? options.selectedRowColor : 'transparent',
}}
onClick={() => setSelectedRow(row.index)}
>
{row.cells.map((cell, i) => {
const link = Array.isArray(options.dataLinks) && options.dataLinks.find(link => link.field === series[0].fields[i].name);
const cellValue = cell.value;
const isBlob = cellValue instanceof Blob;
const highlightOption = options.cellValueToHighlight.find(option => String(cellValue).toLowerCase().includes(option.value.toLowerCase()));
const isHighlighted = Boolean(highlightOption);
const cellStyle = isHighlighted ? { color: highlightOption!.highlightBackground ? undefined : highlightOption!.color, backgroundColor: highlightOption!.highlightBackground ? highlightOption!.color : undefined } : {};
return (
<td {...cell.getCellProps()}
style={{
...cellStyle,
padding: '12px',
borderRight: '1px solid #ddd',
textAlign: 'left',
whiteSpace: options.enableLineWrap ? 'pre-wrap' : 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
maxWidth: options.enableLineWrap ? 'none' : '15ch'
}}
>
<div
style={{ position: 'relative', paddingRight: '20px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}
onMouseEnter={() => setHoveredCell(`${row.index}-${i}`)}
onMouseLeave={() => setHoveredCell(null)}
>
<span style={{
display: 'inline-block',
maxWidth: '100%',
overflow: options.enableLineWrap ? 'visible' : 'hidden',
textOverflow: 'ellipsis',
whiteSpace: options.enableLineWrap ? 'normal' : 'nowrap',
overflowWrap: options.enableLineWrap ? 'break-word' : 'normal',
}}>
{link ? (
<a href={link.url} target="_blank" style={{ color: '#fff' }} rel="noopener noreferrer">{cellValue}</a>
) : isBlob ? (
<img src={URL.createObjectURL(cellValue)} alt="" />
) : (
cellValue
)}
</span>
<div
onClick={(e) => { e.stopPropagation(); setIsCellModalOpen(true); setCurrentCellContent(cellValue); }}
style={{ cursor: 'pointer', display: hoveredCell === `${row.index}-${i}` ? 'block' : 'none', position: 'absolute', right: '0', top: '50%', transform: 'translateY(-50%)' }}
>
<Icon name="eye" />
</div>
</div>
</td>
);
})}
</tr>
);
})}
</tbody>
Any help or push in the right direction would be greatly appreciated!