Header.vue 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <template>
  2. <header
  3. class="w-full flex justify-between gap-5 bg-background-100 p-3 animate__animated animate__fadeInDown animate__faster z-10"
  4. >
  5. <NuxtLoadingIndicator class="w-full" :height="2" color="#e5e7eb" />
  6. <ISandwich
  7. class="w-8 h-8 hover:opacity-50 cursor-pointer duration-150"
  8. @click="sideBar.show()"
  9. />
  10. <div class="flex-auto flex items-center font-semibold">
  11. {{ $router.currentRoute.value.name }}
  12. </div>
  13. <IMoreVertical
  14. v-if="header.menu.length > 0"
  15. class="w-8 h-8 hover:opacity-50 cursor-pointer duration-150 show"
  16. @click="show"
  17. />
  18. <div
  19. v-if="showMenu"
  20. class="fixed top-0 left-0 w-screen h-screen"
  21. >
  22. <div
  23. class="absolute top-0 left-0 w-full h-full bg-black bg-opacity-30 animate__duration"
  24. :class="showAnim ? 'animate__animated animate__fadeIn' : 'animate__animated animate__fadeOut'"
  25. />
  26. <div
  27. class="absolute top-0 left-0 w-full h-full flex justify-end items-start z-40"
  28. :class="showAnim ? 'animate__animated animate__fadeIn' : 'animate__animated animate__fadeOut'"
  29. style="--animate-duration: 200ms"
  30. @click="hide"
  31. >
  32. <div class="m-3 w-fit flex flex-col divide-y-2 divide-stone-700 drop-shadow-lg">
  33. <button
  34. v-for="(item, idx) in header.menu"
  35. :key="idx"
  36. class="flex gap-4 p-3 items-center bg-background-100 hover:bg-stone-700 animate__animated animate__fadeInDown duration-150"
  37. :class="{
  38. 'rounded-t-md': idx === 0,
  39. 'rounded-b-md': idx === header.menu.length - 1,
  40. }"
  41. :style="`--animate-duration: ${(idx + 1) * 50}ms`"
  42. @click="item.action"
  43. >
  44. <img
  45. :src="`/icons/${item.icon}.svg`"
  46. class="w-6 h-6 opacity-50"
  47. :alt="item.icon"
  48. >
  49. <p v-text="item.name" />
  50. </button>
  51. </div>
  52. </div>
  53. </div>
  54. </header>
  55. </template>
  56. <script setup lang="ts">
  57. import { ref } from 'vue'
  58. import { useSideBar } from '~/store/useSideBar'
  59. import { useHeader } from '~/store/useHeader'
  60. import { updateColors } from '~/composables/useColors'
  61. const sideBar = useSideBar()
  62. const header = useHeader()
  63. const showMenu = ref(false)
  64. const showAnim = ref(false)
  65. function hide() {
  66. showAnim.value = false
  67. setTimeout(() => {
  68. showMenu.value = false
  69. }, 100)
  70. updateColors('#212121')
  71. }
  72. function show() {
  73. showMenu.value = true
  74. showAnim.value = true
  75. updateColors('#171717')
  76. }
  77. </script>