MenuScroll.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <!--
  2. Menu de navigation entre les sections d'une page, accrochée au haut de l'écran sur les écrans larges
  3. -->
  4. <template>
  5. <LayoutContainer>
  6. <v-row>
  7. <v-col
  8. cols="12"
  9. >
  10. <v-list
  11. class="menu-container"
  12. density="compact"
  13. :class="{ 'sticky-menu': isSticky }"
  14. >
  15. <div v-for="menu in menus" :key="menu.anchor">
  16. <nuxt-link :to="{ path: '', hash: '#' + menu.anchor }">
  17. <v-list-item
  18. :class="{ active : isSticky && layoutStore.isAnchoredSectionOnScreen[menu.anchor] }"
  19. >
  20. {{ menu.label }}
  21. </v-list-item>
  22. </nuxt-link>
  23. </div>
  24. </v-list>
  25. </v-col>
  26. </v-row>
  27. </LayoutContainer>
  28. </template>
  29. <script setup lang="ts">
  30. import type { PropType } from "@vue/runtime-core";
  31. import type { MenuScroll } from "~/types/interface";
  32. import { useLayoutStore } from "~/stores/layoutStore";
  33. const props = defineProps({
  34. menus: {
  35. type: Array as PropType<Array < MenuScroll >>,
  36. required: true
  37. }
  38. });
  39. const layoutStore = useLayoutStore()
  40. const isSticky: Ref<boolean> = ref(false);
  41. onMounted(() => {
  42. window.addEventListener('scroll', handleScroll);
  43. })
  44. const handleScroll = () => {
  45. isSticky.value = window.scrollY > 800;
  46. }
  47. </script>
  48. <style scoped lang="scss">
  49. .sticky-menu {
  50. position: fixed;
  51. top: 0;
  52. left: 0;
  53. right: 0;
  54. background: var(--neutral-color);
  55. box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  56. }
  57. .menu-container {
  58. z-index: 3;
  59. display: flex;
  60. justify-content: center;
  61. background: var(--neutral-color);
  62. color: var(--on-neutral-color);
  63. font-size: 15px;
  64. line-height: 19px;
  65. align-items: center;
  66. text-align: center;
  67. letter-spacing: 0.18em;
  68. text-transform: uppercase;
  69. border-bottom: 0.1rem solid var(--on-neutral-color-extra-light);
  70. a {
  71. text-decoration: none;
  72. color: var(--on-primary-color);
  73. }
  74. a:hover {
  75. text-decoration: underline;
  76. }
  77. }
  78. .active {
  79. background-color: var(--on-primary-color);
  80. color: var(--primary-color);
  81. border-radius: 16px;
  82. padding: 5px;
  83. }
  84. </style>