Use o componente Timeline para exibir uma lista de itens em uma linha do tempo.
<script setup lang="ts">
import type { TimelineItem } from '@nitro/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>
<NTimeline :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TimelineItem } from '@nitro/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>
<NTimeline :items="items" />
</template>
Use a prop items como um array de objetos com as seguintes propriedades:
date?: stringtitle?: stringdescription?: AvatarPropsicon?: stringavatar?: AvatarPropsvalue?: string | numberslot?: stringclass?: anyui?: { item?: ClassNameValue, container?: ClassNameValue, indicator?: ClassNameValue, separator?: ClassNameValue, wrapper?: ClassNameValue, date?: ClassNameValue, title?: ClassNameValue, description?: ClassNameValue }<script setup lang="ts">
import type { TimelineItem } from '@nitro/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>
<NTimeline :default-value="2" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TimelineItem } from '@nitro/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>
<NTimeline :default-value="2" :items="items" class="w-96" />
</template>
Use a prop color para alterar a cor dos itens ativos em uma Timeline.
<script setup lang="ts">
import type { TimelineItem } from '@nitro/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>
<NTimeline color="neutral" :default-value="2" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TimelineItem } from '@nitro/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>
<NTimeline color="neutral" :default-value="2" :items="items" class="w-96" />
</template>
Use a prop size para alterar o tamanho do Timeline.
<script setup lang="ts">
import type { TimelineItem } from '@nitro/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>
<NTimeline size="xs" :default-value="2" :items="items" class="w-96" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TimelineItem } from '@nitro/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>
<NTimeline size="xs" :default-value="2" :items="items" class="w-96" />
</template>
Use a prop orientation para alterar a orientação do Timeline. O padrão é vertical.
<script setup lang="ts">
import type { TimelineItem } from '@nitro/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>
<NTimeline orientation="horizontal" :default-value="2" :items="items" class="w-full" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TimelineItem } from '@nitro/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>
<NTimeline orientation="horizontal" :default-value="2" :items="items" class="w-full" />
</template>
Use a prop reverse para inverter a direção da Timeline.
<script setup lang="ts">
import type { TimelineItem } from '@nitro/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>
<NTimeline reverse v-model="value" orientation="vertical" :items="items" class="w-full" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { TimelineItem } from '@nitro/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>
<NTimeline reverse v-model="value" orientation="vertical" :items="items" class="w-full" />
</template>
Você pode controlar o item ativo usando a prop default-value ou a diretiva v-model com o value do item. Se nenhum value for fornecido, o padrão é o índice.
value-key para alterar a chave usada para corresponder os itens quando um v-model ou default-value é fornecido.Você pode adicionar um listener @select para tornar os itens clicáveis.
Event e o TimelineItem como primeiro e segundo argumentos, respectivamente.Use a prop ui para criar uma Timeline com layout alternado.
Use a propriedade slot para personalizar um item específico.
Você terá acesso aos seguintes slots:
#{{ item.slot }}-indicator#{{ item.slot }}-date#{{ item.slot }}-title#{{ item.slot }}-descriptionUse os slots disponíveis para criar uma Timeline mais complexa.
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
items | T[] | |
size | 'md' | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" |
color | 'primary' | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "error" | "neutral" |
orientation | 'vertical' | "horizontal" | "vertical"The orientation of the Timeline. |
valueKey | 'value' | keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>The key used to get the value from the item. |
defaultValue | string | number | |
reverse | boolean | |
modelValue | string | number | |
ui | { root?: SlotClass; item?: SlotClass; container?: SlotClass; indicator?: SlotClass; separator?: SlotClass; wrapper?: SlotClass; date?: SlotClass; title?: SlotClass; description?: SlotClass; } |
| Slot | Type |
|---|---|
indicator | { item: T; } |
wrapper | { item: T; } |
date | { item: T; } |
title | { item: T; } |
description | { item: T; } |
| Event | Type |
|---|---|
select | [event: Event, item: T] |
update:modelValue | [value: string | number | undefined] |
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'
},
accent: {
indicator: 'group-data-[state=completed]:bg-accent group-data-[state=active]:bg-accent'
},
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'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/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'
},
accent: {
indicator: 'group-data-[state=completed]:bg-accent group-data-[state=active]:bg-accent'
},
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'
}
}
}
})
]
})