NuGrid provides flexible column sizing with manual resizing, auto-sizing, and programmatic control.
Enable column resizing with the resize-columns prop:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
/>
</template>
Users can drag column borders to resize.
Set column widths in the column definition:
const columns: NuGridColumn<User>[] = [
{
accessorKey: 'id',
header: 'ID',
size: 60, // Default width
minSize: 40, // Minimum when resizing
maxSize: 100, // Maximum when resizing
},
{
accessorKey: 'name',
header: 'Name',
size: 200,
minSize: 100,
// No maxSize = unlimited
},
{
accessorKey: 'email',
header: 'Email',
size: 250,
enableResizing: false, // Disable resizing for this column
},
]
Track column sizes with v-model:
<script setup lang="ts">
const columnSizing = ref<Record<string, number>>({})
</script>
<template>
<NuGrid
v-model:column-sizing="columnSizing"
:data="data"
:columns="columns"
resize-columns
/>
<pre>{{ columnSizing }}</pre>
</template>
Configure how resizing affects other columns:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
:column-sizing-options="{
columnResizeMode: 'onChange', // or 'onEnd'
}"
/>
</template>
| Mode | Description |
|---|---|
onChange | Resize updates during drag |
onEnd | Resize updates when drag ends |
NuGrid can automatically size columns to fit content.
Size columns to fit content when the grid loads:
<template>
<NuGrid
:data="data"
:columns="columns"
:layout="{
autoSize: 'content', // or 'fill'
}"
/>
</template>
| Strategy | Description |
|---|---|
content | Size each column to fit its content exactly |
fill | Size to content, then scale proportionally to fill container width |
false | No auto-sizing (use column size definitions) |
autoSize: 'fill' is set, the grid automatically applies w-full to ensure columns fill the container width. No additional configuration is needed.Trigger auto-sizing programmatically:
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
function autoSizeColumns() {
gridRef.value?.autoSizeColumns('content')
}
function fitToGrid() {
gridRef.value?.autoSizeColumns('fill')
}
</script>
<template>
<div class="mb-4 flex gap-2">
<UButton @click="autoSizeColumns">Fit Content</UButton>
<UButton @click="fitToGrid">Fit Grid</UButton>
</div>
<NuGrid ref="grid" :data="data" :columns="columns" resize-columns />
</template>
Make the grid expand to fill its container width:
<template>
<NuGrid
:data="data"
:columns="columns"
:ui="{ base: 'w-full' }"
/>
</template>
When using full width with auto-sizing, columns will scale to fill the available space.
By default, the grid sizes to fit its content:
<template>
<NuGrid
:data="data"
:columns="columns"
:ui="{ base: 'w-max' }"
/>
</template>
Controls how column resizing affects the grid width:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
:layout="{
resizeMode: 'shift',
}"
/>
</template>
| Setting | Behavior |
|---|---|
resizeMode: 'shift' | Grid width stays fixed; resizing one column shifts adjacent columns (default) |
resizeMode: 'expand' | Grid width adjusts to total column widths |
Example with fill auto-sizing (full width is applied automatically):
<template>
<NuGrid
:data="data"
:columns="columns"
:layout="{
autoSize: 'fill',
resizeMode: 'shift',
}"
/>
</template>
Create columns that grow to fill available space:
const columns: NuGridColumn<User>[] = [
{
accessorKey: 'id',
header: 'ID',
size: 60, // Fixed width
},
{
accessorKey: 'name',
header: 'Name',
size: 200, // Fixed width
},
{
accessorKey: 'description',
header: 'Description',
// No size = flex to fill remaining space
},
]
Save and restore column widths:
<script setup lang="ts">
const columnSizing = ref(
JSON.parse(localStorage.getItem('gridColumnSizes') || '{}')
)
watch(columnSizing, (sizes) => {
localStorage.setItem('gridColumnSizes', JSON.stringify(sizes))
}, { deep: true })
</script>
<template>
<NuGrid
v-model:column-sizing="columnSizing"
:data="data"
:columns="columns"
resize-columns
/>
</template>
Or use state persistence:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
:state-persistence="{
key: 'my-grid',
storage: 'local',
}"
/>
</template>
Users can double-click a column border to auto-size that column:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
:column-sizing-options="{
enableColumnAutoSize: true,
}"
/>
</template>
Customize the resize handle appearance:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
:ui="{
th: '[&_.resize-handle]:bg-primary [&_.resize-handle]:opacity-0 [&:hover_.resize-handle]:opacity-100',
}"
/>
</template>
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
const columnSizing = ref({})
const autoSizeStrategy = ref<'content' | 'fill' | false>('fill')
function applyAutoSize() {
if (autoSizeStrategy.value) {
gridRef.value?.autoSizeColumns(autoSizeStrategy.value)
}
}
function resetSizes() {
columnSizing.value = {}
}
const columns: NuGridColumn<User>[] = [
{ accessorKey: 'id', header: 'ID', size: 60, minSize: 40, maxSize: 100 },
{ accessorKey: 'name', header: 'Name', size: 150, minSize: 100 },
{ accessorKey: 'email', header: 'Email', size: 200, minSize: 150 },
{ accessorKey: 'department', header: 'Department', size: 150 },
{ accessorKey: 'role', header: 'Role', size: 150 },
]
</script>
<template>
<div class="space-y-4">
<div class="flex items-center gap-4">
<USelect
v-model="autoSizeStrategy"
:items="[
{ label: 'Content Width', value: 'content' },
{ label: 'Fill Container', value: 'fill' },
{ label: 'Manual', value: false },
]"
class="w-48"
/>
<UButton v-if="autoSizeStrategy" @click="applyAutoSize">
Apply
</UButton>
<UButton variant="outline" @click="resetSizes">
Reset
</UButton>
</div>
<NuGrid
ref="grid"
v-model:column-sizing="columnSizing"
:data="data"
:columns="columns"
resize-columns
:layout="{ autoSize: autoSizeStrategy }"
:column-sizing-options="{ columnResizeMode: 'onChange' }"
/>
<div class="text-sm text-muted">
Current sizes: {{ JSON.stringify(columnSizing) }}
</div>
</div>
</template>