Skip to content

Commit 8017767

Browse files
J-MichalekbenjamincanacJakub
authored
feat(Timeline): new component (#4215)
Co-authored-by: Benjamin Canac <[email protected]> Co-authored-by: Jakub <[email protected]>
1 parent 536b7af commit 8017767

File tree

20 files changed

+3462
-1
lines changed

20 files changed

+3462
-1
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup lang="ts">
2+
import type { TimelineItem } from '@nuxt/ui'
3+
4+
const items: TimelineItem[] = [{
5+
date: 'Mar 15, 2025',
6+
title: 'Project Kickoff',
7+
icon: 'i-lucide-rocket',
8+
value: 'kickoff'
9+
}, {
10+
date: 'Mar 22, 2025',
11+
title: 'Design Phase',
12+
icon: 'i-lucide-palette',
13+
value: 'design'
14+
}, {
15+
date: 'Mar 29, 2025',
16+
title: 'Development Sprint',
17+
icon: 'i-lucide-code',
18+
value: 'development'
19+
}, {
20+
date: 'Apr 5, 2025',
21+
title: 'Testing & Deployment',
22+
icon: 'i-lucide-check-circle',
23+
value: 'deployment'
24+
}]
25+
</script>
26+
27+
<template>
28+
<UTimeline
29+
:items="items"
30+
:ui="{ item: 'even:flex-row-reverse even:-translate-x-[calc(100%-2rem)] even:text-right' }"
31+
:default-value="2"
32+
class="w-full translate-x-[calc(50%-2rem)]"
33+
/>
34+
</template>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<script setup lang="ts">
2+
import type { TimelineItem } from '@nuxt/ui'
3+
4+
const items = [{
5+
date: 'Mar 15, 2025',
6+
title: 'Project Kickoff',
7+
subtitle: 'Project Initiation',
8+
description: 'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
9+
icon: 'i-lucide-rocket',
10+
value: 'kickoff'
11+
}, {
12+
date: 'Mar 22, 2025',
13+
title: 'Design Phase',
14+
description: 'User research and design workshops. Created wireframes and prototypes for user testing.',
15+
icon: 'i-lucide-palette',
16+
value: 'design'
17+
}, {
18+
date: 'Mar 29, 2025',
19+
title: 'Development Sprint',
20+
description: 'Frontend and backend development. Implemented core features and integrated with APIs.',
21+
icon: 'i-lucide-code',
22+
value: 'development',
23+
slot: 'development' as const,
24+
developers: [
25+
{
26+
src: 'https://github.com/J-Michalek.png'
27+
}, {
28+
src: 'https://github.com/benjamincanac.png'
29+
}
30+
]
31+
}, {
32+
date: 'Apr 5, 2025',
33+
title: 'Testing & Deployment',
34+
description: 'QA testing and performance optimization. Deployed the application to production.',
35+
icon: 'i-lucide-check-circle',
36+
value: 'deployment'
37+
}] satisfies TimelineItem[]
38+
</script>
39+
40+
<template>
41+
<UTimeline :items="items" :default-value="2" class="w-96">
42+
<template #development-title="{ item }">
43+
<div class="flex items-center gap-1">
44+
<span>{{ item.title }}</span>
45+
46+
<UAvatarGroup size="2xs">
47+
<UAvatar v-for="(developer, index) of item.developers" :key="index" v-bind="developer" />
48+
</UAvatarGroup>
49+
</div>
50+
</template>
51+
</UTimeline>
52+
</template>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<script setup lang="ts">
2+
import type { TimelineItem } from '@nuxt/ui'
3+
4+
const items: TimelineItem[] = [{
5+
date: 'Mar 15, 2025',
6+
title: 'Project Kickoff',
7+
description: 'Kicked off the project with team alignment. Set up project milestones and allocated resources.',
8+
icon: 'i-lucide-rocket',
9+
value: 'kickoff'
10+
}, {
11+
date: 'Mar 22, 2025',
12+
title: 'Design Phase',
13+
description: 'User research and design workshops. Created wireframes and prototypes for user testing.',
14+
icon: 'i-lucide-palette',
15+
value: 'design'
16+
}, {
17+
date: 'Mar 29, 2025',
18+
title: 'Development Sprint',
19+
description: 'Frontend and backend development. Implemented core features and integrated with APIs.',
20+
icon: 'i-lucide-code',
21+
value: 'development'
22+
}, {
23+
date: 'Apr 5, 2025',
24+
title: 'Testing & Deployment',
25+
description: 'QA testing and performance optimization. Deployed the application to production.',
26+
icon: 'i-lucide-check-circle',
27+
value: 'deployment'
28+
}]
29+
30+
const active = ref(0)
31+
32+
// Note: This is for demonstration purposes only. Don't do this at home.
33+
onMounted(() => {
34+
setInterval(() => {
35+
active.value = (active.value + 1) % items.length
36+
}, 2000)
37+
})
38+
</script>
39+
40+
<template>
41+
<UTimeline v-model="active" :items="items" class="w-96" />
42+
</template>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<script lang="ts" setup>
2+
import type { TimelineItem } from '@nuxt/ui'
3+
import { useTimeAgo } from '@vueuse/core'
4+
5+
const items = [{
6+
username: 'J-Michalek',
7+
date: '2025-05-24T14:58:55Z',
8+
action: 'opened this',
9+
avatar: {
10+
src: 'https://github.com/J-Michalek.png'
11+
}
12+
}, {
13+
username: 'J-Michalek',
14+
date: '2025-05-26T19:30:14+02:00',
15+
action: 'marked this pull request as ready for review',
16+
icon: 'i-lucide-check-circle'
17+
}, {
18+
username: 'benjamincanac',
19+
date: '2025-05-27T11:01:20Z',
20+
action: 'commented on this',
21+
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.',
22+
avatar: {
23+
src: 'https://github.com/benjamincanac.png'
24+
}
25+
}, {
26+
username: 'J-Michalek',
27+
date: '2025-05-27T11:01:20Z',
28+
action: 'commented on this',
29+
description: 'Looks great! Good job on cleaning it up.',
30+
avatar: {
31+
src: 'https://github.com/J-Michalek.png'
32+
}
33+
}, {
34+
username: 'benjamincanac',
35+
date: '2025-05-27T11:01:20Z',
36+
action: 'merged this',
37+
icon: 'i-lucide-git-merge'
38+
}] satisfies TimelineItem[]
39+
</script>
40+
41+
<template>
42+
<UTimeline
43+
:items="items"
44+
size="xs"
45+
class="w-96"
46+
:ui="{
47+
date: 'float-end ms-1',
48+
description: 'px-3 py-2 ring ring-default mt-2 rounded-md text-default'
49+
}"
50+
>
51+
<template #title="{ item }">
52+
<span>{{ item.username }}</span>
53+
<span class="font-normal text-muted">&nbsp;{{ item.action }}</span>
54+
</template>
55+
56+
<template #date="{ item }">
57+
{{ useTimeAgo(new Date(item.date)) }}
58+
</template>
59+
</UTimeline>
60+
</template>

docs/content/3.components/stepper.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ Use the `#content` slot to customize the content of each item.
200200

201201
Use the `slot` property to customize a specific item.
202202

203+
You will have access to the following slots:
204+
205+
- `#{{ item.slot }}`{lang="ts-type"}
206+
203207
:component-example{name="stepper-custom-slot-example"}
204208

205209
## API

docs/content/3.components/tabs.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ Use the `#content` slot to customize the content of each item.
222222

223223
Use the `slot` property to customize a specific item.
224224

225+
You will have access to the following slots:
226+
227+
- `#{{ item.slot }}`{lang="ts-type"}
228+
225229
:component-example{name="tabs-custom-slot-example"}
226230

227231
## API

0 commit comments

Comments
 (0)