-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from qianmoQ/feature-components
Support timeline
- Loading branch information
Showing
10 changed files
with
314 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export interface Timeline | ||
{ | ||
id?: number | string | ||
title?: string | ||
time?: string | ||
tip?: string | ||
description?: string | ||
type?: 'opened' | 'commented' | 'closed' | ||
children?: Timeline[] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<template> | ||
<div v-for="item in items"> | ||
<div class="ps-2 my-2 first:mt-0"> | ||
<h3 class="text-xs font-medium uppercase text-gray-500 dark:text-neutral-400">{{ item.title }}</h3> | ||
</div> | ||
<div v-for="child in item.children" class="flex gap-x-3"> | ||
<div | ||
class="relative last:after:hidden after:absolute after:top-7 after:bottom-0 after:start-3.5 after:w-px after:-translate-x-[0.5px] after:bg-gray-200 dark:after:bg-neutral-700"> | ||
<div class="relative z-10 size-7 flex justify-center items-center"> | ||
<div class="size-2 rounded-full bg-gray-400 dark:bg-neutral-600"></div> | ||
</div> | ||
</div> | ||
<slot v-if="$slots.item" name="item" :item="child"/> | ||
<div v-else class="grow pt-0.5 pb-8"> | ||
<h3 class="flex gap-x-1.5 font-semibold text-gray-800 dark:text-white">{{ child.title }}</h3> | ||
<p class="mt-1 text-sm text-gray-600 dark:text-neutral-400">{{ child.description }}</p> | ||
<button type="button" | ||
class="mt-1 -ms-1 p-1 inline-flex items-center gap-x-2 text-xs rounded-lg border border-transparent text-gray-500 hover:bg-gray-100 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:bg-neutral-700"> | ||
{{ child.time }} | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent } from 'vue' | ||
import { Timeline } from '@/views/components/timeline/Timeline.ts' | ||
export default defineComponent({ | ||
name: 'DefaultTimeline', | ||
props: { | ||
items: { | ||
type: Array<Timeline>, | ||
required: true | ||
} | ||
} | ||
}) | ||
</script> |
50 changes: 50 additions & 0 deletions
50
src/views/components/timeline/discussion/DiscussionTimeline.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<template> | ||
<div | ||
class="space-y-8 relative before:absolute before:inset-0 before:ml-5 before:-translate-x-px md:before:ml-[8.75rem] md:before:translate-x-0 before:h-full before:w-0.5 before:bg-gradient-to-b before:from-transparent before:via-slate-300 before:to-transparent"> | ||
<div v-for="item in items" class="relative"> | ||
<div class="md:flex items-center md:space-x-4 mb-3"> | ||
<div class="flex items-center space-x-4 md:space-x-2 md:space-x-reverse"> | ||
<div v-if="item.type === 'opened'" class="flex items-center justify-center w-10 h-10 rounded-full bg-white shadow md:order-1"> | ||
<svg class="fill-emerald-500" xmlns="http://www.w3.org/2000/svg" width="16" height="16"> | ||
<path d="M8 0a8 8 0 1 0 8 8 8.009 8.009 0 0 0-8-8Zm0 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z"/> | ||
</svg> | ||
</div> | ||
<div v-else-if="item.type === 'commented'" class="flex items-center justify-center w-10 h-10 rounded-full bg-white shadow md:order-1"> | ||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"> | ||
<path class="fill-slate-300" | ||
d="M14.853 6.861C14.124 10.348 10.66 13 6.5 13c-.102 0-.201-.016-.302-.019C7.233 13.618 8.557 14 10 14c.51 0 1.003-.053 1.476-.143L14.2 15.9a.499.499 0 0 0 .8-.4v-3.515c.631-.712 1-1.566 1-2.485 0-.987-.429-1.897-1.147-2.639Z"/> | ||
<path class="fill-slate-500" | ||
d="M6.5 0C2.91 0 0 2.462 0 5.5c0 1.075.37 2.074 1 2.922V11.5a.5.5 0 0 0 .8.4l1.915-1.436c.845.34 1.787.536 2.785.536 3.59 0 6.5-2.462 6.5-5.5S10.09 0 6.5 0Z"/> | ||
</svg> | ||
</div> | ||
<div v-else-if="item.type === 'closed'" class="flex items-center justify-center w-10 h-10 rounded-full bg-white shadow md:order-1"> | ||
<svg class="fill-red-500" xmlns="http://www.w3.org/2000/svg" width="16" height="16"> | ||
<path d="M8 0a8 8 0 1 0 8 8 8.009 8.009 0 0 0-8-8Zm0 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z"/> | ||
</svg> | ||
</div> | ||
<div v-else class="flex items-center justify-center w-10 h-10 rounded-full bg-white shadow md:order-1"/> | ||
<time class="font-caveat font-medium text-xl text-indigo-500 md:w-28">{{ item.time }}</time> | ||
</div> | ||
<div class="text-slate-500 ml-14"><span class="text-slate-900 font-bold">{{ item.title }}</span> {{ item.type }}</div> | ||
</div> | ||
<div class="bg-white p-4 rounded border border-slate-200 text-slate-500 shadow ml-14 md:ml-44"> | ||
{{ item.description }} | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent } from 'vue' | ||
import { Timeline } from '@/views/components/timeline/Timeline.ts' | ||
export default defineComponent({ | ||
name: 'DiscussionTimeline', | ||
props: { | ||
items: { | ||
type: Array<Timeline>, | ||
required: true | ||
} | ||
} | ||
}) | ||
</script> |
32 changes: 32 additions & 0 deletions
32
src/views/components/timeline/milestone/MilestoneTimeline.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<template> | ||
<div v-for="item in items" class="relative pl-8 sm:pl-32 py-6 group"> | ||
<slot v-if="$slots.item" name="item" :item="item"/> | ||
<div v-else> | ||
<div class="font-medium text-2xl text-indigo-500 mb-1 sm:mb-0">{{ item.title }}</div> | ||
<div | ||
class="flex flex-col sm:flex-row items-start mb-1 group-last:before:hidden before:absolute before:left-2 sm:before:left-0 before:h-full before:px-px before:bg-slate-300 sm:before:ml-[6.5rem] before:self-start before:-translate-x-1/2 before:translate-y-3 after:absolute after:left-2 sm:after:left-0 after:w-2 after:h-2 after:bg-indigo-600 after:border-4 after:box-content after:border-slate-50 after:rounded-full sm:after:ml-[6.5rem] after:-translate-x-1/2 after:translate-y-1.5"> | ||
<span | ||
class="sm:absolute left-0 translate-y-0.5 inline-flex items-center justify-center text-xs font-semibold uppercase w-20 h-6 mb-3 sm:mb-0 text-emerald-600 bg-emerald-100 rounded-full"> | ||
{{ item.time }} | ||
</span> | ||
<div class="text-xl font-bold text-slate-900">{{ item.tip }}</div> | ||
</div> | ||
<div class="text-slate-500">{{ item.description }}</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent } from 'vue' | ||
import { Timeline } from '@/views/components/timeline/Timeline.ts' | ||
export default defineComponent({ | ||
name: 'MilestoneTimeline', | ||
props: { | ||
items: { | ||
type: Array<Timeline>, | ||
required: true | ||
} | ||
} | ||
}) | ||
</script> |
38 changes: 38 additions & 0 deletions
38
src/views/components/timeline/progress/ProgressTimeline.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<template> | ||
<div | ||
class="space-y-8 relative before:absolute before:inset-0 before:ml-5 before:-translate-x-px md:before:mx-auto md:before:translate-x-0 before:h-full before:w-0.5 before:bg-gradient-to-b before:from-transparent before:via-slate-300 before:to-transparent"> | ||
<div v-for="item in items" class="relative flex items-center justify-between md:justify-normal md:odd:flex-row-reverse group is-active"> | ||
<slot v-if="$slots.item" name="item" :item="item"/> | ||
<template v-else> | ||
<div | ||
class="flex items-center justify-center w-10 h-10 rounded-full border border-white bg-slate-300 group-[.is-active]:bg-emerald-500 text-slate-500 group-[.is-active]:text-emerald-50 shadow shrink-0 md:order-1 md:group-odd:-translate-x-1/2 md:group-even:translate-x-1/2"> | ||
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="12" height="10"> | ||
<path fill-rule="nonzero" d="M10.422 1.257 4.655 7.025 2.553 4.923A.916.916 0 0 0 1.257 6.22l2.75 2.75a.916.916 0 0 0 1.296 0l6.415-6.416a.916.916 0 0 0-1.296-1.296Z"/> | ||
</svg> | ||
</div> | ||
<div class="w-[calc(100%-4rem)] md:w-[calc(50%-2.5rem)] bg-white p-4 rounded border border-slate-200 shadow"> | ||
<div class="flex items-center justify-between space-x-2 mb-1"> | ||
<div class="font-bold text-slate-900">{{ item.title }}</div> | ||
<time class="font-caveat font-medium text-indigo-500">{{ item.time }}</time> | ||
</div> | ||
<div class="text-slate-500">{{ item.description }}</div> | ||
</div> | ||
</template> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent } from 'vue' | ||
import { Timeline } from '@/views/components/timeline/Timeline.ts' | ||
export default defineComponent({ | ||
name: 'ProgressTimeline', | ||
props: { | ||
items: { | ||
type: Array<Timeline>, | ||
required: true | ||
} | ||
} | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
<template> | ||
<div class="flex w-full flex-col gap-4 md:gap-8 md:p-8 lg:grid lg:grid-cols-2"> | ||
<ICard body-class="pt-3"> | ||
<template #title>Default</template> | ||
<DefaultTimeline :items="items"/> | ||
</ICard> | ||
<ICard body-class="pt-3"> | ||
<template #title>Custom Slot</template> | ||
<DefaultTimeline :items="items"> | ||
<template #item="{ item }"> | ||
<div class="grow pt-0.5 pb-8"> | ||
<h3 class="flex gap-x-1.5 font-semibold text-gray-800 dark:text-white"> | ||
<svg class="flex-shrink-0 size-4 mt-1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" | ||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | ||
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path> | ||
<polyline points="14 2 14 8 20 8"></polyline> | ||
<line x1="16" x2="8" y1="13" y2="13"></line> | ||
<line x1="16" x2="8" y1="17" y2="17"></line> | ||
<line x1="10" x2="8" y1="9" y2="9"></line> | ||
</svg> | ||
{{ item.title }} | ||
</h3> | ||
<p class="mt-1 text-sm text-gray-600 dark:text-neutral-400"> | ||
{{ item.description }} | ||
</p> | ||
<button type="button" | ||
class="mt-1 -ms-1 p-1 inline-flex items-center gap-x-2 text-xs rounded-lg border border-transparent text-gray-500 hover:bg-gray-100 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-400 dark:hover:bg-neutral-700"> | ||
<img class="flex-shrink-0 size-4 rounded-full" src="https://avatars.githubusercontent.com/u/135088160?s=200&v=4" alt="Image Description"> | ||
{{ item.time }} | ||
</button> | ||
</div> | ||
</template> | ||
</DefaultTimeline> | ||
</ICard> | ||
<ICard body-class="pt-3"> | ||
<template #title>Milestone</template> | ||
<MilestoneTimeline :items="items[0].children as any[]"/> | ||
</ICard> | ||
<ICard body-class="pt-3"> | ||
<template #title>Milestone Slot</template> | ||
<MilestoneTimeline :items="items[0].children as any[]"> | ||
<template #item="{ item }"> | ||
<div | ||
class="flex flex-col sm:flex-row items-start mb-1 group-last:before:hidden before:absolute before:left-2 sm:before:left-0 before:h-full before:px-px before:bg-slate-300 sm:before:ml-[6.5rem] before:self-start before:-translate-x-1/2 before:translate-y-3 after:absolute after:left-2 sm:after:left-0 after:w-2 after:h-2 after:bg-indigo-600 after:border-4 after:box-content after:border-slate-50 after:rounded-full sm:after:ml-[6.5rem] after:-translate-x-1/2 after:translate-y-1.5"> | ||
<div class="text-xl font-bold text-slate-900">{{ item.title }}</div> | ||
</div> | ||
</template> | ||
</MilestoneTimeline> | ||
</ICard> | ||
<ICard body-class="pt-3"> | ||
<template #title>Progress</template> | ||
<ProgressTimeline :items="items[0].children as any[]"/> | ||
</ICard> | ||
<ICard body-class="pt-3"> | ||
<template #title>Progress Slot</template> | ||
<ProgressTimeline :items="items[0].children as any[]"> | ||
<template #item="{ item }"> | ||
<div | ||
class="flex items-center justify-center w-10 h-10 rounded-full border border-white bg-slate-300 group-[.is-active]:bg-emerald-500 text-slate-500 group-[.is-active]:text-emerald-50 shadow shrink-0 md:order-1 md:group-odd:-translate-x-1/2 md:group-even:translate-x-1/2"> | ||
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="12" height="12"> | ||
<path d="M12 10v2H7V8.496a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5V12H0V4.496a.5.5 0 0 1 .206-.4l5.5-4a.5.5 0 0 1 .588 0l5.5 4a.5.5 0 0 1 .206.4V10Z"/> | ||
</svg> | ||
</div> | ||
<div class="w-[calc(100%-4rem)] md:w-[calc(50%-2.5rem)] bg-white p-4 rounded border border-slate-200 shadow"> | ||
<div class="flex items-center justify-between space-x-2 mb-1"> | ||
<div class="font-bold text-slate-900">{{ item.title }}</div> | ||
<time class="font-caveat font-medium text-amber-500">{{ item.time }}</time> | ||
</div> | ||
<div class="text-slate-500">{{ item.description }}</div> | ||
</div> | ||
</template> | ||
</ProgressTimeline> | ||
</ICard> | ||
<ICard body-class="pt-3"> | ||
<template #title>Discussion</template> | ||
<DiscussionTimeline :items="items[0].children as any[]"/> | ||
</ICard> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent } from 'vue' | ||
import ICard from '@/ui/card/card.vue' | ||
import DefaultTimeline from '@/views/components/timeline/default/DefaultTimeline.vue' | ||
import MilestoneTimeline from '@/views/components/timeline/milestone/MilestoneTimeline.vue' | ||
import ProgressTimeline from '@/views/components/timeline/progress/ProgressTimeline.vue' | ||
import DiscussionTimeline from '@/views/components/timeline/discussion/DiscussionTimeline.vue' | ||
import { Timeline } from '@/views/components/timeline/Timeline.ts' | ||
export default defineComponent({ | ||
name: 'TimelineHome', | ||
components: { DiscussionTimeline, ProgressTimeline, MilestoneTimeline, DefaultTimeline, ICard }, | ||
data() | ||
{ | ||
return { | ||
items: [ | ||
{ | ||
title: 'Shadcn UI', | ||
children: [ | ||
{ | ||
title: 'Shadcn UI', | ||
description: 'Learn Shadcn UI', | ||
time: '2024-04-17', | ||
type: 'opened' | ||
}, | ||
{ | ||
title: 'Shadcn UI 002', | ||
description: 'Learn Shadcn UI 002', | ||
tip: 'Tip Shadcn UI 002', | ||
time: '2024-04-17', | ||
type: 'commented' | ||
}, | ||
{ | ||
title: 'Shadcn UI 003', | ||
description: 'Learn Shadcn UI 003', | ||
tip: 'Tip Shadcn UI 003', | ||
time: '2024-04-17', | ||
type: 'closed' | ||
} | ||
] | ||
}, | ||
{ | ||
title: 'Vue 3', | ||
children: [ | ||
{ | ||
title: 'Vue 3', | ||
description: 'Learn Vue 3', | ||
time: '2024-04-17 10:00:00' | ||
} | ||
] | ||
} | ||
] as Timeline[] | ||
} | ||
} | ||
}) | ||
</script> |