AppSubSidebar.vue 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <script setup>
  2. import { ref } from 'vue'
  3. import { Link } from '@inertiajs/inertia-vue3'
  4. defineProps({
  5. items: Array,
  6. root: {
  7. type: Boolean,
  8. default: false,
  9. },
  10. })
  11. const emits = defineEmits(['menuitem-click'])
  12. const activeIndex = ref(null)
  13. const onMenuItemClick = (event, item, index) => {
  14. if (item.disabled) {
  15. event.preventDefault()
  16. return
  17. }
  18. if (!item.to && !item.url) {
  19. event.preventDefault()
  20. }
  21. if (item.command) {
  22. item.command({ originalEvent: event, item: item })
  23. }
  24. activeIndex.value = index === activeIndex.value ? null : index
  25. emits('menuitem-click', {
  26. originalEvent: event,
  27. item: item,
  28. })
  29. }
  30. const visible = (item) => {
  31. return typeof item.visible === 'function' ? item.visible() : item.visible !== false
  32. }
  33. </script>
  34. <template>
  35. <ul v-if="items">
  36. <template v-for="(item, i) of items">
  37. <li
  38. v-if="visible(item) && !item.separator"
  39. role="none"
  40. :key="item.label || i"
  41. :class="[
  42. { 'layout-menuitem-category': root, 'active-menuitem': activeIndex === i && !item.to && !item.disabled },
  43. ]"
  44. >
  45. <template v-if="root">
  46. <div class="layout-menuitem-root-text" :aria-label="item.label">{{ item.label }}</div>
  47. <AppSubSidebar :items="visible(item) && item.items" @menuitem-click="$emit('menuitem-click', $event)" />
  48. </template>
  49. <template v-else>
  50. <Link
  51. v-if="item.to"
  52. role="menuitem"
  53. :href="item.to"
  54. :class="[
  55. item.class,
  56. 'p-ripple',
  57. {
  58. 'p-disabled': item.disabled,
  59. 'router-link-exact-active': $page.component.startsWith(item.component) || $page.url.startsWith(item.to),
  60. },
  61. ]"
  62. :style="item.style"
  63. :target="item.target"
  64. :aria-label="item.label"
  65. @click="onMenuItemClick($event, item, i)"
  66. >
  67. <i :class="item.icon"></i>
  68. <span>{{ item.label }}</span>
  69. <i v-if="item.items" class="pi pi-fw pi-angle-down menuitem-toggle-icon"></i>
  70. <Badge v-if="item.badge" :value="item.badge"></Badge>
  71. </Link>
  72. <a
  73. v-if="!item.to"
  74. v-ripple
  75. role="menuitem"
  76. :href="item.url || '#'"
  77. :style="item.style"
  78. :class="[item.class, 'p-ripple', { 'p-disabled': item.disabled }]"
  79. :target="item.target"
  80. :aria-label="item.label"
  81. @click="onMenuItemClick($event, item, i)"
  82. >
  83. <i :class="item.icon"></i>
  84. <span>{{ item.label }}</span>
  85. <i v-if="item.items" class="pi pi-fw pi-angle-down menuitem-toggle-icon"></i>
  86. <Badge v-if="item.badge" :value="item.badge"></Badge>
  87. </a>
  88. <transition name="layout-submenu-wrapper">
  89. <AppSubSidebar
  90. v-show="activeIndex === i"
  91. :items="visible(item) && item.items"
  92. @menuitem-click="$emit('menuitem-click', $event)"
  93. />
  94. </transition>
  95. </template>
  96. </li>
  97. <li
  98. v-if="visible(item) && item.separator"
  99. role="separator"
  100. class="p-menu-separator"
  101. :style="item.style"
  102. :key="'separator' + i"
  103. ></li>
  104. </template>
  105. </ul>
  106. </template>