|
| 1 | +<template> |
| 2 | + <button |
| 3 | + class="flex flex-col items-center justify-center gap-1 px-4 cursor-pointer tg-text-subtitle" |
| 4 | + @click="(isMainPage && canScrollToTop && isThisRoute) ? handleScrollToTop() : handleRedirect(route.path)" |
| 5 | + > |
| 6 | + <div |
| 7 | + class="relative py-1 w-full rounded-2xl flex flex-row items-center justify-center" |
| 8 | + :class="[ |
| 9 | + (isThisRoute || isThisName) && 'tg-bg-button tg-text-button motion-translate-y-in', |
| 10 | + ]" |
| 11 | + > |
| 12 | + <UIcon |
| 13 | + v-if="isMainPage && canScrollToTop && isThisRoute" |
| 14 | + name="i-lucide-arrow-up" |
| 15 | + class="size-6 motion-preset-shake" |
| 16 | + /> |
| 17 | + <UIcon |
| 18 | + v-else-if="router.currentRoute.value.meta.canReturn && isThisName" |
| 19 | + name="i-lucide-undo-2" |
| 20 | + class="size-6 motion-preset-shake" |
| 21 | + /> |
| 22 | + <UChip |
| 23 | + v-else |
| 24 | + size="3xl" |
| 25 | + color="error" |
| 26 | + :show="!!route.badge && route.badge !== '0'" |
| 27 | + :text="route.badge" |
| 28 | + :ui="{ |
| 29 | + base: '-right-1 px-1.5 py-2 ring-2 tg-text-button font-bold motion-translate-y-loop-25 motion-duration-3500', |
| 30 | + }" |
| 31 | + > |
| 32 | + <UIcon |
| 33 | + :name="route.icon" |
| 34 | + class="size-6 motion-preset-shake" |
| 35 | + /> |
| 36 | + </UChip> |
| 37 | + </div> |
| 38 | + <p |
| 39 | + class="text-xs font-medium" |
| 40 | + :class="[ |
| 41 | + (isThisRoute || isThisName) && 'tg-text', |
| 42 | + ]" |
| 43 | + > |
| 44 | + {{ route.title }} |
| 45 | + </p> |
| 46 | + </button> |
| 47 | +</template> |
| 48 | + |
| 49 | +<script setup lang="ts"> |
| 50 | +const { route } = defineProps<{ route: NavigationRoute }>() |
| 51 | +
|
| 52 | +const { vibrate } = useFeedback() |
| 53 | +const { canScrollToTop, isMainPage } = useNavigation() |
| 54 | +const router = useRouter() |
| 55 | +
|
| 56 | +const isThisRoute = computed(() => route.exact ? router.currentRoute.value.path === route.path : router.currentRoute.value.path.startsWith(route.path)) |
| 57 | +const isThisName = computed(() => route.names.includes(router.currentRoute.value.name)) |
| 58 | +
|
| 59 | +function handleScrollToTop() { |
| 60 | + vibrate() |
| 61 | + window.scrollTo({ top: 0, behavior: 'smooth' }) |
| 62 | +} |
| 63 | +
|
| 64 | +function handleRedirect(path: string) { |
| 65 | + vibrate() |
| 66 | + router.push(path) |
| 67 | +} |
| 68 | +</script> |
0 commit comments