Essentials

Row Selection

Enable single or multi-row selection in NuGrid.

NuGrid provides flexible row selection with support for single and multi-select modes, keyboard shortcuts, and programmatic control.

ID
Name
Department
Role
1
Alice Johnson
Engineering
Developer
2
Bob Smith
Marketing
Manager
3
Carol White
Engineering
Lead
4
David Brown
HR
Specialist
5
Emma Davis
Engineering
Developer
0 row(s) selected
<script setup lang="ts">
import type { NuGridColumn } from '#nu-grid/types'

interface Employee {
  id: number
  name: string
  department: string
  role: string
}

const data = ref<Employee[]>([
  { id: 1, name: 'Alice Johnson', department: 'Engineering', role: 'Developer' },
  { id: 2, name: 'Bob Smith', department: 'Marketing', role: 'Manager' },
  { id: 3, name: 'Carol White', department: 'Engineering', role: 'Lead' },
  { id: 4, name: 'David Brown', department: 'HR', role: 'Specialist' },
  { id: 5, name: 'Emma Davis', department: 'Engineering', role: 'Developer' },
])

const columns: NuGridColumn<Employee>[] = [
  { accessorKey: 'id', header: 'ID', size: 60 },
  { accessorKey: 'name', header: 'Name', size: 150 },
  { accessorKey: 'department', header: 'Department', size: 120 },
  { accessorKey: 'role', header: 'Role', size: 120 },
]

const rowSelection = ref({})
const table = useTemplateRef('table')

const selectedCount = computed(() => {
  return Object.values(rowSelection.value).filter(Boolean).length
})
</script>

<template>
  <div class="w-full space-y-4">
    <NuGrid
      ref="table"
      v-model:row-selection="rowSelection"
      :data="data"
      :columns="columns"
      selection="multi"
      :ui="{
        base: 'w-full border-separate border-spacing-0',
        thead: '[&>tr]:bg-elevated/50',
        th: 'py-2 border-y border-default first:border-l last:border-r first:rounded-l-lg last:rounded-r-lg',
        td: 'border-b border-default',
      }"
    />
    <div class="text-sm text-muted">{{ selectedCount }} row(s) selected</div>
  </div>
</template>

Basic Selection

Enable row selection with the selection prop:

<template>
  <!-- Multi-select with checkboxes -->
  <NuGrid :data="data" :columns="columns" selection="multi" />

  <!-- Single-select (radio button style) -->
  <NuGrid :data="data" :columns="columns" selection="single" />
</template>

Selection State

Track selection state with v-model:

<script setup lang="ts">
const rowSelection = ref<Record<string, boolean>>({})

// Pre-select rows
const rowSelection = ref({
  '0': true,  // First row selected
  '2': true,  // Third row selected
})
</script>

<template>
  <NuGrid
    v-model:row-selection="rowSelection"
    :data="data"
    :columns="columns"
    selection="multi"
  />
</template>

Selection Options

For more control, pass an options object:

<script setup lang="ts">
const selectionOptions = computed(() => ({
  mode: 'multi',           // 'single' or 'multi'
  hidden: false,           // Hide selection column
  enabled: true,           // Enable/disable selection
  rowSelectionEnabled: (row) => row.original.status !== 'locked',
}))
</script>

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    :selection="selectionOptions"
  />
</template>

Options Reference

OptionTypeDescription
mode'single' | 'multi'Selection mode
hiddenbooleanHide the selection checkbox column
enabledbooleanEnable/disable all selection
rowSelectionEnabled(row) => booleanPer-row selection control

Per-Row Selection Control

Disable selection for specific rows:

<script setup lang="ts">
const selectionOptions = {
  mode: 'multi',
  rowSelectionEnabled: (row) => {
    // Disable selection for inactive users
    return row.original.status !== 'inactive'
  },
}
</script>

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    :selection="selectionOptions"
  />
</template>

Getting Selected Rows

Access selected rows via the grid ref:

<script setup lang="ts">
const gridRef = useTemplateRef('grid')

function processSelectedRows() {
  const selected = gridRef.value?.getSelectedRows()
  console.log('Selected:', selected)
}

function clearSelection() {
  rowSelection.value = {}
}
</script>

<template>
  <NuGrid
    ref="grid"
    v-model:row-selection="rowSelection"
    :data="data"
    :columns="columns"
    selection="multi"
  />

  <div class="mt-4 flex gap-2">
    <UButton @click="processSelectedRows">Process Selected</UButton>
    <UButton color="neutral" @click="clearSelection">Clear</UButton>
  </div>
</template>

Selection Events

Listen to selection changes:

<script setup lang="ts">
function onRowSelectionChanged(selection: Record<string, boolean>) {
  const selectedCount = Object.values(selection).filter(Boolean).length
  console.log(`${selectedCount} rows selected`)
}
</script>

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    selection="multi"
    @row-selection-changed="onRowSelectionChanged"
  />
</template>

Keyboard Shortcuts

When selection is enabled:

KeyAction
SpaceToggle selection on focused row
Shift + ClickSelect range (multi-select)
Ctrl/Cmd + ClickToggle individual row (multi-select)

Hidden Selection Column

Keep selection functionality without showing checkboxes:

<template>
  <NuGrid
    v-model:row-selection="rowSelection"
    :data="data"
    :columns="columns"
    :selection="{ mode: 'multi', hidden: true }"
  />
</template>

With hidden selection, users can still select rows by clicking on them.

Selection with Focus Mode

Combine selection with row focus mode for a master-detail pattern:

<script setup lang="ts">
const focusedRowId = ref<string | null>(null)
</script>

<template>
  <div class="flex gap-4">
    <NuGrid
      v-model:focused-row-id="focusedRowId"
      :data="data"
      :columns="columns"
      :focus="{ mode: 'row' }"
      selection="single"
      class="flex-1"
    />

    <div v-if="focusedRowId" class="w-80">
      <!-- Detail panel for focused row -->
    </div>
  </div>
</template>

Styling Selected Rows

Selected rows receive the data-selected="true" attribute. Style them with CSS:

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    selection="multi"
    :ui="{
      tbody: '[&>tr[data-selected=true]]:bg-primary/10',
    }"
  />
</template>

Example: Bulk Actions

A common pattern with selection:

<script setup lang="ts">
const gridRef = useTemplateRef('grid')
const rowSelection = ref({})

const selectedCount = computed(() =>
  Object.values(rowSelection.value).filter(Boolean).length
)

async function deleteSelected() {
  const selected = gridRef.value?.getSelectedRows()
  if (!selected?.length) return

  // Confirm and delete
  await deleteUsers(selected.map(u => u.id))

  // Clear selection after delete
  rowSelection.value = {}
}
</script>

<template>
  <div>
    <div class="mb-4 flex items-center gap-2">
      <UButton
        v-if="selectedCount > 0"
        color="error"
        icon="i-lucide-trash"
        @click="deleteSelected"
      >
        Delete {{ selectedCount }} selected
      </UButton>
    </div>

    <NuGrid
      ref="grid"
      v-model:row-selection="rowSelection"
      :data="data"
      :columns="columns"
      selection="multi"
    />
  </div>
</template>

Next Steps

Focus & Navigation

Configure keyboard navigation and focus modes.

Sorting & Filtering

Sort and filter your grid data.