Logo VitNode
Documentation

Data Table

Bulk Actions

Tick a few rows and act on all of them at once from a floating bar.

Preview

Usage

Passing bulkActions turns selection on. Each row gets a checkbox, and the header checkbox ticks the whole page. While anything is ticked, a bar floats at the bottom of the viewport with the count, your actions and a clear button.

<ContentDataTable
  id="users-table"
  bulkActions={<DeleteBulkAction />}
  columns={columns}
  edges={data.edges}
  pageInfo={data.pageInfo}
  order={{ defaultOrder: { column: 'name', order: 'asc' } }}
/>

Actions render inside the bar, so they read the ticked ids with useDataTableSelection(). No props to thread through.

delete-bulk-action.tsx
import { useDataTableSelection } from '@vitnode/core/components/table/selection'
import { Button } from '@vitnode/core/components/ui/button'

export const DeleteBulkAction = () => {
  const { clear, selected } = useDataTableSelection()

  return (
    <Button
      onClick={async () => {
        await deleteUsers(selected)
        clear()
      }}
      variant="destructive"
    >
      <Trash2Icon />
      Delete
    </Button>
  )
}

Selection is per page

Selection only covers the rows on screen. When paging, search or a filter brings different rows, ticks on rows that left are dropped. A bulk action never touches a row nobody can see.

After a partial success, revalidate. Rows that were refused stay on screen and stay ticked, so the bar points at the work that's left.

There is no bulk endpoint

bulkActions hands you ids, nothing more. If your action loops a single-row endpoint, cap the fan-out and report outcomes per reason, so a partial success can say so.

useDataTableSelection

Prop

Type

The hook throws outside a table with bulkActions.