Sidenav.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <template>
  2. <aside class="flex h-full justify-between md:flex-col">
  3. <nav class="flex flex-nowrap md:flex-col flex-1 md:flex-none">
  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. >
  11. <i v-if="navigation.icon" class="material-icons">
  12. {{ navigation.icon }}
  13. </i>
  14. <div v-if="navigation.svg">
  15. <SmartIcon :name="navigation.svg" class="svg-icons" />
  16. </div>
  17. <span v-if="EXPAND_NAVIGATION">{{ navigation.title }}</span>
  18. <tippy
  19. v-if="!EXPAND_NAVIGATION"
  20. :placement="windowInnerWidth.x.value >= 768 ? 'right' : 'bottom'"
  21. theme="tooltip"
  22. :content="navigation.title"
  23. />
  24. </NuxtLink>
  25. </nav>
  26. </aside>
  27. </template>
  28. <script setup lang="ts">
  29. import { useContext } from "@nuxtjs/composition-api"
  30. import useWindowSize from "~/helpers/utils/useWindowSize"
  31. import { useSetting } from "~/newstore/settings"
  32. const {
  33. app: { i18n },
  34. } = useContext()
  35. const t = i18n.t.bind(i18n)
  36. const windowInnerWidth = useWindowSize()
  37. const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
  38. const primaryNavigation = [
  39. {
  40. target: "index",
  41. svg: "link-2",
  42. title: t("navigation.rest"),
  43. },
  44. {
  45. target: "graphql",
  46. svg: "graphql",
  47. title: t("navigation.graphql"),
  48. },
  49. {
  50. target: "realtime",
  51. svg: "globe",
  52. title: t("navigation.realtime"),
  53. },
  54. {
  55. target: "documentation",
  56. svg: "book-open",
  57. title: t("navigation.doc"),
  58. },
  59. {
  60. target: "settings",
  61. svg: "settings",
  62. title: t("navigation.settings"),
  63. },
  64. ]
  65. </script>
  66. <style scoped lang="scss">
  67. .nav-link {
  68. @apply relative;
  69. @apply p-4;
  70. @apply flex flex-col flex-1;
  71. @apply items-center;
  72. @apply justify-center;
  73. @apply hover:(bg-primaryDark text-secondaryDark);
  74. @apply focus-visible:text-secondaryDark;
  75. &::after {
  76. @apply absolute;
  77. @apply inset-x-0;
  78. @apply md:inset-x-auto;
  79. @apply md:inset-y-0;
  80. @apply bottom-0;
  81. @apply md:bottom-auto;
  82. @apply md:left-0;
  83. @apply z-2;
  84. @apply h-0.5;
  85. @apply md:h-full;
  86. @apply w-full;
  87. @apply md:w-0.5;
  88. content: "";
  89. }
  90. &:focus::after {
  91. @apply bg-divider;
  92. }
  93. .material-icons,
  94. .svg-icons {
  95. @apply opacity-75;
  96. }
  97. span {
  98. @apply mt-2;
  99. @apply font-font-medium;
  100. font-size: calc(var(--body-font-size) - 0.062rem);
  101. }
  102. &.exact-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. }
  115. </style>