Skip to main content

CnTimelineStages

Visualizes sequential progression through named stages. Stages are automatically classified as completed (before current), current, or upcoming (after current). Supports horizontal and vertical orientations, small/medium sizes, clickable stages with keyboard navigation (roving tabindex), and ARIA roles.

Try it

Loading CnTimelineStages playground…

Usage

<!-- Basic horizontal timeline -->
<CnTimelineStages
:stages="[
{ id: 'new', label: 'New' },
{ id: 'review', label: 'In Review', subtitle: 'Since Mar 15' },
{ id: 'approved', label: 'Approved' },
{ id: 'done', label: 'Done' },
]"
current-stage="review" />

<!-- Vertical, clickable — for pipeline stage selection -->
<CnTimelineStages
:stages="pipelineStages"
:current-stage="deal.stage"
orientation="vertical"
:clickable="true"
@stage-click="onStageClick" />

<!-- Small size, custom indicator via slot -->
<CnTimelineStages :stages="stages" current-stage="active" size="small">
<template #indicator="{ stage, state }">
<span :class="['my-dot', `my-dot--${state}`]" />
</template>
</CnTimelineStages>
function onStageClick({ stage, index }) {
updateDealStage(stage.id)
}

Props

PropTypeRequiredDefaultDescription
stagesArrayStage objects: { id, label, subtitle? }. id must be unique; subtitle is optional secondary text
currentStageString | Numbernullid of the active stage. Stages before it are completed, stages after are upcoming. null = all upcoming
orientationString'horizontal'Layout direction: 'horizontal' or 'vertical'
sizeString'medium'Indicator size: 'medium' (32px) or 'small' (20px)
clickableBooleanfalseWhether stages emit stage-click and support arrow-key navigation
ariaLabelString'Progress stages'Accessible label for the timeline container

Events

EventPayloadDescription
stage-click{ stage, index }Emitted when a clickable stage is activated via click, Enter, or Space

Slots

SlotScopeDescription
indicator{ stage, index, state }Custom indicator element replacing the default checkmark/dot
label{ stage, index, state }Custom label block replacing the default label + subtitle

Stage states

StateCondition
'completed'Stage index < current stage index
'current'Stage matches currentStage
'upcoming'Stage index > current stage index

Reference (auto-generated)

The tables below are generated from the SFC source via vue-docgen-cli. They reflect what's actually in CnTimelineStages.vue and update automatically whenever the component changes.

Props

NameTypeRequiredDefaultDescription
stages{ id: string, label: string, subtitle: string }[]Array of stage objects. Each must have id (unique) and label (display text). Optional subtitle for secondary text below the label.
currentStageunionnullThe id of the currently active stage. Stages before it are "completed", stages after it are "upcoming". If null/undefined or not matching any id, all stages are "upcoming".
orientationstring'horizontal'Layout orientation: "horizontal" (left-to-right) or "vertical" (top-to-bottom).
sizestring'medium'Size variant: "medium" (32px indicators) or "small" (20px indicators).
clickablebooleanfalseWhether stages are clickable. When true, stages emit stage-click on click/Enter/Space and support keyboard navigation with arrow keys.
ariaLabelstring() =&gt; t('nextcloud-vue', 'Progress stages')Accessible label for the timeline container.

Events

NamePayloadDescription
stage-clickEmitted when a clickable stage is activated (click, Enter, or Space).

Slots

NameBindingsDescription
indicatorstage, index, state
labelstage, index, state