-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Environment
Operating system Windows 10.0.22631
CPU 13th Gen Intel(R) Core(TM) i7-1355U (12 cores)
Node.js version v22.15.0
nuxt/cli version 3.33.1
Package manager pnpm 10.29.2
Nuxt version 4.3.1
Nitro version 2.13.1
Builder vite 7.3.1
Config compatibilityDate, css, devtools, eslint, modules, routeRules
Modules @nuxt/eslint 1.15.1, @nuxt/ui 4.4.0
Is this bug related to Nuxt or Vue?
Nuxt
Package
v4.x
Version
v4.4.0
Reproduction
Sandbox is not working properly so I created a repo with all steps listed below in Additional context
https://github.com/chrisbyte/nuxt-4.4.0-test
Here is the page taken directly from the documentation, but with an Add button to add new rows
<script setup lang="ts">
import { resolveComponent } from 'vue'
import type { TableColumn, TableRow } from '@nuxt/ui'
import { getGroupedRowModel } from '@tanstack/vue-table'
import type { GroupingOptions } from '@tanstack/vue-table'
const UBadge = resolveComponent('UBadge')
type Account = {
id: string
name: string
}
type PaymentStatus = 'paid' | 'failed' | 'refunded'
type Payment = {
id: string
date: string
status: PaymentStatus
email: string
amount: number
account: Account
}
const getColorByStatus = (status: PaymentStatus) => {
return {
paid: 'success',
failed: 'error',
refunded: 'neutral'
}[status]
}
const data = ref<Payment[]>([
{
id: '4600',
date: '2024-03-11T15:30:00',
status: 'paid',
email: 'james.anderson@example.com',
amount: 594,
account: {
id: '1',
name: 'Account 1'
}
},
{
id: '4599',
date: '2024-03-11T10:10:00',
status: 'failed',
email: 'mia.white@example.com',
amount: 276,
account: {
id: '2',
name: 'Account 2'
}
},
{
id: '4598',
date: '2024-03-11T08:50:00',
status: 'refunded',
email: 'william.brown@example.com',
amount: 315,
account: {
id: '1',
name: 'Account 1'
}
},
{
id: '4597',
date: '2024-03-10T19:45:00',
status: 'paid',
email: 'emma.davis@example.com',
amount: 529,
account: {
id: '2',
name: 'Account 2'
}
},
{
id: '4596',
date: '2024-03-10T15:55:00',
status: 'paid',
email: 'ethan.harris@example.com',
amount: 639,
account: {
id: '1',
name: 'Account 1'
}
}
])
const columns: TableColumn<Payment>[] = [
{
id: 'title',
header: 'Item'
},
{
id: 'account_id',
accessorKey: 'account.id'
},
{
accessorKey: 'id',
header: '#',
cell: ({ row }) =>
row.getIsGrouped() ? `${row.getValue('id')} records` : `#${row.getValue('id')}`,
aggregationFn: 'count'
},
{
accessorKey: 'date',
header: 'Date',
cell: ({ row }) => {
return new Date(row.getValue('date')).toLocaleString('en-US', {
day: 'numeric',
month: 'short',
hour: '2-digit',
minute: '2-digit',
hour12: false
})
},
aggregationFn: 'max'
},
{
accessorKey: 'status',
header: 'Status'
},
{
accessorKey: 'email',
header: 'Email',
meta: {
class: {
td: 'w-full'
}
},
cell: ({ row }) =>
row.getIsGrouped() ? `${row.getValue('email')} customers` : row.getValue('email'),
aggregationFn: 'uniqueCount'
},
{
accessorKey: 'amount',
header: 'Amount',
meta: {
class: {
th: 'text-right',
td: 'text-right font-medium'
}
},
cell: ({ row }) => {
const amount = Number.parseFloat(row.getValue('amount'))
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'EUR'
}).format(amount)
},
aggregationFn: 'sum'
},
{
accessorKey: 'action',
header: ''
}
]
const grouping_options = ref<GroupingOptions>({
groupedColumnMode: 'remove',
getGroupedRowModel: getGroupedRowModel()
})
const addRow = (row: TableRow<Payment>) => {
data.value.push({
id: crypto.randomUUID(),
date: '2024-03-11T15:30:00',
status: row.original.status,
email: 'james.anderson@example.com',
amount: 594,
account: {
id: row.original.account.id,
name: row.original.account.name
}
})
row.toggleExpanded(true)
}
</script>
<template>
<UTable
expanded
:data="data"
:columns="columns"
:grouping="['account_id', 'status']"
:grouping-options="grouping_options"
:ui="{
root: 'min-w-full',
td: 'empty:p-0' // helps with the colspaned row added for expand slot
}"
>
<template #title-cell="{ row }">
<div v-if="row.getIsGrouped()" class="flex items-center">
<span class="inline-block" :style="{ width: `calc(${row.depth} * 1rem)` }" />
<UButton
variant="outline"
color="neutral"
class="mr-2"
size="xs"
:icon="row.getIsExpanded() ? 'i-lucide-minus' : 'i-lucide-plus'"
@click="row.toggleExpanded()"
/>
<strong v-if="row.groupingColumnId === 'account_id'">{{
row.original.account.name
}}</strong>
<UBadge
v-else-if="row.groupingColumnId === 'status'"
:color="getColorByStatus(row.original.status)"
class="capitalize"
variant="subtle"
>
{{ row.original.status }}
</UBadge>
</div>
</template>
<template #action-cell="{ row }">
<UButton
v-if="row.getIsGrouped()"
size="sm"
variant="ghost"
icon="i-lucide-plus"
label="Add"
@click="addRow(row)"
/>
</template>
</UTable>
</template>Description
With @nuxt/ui v4.4.0, when adding a new row to a grouped UTable, it will collapse all expanded groups. This is not expected behavior, it should instead leave any expanded groups as they are. This was not happening in v4.2.0 which is what we upgraded from.
Also, setting row.toggleExpanded(true) does not seem to expand the grouped row.
Additional context
- Created a new project with
npm create nuxt@latest test4.4 - Made sure @nuxt/ui was latest v4.4.0
- Followed the UTable with grouped rows example from the nuxt ui documentation: https://ui.nuxt.com/docs/components/table#with-grouped-rows
- Set UTable default to
expandedand added a button at the end of the row to add more rows - Expected the rows to add and keep expanded, but entire table collapses. This was not happening in @nuxt/ui v4.2.0
Logs
After click "Add" button on "Account 1" everything collapses

