diff --git a/web/default/src/components/data-table/core/data-table-row.tsx b/web/default/src/components/data-table/core/data-table-row.tsx
index 0730380e..6ae1cf98 100644
--- a/web/default/src/components/data-table/core/data-table-row.tsx
+++ b/web/default/src/components/data-table/core/data-table-row.tsx
@@ -17,7 +17,12 @@ along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
import * as React from 'react'
-import { flexRender, type Cell, type Row } from '@tanstack/react-table'
+import {
+ flexRender,
+ type Cell,
+ type Row,
+ type Table as TanstackTable,
+} from '@tanstack/react-table'
import { cn } from '@/lib/utils'
import { TableCell, TableRow } from '@/components/ui/table'
import { TruncatedCell } from './truncated-cell'
@@ -27,6 +32,7 @@ type DataTableRowProps = {
row: Row
className?: string
getColumnClassName?: DataTableColumnClassName
+ cellRenderColumns?: TanstackTable['options']['columns']
} & Omit, 'children'>
type DataTableRowInnerProps = DataTableRowProps & {
@@ -38,8 +44,13 @@ function DataTableRowInner({
isSelected,
className,
getColumnClassName,
+ cellRenderColumns,
...rowProps
}: DataTableRowInnerProps) {
+ // Destructured only to keep it out of `rowProps` (it is not a valid DOM attr)
+ // and to feed the memo comparator below; it is intentionally unused here.
+ void cellRenderColumns
+
return (
({
}
const MemoizedDataTableRow = React.memo(DataTableRowInner, (prev, next) => {
- // Do not read row.getIsSelected() here: TanStack row objects may keep a stable
- // reference while their selection state changes.
+ // Do not read row.getIsSelected() inside the comparator: TanStack row objects
+ // keep a stable reference while their selection state mutates, so reading it
+ // here compares identical live values and misses selection changes. Selection
+ // is lifted to the `isSelected` prop, captured per render in DataTableRow.
+ //
+ // Column cell renderers (and getColumnClassName) can close over external
+ // state while the row stays stable, so column definitions and the class
+ // resolver are part of the render identity and must be compared too.
return (
prev.row === next.row &&
prev.className === next.className &&
+ prev.isSelected === next.isSelected &&
prev.getColumnClassName === next.getColumnClassName &&
- prev.isSelected === next.isSelected
+ prev.cellRenderColumns === next.cellRenderColumns
)
}) as typeof DataTableRowInner
diff --git a/web/default/src/components/data-table/core/data-table-view.tsx b/web/default/src/components/data-table/core/data-table-view.tsx
index 9bc1d1e4..3def71dc 100644
--- a/web/default/src/components/data-table/core/data-table-view.tsx
+++ b/web/default/src/components/data-table/core/data-table-view.tsx
@@ -136,8 +136,8 @@ function SplitHeaderTableView({