Sidenav.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <aside class="flex justify-between h-full md:flex-col">
  3. <nav class="flex flex-1 flex-nowrap md:flex-col md:flex-none bg-primary">
  4. <NuxtLink
  5. v-for="(navigation, index) in primaryNavigation"
  6. :key="`navigation-${index}`"
  7. :to="localePath(navigation.target)"
  8. class="nav-link"
  9. tabindex="0"
  10. :exact="navigation.exact"
  11. >
  12. <div v-if="navigation.svg">
  13. <SmartIcon :name="navigation.svg" class="svg-icons" />
  14. </div>
  15. <span v-if="EXPAND_NAVIGATION">{{ navigation.title }}</span>
  16. <tippy
  17. v-if="!EXPAND_NAVIGATION"
  18. :placement="mdAndLarger ? 'right' : 'bottom'"
  19. theme="tooltip"
  20. :content="navigation.title"
  21. />
  22. </NuxtLink>
  23. </nav>
  24. </aside>
  25. </template>
  26. <script setup lang="ts">
  27. import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
  28. import { useSetting } from "~/newstore/settings"
  29. import { useI18n } from "~/helpers/utils/composables"
  30. const t = useI18n()
  31. const breakpoints = useBreakpoints(breakpointsTailwind)
  32. const mdAndLarger = breakpoints.greater("md")
  33. const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
  34. const primaryNavigation = [
  35. {
  36. target: "index",
  37. svg: "link-2",
  38. title: t("navigation.rest"),
  39. exact: true,
  40. },
  41. {
  42. target: "graphql",
  43. svg: "graphql",
  44. title: t("navigation.graphql"),
  45. exact: false,
  46. },
  47. {
  48. target: "realtime",
  49. svg: "globe",
  50. title: t("navigation.realtime"),
  51. exact: false,
  52. },
  53. {
  54. target: "documentation",
  55. svg: "book-open",
  56. title: t("navigation.doc"),
  57. exact: false,
  58. },
  59. {
  60. target: "settings",
  61. svg: "settings",
  62. title: t("navigation.settings"),
  63. exact: false,
  64. },
  65. ]
  66. </script>
  67. <style scoped lang="scss">
  68. .nav-link {
  69. @apply relative;
  70. @apply p-4;
  71. @apply flex flex-col flex-1;
  72. @apply items-center;
  73. @apply justify-center;
  74. @apply hover:(bg-primaryDark text-secondaryDark);
  75. @apply focus-visible:text-secondaryDark;
  76. &::after {
  77. @apply absolute;
  78. @apply inset-x-0;
  79. @apply md:inset-x-auto;
  80. @apply md:inset-y-0;
  81. @apply bottom-0;
  82. @apply md:bottom-auto;
  83. @apply md:left-0;
  84. @apply z-2;
  85. @apply h-0.5;
  86. @apply md:h-full;
  87. @apply w-full;
  88. @apply md:w-0.5;
  89. content: "";
  90. }
  91. &:focus::after {
  92. @apply bg-divider;
  93. }
  94. .material-icons,
  95. .svg-icons {
  96. @apply opacity-75;
  97. }
  98. span {
  99. @apply mt-2;
  100. @apply text-tiny;
  101. }
  102. &.active-link {
  103. @apply text-secondaryDark;
  104. @apply bg-primaryLight;
  105. @apply hover:text-secondaryDark;
  106. .material-icons,
  107. .svg-icons {
  108. @apply opacity-100;
  109. }
  110. &::after {
  111. @apply bg-accent;
  112. }
  113. }
  114. &.exact-active-link {
  115. @apply text-secondaryDark;
  116. @apply bg-primaryLight;
  117. @apply hover:text-secondaryDark;
  118. .material-icons,
  119. .svg-icons {
  120. @apply opacity-100;
  121. }
  122. &::after {
  123. @apply bg-accent;
  124. }
  125. }
  126. }
  127. </style>