Advanced

Multi-Row Layout

Multiple visual rows per data row.

NuGrid supports multi-row layouts where a single data row spans multiple visual rows, useful for displaying complex data with notes or descriptions.

Interactive Demo

Basic Usage

Enable multi-row layout with the multiRow prop:

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    :multi-row="{ enabled: true, rowCount: 2 }"
  />
</template>

Column Row Assignment

Assign columns to specific visual rows:

<script setup lang="ts">
const columns: NuGridColumn<Employee>[] = [
  // Row 0 - Main info
  { accessorKey: 'id', header: 'ID', row: 0 },
  { accessorKey: 'name', header: 'Name', row: 0 },
  { accessorKey: 'email', header: 'Email', row: 0 },

  // Row 1 - Additional info
  { accessorKey: 'department', header: 'Department', row: 1 },
  { accessorKey: 'salary', header: 'Salary', row: 1 },

  // Row 2 - Notes (spans all columns)
  {
    accessorKey: 'notes',
    header: 'Notes',
    row: 2,
    span: '*',  // Span all columns
    wrapText: true,
  },
]
</script>

Multi-Row Options

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    :multi-row="{
      enabled: true,
      rowCount: 3,
      alignColumns: true,  // Align columns across rows
    }"
  />
</template>

Options Reference

OptionTypeDefaultDescription
enabledbooleanfalseEnable multi-row layout
rowCountnumber2Number of visual rows per data row
alignColumnsbooleanfalseAlign column widths across rows

Column Properties for Multi-Row

PropertyTypeDescription
rownumberVisual row index (0-based)
spannumber | '*'Column span (or '*' for all remaining columns)
wrapTextbooleanEnable text wrapping

Complete Example

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

interface Employee {
  id: number
  name: string
  email: string
  department: string
  salary: number
  hireDate: string
  notes: string
}

const data = ref<Employee[]>([
  {
    id: 1,
    name: 'Sarah Johnson',
    email: 'sarah@example.com',
    department: 'Engineering',
    salary: 125000,
    hireDate: '2020-03-15',
    notes: 'Senior engineer with expertise in distributed systems.',
  },
  // ... more data
])

const multiRowEnabled = ref(true)

const columns = computed<NuGridColumn<Employee>[]>(() => [
  // Row 0 - Identity
  { accessorKey: 'id', header: 'ID', size: 60, row: 0, enableEditing: false },
  { accessorKey: 'name', header: 'Name', size: 150, row: 0 },
  { accessorKey: 'email', header: 'Email', size: 200, row: 0 },
  { accessorKey: 'department', header: 'Department', size: 120, row: 0 },

  // Row 1 - Compensation & Dates
  {
    accessorKey: 'salary',
    header: 'Salary',
    size: 100,
    row: multiRowEnabled.value ? 1 : 0,
    cell: ({ row }) => `$${row.original.salary.toLocaleString()}`,
  },
  {
    accessorKey: 'hireDate',
    header: 'Hire Date',
    size: 110,
    row: multiRowEnabled.value ? 1 : 0,
  },

  // Row 2 - Notes (spans full width in multi-row mode)
  {
    accessorKey: 'notes',
    header: 'Notes',
    size: multiRowEnabled.value ? 400 : 200,
    row: multiRowEnabled.value ? 2 : 0,
    span: multiRowEnabled.value ? '*' : undefined,
    wrapText: multiRowEnabled.value,
  },
])
</script>

<template>
  <UButton
    :color="multiRowEnabled ? 'primary' : 'neutral'"
    @click="multiRowEnabled = !multiRowEnabled"
  >
    Multi-Row: {{ multiRowEnabled ? 'On' : 'Off' }}
  </UButton>

  <NuGrid
    :data="data"
    :columns="columns"
    :multi-row="multiRowEnabled ? { enabled: true, rowCount: 3, alignColumns: true } : false"
    :editing="{ enabled: true, startClicks: 'double' }"
  />
</template>

Excel Export with Multi-Row

When exporting to Excel, each data row is exported as a single Excel row regardless of the multi-row display:

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

async function exportToExcel() {
  // Each data row becomes one Excel row
  await gridRef.value?.excelExport('employees', 'Data')
}
</script>
Multi-row layouts are purely visual. The underlying data structure remains unchanged, making it easy to export or manipulate data normally.