index.pug 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. //- app/shared/MultiLevelMenu/index.pug
  2. nav.relative
  3. .flex.space-x-2
  4. .menu-item.relative(
  5. v-for='item in menuItems'
  6. :key='item.id'
  7. @mouseenter='openSubmenu = item.id'
  8. @mouseleave='openSubmenu = null'
  9. @click='handleMobileClick(item)'
  10. )
  11. button.flex.items-center.px-4.py-2.text-sm.font-medium.text-white.rounded-md.transition-all.duration-200(
  12. :class='getMenuItemClasses(item)'
  13. :aria-expanded='openSubmenu === item.id'
  14. )
  15. | {{ item.title }}
  16. svg.w-4.h-4.ml-1(
  17. :class='{"transform rotate-180": openSubmenu === item.id, "hidden": !item.children}'
  18. fill='none' stroke='currentColor' viewBox='0 0 24 24'
  19. )
  20. path(stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7')
  21. //- Выпадающее меню
  22. transition(
  23. enter-active-class='transition-all duration-300 ease-out'
  24. enter-from-class='opacity-0 transform -translate-y-2'
  25. enter-to-class='opacity-100 transform translate-y-0'
  26. leave-active-class='transition-all duration-200 ease-in'
  27. leave-from-class='opacity-100 transform translate-y-0'
  28. leave-to-class='opacity-0 transform -translate-y-2'
  29. )
  30. .absolute.left-0.mt-2.w-56.rounded-lg.shadow-xl.bg-white.ring-1.ring-black.ring-opacity-5.z-50( class="dark:bg-gray-800"
  31. v-if='item.children && openSubmenu === item.id'
  32. @mouseenter='openSubmenu = item.id'
  33. )
  34. .py-2
  35. .submenu-item.relative(
  36. v-for='child in item.children'
  37. :key='child.id'
  38. @mouseenter='openSubsubmenu = child.id'
  39. @mouseleave='openSubsubmenu = null'
  40. )
  41. .flex.items-center.justify-between.px-4.py-2.text-sm.text-gray-700.cursor-pointer.transition-colors.duration-200(
  42. :class='"dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700" + {"rounded-lg": !child.children}'
  43. )
  44. | {{ child.title }}
  45. svg.w-4.h-4(
  46. :class='{"transform rotate-90": openSubsubmenu === child.id, "hidden": !child.children}'
  47. fill='none' stroke='currentColor' viewBox='0 0 24 24'
  48. )
  49. path(stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5l7 7-7-7')
  50. //- Второй уровень
  51. transition(
  52. enter-active-class='transition-all duration-300 ease-out'
  53. enter-from-class='opacity-0 transform translate-x-2'
  54. enter-to-class='opacity-100 transform translate-x-0'
  55. )
  56. .absolute.left-full.top-0.ml-1.w-56.rounded-lg.shadow-xl.bg-white.ring-1.ring-black.ring-opacity-5.z-50( class="dark:bg-gray-800"
  57. v-if='child.children && openSubsubmenu === child.id'
  58. )
  59. .py-2
  60. .px-4.py-2.text-sm.text-gray-700.cursor-pointer.transition-colors.duration-200(class="dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
  61. v-for='subchild in child.children'
  62. :key='subchild.id'
  63. ) {{ subchild.title }}
  64. //- Mobile menu button (скрытый на десктопе)
  65. button.mobile-menu-button(class='md:hidden p-2 rounded-md text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700')
  66. svg.w-6.h-6(fill='none' stroke='currentColor' viewBox='0 0 24 24')
  67. path(stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 6h16M4 12h16M4 18h16')