Advanced

Action Menu

Row action menus with custom items.

NuGrid supports row action menus that appear when clicking an action button or right-clicking a row.

Interactive Demo

Basic Usage

Define action items for each row:

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

function getRowActions(row: NuGridRow<User>): NuGridActionMenuItem[] {
  return [
    { label: 'View', icon: 'i-lucide-eye' },
    { label: 'Edit', icon: 'i-lucide-pencil' },
    { type: 'separator' },
    { label: 'Delete', icon: 'i-lucide-trash', color: 'error' },
  ]
}
</script>

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    :actions="{ getActions: getRowActions }"
  />
</template>

Action Item Types

Basic Action

{
  label: 'Edit',
  icon: 'i-lucide-pencil',
  onSelect: () => editItem(row.original)
}

Separator

{ type: 'separator' }

Label (Non-clickable Header)

{ type: 'label', label: 'Actions' }

Colored Action

{
  label: 'Delete',
  icon: 'i-lucide-trash',
  color: 'error',
  onSelect: () => deleteItem(row.original)
}

Complete Example

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

const toast = useToast()

interface User {
  id: number
  name: string
  email: string
  status: 'active' | 'inactive'
}

const data = ref<User[]>([
  { id: 1, name: 'Alice', email: 'alice@example.com', status: 'active' },
  { id: 2, name: 'Bob', email: 'bob@example.com', status: 'inactive' },
])

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

function getRowActions(row: NuGridRow<User>): NuGridActionMenuItem[] {
  return [
    { type: 'label', label: 'Actions' },
    {
      label: 'Copy ID',
      icon: 'i-lucide-copy',
      onSelect: () => {
        navigator.clipboard.writeText(String(row.original.id))
        toast.add({ title: 'Copied', description: 'ID copied to clipboard' })
      },
    },
    {
      label: 'View Details',
      icon: 'i-lucide-eye',
      onSelect: () => {
        toast.add({ title: 'View', description: `Viewing ${row.original.name}` })
      },
    },
    { type: 'separator' },
    {
      label: row.original.status === 'active' ? 'Deactivate' : 'Activate',
      icon: row.original.status === 'active' ? 'i-lucide-user-x' : 'i-lucide-user-check',
      onSelect: () => {
        row.original.status = row.original.status === 'active' ? 'inactive' : 'active'
      },
    },
    { type: 'separator' },
    {
      label: 'Delete',
      icon: 'i-lucide-trash',
      color: 'error',
      onSelect: () => {
        data.value = data.value.filter(u => u.id !== row.original.id)
        toast.add({ title: 'Deleted', description: `Removed ${row.original.name}` })
      },
    },
  ]
}
</script>

<template>
  <NuGrid
    :data="data"
    :columns="columns"
    :actions="{ getActions: getRowActions }"
  />
</template>

Action Column Pinning

Pin the action column to the right edge:

<script setup lang="ts">
const columnPinning = ref({
  left: ['id'],
  right: ['__actions'],  // Use '__actions' for the action column
})
</script>

<template>
  <NuGrid
    v-model:column-pinning="columnPinning"
    :data="data"
    :columns="columns"
    :actions="{ getActions: getRowActions }"
  />
</template>
The action menu is built using Nuxt UI's dropdown component, so it inherits your app's styling and supports keyboard navigation.