Skip to content

v4.4.0 UTable with grouping auto collapses all groups when adding rows #6030

@chrisbyte

Description

@chrisbyte

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

  1. Created a new project with npm create nuxt@latest test4.4
  2. Made sure @nuxt/ui was latest v4.4.0
  3. Followed the UTable with grouped rows example from the nuxt ui documentation: https://ui.nuxt.com/docs/components/table#with-grouped-rows
  4. Set UTable default to expanded and added a button at the end of the row to add more rows
  5. Expected the rows to add and keep expanded, but entire table collapses. This was not happening in @nuxt/ui v4.2.0

Logs

Default expanded
Image

After click "Add" button on "Account 1" everything collapses
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageAwaiting initial review and prioritizationv4#4488

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions