Components

Timeline

Render a chronological feed of events with UiTimeline.

UiTimeline renders an ordered list of events, each with a dot, icon, or image marker connected by a line. Use it for activity feeds, order/status history, or changelogs.

Basic timeline

Without icon or imageUrl, items render a plain dot marker.

<script setup lang="ts">
import type { ITimelineItem } from '@colorffy/ui'

const items: ITimelineItem[] = [
  { id: '1', title: 'Cuenta creada', text: 'Bienvenido a la plataforma', time: 'Hace 3 días' },
  { id: '2', title: 'Perfil verificado', text: 'Documentos aprobados', time: 'Hace 2 días' },
  { id: '3', title: 'Primer proyecto', text: 'Proyecto Atlas iniciado', time: 'Hace 1 día' },
]
</script>

<template>
  <UiTimeline :items="items" />
</template>

Icon markers

Set icon (a Material Symbols HTML entity) and optionally variant to color the marker with the shared semantic palette.

<script setup lang="ts">
import type { ITimelineItem } from '@colorffy/ui'

const items: ITimelineItem[] = [
  { id: '1', title: 'Nuevo despliegue', text: 'Proyecto Atlas v2.4.0 publicado', time: 'Hace 3 días', icon: '&#xe1b6;', variant: 'success' },
  { id: '2', title: 'Alerta de uso', text: 'API alcanzó el 80% del límite', time: 'Hace 1 día', icon: '&#xe002;', variant: 'warning' },
]
</script>

<template>
  <UiTimeline :items="items" />
</template>

Image markers

Set imageUrl (and imageAlt) to render an avatar-style marker instead of an icon. imageUrl takes precedence over icon.

<template>
  <UiTimeline
    :items="[
      { id: '1', title: 'Ana Morales', text: 'Aprobó la propuesta', time: 'Hace 4 horas', imageUrl: 'https://i.pravatar.cc/88?img=5', imageAlt: 'Foto de Ana Morales' },
    ]"
  />
</template>

Alternate alignment

Set align="alternate" to center the connector line and zig-zag content left/right (e.g. a company timeline or roadmap).

<template>
  <UiTimeline :items="items" align="alternate" />
</template>

Custom item body

Provide a custom body for a specific item via the #item-<id> named slot, or handle every item the same way via the scoped #item slot ({ item }). Either slot overrides the default title/text/time markup.

<template>
  <UiTimeline :items="items">
    <template #item-release="{ item }">
      <p class="subtitle-1 mb-1">{{ item.title }}</p>
      <UiBadge text="Producción" variant="tonal tonal-success" size="sm" />
    </template>
  </UiTimeline>
</template>

Props

PropTypeDefaultDescription
itemsITimelineItem[][]Array of timeline items to render.
align'start' | 'alternate''start'Layout alignment. 'alternate' centers the connector line and alternates content left/right.
customClassstring | string[] | Record<string, boolean> | nullExtra classes for the root element.

ITimelineItem

PropertyTypeDescription
idstringUnique identifier. Used as the render key and to target the #item-<id> slot.
titlestring | nullTitle text displayed prominently.
textstring | nullSupporting text.
timestring | nullTimestamp/label rendered above the title.
iconstring | nullMaterial Symbols icon code for the marker.
imageUrlstring | nullImage URL rendered in place of the icon/dot marker. Takes precedence over icon.
imageAltstring | nullAlt text for the image.
variantThemeColor | nullSemantic color applied to the dot/icon marker.

Slots: #item-<id> per-item custom body (takes precedence); #item scoped slot ({ item }) applied to every item as a fallback; both fall back to the default title/text/time markup when unused.

The marker's icon wrapper reuses the same footprint as UiListItem's icon wrapper, so a list and a timeline placed side by side stay visually aligned.
Copyright © 2026