Cell Data Types
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="text-muted mb-3 text-sm">
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>
Automatic Type Inference
NuGrid automatically infers data types from your row data, similar to AG Grid. This means you often don't need to manually specify cellDataType for each column.
How It Works
When data is loaded, NuGrid examines the values in each column and detects the appropriate type:
| Detected Type | Detection Logic |
|---|---|
boolean | Values are true or false |
date | Values are JavaScript Date objects |
currency | String with currency symbol ($123.45) OR number with 2 decimals + column name contains price/cost/amount/total/fee/salary/etc. |
percentage | String with percent sign (45%) OR number 0-1 + column name contains percent/rate/ratio |
number | Numeric values |
text | Default fallback for strings |
Example
// No cellDataType needed - types are inferred automatically!
const columns = [
{ accessorKey: 'name', header: 'Name' }, // Inferred: 'text'
{ accessorKey: 'price', header: 'Price' }, // Inferred: 'currency' (2 decimals + "price")
{ accessorKey: 'discountRate', header: 'Rate' }, // Inferred: 'percentage' (0-1 + "rate")
{ accessorKey: 'inStock', header: 'In Stock' }, // Inferred: 'boolean'
{ accessorKey: 'orderDate', header: 'Date' }, // Inferred: 'date' (Date object)
]
const data = [
{
name: 'Laptop',
price: 1299.99, // Currency: 2 decimals + column name
discountRate: 0.15, // Percentage: 0-1 + column name
inStock: true, // Boolean
orderDate: new Date(), // Date object
},
]
Disabling Type Inference
Globally: Set dataTypeInference to false on the grid:
<NuGrid
:data="data"
:columns="columns"
:data-type-inference="false"
/>
Per column: Set cellDataType to false to disable inference for that column:
{
accessorKey: 'price',
header: 'Price',
cellDataType: false, // No inference, use default text rendering
}
Explicit type: Setting any cellDataType value prevents inference for that column:
{
accessorKey: 'amount',
header: 'Amount',
cellDataType: 'number', // Use number, not currency
}
Available Cell Types
| Type | Description | Display | Editor |
|---|---|---|---|
text | Plain text | Text | Text input |
number | Numeric values | Formatted number | Number input |
currency | Money values | Currency format | Number input |
percentage | Percentage values | Formatted with % | Number input with % |
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 |
Using Cell Data Types
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' },
]
Text
Plain text display and editing:
{
accessorKey: 'name',
header: 'Name',
cellDataType: 'text',
}
Number
Numeric values with formatting:
{
accessorKey: 'quantity',
header: 'Quantity',
cellDataType: 'number',
cellDataTypeOptions: {
locale: 'en-US',
minimumFractionDigits: 0,
maximumFractionDigits: 2,
},
}
Currency
Money values with currency formatting:
{
accessorKey: 'price',
header: 'Price',
cellDataType: 'currency',
cellDataTypeOptions: {
currency: 'USD',
locale: 'en-US',
},
}
Currency Options
| Option | Type | Default | Description |
|---|---|---|---|
currency | string | 'USD' | Currency code |
locale | string | 'en-US' | Locale for formatting |
Percentage
Percentage values with % formatting:
{
accessorKey: 'discountRate',
header: 'Discount',
cellDataType: 'percentage',
}
Storage Modes
Percentages can be stored as decimals (0-1) or as whole numbers (0-100):
// Stored as decimal (0.15 displays as "15.0%")
{
accessorKey: 'rate',
cellDataType: 'percentage',
percentageStorage: 'decimal', // Default
}
// Stored as whole number (15 displays as "15.0%")
{
accessorKey: 'rate',
cellDataType: 'percentage',
percentageStorage: 'percent',
}
Percentage Options
| Option | Type | Default | Description |
|---|---|---|---|
percentageStorage | 'decimal' | 'percent' | 'decimal' | How values are stored |
percentageDecimals | number | 1 | Decimal places to display |
Boolean
Checkbox display and editing:
{
accessorKey: 'active',
header: 'Active',
cellDataType: 'boolean',
}
Boolean cells render as checkboxes and toggle on click or space key.
Date
Date display with formatting:
{
accessorKey: 'createdAt',
header: 'Created',
cellDataType: 'date',
cellDataTypeOptions: {
format: 'MMM dd, yyyy',
locale: 'en-US',
},
}
Date Options
| Option | Type | Default | Description |
|---|---|---|---|
format | string | 'PP' | Date format string |
locale | string | System locale | Locale for formatting |
Rating
Star rating display:
{
accessorKey: 'rating',
header: 'Rating',
cellDataType: 'rating',
cellDataTypeOptions: {
max: 5,
color: 'yellow',
},
}
Rating Options
| Option | Type | Default | Description |
|---|---|---|---|
max | number | 5 | Maximum rating value |
color | string | 'yellow' | Star color |
Selection
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'],
},
}
Selection Options
| Option | Type | Description |
|---|---|---|
options | string[] | { label, value }[] | Available options |
placeholder | string | Placeholder text |
searchable | boolean | Enable search |
Lookup
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',
},
},
]
Lookup Options
| 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 |
Action Menu
Add row actions menu:
{
id: 'actions',
header: 'Actions',
cellDataType: 'action-menu',
}
See Row Actions for complete action menu documentation.
Custom Cell Renderers
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,
})
},
}
Registering Custom Cell Types
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',
}
Example: Multiple Data Types
<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>