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: 'fitCell', // or 'fitGrid'
}"
/>
</template>
| Strategy | Description |
|---|---|
fitCell | Size each column to fit its content |
fitGrid | Distribute available width across columns |
false | No auto-sizing |
Trigger auto-sizing programmatically:
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
function autoSizeColumns() {
gridRef.value?.autoSizeColumns('fitCell')
}
function fitToGrid() {
gridRef.value?.autoSizeColumns('fitGrid')
}
</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>
Prevent the grid from shrinking when columns resize:
<template>
<NuGrid
:data="data"
:columns="columns"
resize-columns
:layout="{
maintainWidth: true,
}"
/>
</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<'fitCell' | 'fitGrid' | false>('fitGrid')
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: 'Fit Cell Contents', value: 'fitCell' },
{ label: 'Fit Grid Width', value: 'fitGrid' },
{ 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>