Advanced

Focused Row

Programmatic focus control and tracking.

NuGrid provides two-way binding for the focused row ID, allowing you to track and control which row is focused.

Interactive Demo

Two-Way Binding

Use v-model:focused-row-id to track and control focus:

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

<template>
  <NuGrid
    v-model:focused-row-id="focusedRowId"
    :data="data"
    :columns="columns"
    :focus="{ mode: 'cell' }"
  />

  <p>Currently focused: {{ focusedRowId ?? 'None' }}</p>
</template>

Programmatic Focus

Focus a specific row using the grid ref:

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

function focusRow(id: string) {
  gridRef.value?.focusRowById(id)
}

function focusWithScroll(id: string) {
  gridRef.value?.focusRowById(id, { align: 'top' })
}
</script>

<template>
  <UButton @click="focusRow('5')">Focus Row 5</UButton>

  <NuGrid
    ref="grid"
    v-model:focused-row-id="focusedRowId"
    :data="data"
    :columns="columns"
  />
</template>

Scroll Alignment Options

When focusing a row programmatically, you can control scroll behavior:

// Scroll to bring row into view with minimum movement
gridRef.value?.focusRowById(id, { align: 'nearest' })

// Scroll row to top of viewport
gridRef.value?.focusRowById(id, { align: 'top' })

// Center row in viewport
gridRef.value?.focusRowById(id, { align: 'center' })

Focus Options

Configure focus behavior with the focus prop:

<template>
  <NuGrid
    v-model:focused-row-id="focusedRowId"
    :data="data"
    :columns="columns"
    :focus="{
      mode: 'cell',           // 'cell' or 'row'
      retain: true,           // Keep focus when clicking outside
      alignOnModel: 'top',    // Scroll alignment when focusedRowId changes
    }"
  />
</template>

Tracking Cell Focus

To track the focused column as well, use the @focused-cell-changed event:

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

function onFocusedCellChanged(event: { rowId: string | null, columnId: string | null }) {
  focusedColumnId.value = event.columnId
}
</script>

<template>
  <NuGrid
    v-model:focused-row-id="focusedRowId"
    :data="data"
    :columns="columns"
    :focus="{ mode: 'cell' }"
    @focused-cell-changed="onFocusedCellChanged"
  />

  <p>Row: {{ focusedRowId }}, Column: {{ focusedColumnId }}</p>
</template>

Complete Example

<script setup lang="ts">
import type { NuGridColumn } from '#nu-grid/types'

const gridRef = useTemplateRef('grid')
const focusedRowId = ref<string | null>(null)

const data = ref([
  { id: 1, name: 'Alice', department: 'Engineering' },
  { id: 2, name: 'Bob', department: 'Marketing' },
  // ... more rows
])

const columns: NuGridColumn<User>[] = [
  { accessorKey: 'id', header: 'ID' },
  { accessorKey: 'name', header: 'Name' },
  { accessorKey: 'department', header: 'Department' },
]

function focusFirst() {
  gridRef.value?.focusRowById('1', { align: 'top' })
}

function focusLast() {
  const lastId = String(data.value[data.value.length - 1]?.id)
  gridRef.value?.focusRowById(lastId, { align: 'top' })
}

function clearFocus() {
  focusedRowId.value = null
}
</script>

<template>
  <div class="flex gap-2 mb-4">
    <UButton @click="focusFirst">Focus First</UButton>
    <UButton @click="focusLast">Focus Last</UButton>
    <UButton @click="clearFocus">Clear Focus</UButton>
  </div>

  <NuGrid
    ref="grid"
    v-model:focused-row-id="focusedRowId"
    :data="data"
    :columns="columns"
    :focus="{ mode: 'cell', alignOnModel: 'top' }"
  />
</template>
Setting focusedRowId to an invalid ID will log a warning and be ignored. The ID must correspond to an existing row in the data.