NuGrid supports multi-level row grouping, allowing you to organize data hierarchically with expandable/collapsible sections.
Enable grouping by specifying which columns to group by:
<script setup lang="ts">
// Group by a single column
const grouping = ref(['department'])
</script>
<template>
<NuGrid
v-model:grouping="grouping"
:data="data"
:columns="columns"
:layout="{ mode: 'group' }"
/>
</template>
Create nested groups by specifying multiple columns:
<script setup lang="ts">
// 3-tier grouping: region > country > status
const grouping = ref(['region', 'country', 'status'])
</script>
<template>
<NuGrid
v-model:grouping="grouping"
:data="data"
:columns="columns"
:layout="{ mode: 'group' }"
/>
</template>
Groups share the same header row:
<template>
<NuGrid
v-model:grouping="grouping"
:data="data"
:columns="columns"
:layout="{ mode: 'group' }"
/>
</template>
Each group section has its own header:
<template>
<NuGrid
v-model:grouping="grouping"
:data="data"
:columns="columns"
:layout="{ mode: 'splitgroup' }"
/>
</template>
<script setup lang="ts">
import type { NuGridColumn } from '#nu-grid/types'
interface Product {
id: number
name: string
region: string
country: string
status: 'active' | 'inactive'
price: number
}
const data = ref<Product[]>([
{ id: 1, name: 'Laptop', region: 'North America', country: 'USA', status: 'active', price: 1299 },
{ id: 2, name: 'Mouse', region: 'North America', country: 'USA', status: 'active', price: 29 },
{ id: 3, name: 'Monitor', region: 'North America', country: 'Canada', status: 'active', price: 349 },
{ id: 4, name: 'Keyboard', region: 'Europe', country: 'UK', status: 'inactive', price: 89 },
{ id: 5, name: 'Webcam', region: 'Europe', country: 'Germany', status: 'active', price: 129 },
// ... more data
])
// Group by region, then by country
const grouping = ref(['region', 'country'])
const columns: NuGridColumn<Product>[] = [
{ accessorKey: 'name', header: 'Product Name' },
{ accessorKey: 'region', header: 'Region' },
{ accessorKey: 'country', header: 'Country' },
{ accessorKey: 'status', header: 'Status' },
{
accessorKey: 'price',
header: 'Price',
cell: ({ row }) => `$${row.original.price.toFixed(2)}`,
},
]
</script>
<template>
<NuGrid
v-model:grouping="grouping"
:data="data"
:columns="columns"
:layout="{ mode: 'group' }"
:focus="{ retain: true }"
/>
</template>
Groups can be expanded and collapsed by clicking on the group header row. The expansion state is managed automatically, but you can control it programmatically:
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
function expandAll() {
gridRef.value?.tableApi?.toggleAllRowsExpanded(true)
}
function collapseAll() {
gridRef.value?.tableApi?.toggleAllRowsExpanded(false)
}
</script>
<template>
<div class="flex gap-2 mb-4">
<UButton @click="expandAll">Expand All</UButton>
<UButton @click="collapseAll">Collapse All</UButton>
</div>
<NuGrid
ref="grid"
v-model:grouping="grouping"
:data="data"
:columns="columns"
:layout="{ mode: 'group' }"
/>
</template>
Nested groups automatically receive visual indentation to show the hierarchy level. The indentation is styled through the theme system.