Skip to content

Timeline slot issue #4394

@Kevin-Ethiqais

Description

@Kevin-Ethiqais

Environment

  • Operating System: Darwin
  • Node Version: v23.11.0
  • Nuxt Version: 3.17.5
  • CLI Version: 3.25.1
  • Nitro Version: 2.11.12
  • Package Manager: npm@10.9.2
  • Builder: -
  • User Config: devtools, typescript, css, compatibilityDate, devServer, vite, runtimeConfig, app, ui, scripts, piniaPluginPersistedstate, modules, sentry, sourcemap
  • Runtime Modules: @nuxt/ui@3.1.3, @pinia/nuxt@0.11.1, pinia-plugin-persistedstate/nuxt@4.3.0, @sentry/nuxt/module@9.31.0, @nuxt/scripts@0.11.8, @nuxt/eslint@1.4.1, nuxt-charts@0.1.11, @nuxtjs/mdc@0.17.0
  • Build Modules: -

Is this bug related to Nuxt or Vue?

Nuxt

Version

Local build based on commit 04f12ad

Reproduction

<script lang="ts" setup>
import type { TimelineItem } from '@nuxt/ui'
import { useTimeAgo } from '@vueuse/core'

const items = [
  {
    username: 'J-Michalek',
    date: '2025-05-24T14:58:55Z',
    action: 'opened this',
    avatar: {
      src: 'https://github.com/J-Michalek.png'
    }
  },
  {
    username: 'J-Michalek',
    date: '2025-05-26T19:30:14+02:00',
    action: 'marked this pull request as ready for review',
    icon: 'i-lucide-check-circle'
  },
  {
    username: 'benjamincanac',
    date: '2025-05-27T11:01:20Z',
    action: 'commented on this',
    description:
      "I've made a few changes, let me know what you think! Basically I updated the design, removed unnecessary divs, used Avatar component for the indicator since it supports icon already.",
    avatar: {
      src: 'https://github.com/benjamincanac.png'
    }
  },
  {
    username: 'J-Michalek',
    date: '2025-05-27T11:01:20Z',
    action: 'commented on this',
    description: 'Looks great! Good job on cleaning it up.',
    avatar: {
      src: 'https://github.com/J-Michalek.png'
    }
  },
  {
    username: 'benjamincanac',
    date: '2025-05-27T11:01:20Z',
    action: 'merged this',
    icon: 'i-lucide-git-merge'
  }
] satisfies TimelineItem[]
</script>

<template>  
  <UTimeline
    :items="items"
    size="lg"
    :ui="{
      date: 'float-end ms-1',
      description: 'px-3 py-2 ring ring-default mt-2 rounded-md text-default'
    }"
  >
    <template #title="{ item }">
      <span>{{ item.username }}</span>
      <span class="font-normal text-muted">&nbsp;{{ item.action }}</span>
    </template>

    <template #description="{ item }">
      
    </template>

    <template #date="{ item }">
      <UTooltip
        v-if="item.date"
        :text="new Date(item.date).toLocaleString()"
        placement="bottom-end"
      >
        <span>{{ useTimeAgo(new Date(item.date)) }}</span>
      </UTooltip>
    </template>
  </UTimeline>
</template>

Description

I'm testing the timeline component for future integration, and I noticed that using slots even if the value is empty and no html is passed it applies the styles.

Image

I don't know if it's a good solution but something like this can do the trick :

        <div v-if="item.description || (!!slots.description && item.description)" :class="ui.description({ class: [props.ui?.description, item.ui?.description] })">
          <slot :name="((item.slot ? `${item.slot}-description` : 'description') as keyof TimelineSlots<T>)" :item="(item as Extract<T, { slot: string; }>)">
            {{ item.description }}
          </slot>
        </div>

Additional context

No response

Logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingv3#1289

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions