Skip to content

Keep Sticky Columns Clear of Overlay Scrollbars

macOS overlay scrollbars sit on top of content and can cover the last sticky-right column. The header and cell render params expose overlaidByScrollbar — true when an overlay scrollbar covers this cell — so you can add compensating right padding only when needed.

  • overlaidByScrollbar — render-param flag in cell and header renderers
  • sticky="right" — column pin where the bug shows up
import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table'

import { columns, rows } from './data'
import { localModel } from '@virtuoso.dev/data-table'

const model = localModel({ data: rows })

export default function App() {
  return (
    <DataTable className="rounded-xl" model={model} style={{ height: 400 }}>
      <DataTableColumn field="sku" sticky="left">
        <DataTableColumnHeader>SKU</DataTableColumnHeader>
        <DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
      </DataTableColumn>

      {columns.map((column) => (
        <DataTableColumn field={column} key={column}>
          <DataTableColumnHeader className="min-w-[130px]">{column}</DataTableColumnHeader>
          <DataTableCell>{({ row }) => String(row.data[column])}</DataTableCell>
        </DataTableColumn>
      ))}

      <DataTableColumn field="actions" sticky="right">
        <DataTableColumnHeader className="min-w-[150px] justify-end">
          {({ overlaidByScrollbar }) => (
            <span
              style={{
                paddingRight: overlaidByScrollbar ? 'calc(0.75rem + var(--overlay-scrollbar-visible-size))' : '0.75rem',
              }}
            >
              Actions
            </span>
          )}
        </DataTableColumnHeader>
        <DataTableCell className="text-right text-sm text-muted-foreground">
          {({ overlaidByScrollbar }) => (
            <span
              style={{
                paddingRight: overlaidByScrollbar ? 'calc(0.75rem + var(--overlay-scrollbar-visible-size))' : '0.75rem',
              }}
            >
              Edit · Duplicate
            </span>
          )}
        </DataTableCell>
      </DataTableColumn>
    </DataTable>
  )
}

Only sticky-right columns need this. The bug is platform-specific (macOS, sometimes iPadOS) — easy to miss in development on other platforms, so bake the padding in early.

Column widths come from header measurements. Set min-w-* on the header only; never on DataTableCell. A width class on the cell competes with the engine’s column-width sync and the cells start overlapping each other when the table re-measures.