Timeline

Timeline visualizes a series of chained events.


npx openvolt-vue add Timeline


import Timeline from '@/volt/Timeline.vue';

Timeline requires a value for the collection of events and content slot that receives an object as a parameter to return content.

  1. Ordered
  2. Processing
  3. Shipped
  4. Delivered

<template>
    <div class="card">
        <Timeline :value="events">
            <template #content="slotProps">
                {{ slotProps.item.status }}
            </template>
        </Timeline>
    </div>
</template>

<script setup lang="ts">
import Timeline from '@/volt/Timeline.vue';
import { ref } from 'vue';

const events = ref([
    { status: 'Ordered', date: '15/10/2020 10:30', icon: 'pi pi-shopping-cart', color: '#9C27B0' },
    { status: 'Processing', date: '15/10/2020 14:00', icon: 'pi pi-cog', color: '#673AB7' },
    { status: 'Shipped', date: '15/10/2020 16:15', icon: 'pi pi-shopping-cart', color: '#FF9800' },
    { status: 'Delivered', date: '16/10/2020 10:00', icon: 'pi pi-check', color: '#607D8B' }
]);
</script>

Content location relative the line is defined with the align property.

  1. Ordered
  2. Processing
  3. Shipped
  4. Delivered
  1. Ordered
  2. Processing
  3. Shipped
  4. Delivered
  1. Ordered
  2. Processing
  3. Shipped
  4. Delivered

<template>
    <div class="card flex flex-wrap gap-12">
        <Timeline :value="events" class="w-full md:w-80">
            <template #content="slotProps">
                {{ slotProps.item.status }}
            </template>
        </Timeline>

        <Timeline :value="events" align="right" class="w-full md:w-80">
            <template #content="slotProps">
                {{ slotProps.item.status }}
            </template>
        </Timeline>

        <Timeline :value="events" align="alternate" class="w-full md:w-80">
            <template #content="slotProps">
                {{ slotProps.item.status }}
            </template>
        </Timeline>
    </div>
</template>

<script setup lang="ts">
import Timeline from '@/volt/Timeline.vue';
import { ref } from 'vue';

const events = ref([
    { status: 'Ordered', date: '15/10/2020 10:30', icon: 'pi pi-shopping-cart', color: '#9C27B0' },
    { status: 'Processing', date: '15/10/2020 14:00', icon: 'pi pi-cog', color: '#673AB7' },
    { status: 'Shipped', date: '15/10/2020 16:15', icon: 'pi pi-shopping-cart', color: '#FF9800' },
    { status: 'Delivered', date: '16/10/2020 10:00', icon: 'pi pi-check', color: '#607D8B' }
]);
</script>

Additional content at the other side of the line can be provided with the opposite property.

  1. 15/10/2020 10:30
    Ordered
  2. 15/10/2020 14:00
    Processing
  3. 15/10/2020 16:15
    Shipped
  4. 16/10/2020 10:00
    Delivered

<template>
    <div class="card">
        <Timeline :value="events">
            <template #opposite="slotProps">
                <small class="text-surface-500 dark:text-surface-400">{{ slotProps.item.date }}</small>
            </template>
            <template #content="slotProps">
                {{ slotProps.item.status }}
            </template>
        </Timeline>
    </div>
</template>

<script setup lang="ts">
import Timeline from '@/volt/Timeline.vue';
import { ref } from 'vue';

const events = ref([
    { status: 'Ordered', date: '15/10/2020 10:30', icon: 'pi pi-shopping-cart', color: '#9C27B0' },
    { status: 'Processing', date: '15/10/2020 14:00', icon: 'pi pi-cog', color: '#673AB7' },
    { status: 'Shipped', date: '15/10/2020 16:15', icon: 'pi pi-shopping-cart', color: '#FF9800' },
    { status: 'Delivered', date: '16/10/2020 10:00', icon: 'pi pi-check', color: '#607D8B' }
]);
</script>

Sample implementation with custom content and styled markers.


<template>
    <div class="card">
        <Timeline :value="events" align="alternate">
            <template #marker="slotProps">
                <span class="flex w-8 h-8 items-center justify-center text-white rounded-full z-10 shadow-xs" :style="{ backgroundColor: slotProps.item.color }">
                    <i :class="slotProps.item.icon"></i>
                </span>
            </template>
            <template #content="slotProps">
                <Card class="mt-4">
                    <template #title>
                        {{ slotProps.item.status }}
                    </template>
                    <template #subtitle>
                        {{ slotProps.item.date }}
                    </template>
                    <template #content>
                        <img v-if="slotProps.item.image" :src="`https://primefaces.org/cdn/primevue/images/product/${slotProps.item.image}`" :alt="slotProps.item.name" width="200" class="shadow-xs" />
                        <p>
                            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore sed consequuntur error repudiandae numquam deserunt quisquam repellat libero asperiores earum nam nobis, culpa ratione quam perferendis esse, cupiditate
                            neque quas!
                        </p>
                        <Button label="Read more" text></Button>
                    </template>
                </Card>
            </template>
        </Timeline>
    </div>
</template>

<script setup lang="ts">
import Timeline from '@/volt/Timeline.vue';
import { ref } from 'vue';

const events = ref([
    { status: 'Ordered', date: '15/10/2020 10:30', icon: 'pi pi-shopping-cart', color: '#9C27B0', image: 'game-controller.jpg' },
    { status: 'Processing', date: '15/10/2020 14:00', icon: 'pi pi-cog', color: '#673AB7' },
    { status: 'Shipped', date: '15/10/2020 16:15', icon: 'pi pi-shopping-cart', color: '#FF9800' },
    { status: 'Delivered', date: '16/10/2020 10:00', icon: 'pi pi-check', color: '#607D8B' }
]);
</script>

TimeLine orientation is controlled with the layout property, default is vertical having horizontal as the alternative.

  1. 2020
  2. 2021
  3. 2022
  4. 2023
  1. 2020
  2. 2021
  3. 2022
  4. 2023
  1.  
    2020
  2.  
    2021
  3.  
    2022
  4.  
    2023

<template>
     <div class="card flex flex-col gap-4">
        <Timeline :value="events" layout="horizontal" align="top">
            <template #content="slotProps">
                {{ slotProps.item }}
            </template>
        </Timeline>

        <Timeline :value="events" layout="horizontal" align="bottom">
            <template #content="slotProps">
                {{ slotProps.item }}
            </template>
        </Timeline>

        <Timeline :value="events" layout="horizontal" align="alternate">
            <template #opposite> &nbsp; </template>
            <template #content="slotProps">
                {{ slotProps.item }}
            </template>
        </Timeline>
    </div>
</template>

<script setup lang="ts">
import Timeline from '@/volt/Timeline.vue';
import { ref } from 'vue';

const events = ref(['2020', '2021', '2022', '2023']);
</script>