AppSubSidebar.vue 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. :key="item.label || i"
  40. :class="[
  41. { 'layout-menuitem-category': root, 'active-menuitem': activeIndex === i && !item.to && !item.disabled },
  42. ]"
  43. role="none"
  44. >
  45. <template v-if="root">
  46. <div class="layout-menuitem-root-text" :aria-label="item.label">{{ item.label }}</div>
  47. <AppSubSidebar
  48. :items="visible(item) && item.items"
  49. @menuitem-click="$emit('menuitem-click', $event)"
  50. ></AppSubSidebar>
  51. </template>
  52. <template v-else>
  53. <Link
  54. v-if="item.to"
  55. v-ripple
  56. role="menuitem"
  57. :href="item.to"
  58. :class="[
  59. item.class,
  60. 'p-ripple',
  61. {
  62. 'p-disabled': item.disabled,
  63. 'router-link-active': $page.component.startsWith(item.component) || $page.url.startsWith(item.to),
  64. 'router-link-exact-active': $page.component.startsWith(item.component) || $page.url.startsWith(item.to),
  65. },
  66. ]"
  67. :style="item.style"
  68. :target="item.target"
  69. :aria-label="item.label"
  70. @click="onMenuItemClick($event, item, i)"
  71. >
  72. <i :class="item.icon"></i>
  73. <span>{{ item.label }}</span>
  74. <i v-if="item.items" class="pi pi-fw pi-angle-down menuitem-toggle-icon"></i>
  75. <Badge v-if="item.badge" :value="item.badge"></Badge>
  76. </Link>
  77. <a
  78. v-if="!item.to"
  79. v-ripple
  80. role="menuitem"
  81. :style="item.style"
  82. :class="[item.class, 'p-ripple', { 'p-disabled': item.disabled }]"
  83. :href="item.url || '#'"
  84. :target="item.target"
  85. :aria-label="item.label"
  86. @click="onMenuItemClick($event, item, i)"
  87. >
  88. <i :class="item.icon"></i>
  89. <span>{{ item.label }}</span>
  90. <i v-if="item.items" class="pi pi-fw pi-angle-down menuitem-toggle-icon"></i>
  91. <Badge v-if="item.badge" :value="item.badge"></Badge>
  92. </a>
  93. <transition name="layout-submenu-wrapper">
  94. <AppSubSidebar
  95. v-show="activeIndex === i"
  96. :items="visible(item) && item.items"
  97. @menuitem-click="$emit('menuitem-click', $event)"
  98. ></AppSubSidebar>
  99. </transition>
  100. </template>
  101. </li>
  102. <li
  103. class="p-menu-separator"
  104. v-if="visible(item) && item.separator"
  105. role="separator"
  106. :style="item.style"
  107. :key="'separator' + i"
  108. ></li>
  109. </template>
  110. </ul>
  111. </template>