NuGrid provides built-in cell data types that handle formatting, display, and editing for common data formats.
Different cell data types provide appropriate editors: text input, number input, date picker, and checkbox.
<script setup lang="ts">
import type { NuGridColumn } from '#nu-grid/types'
interface Product {
id: number
name: string
price: number
releaseDate: string
inStock: boolean
}
const data = ref<Product[]>([
{ id: 1, name: 'Laptop', price: 1299.99, releaseDate: '2024-01-15', inStock: true },
{ id: 2, name: 'Mouse', price: 29.99, releaseDate: '2023-06-10', inStock: true },
{ id: 3, name: 'Cable', price: 12.99, releaseDate: '2023-03-22', inStock: false },
{ id: 4, name: 'Monitor', price: 599.99, releaseDate: '2024-08-05', inStock: true },
])
const columns: NuGridColumn<Product>[] = [
{ accessorKey: 'id', header: 'ID', size: 60, enableEditing: false, cellDataType: 'number' },
{ accessorKey: 'name', header: 'Name', size: 120, cellDataType: 'text' },
{
accessorKey: 'price',
header: 'Price',
size: 100,
cellDataType: 'number',
cell: ({ row }) => `$${row.original.price.toFixed(2)}`,
},
{
accessorKey: 'releaseDate',
header: 'Release Date',
size: 130,
cellDataType: 'date',
cell: ({ row }) => new Date(row.original.releaseDate).toLocaleDateString(),
},
{ accessorKey: 'inStock', header: 'In Stock', size: 100, cellDataType: 'boolean' },
]
const toast = useToast()
function onCellValueChanged(event: { row: any; column: any; oldValue: any; newValue: any }) {
toast.add({
title: 'Cell Updated',
description: `${event.column.id}: "${event.oldValue}" → "${event.newValue}"`,
color: 'success',
})
}
</script>
<template>
<div class="w-full">
<p class="mb-3 text-sm text-muted">
Different cell data types provide appropriate editors: text input, number input, date picker,
and checkbox.
</p>
<NuGrid
:data="data"
:columns="columns"
:editing="{ enabled: true, startClicks: 'double' }"
: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',
}"
@cell-value-changed="onCellValueChanged"
/>
</div>
</template>
| Type | Description | Display | Editor |
|---|---|---|---|
text | Plain text | Text | Text input |
number | Numeric values | Formatted number | Number input |
currency | Money values | Currency format | Number input |
boolean | True/false values | Checkbox | Checkbox |
date | Date values | Formatted date | Date picker |
rating | Star ratings | Stars | Star selector |
selection | Select from options | Selected value | Dropdown |
lookup | Lookup values | Resolved value | Lookup picker |
action-menu | Row actions | Action button | Menu |
Specify the cellDataType on a column:
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' },
]
Plain text display and editing:
{
accessorKey: 'name',
header: 'Name',
cellDataType: 'text',
}
Numeric values with formatting:
{
accessorKey: 'quantity',
header: 'Quantity',
cellDataType: 'number',
cellDataTypeOptions: {
locale: 'en-US',
minimumFractionDigits: 0,
maximumFractionDigits: 2,
},
}
Money values with currency formatting:
{
accessorKey: 'price',
header: 'Price',
cellDataType: 'currency',
cellDataTypeOptions: {
currency: 'USD',
locale: 'en-US',
},
}
| Option | Type | Default | Description |
|---|---|---|---|
currency | string | 'USD' | Currency code |
locale | string | 'en-US' | Locale for formatting |
Checkbox display and editing:
{
accessorKey: 'active',
header: 'Active',
cellDataType: 'boolean',
}
Boolean cells render as checkboxes and toggle on click or space key.
Date display with formatting:
{
accessorKey: 'createdAt',
header: 'Created',
cellDataType: 'date',
cellDataTypeOptions: {
format: 'MMM dd, yyyy',
locale: 'en-US',
},
}
| Option | Type | Default | Description |
|---|---|---|---|
format | string | 'PP' | Date format string |
locale | string | System locale | Locale for formatting |
Star rating display:
{
accessorKey: 'rating',
header: 'Rating',
cellDataType: 'rating',
cellDataTypeOptions: {
max: 5,
color: 'yellow',
},
}
| Option | Type | Default | Description |
|---|---|---|---|
max | number | 5 | Maximum rating value |
color | string | 'yellow' | Star color |
Dropdown selection from predefined options:
{
accessorKey: 'status',
header: 'Status',
cellDataType: 'selection',
cellDataTypeOptions: {
options: [
{ label: 'Active', value: 'active' },
{ label: 'Pending', value: 'pending' },
{ label: 'Inactive', value: 'inactive' },
],
},
}
Or with simple string array:
{
accessorKey: 'category',
header: 'Category',
cellDataType: 'selection',
cellDataTypeOptions: {
options: ['Electronics', 'Clothing', 'Food', 'Other'],
},
}
| Option | Type | Description |
|---|---|---|
options | string[] | { label, value }[] | Available options |
placeholder | string | Placeholder text |
searchable | boolean | Enable search |
Lookup values from a reference dataset:
const users = ref([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Carol' },
])
const columns = [
{
accessorKey: 'assigneeId',
header: 'Assignee',
cellDataType: 'lookup',
cellDataTypeOptions: {
options: users,
labelKey: 'name',
valueKey: 'id',
},
},
]
| Option | Type | Description |
|---|---|---|
options | Ref<any[]> | any[] | Lookup data source |
labelKey | string | Key for display label |
valueKey | string | Key for value |
searchable | boolean | Enable search |
Add row actions menu:
{
id: 'actions',
header: 'Actions',
cellDataType: 'action-menu',
}
See Row Actions for complete action menu documentation.
Override the default renderer while keeping the data type:
{
accessorKey: 'status',
header: 'Status',
cellDataType: 'selection',
cellDataTypeOptions: {
options: ['active', 'pending', 'inactive'],
},
// Custom display while keeping selection editor
cell: ({ row }) => {
const colors = {
active: 'success',
pending: 'warning',
inactive: 'error',
}
return h(UBadge, {
color: colors[row.original.status],
label: row.original.status,
})
},
}
Create custom cell types using the cell type registry:
// plugins/custom-cell-types.ts
import { useNuGridCellTypeRegistry } from '#nu-grid'
export default defineNuxtPlugin(() => {
const registry = useNuGridCellTypeRegistry()
registry.register('percentage', {
display: ({ value }) => `${(value * 100).toFixed(1)}%`,
editor: defineComponent({
// Custom editor component
}),
})
})
Then use it:
{
accessorKey: 'completion',
header: 'Progress',
cellDataType: 'percentage',
}
<script setup lang="ts">
interface Product {
id: number
name: string
category: string
price: number
stock: number
active: boolean
rating: number
createdAt: Date
}
const columns: NuGridColumn<Product>[] = [
{
accessorKey: 'name',
header: 'Name',
cellDataType: 'text',
},
{
accessorKey: 'category',
header: 'Category',
cellDataType: 'selection',
cellDataTypeOptions: {
options: ['Electronics', 'Clothing', 'Food', 'Home'],
},
},
{
accessorKey: 'price',
header: 'Price',
cellDataType: 'currency',
cellDataTypeOptions: { currency: 'USD' },
},
{
accessorKey: 'stock',
header: 'Stock',
cellDataType: 'number',
},
{
accessorKey: 'active',
header: 'Active',
cellDataType: 'boolean',
},
{
accessorKey: 'rating',
header: 'Rating',
cellDataType: 'rating',
cellDataTypeOptions: { max: 5 },
},
{
accessorKey: 'createdAt',
header: 'Created',
cellDataType: 'date',
cellDataTypeOptions: { format: 'PP' },
},
]
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:editing="{ enabled: true }"
/>
</template>