Essentials

Columns

Learn how to configure columns in NuGrid.

Columns are the foundation of NuGrid. They define how your data is displayed, edited, and interacted with.

ID
Product Name
Price
Category
In Stock
1
Laptop Pro
$1299.99
Electronics
Yes
2
Wireless Mouse
$29.99
Accessories
Yes
3
USB-C Cable
$12.99
Accessories
No
4
Monitor 4K
$599.99
Electronics
Yes
5
Keyboard
$149.99
Accessories
Yes
<script setup lang="ts">
import type { NuGridColumn } from '#nu-grid/types'

interface Product {
  id: number
  name: string
  price: number
  category: string
  inStock: boolean
}

const data = ref<Product[]>([
  { id: 1, name: 'Laptop Pro', price: 1299.99, category: 'Electronics', inStock: true },
  { id: 2, name: 'Wireless Mouse', price: 29.99, category: 'Accessories', inStock: true },
  { id: 3, name: 'USB-C Cable', price: 12.99, category: 'Accessories', inStock: false },
  { id: 4, name: 'Monitor 4K', price: 599.99, category: 'Electronics', inStock: true },
  { id: 5, name: 'Keyboard', price: 149.99, category: 'Accessories', inStock: true },
])

const columns: NuGridColumn<Product>[] = [
  {
    accessorKey: 'id',
    header: 'ID',
    size: 60,
    enableEditing: false,
  },
  {
    accessorKey: 'name',
    header: 'Product Name',
    size: 150,
  },
  {
    accessorKey: 'price',
    header: 'Price',
    size: 100,
    cell: ({ row }) => `$${row.original.price.toFixed(2)}`,
  },
  {
    accessorKey: 'category',
    header: 'Category',
    size: 120,
  },
  {
    accessorKey: 'inStock',
    header: 'In Stock',
    size: 100,
    cell: ({ row }) =>
      h(
        'span',
        {
          class: row.original.inStock ? 'text-success' : 'text-error',
        },
        row.original.inStock ? 'Yes' : 'No',
      ),
  },
]
</script>

<template>
  <div class="w-full">
    <NuGrid
      :data="data"
      :columns="columns"
      resize-columns
      :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>
</template>

Basic Column Definition

At minimum, a column needs an accessorKey that matches a property in your data:

import type { NuGridColumn } from '#nu-grid/types'

interface User {
  id: number
  name: string
  email: string
}

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

Column Properties

Sizing

Control column width with sizing properties:

const columns: NuGridColumn<User>[] = [
  {
    accessorKey: 'id',
    header: 'ID',
    size: 60,      // Default width in pixels
    minSize: 40,   // Minimum width when resizing
    maxSize: 100,  // Maximum width when resizing
  },
  {
    accessorKey: 'name',
    header: 'Name',
    size: 200,
    minSize: 100,
  },
]

Feature Toggles

Enable or disable features per column:

const columns: NuGridColumn<User>[] = [
  {
    accessorKey: 'id',
    header: 'ID',
    enableSorting: false,    // Disable sorting for this column
    enableEditing: false,    // Disable editing for this column
    enableResizing: false,   // Disable resizing for this column
    enableHiding: false,     // Prevent column from being hidden
    enablePinning: true,     // Allow column pinning
  },
]

Custom Cell Rendering

Customize how cell content is displayed:

const columns: NuGridColumn<User>[] = [
  {
    accessorKey: 'name',
    header: 'Name',
    cell: ({ row }) => {
      return h('div', { class: 'flex items-center gap-2' }, [
        h('img', { src: row.original.avatar, class: 'w-6 h-6 rounded-full' }),
        h('span', row.original.name),
      ])
    },
  },
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) => {
      const colors = {
        active: 'text-success',
        inactive: 'text-error',
      }
      return h('span', { class: colors[row.original.status] }, row.original.status)
    },
  },
]

Custom Header Rendering

Customize the column header:

const columns: NuGridColumn<User>[] = [
  {
    accessorKey: 'email',
    header: ({ column }) => {
      const isSorted = column.getIsSorted()

      return h(UButton, {
        color: 'neutral',
        variant: 'ghost',
        label: 'Email',
        icon: isSorted === 'asc' ? 'i-lucide-arrow-up' : 'i-lucide-arrow-down',
        onClick: () => column.toggleSorting(),
      })
    },
  },
]

Cell Data Types

NuGrid includes built-in cell types for common data formats. These provide appropriate formatting and editing:

const columns: NuGridColumn<Product>[] = [
  { accessorKey: 'name', header: 'Name', cellDataType: 'text' },
  { accessorKey: 'price', header: 'Price', cellDataType: 'currency' },
  { accessorKey: 'quantity', header: 'Qty', cellDataType: 'number' },
  { accessorKey: 'active', header: 'Active', cellDataType: 'boolean' },
  { accessorKey: 'createdAt', header: 'Created', cellDataType: 'date' },
  { accessorKey: 'rating', header: 'Rating', cellDataType: 'rating' },
]

Available Cell Types

TypeDescription
textPlain text with text input editor
numberNumeric values with number input
currencyCurrency formatted values
booleanCheckbox display and editor
dateDate values with date picker
ratingStar rating display
selectionDropdown selection
lookupLookup from options
action-menuAction menu column

Column Groups

Group related columns under a common header:

import { createColumnHelper } from '#nu-grid'

const columnHelper = createColumnHelper<User>()

const columns = [
  columnHelper.group({
    id: 'personal',
    header: 'Personal Info',
    columns: [
      { accessorKey: 'name', header: 'Name' },
      { accessorKey: 'email', header: 'Email' },
    ],
  }),
  columnHelper.group({
    id: 'work',
    header: 'Work Info',
    columns: [
      { accessorKey: 'department', header: 'Department' },
      { accessorKey: 'role', header: 'Role' },
    ],
  }),
]

Column Pinning

Pin columns to the left or right edge:

<script setup lang="ts">
const columnPinning = ref({
  left: ['id', '__selection'],  // Pin selection and ID to left
  right: ['__actions'],         // Pin actions to right
})
</script>

<template>
  <NuGrid
    v-model:column-pinning="columnPinning"
    :data="data"
    :columns="columns"
  />
</template>

Column Visibility

Control which columns are visible:

<script setup lang="ts">
const columnVisibility = ref({
  email: false,    // Hide email column
  phone: false,    // Hide phone column
})
</script>

<template>
  <NuGrid
    v-model:column-visibility="columnVisibility"
    :data="data"
    :columns="columns"
  />
</template>

Column Resizing

Enable column resizing:

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    resize-columns
    :column-sizing-options="{
      columnResizeMode: 'onChange',
    }"
  />
</template>

Add Row Column Options

Configure how columns behave in the add-new-row:

const columns: NuGridColumn<Product>[] = [
  {
    accessorKey: 'id',
    header: 'ID',
    showNew: false,      // Hide in add row (auto-generated)
  },
  {
    accessorKey: 'name',
    header: 'Name',
    requiredNew: true,   // Required in add row
  },
  {
    accessorKey: 'price',
    header: 'Price',
    defaultValue: 0,     // Default value in add row
    validateNew: (value) => {
      if (value < 0) {
        return { valid: false, message: 'Price must be positive' }
      }
      return { valid: true }
    },
  },
]

Next Steps

Row Selection

Enable row selection in your grid.

Focus & Navigation

Configure keyboard navigation.