NavDropdownLink.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <template>
  2. <div class="nav-dropdown-link" :class="{ open }">
  3. <button class="button" :aria-label="item.ariaLabel" @click="toggle">
  4. <span class="button-text">{{ item.text }}</span>
  5. <span class="button-arrow" :class="open ? 'down' : 'right'" />
  6. </button>
  7. <ul class="dialog">
  8. <li v-for="item in item.items" :key="item.text" class="dialog-item">
  9. <NavDropdownLinkItem :item="item" />
  10. </li>
  11. </ul>
  12. </div>
  13. </template>
  14. <script setup lang="ts">
  15. import { defineProps, ref, watch } from 'vue'
  16. import { useRoute } from 'vitepress'
  17. import type { DefaultTheme } from '../config'
  18. import NavDropdownLinkItem from './NavDropdownLinkItem.vue'
  19. defineProps<{
  20. item: DefaultTheme.NavItemWithChildren
  21. }>()
  22. const route = useRoute()
  23. const open = ref(false)
  24. watch(
  25. () => route.path,
  26. () => {
  27. open.value = false
  28. }
  29. )
  30. function toggle() {
  31. open.value = !open.value
  32. }
  33. </script>
  34. <style scoped>
  35. .nav-dropdown-link {
  36. position: relative;
  37. height: 36px;
  38. overflow: hidden;
  39. cursor: pointer;
  40. }
  41. @media (min-width: 720px) {
  42. .nav-dropdown-link {
  43. height: auto;
  44. overflow: visible;
  45. }
  46. .nav-dropdown-link:hover .dialog {
  47. display: block;
  48. }
  49. }
  50. .nav-dropdown-link.open {
  51. height: auto;
  52. }
  53. .button {
  54. display: block;
  55. border: 0;
  56. padding: 0 1.5rem;
  57. width: 100%;
  58. text-align: left;
  59. line-height: 36px;
  60. font-family: var(--font-family-base);
  61. font-size: 1rem;
  62. font-weight: 600;
  63. color: var(--c-text);
  64. white-space: nowrap;
  65. background-color: transparent;
  66. cursor: pointer;
  67. }
  68. .button:focus {
  69. outline: 0;
  70. }
  71. @media (min-width: 720px) {
  72. .button {
  73. border-bottom: 2px solid transparent;
  74. padding: 0;
  75. line-height: 24px;
  76. font-size: 0.9rem;
  77. font-weight: 500;
  78. }
  79. }
  80. .button-arrow {
  81. display: inline-block;
  82. margin-top: -1px;
  83. margin-left: 8px;
  84. border-top: 6px solid #ccc;
  85. border-right: 4px solid transparent;
  86. border-bottom: 0;
  87. border-left: 4px solid transparent;
  88. vertical-align: middle;
  89. }
  90. .button-arrow.right {
  91. transform: rotate(-90deg);
  92. }
  93. @media (min-width: 720px) {
  94. .button-arrow.right {
  95. transform: rotate(0);
  96. }
  97. }
  98. .dialog {
  99. margin: 0;
  100. padding: 0;
  101. list-style: none;
  102. }
  103. @media (min-width: 720px) {
  104. .dialog {
  105. display: none;
  106. position: absolute;
  107. top: 26px;
  108. right: -8px;
  109. border-radius: 6px;
  110. padding: 12px 0;
  111. min-width: 128px;
  112. background-color: var(--c-bg);
  113. box-shadow: var(--shadow-3);
  114. }
  115. }
  116. </style>