Skip to content

External Toolbar

A control panel beside the table reads scrollLocation$ and publishes scrollToRow$ and setColumnSticky$ through a shared engineRef. Virtualization and feature state stay inside the table engine; React state stays out of it.

  • useEngineRef()
  • useRemoteCellValue()
  • useRemotePublisher()
import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table'
import { localModel, useEngineRef } from '@virtuoso.dev/data-table'

import { ControlPanel } from './ControlPanel'
import { products } from './data'

const model = localModel({ data: products })

export default function App() {
  const engineRef = useEngineRef()

  return (
    <div className="grid gap-4 lg:grid-cols-[280px_minmax(0,1fr)]">
      <ControlPanel engineRef={engineRef} />

      <DataTable className="rounded-xl" model={model} engineRef={engineRef} style={{ height: 420 }}>
        <DataTableColumn field="name">
          <DataTableColumnHeader>Product</DataTableColumnHeader>
          <DataTableCell className="font-medium">{({ row }) => row.data.name}</DataTableCell>
        </DataTableColumn>
        <DataTableColumn field="category">
          <DataTableColumnHeader>Category</DataTableColumnHeader>
          <DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
        </DataTableColumn>
        <DataTableColumn field="status">
          <DataTableColumnHeader>Status</DataTableColumnHeader>
          <DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
        </DataTableColumn>
        <DataTableColumn field="region">
          <DataTableColumnHeader>Region</DataTableColumnHeader>
          <DataTableCell>{({ cellValue }) => String(cellValue)}</DataTableCell>
        </DataTableColumn>
      </DataTable>
    </div>
  )
}

The cells and actions you publish to (scrollToRow$, setColumnSticky$, scrollLocation$, etc.) are the public API surface for this table — pin their names in tests and treat renames the same way you’d treat a prop rename.