Sidenav.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <aside class="flex h-full justify-between md:flex-col">
  3. <nav class="flex flex-nowrap flex-1 md:flex-col 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 useWindowSize from "~/helpers/utils/useWindowSize"
  30. import { useSetting } from "~/newstore/settings"
  31. import { useI18n } from "~/helpers/utils/composables"
  32. const t = useI18n()
  33. const windowInnerWidth = useWindowSize()
  34. const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
  35. const primaryNavigation = [
  36. {
  37. target: "index",
  38. svg: "link-2",
  39. title: t("navigation.rest"),
  40. },
  41. {
  42. target: "graphql",
  43. svg: "graphql",
  44. title: t("navigation.graphql"),
  45. },
  46. {
  47. target: "realtime",
  48. svg: "globe",
  49. title: t("navigation.realtime"),
  50. },
  51. {
  52. target: "documentation",
  53. svg: "book-open",
  54. title: t("navigation.doc"),
  55. },
  56. {
  57. target: "settings",
  58. svg: "settings",
  59. title: t("navigation.settings"),
  60. },
  61. ]
  62. </script>
  63. <style scoped lang="scss">
  64. .nav-link {
  65. @apply relative;
  66. @apply p-4;
  67. @apply flex flex-col flex-1;
  68. @apply items-center;
  69. @apply justify-center;
  70. @apply hover:(bg-primaryDark text-secondaryDark);
  71. @apply focus-visible:text-secondaryDark;
  72. &::after {
  73. @apply absolute;
  74. @apply inset-x-0;
  75. @apply md:inset-x-auto;
  76. @apply md:inset-y-0;
  77. @apply bottom-0;
  78. @apply md:bottom-auto;
  79. @apply md:left-0;
  80. @apply z-2;
  81. @apply h-0.5;
  82. @apply md:h-full;
  83. @apply w-full;
  84. @apply md:w-0.5;
  85. content: "";
  86. }
  87. &:focus::after {
  88. @apply bg-divider;
  89. }
  90. .material-icons,
  91. .svg-icons {
  92. @apply opacity-75;
  93. }
  94. span {
  95. @apply mt-2;
  96. @apply font-font-medium;
  97. font-size: calc(var(--body-font-size) - 0.062rem);
  98. }
  99. &.exact-active-link {
  100. @apply text-secondaryDark;
  101. @apply bg-primaryLight;
  102. @apply hover:text-secondaryDark;
  103. .material-icons,
  104. .svg-icons {
  105. @apply opacity-100;
  106. }
  107. &::after {
  108. @apply bg-accent;
  109. }
  110. }
  111. }
  112. </style>