Timeline

GitHub
一个显示带有日期、标题、图标或头像的事件序列的组件。

用法

items 属性用作具有以下属性的对象数组

  • date?: string
  • title?: string
  • description?: AvatarProps
  • icon?: string
  • avatar?: AvatarProps
  • value?: string | number
  • slot?: string
  • class?: any
  • ui?: { item?: ClassNameValue, container?: ClassNameValue, indicator?: ClassNameValue, separator?: ClassNameValue, wrapper?: ClassNameValue, date?: ClassNameValue, title?: ClassNameValue, description?: ClassNameValue }
2025年3月15日
项目启动
与团队统一目标,项目正式启动。设定了项目里程碑并分配了资源。
2025年3月22日
设计阶段
用户研究和设计工作坊。为用户测试创建了线框图和原型。
2025年3月29日
开发冲刺
前端和后端开发。实现了核心功能并与API集成。
2025年4月5日
测试与部署
质量保证测试和性能优化。将应用程序部署到生产环境。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items = ref<TimelineItem[]>([
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    description: 'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
    icon: 'i-lucide-rocket'
  },
  {
    date: 'Mar 22 2025',
    title: 'Design Phase',
    description: 'User research and design workshops. Created wireframes and prototypes for user testing.',
    icon: 'i-lucide-palette'
  },
  {
    date: 'Mar 29 2025',
    title: 'Development Sprint',
    description: 'Frontend and backend development. Implemented core features and integrated with APIs.',
    icon: 'i-lucide-code'
  },
  {
    date: 'Apr 5 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization. Deployed the application to production.',
    icon: 'i-lucide-check-circle'
  }
])
</script>

<template>
  <UTimeline :default-value="2" :items="items" class="w-96" />
</template>

颜色

使用 color 属性来更改时间轴中活跃项目的颜色。

2025年3月15日
项目启动
与团队统一目标,项目正式启动。设定了项目里程碑并分配了资源。
2025年3月22日
设计阶段
用户研究和设计工作坊。为用户测试创建了线框图和原型。
2025年3月29日
开发冲刺
前端和后端开发。实现了核心功能并与API集成。
2025年4月5日
测试与部署
质量保证测试和性能优化。将应用程序部署到生产环境。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items = ref<TimelineItem[]>([
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    description: 'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
    icon: 'i-lucide-rocket'
  },
  {
    date: 'Mar 22 2025',
    title: 'Design Phase',
    description: 'User research and design workshops. Created wireframes and prototypes for user testing.',
    icon: 'i-lucide-palette'
  },
  {
    date: 'Mar 29 2025',
    title: 'Development Sprint',
    description: 'Frontend and backend development. Implemented core features and integrated with APIs.',
    icon: 'i-lucide-code'
  },
  {
    date: 'Apr 5 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization. Deployed the application to production.',
    icon: 'i-lucide-check-circle'
  }
])
</script>

<template>
  <UTimeline color="neutral" :default-value="2" :items="items" class="w-96" />
</template>

尺寸

使用 size 属性来更改时间轴的大小。

2025年3月15日
项目启动
与团队统一目标,项目正式启动。设定了项目里程碑并分配了资源。
2025年3月22日
设计阶段
用户研究和设计工作坊。为用户测试创建了线框图和原型。
2025年3月29日
开发冲刺
前端和后端开发。实现了核心功能并与API集成。
2025年4月5日
测试与部署
质量保证测试和性能优化。将应用程序部署到生产环境。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items = ref<TimelineItem[]>([
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    description: 'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
    icon: 'i-lucide-rocket'
  },
  {
    date: 'Mar 22 2025',
    title: 'Design Phase',
    description: 'User research and design workshops. Created wireframes and prototypes for user testing.',
    icon: 'i-lucide-palette'
  },
  {
    date: 'Mar 29 2025',
    title: 'Development Sprint',
    description: 'Frontend and backend development. Implemented core features and integrated with APIs.',
    icon: 'i-lucide-code'
  },
  {
    date: 'Apr 5 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization. Deployed the application to production.',
    icon: 'i-lucide-check-circle'
  }
])
</script>

<template>
  <UTimeline size="xs" :default-value="2" :items="items" class="w-96" />
</template>

方向

使用 orientation 属性来更改时间轴的方向。默认为 vertical

2025年3月15日
项目启动
与团队统一目标,项目正式启动。
2025年3月22日
设计阶段
用户研究和设计工作坊。
2025年3月29日
开发冲刺
前端和后端开发。
2025年4月5日
测试与部署
质量保证测试和性能优化。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items = ref<TimelineItem[]>([
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    description: 'Kicked off the project with team alignment.',
    icon: 'i-lucide-rocket'
  },
  {
    date: 'Mar 22 2025',
    title: 'Design Phase',
    description: 'User research and design workshops.',
    icon: 'i-lucide-palette'
  },
  {
    date: 'Mar 29 2025',
    title: 'Development Sprint',
    description: 'Frontend and backend development.',
    icon: 'i-lucide-code'
  },
  {
    date: 'Apr 5 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization.',
    icon: 'i-lucide-check-circle'
  }
])
</script>

<template>
  <UTimeline orientation="horizontal" :default-value="2" :items="items" class="w-full" />
</template>

反转

使用 reverse 属性来反转时间轴的方向。

2025年3月15日
项目启动
与团队统一目标,项目正式启动。
2025年3月22日
设计阶段
用户研究和设计工作坊。
2025年3月29日
开发冲刺
前端和后端开发。
2025年4月5日
测试与部署
质量保证测试和性能优化。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items = ref<TimelineItem[]>([
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    description: 'Kicked off the project with team alignment.',
    icon: 'i-lucide-rocket'
  },
  {
    date: 'Mar 22 2025',
    title: 'Design Phase',
    description: 'User research and design workshops.',
    icon: 'i-lucide-palette'
  },
  {
    date: 'Mar 29 2025',
    title: 'Development Sprint',
    description: 'Frontend and backend development.',
    icon: 'i-lucide-code'
  },
  {
    date: 'Apr 5 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization.',
    icon: 'i-lucide-check-circle'
  }
])
</script>

<template>
  <UTimeline reverse v-model="value" orientation="vertical" :items="items" class="w-full" />
</template>

示例

控制活动项目

您可以通过使用 default-value 属性或带有项目索引的 v-model 指令来控制活跃项目。

2025年3月15日
项目启动
与团队统一目标,项目正式启动。设定了项目里程碑并分配了资源。
2025年3月22日
设计阶段
用户研究和设计工作坊。为用户测试创建了线框图和原型。
2025年3月29日
开发冲刺
前端和后端开发。实现了核心功能并与API集成。
2025年4月5日
测试与部署
质量保证测试和性能优化。将应用程序部署到生产环境。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items: TimelineItem[] = [
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    description:
      'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
    icon: 'i-lucide-rocket',
    value: 'kickoff'
  },
  {
    date: 'Mar 22, 2025',
    title: 'Design Phase',
    description:
      'User research and design workshops. Created wireframes and prototypes for user testing.',
    icon: 'i-lucide-palette',
    value: 'design'
  },
  {
    date: 'Mar 29, 2025',
    title: 'Development Sprint',
    description:
      'Frontend and backend development. Implemented core features and integrated with APIs.',
    icon: 'i-lucide-code',
    value: 'development'
  },
  {
    date: 'Apr 5, 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization. Deployed the application to production.',
    icon: 'i-lucide-check-circle',
    value: 'deployment'
  }
]

const active = ref(0)

// Note: This is for demonstration purposes only. Don't do this at home.
onMounted(() => {
  setInterval(() => {
    active.value = (active.value + 1) % items.length
  }, 2000)
})
</script>

<template>
  <UTimeline v-model="active" :items="items" class="w-96" />
</template>
如果提供了项目的值,您也可以传递该值。

交替布局

使用 ui 属性创建交替布局的时间轴。

2025年3月15日
项目启动
2025年3月22日
设计阶段
2025年3月29日
开发冲刺
2025年4月5日
测试与部署
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items: TimelineItem[] = [
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    icon: 'i-lucide-rocket',
    value: 'kickoff'
  },
  {
    date: 'Mar 22, 2025',
    title: 'Design Phase',
    icon: 'i-lucide-palette',
    value: 'design'
  },
  {
    date: 'Mar 29, 2025',
    title: 'Development Sprint',
    icon: 'i-lucide-code',
    value: 'development'
  },
  {
    date: 'Apr 5, 2025',
    title: 'Testing & Deployment',
    icon: 'i-lucide-check-circle',
    value: 'deployment'
  }
]
</script>

<template>
  <UTimeline
    :items="items"
    :default-value="2"
    :ui="{ item: 'even:flex-row-reverse even:-translate-x-[calc(100%-2rem)] even:text-right' }"
    class="translate-x-[calc(50%-1rem)]"
  />
</template>

带自定义插槽

使用 slot 属性自定义特定项。

您将可以使用以下插槽

  • #{{ item.slot }}-indicator
  • #{{ item.slot }}-date
  • #{{ item.slot }}-title
  • #{{ item.slot }}-description
2025年3月15日
项目启动
与团队统一目标,项目正式启动。设定了项目里程碑并分配了资源。
2025年3月22日
设计阶段
用户研究和设计工作坊。为用户测试创建了线框图和原型。
2025年3月29日
开发冲刺
前端和后端开发。实现了核心功能并与API集成。
2025年4月5日
测试与部署
质量保证测试和性能优化。将应用程序部署到生产环境。
<script setup lang="ts">
import type { TimelineItem } from '@nuxt/ui'

const items = [
  {
    date: 'Mar 15, 2025',
    title: 'Project Kickoff',
    subtitle: 'Project Initiation',
    description:
      'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
    icon: 'i-lucide-rocket',
    value: 'kickoff'
  },
  {
    date: 'Mar 22, 2025',
    title: 'Design Phase',
    description:
      'User research and design workshops. Created wireframes and prototypes for user testing.',
    icon: 'i-lucide-palette',
    value: 'design'
  },
  {
    date: 'Mar 29, 2025',
    title: 'Development Sprint',
    description:
      'Frontend and backend development. Implemented core features and integrated with APIs.',
    icon: 'i-lucide-code',
    value: 'development',
    slot: 'development' as const,
    developers: [
      {
        src: 'https://github.com/J-Michalek.png'
      },
      {
        src: 'https://github.com/benjamincanac.png'
      }
    ]
  },
  {
    date: 'Apr 5, 2025',
    title: 'Testing & Deployment',
    description: 'QA testing and performance optimization. Deployed the application to production.',
    icon: 'i-lucide-check-circle',
    value: 'deployment'
  }
] satisfies TimelineItem[]
</script>

<template>
  <UTimeline :items="items" :default-value="2" class="w-96">
    <template #development-title="{ item }">
      <div class="flex items-center gap-1">
        <span>{{ item.title }}</span>

        <UAvatarGroup size="2xs">
          <UAvatar v-for="(developer, index) of item.developers" :key="index" v-bind="developer" />
        </UAvatarGroup>
      </div>
    </template>
  </UTimeline>
</template>

使用插槽

使用可用的插槽来创建更复杂的时间轴。

2个月前
J-Michalek 创建了此项目
2个月前
J-Michalek 将此拉取请求标记为待审阅
2个月前
benjamincanac 对此发表了评论
我做了一些修改,告诉我你的想法!基本上,我更新了设计,删除了不必要的div,并使用Avatar组件作为指示器,因为它已经支持图标了。
2个月前
J-Michalek 对此发表了评论
看起来很棒!清理得很好。
2个月前
benjamincanac 合并了此项
<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="xs"
    :ui="{
      date: 'float-end ms-1',
      description: 'px-3 py-2 ring ring-default mt-2 rounded-md text-default'
    }"
    class="w-96"
  >
    <template #title="{ item }">
      <span>{{ item.username }}</span>
      <span class="font-normal text-muted">&nbsp;{{ item.action }}</span>
    </template>

    <template #date="{ item }">
      {{ useTimeAgo(new Date(item.date)) }}
    </template>
  </UTimeline>
</template>

API

属性

属性默认值类型
as

'div'

any

此组件应渲染为的元素或组件。

items

TimelineItem[]

尺寸

'md'

"3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl"

颜色

'primary'

"error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"

方向

'vertical'

"horizontal" | "vertical"

时间轴的方向。

defaultValue

string | number

反向

boolean

modelValue

string | number

ui

{ root?: ClassNameValue; item?: ClassNameValue; container?: ClassNameValue; indicator?: ClassNameValue; separator?: ClassNameValue; wrapper?: ClassNameValue; date?: ClassNameValue; title?: ClassNameValue; description?: ClassNameValue; }

插槽

插槽类型
indicator

{ item: TimelineItem; }

日期

{ item: TimelineItem; }

title

{ item: TimelineItem; }

description

{ item: TimelineItem; }

事件

事件类型
update:modelValue

[value: string | number | undefined]

主题

app.config.ts
export default defineAppConfig({
  ui: {
    timeline: {
      slots: {
        root: 'flex gap-1.5',
        item: 'group relative flex flex-1 gap-3',
        container: 'relative flex items-center gap-1.5',
        indicator: 'group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted text-muted',
        separator: 'flex-1 rounded-full bg-elevated',
        wrapper: 'w-full',
        date: 'text-dimmed text-xs/5',
        title: 'font-medium text-highlighted text-sm',
        description: 'text-muted text-wrap text-sm'
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'flex-row w-full',
            item: 'flex-col',
            separator: 'h-0.5'
          },
          vertical: {
            root: 'flex-col',
            container: 'flex-col',
            separator: 'w-0.5'
          }
        },
        color: {
          primary: {
            indicator: 'group-data-[state=completed]:bg-primary group-data-[state=active]:bg-primary'
          },
          secondary: {
            indicator: 'group-data-[state=completed]:bg-secondary group-data-[state=active]:bg-secondary'
          },
          success: {
            indicator: 'group-data-[state=completed]:bg-success group-data-[state=active]:bg-success'
          },
          info: {
            indicator: 'group-data-[state=completed]:bg-info group-data-[state=active]:bg-info'
          },
          warning: {
            indicator: 'group-data-[state=completed]:bg-warning group-data-[state=active]:bg-warning'
          },
          error: {
            indicator: 'group-data-[state=completed]:bg-error group-data-[state=active]:bg-error'
          },
          neutral: {
            indicator: 'group-data-[state=completed]:bg-inverted group-data-[state=active]:bg-inverted'
          }
        },
        size: {
          '3xs': '',
          '2xs': '',
          xs: '',
          sm: '',
          md: '',
          lg: '',
          xl: '',
          '2xl': '',
          '3xl': ''
        },
        reverse: {
          true: ''
        }
      },
      compoundVariants: [
        {
          color: 'primary',
          reverse: false,
          class: {
            separator: 'group-data-[state=completed]:bg-primary'
          }
        },
        {
          color: 'primary',
          reverse: true,
          class: {
            separator: 'group-data-[state=active]:bg-primary group-data-[state=completed]:bg-primary'
          }
        },
        {
          color: 'neutral',
          reverse: false,
          class: {
            separator: 'group-data-[state=completed]:bg-inverted'
          }
        },
        {
          color: 'neutral',
          reverse: true,
          class: {
            separator: 'group-data-[state=active]:bg-inverted group-data-[state=completed]:bg-inverted'
          }
        },
        {
          orientation: 'horizontal',
          size: '3xs',
          class: {
            wrapper: 'pe-4.5'
          }
        },
        {
          orientation: 'horizontal',
          size: '2xs',
          class: {
            wrapper: 'pe-5'
          }
        },
        {
          orientation: 'horizontal',
          size: 'xs',
          class: {
            wrapper: 'pe-5.5'
          }
        },
        {
          orientation: 'horizontal',
          size: 'sm',
          class: {
            wrapper: 'pe-6'
          }
        },
        {
          orientation: 'horizontal',
          size: 'md',
          class: {
            wrapper: 'pe-6.5'
          }
        },
        {
          orientation: 'horizontal',
          size: 'lg',
          class: {
            wrapper: 'pe-7'
          }
        },
        {
          orientation: 'horizontal',
          size: 'xl',
          class: {
            wrapper: 'pe-7.5'
          }
        },
        {
          orientation: 'horizontal',
          size: '2xl',
          class: {
            wrapper: 'pe-8'
          }
        },
        {
          orientation: 'horizontal',
          size: '3xl',
          class: {
            wrapper: 'pe-8.5'
          }
        },
        {
          orientation: 'vertical',
          size: '3xs',
          class: {
            wrapper: '-mt-0.5 pb-4.5'
          }
        },
        {
          orientation: 'vertical',
          size: '2xs',
          class: {
            wrapper: 'pb-5'
          }
        },
        {
          orientation: 'vertical',
          size: 'xs',
          class: {
            wrapper: 'mt-0.5 pb-5.5'
          }
        },
        {
          orientation: 'vertical',
          size: 'sm',
          class: {
            wrapper: 'mt-1 pb-6'
          }
        },
        {
          orientation: 'vertical',
          size: 'md',
          class: {
            wrapper: 'mt-1.5 pb-6.5'
          }
        },
        {
          orientation: 'vertical',
          size: 'lg',
          class: {
            wrapper: 'mt-2 pb-7'
          }
        },
        {
          orientation: 'vertical',
          size: 'xl',
          class: {
            wrapper: 'mt-2.5 pb-7.5'
          }
        },
        {
          orientation: 'vertical',
          size: '2xl',
          class: {
            wrapper: 'mt-3 pb-8'
          }
        },
        {
          orientation: 'vertical',
          size: '3xl',
          class: {
            wrapper: 'mt-3.5 pb-8.5'
          }
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        timeline: {
          slots: {
            root: 'flex gap-1.5',
            item: 'group relative flex flex-1 gap-3',
            container: 'relative flex items-center gap-1.5',
            indicator: 'group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted text-muted',
            separator: 'flex-1 rounded-full bg-elevated',
            wrapper: 'w-full',
            date: 'text-dimmed text-xs/5',
            title: 'font-medium text-highlighted text-sm',
            description: 'text-muted text-wrap text-sm'
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'flex-row w-full',
                item: 'flex-col',
                separator: 'h-0.5'
              },
              vertical: {
                root: 'flex-col',
                container: 'flex-col',
                separator: 'w-0.5'
              }
            },
            color: {
              primary: {
                indicator: 'group-data-[state=completed]:bg-primary group-data-[state=active]:bg-primary'
              },
              secondary: {
                indicator: 'group-data-[state=completed]:bg-secondary group-data-[state=active]:bg-secondary'
              },
              success: {
                indicator: 'group-data-[state=completed]:bg-success group-data-[state=active]:bg-success'
              },
              info: {
                indicator: 'group-data-[state=completed]:bg-info group-data-[state=active]:bg-info'
              },
              warning: {
                indicator: 'group-data-[state=completed]:bg-warning group-data-[state=active]:bg-warning'
              },
              error: {
                indicator: 'group-data-[state=completed]:bg-error group-data-[state=active]:bg-error'
              },
              neutral: {
                indicator: 'group-data-[state=completed]:bg-inverted group-data-[state=active]:bg-inverted'
              }
            },
            size: {
              '3xs': '',
              '2xs': '',
              xs: '',
              sm: '',
              md: '',
              lg: '',
              xl: '',
              '2xl': '',
              '3xl': ''
            },
            reverse: {
              true: ''
            }
          },
          compoundVariants: [
            {
              color: 'primary',
              reverse: false,
              class: {
                separator: 'group-data-[state=completed]:bg-primary'
              }
            },
            {
              color: 'primary',
              reverse: true,
              class: {
                separator: 'group-data-[state=active]:bg-primary group-data-[state=completed]:bg-primary'
              }
            },
            {
              color: 'neutral',
              reverse: false,
              class: {
                separator: 'group-data-[state=completed]:bg-inverted'
              }
            },
            {
              color: 'neutral',
              reverse: true,
              class: {
                separator: 'group-data-[state=active]:bg-inverted group-data-[state=completed]:bg-inverted'
              }
            },
            {
              orientation: 'horizontal',
              size: '3xs',
              class: {
                wrapper: 'pe-4.5'
              }
            },
            {
              orientation: 'horizontal',
              size: '2xs',
              class: {
                wrapper: 'pe-5'
              }
            },
            {
              orientation: 'horizontal',
              size: 'xs',
              class: {
                wrapper: 'pe-5.5'
              }
            },
            {
              orientation: 'horizontal',
              size: 'sm',
              class: {
                wrapper: 'pe-6'
              }
            },
            {
              orientation: 'horizontal',
              size: 'md',
              class: {
                wrapper: 'pe-6.5'
              }
            },
            {
              orientation: 'horizontal',
              size: 'lg',
              class: {
                wrapper: 'pe-7'
              }
            },
            {
              orientation: 'horizontal',
              size: 'xl',
              class: {
                wrapper: 'pe-7.5'
              }
            },
            {
              orientation: 'horizontal',
              size: '2xl',
              class: {
                wrapper: 'pe-8'
              }
            },
            {
              orientation: 'horizontal',
              size: '3xl',
              class: {
                wrapper: 'pe-8.5'
              }
            },
            {
              orientation: 'vertical',
              size: '3xs',
              class: {
                wrapper: '-mt-0.5 pb-4.5'
              }
            },
            {
              orientation: 'vertical',
              size: '2xs',
              class: {
                wrapper: 'pb-5'
              }
            },
            {
              orientation: 'vertical',
              size: 'xs',
              class: {
                wrapper: 'mt-0.5 pb-5.5'
              }
            },
            {
              orientation: 'vertical',
              size: 'sm',
              class: {
                wrapper: 'mt-1 pb-6'
              }
            },
            {
              orientation: 'vertical',
              size: 'md',
              class: {
                wrapper: 'mt-1.5 pb-6.5'
              }
            },
            {
              orientation: 'vertical',
              size: 'lg',
              class: {
                wrapper: 'mt-2 pb-7'
              }
            },
            {
              orientation: 'vertical',
              size: 'xl',
              class: {
                wrapper: 'mt-2.5 pb-7.5'
              }
            },
            {
              orientation: 'vertical',
              size: '2xl',
              class: {
                wrapper: 'mt-3 pb-8'
              }
            },
            {
              orientation: 'vertical',
              size: '3xl',
              class: {
                wrapper: 'mt-3.5 pb-8.5'
              }
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary'
          }
        }
      }
    })
  ]
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'

export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      ui: {
        timeline: {
          slots: {
            root: 'flex gap-1.5',
            item: 'group relative flex flex-1 gap-3',
            container: 'relative flex items-center gap-1.5',
            indicator: 'group-data-[state=completed]:text-inverted group-data-[state=active]:text-inverted text-muted',
            separator: 'flex-1 rounded-full bg-elevated',
            wrapper: 'w-full',
            date: 'text-dimmed text-xs/5',
            title: 'font-medium text-highlighted text-sm',
            description: 'text-muted text-wrap text-sm'
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'flex-row w-full',
                item: 'flex-col',
                separator: 'h-0.5'
              },
              vertical: {
                root: 'flex-col',
                container: 'flex-col',
                separator: 'w-0.5'
              }
            },
            color: {
              primary: {
                indicator: 'group-data-[state=completed]:bg-primary group-data-[state=active]:bg-primary'
              },
              secondary: {
                indicator: 'group-data-[state=completed]:bg-secondary group-data-[state=active]:bg-secondary'
              },
              success: {
                indicator: 'group-data-[state=completed]:bg-success group-data-[state=active]:bg-success'
              },
              info: {
                indicator: 'group-data-[state=completed]:bg-info group-data-[state=active]:bg-info'
              },
              warning: {
                indicator: 'group-data-[state=completed]:bg-warning group-data-[state=active]:bg-warning'
              },
              error: {
                indicator: 'group-data-[state=completed]:bg-error group-data-[state=active]:bg-error'
              },
              neutral: {
                indicator: 'group-data-[state=completed]:bg-inverted group-data-[state=active]:bg-inverted'
              }
            },
            size: {
              '3xs': '',
              '2xs': '',
              xs: '',
              sm: '',
              md: '',
              lg: '',
              xl: '',
              '2xl': '',
              '3xl': ''
            },
            reverse: {
              true: ''
            }
          },
          compoundVariants: [
            {
              color: 'primary',
              reverse: false,
              class: {
                separator: 'group-data-[state=completed]:bg-primary'
              }
            },
            {
              color: 'primary',
              reverse: true,
              class: {
                separator: 'group-data-[state=active]:bg-primary group-data-[state=completed]:bg-primary'
              }
            },
            {
              color: 'neutral',
              reverse: false,
              class: {
                separator: 'group-data-[state=completed]:bg-inverted'
              }
            },
            {
              color: 'neutral',
              reverse: true,
              class: {
                separator: 'group-data-[state=active]:bg-inverted group-data-[state=completed]:bg-inverted'
              }
            },
            {
              orientation: 'horizontal',
              size: '3xs',
              class: {
                wrapper: 'pe-4.5'
              }
            },
            {
              orientation: 'horizontal',
              size: '2xs',
              class: {
                wrapper: 'pe-5'
              }
            },
            {
              orientation: 'horizontal',
              size: 'xs',
              class: {
                wrapper: 'pe-5.5'
              }
            },
            {
              orientation: 'horizontal',
              size: 'sm',
              class: {
                wrapper: 'pe-6'
              }
            },
            {
              orientation: 'horizontal',
              size: 'md',
              class: {
                wrapper: 'pe-6.5'
              }
            },
            {
              orientation: 'horizontal',
              size: 'lg',
              class: {
                wrapper: 'pe-7'
              }
            },
            {
              orientation: 'horizontal',
              size: 'xl',
              class: {
                wrapper: 'pe-7.5'
              }
            },
            {
              orientation: 'horizontal',
              size: '2xl',
              class: {
                wrapper: 'pe-8'
              }
            },
            {
              orientation: 'horizontal',
              size: '3xl',
              class: {
                wrapper: 'pe-8.5'
              }
            },
            {
              orientation: 'vertical',
              size: '3xs',
              class: {
                wrapper: '-mt-0.5 pb-4.5'
              }
            },
            {
              orientation: 'vertical',
              size: '2xs',
              class: {
                wrapper: 'pb-5'
              }
            },
            {
              orientation: 'vertical',
              size: 'xs',
              class: {
                wrapper: 'mt-0.5 pb-5.5'
              }
            },
            {
              orientation: 'vertical',
              size: 'sm',
              class: {
                wrapper: 'mt-1 pb-6'
              }
            },
            {
              orientation: 'vertical',
              size: 'md',
              class: {
                wrapper: 'mt-1.5 pb-6.5'
              }
            },
            {
              orientation: 'vertical',
              size: 'lg',
              class: {
                wrapper: 'mt-2 pb-7'
              }
            },
            {
              orientation: 'vertical',
              size: 'xl',
              class: {
                wrapper: 'mt-2.5 pb-7.5'
              }
            },
            {
              orientation: 'vertical',
              size: '2xl',
              class: {
                wrapper: 'mt-3 pb-8'
              }
            },
            {
              orientation: 'vertical',
              size: '3xl',
              class: {
                wrapper: 'mt-3.5 pb-8.5'
              }
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary'
          }
        }
      }
    })
  ]
})
为便于阅读,compoundVariants 中的某些颜色已省略。请在 GitHub 上查看源代码。