NuGrid provides powerful keyboard navigation with two focus modes: cell focus for spreadsheet-like navigation, and row focus for list-like navigation.
Try the keyboard navigation below. Click a cell to focus it, then use arrow keys to navigate:
Navigate between individual cells (default):
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="{ mode: 'cell' }"
/>
</template>
Navigate between entire rows:
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="{ mode: 'row' }"
/>
</template>
Configure focus behavior with the focus prop:
<script setup lang="ts">
const focusOptions = {
mode: 'cell', // 'cell' or 'row'
retain: true, // Retain focus when clicking outside
cmdArrows: 'paging', // Cmd+Arrow behavior: 'paging' or 'firstlast'
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="focusOptions"
/>
</template>
| Option | Type | Default | Description |
|---|---|---|---|
mode | 'cell' | 'row' | 'cell' | Focus mode |
retain | boolean | false | Keep focus when clicking outside grid |
cmdArrows | 'paging' | 'firstlast' | 'firstlast' | Cmd/Ctrl+Arrow behavior |
Track the focused cell or row:
<script setup lang="ts">
const focusedRowId = ref<string | null>(null)
const focusedColumnId = ref<string | null>(null)
</script>
<template>
<NuGrid
v-model:focused-row-id="focusedRowId"
v-model:focused-column-id="focusedColumnId"
:data="data"
:columns="columns"
:focus="{ mode: 'cell' }"
/>
<div class="mt-4">
Focused: Row {{ focusedRowId }}, Column {{ focusedColumnId }}
</div>
</template>
Listen to focus changes:
<script setup lang="ts">
function onFocusedCellChanged(event) {
console.log('Cell focus:', {
rowId: event.rowId,
columnId: event.columnId,
rowIndex: event.rowIndex,
columnIndex: event.columnIndex,
})
}
function onFocusedRowChanged(event) {
console.log('Row focus:', {
rowId: event.rowId,
rowIndex: event.rowIndex,
previousRowIndex: event.previousRowIndex,
})
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="{ mode: 'cell' }"
@focused-cell-changed="onFocusedCellChanged"
@focused-row-changed="onFocusedRowChanged"
/>
</template>
| Key | Action |
|---|---|
Arrow keys | Move focus one cell |
Tab | Move to next cell |
Shift + Tab | Move to previous cell |
Home | Move to first cell in row |
End | Move to last cell in row |
Ctrl/Cmd + Home | Move to first cell |
Ctrl/Cmd + End | Move to last cell |
Page Up | Move up one page |
Page Down | Move down one page |
Ctrl/Cmd + Arrow | Jump to edge or page (configurable) |
| Key | Action |
|---|---|
Arrow Up/Down | Move focus one row |
Home | Move to first row |
End | Move to last row |
Page Up | Move up one page |
Page Down | Move down one page |
Configure how Cmd+Arrow (Mac) / Ctrl+Arrow (Windows) works:
<template>
<!-- Jump to first/last cell (default) -->
<NuGrid
:data="data"
:columns="columns"
:focus="{ cmdArrows: 'firstlast' }"
/>
<!-- Page up/down (Excel-like) -->
<NuGrid
:data="data"
:columns="columns"
:focus="{ cmdArrows: 'paging' }"
/>
</template>
By default, focus is lost when clicking outside the grid. Enable retain to keep focus:
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="{ retain: true }"
/>
</template>
This is useful when building interfaces where the grid should maintain keyboard navigation context.
Set focus programmatically via the grid ref:
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
function focusFirstCell() {
gridRef.value?.setFocusedCell(0, 0)
}
function focusCell(rowIndex: number, columnId: string) {
gridRef.value?.setFocusedCell(rowIndex, columnId)
}
</script>
<template>
<NuGrid ref="grid" :data="data" :columns="columns" />
<UButton @click="focusFirstCell">Focus First Cell</UButton>
</template>
Disable focus for specific columns:
const columns: NuGridColumn<User>[] = [
{
accessorKey: 'id',
header: 'ID',
enableFocusing: false, // Skip this column during navigation
},
{
accessorKey: 'name',
header: 'Name',
},
]
Focus integrates with cell editing. When a cell is focused:
| Key | Action |
|---|---|
Enter | Start editing (if enabled) |
F2 | Start editing (if enabled) |
Backspace/Delete | Clear and start editing |
Any character | Replace and start editing |
See Cell Editing for more details.
Focused cells receive focus styling via CSS. Customize with the ui prop:
<template>
<NuGrid
:data="data"
:columns="columns"
:ui="{
td: '[&[data-focused=true]]:ring-2 [&[data-focused=true]]:ring-primary',
}"
/>
</template>
<script setup lang="ts">
const focusedRowId = ref<string | null>(null)
const focusedItem = computed(() => {
if (!focusedRowId.value) return null
return data.value.find(item => String(item.id) === focusedRowId.value)
})
</script>
<template>
<div class="flex gap-4">
<NuGrid
v-model:focused-row-id="focusedRowId"
:data="data"
:columns="columns"
:focus="{ mode: 'row', retain: true }"
class="flex-1"
/>
<div v-if="focusedItem" class="w-80 rounded-lg border p-4">
<h3 class="text-lg font-semibold">{{ focusedItem.name }}</h3>
<p class="text-muted">{{ focusedItem.email }}</p>
<!-- More details... -->
</div>
</div>
</template>