update aside

This commit is contained in:
Dede Fuji Abdul 2023-10-18 10:31:17 +07:00
parent cce938fa8f
commit 3bd24a17f4
7 changed files with 183 additions and 201 deletions

View File

@ -1281,11 +1281,6 @@ select {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-12 {
--tw-translate-y: -3rem;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-2\/4 {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@ -1454,12 +1449,6 @@ select {
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.space-x-0 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0px * var(--tw-space-x-reverse));
margin-left: calc(0px * calc(1 - var(--tw-space-x-reverse)));
}
.divide-y > :not([hidden]) ~ :not([hidden]) {
--tw-divide-y-reverse: 0;
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
@ -1522,6 +1511,10 @@ select {
border-radius: 0.75rem;
}
.rounded-none {
border-radius: 0px;
}
.rounded-2xl {
border-radius: 1rem;
}
@ -1624,16 +1617,6 @@ select {
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.bg-blue-100 {
--tw-bg-opacity: 1;
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
}
.bg-blue-600 {
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
}
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
@ -1664,11 +1647,6 @@ select {
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
}
.bg-green-100 {
--tw-bg-opacity: 1;
background-color: rgb(220 252 231 / var(--tw-bg-opacity));
}
.bg-green-400 {
--tw-bg-opacity: 1;
background-color: rgb(74 222 128 / var(--tw-bg-opacity));
@ -1684,16 +1662,6 @@ select {
background-color: rgb(243 247 249 / var(--tw-bg-opacity));
}
.bg-orange-100 {
--tw-bg-opacity: 1;
background-color: rgb(255 237 213 / var(--tw-bg-opacity));
}
.bg-orange-600 {
--tw-bg-opacity: 1;
background-color: rgb(234 88 12 / var(--tw-bg-opacity));
}
.bg-primary-100 {
--tw-bg-opacity: 1;
background-color: rgb(205 222 227 / var(--tw-bg-opacity));
@ -1753,16 +1721,6 @@ select {
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.bg-red-50 {
--tw-bg-opacity: 1;
background-color: rgb(255 229 229 / var(--tw-bg-opacity));
}
.bg-yellow-50 {
--tw-bg-opacity: 1;
background-color: rgb(255 255 229 / var(--tw-bg-opacity));
}
.bg-yellow-100 {
--tw-bg-opacity: 1;
background-color: rgb(255 255 204 / var(--tw-bg-opacity));
@ -1793,6 +1751,10 @@ select {
--tw-bg-opacity: 0.8;
}
.fill-gray-400 {
fill: #9ca3af;
}
.fill-gray-500 {
fill: #6b7280;
}
@ -1809,8 +1771,12 @@ select {
fill: #007b8d;
}
.fill-gray-400 {
fill: #9ca3af;
.fill-white {
fill: #fff;
}
.stroke-white {
stroke: #fff;
}
.p-1 {
@ -2004,6 +1970,10 @@ select {
padding-top: 1.25rem;
}
.pl-4 {
padding-left: 1rem;
}
.text-left {
text-align: left;
}
@ -2136,11 +2106,6 @@ select {
color: rgb(96 165 250 / var(--tw-text-opacity));
}
.text-blue-600 {
--tw-text-opacity: 1;
color: rgb(37 99 235 / var(--tw-text-opacity));
}
.text-dark {
--tw-text-opacity: 1;
color: rgb(21 22 23 / var(--tw-text-opacity));
@ -2226,6 +2191,11 @@ select {
color: rgb(204 0 0 / var(--tw-text-opacity));
}
.text-secondary-600 {
--tw-text-opacity: 1;
color: rgb(0 123 141 / var(--tw-text-opacity));
}
.text-slate-600 {
--tw-text-opacity: 1;
color: rgb(71 85 105 / var(--tw-text-opacity));
@ -2256,11 +2226,6 @@ select {
color: rgb(153 153 0 / var(--tw-text-opacity));
}
.text-secondary-600 {
--tw-text-opacity: 1;
color: rgb(0 123 141 / var(--tw-text-opacity));
}
.text-opacity-100 {
--tw-text-opacity: 1;
}
@ -2509,11 +2474,6 @@ select {
overflow-y: auto;
}
.hover\:bg-blue-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
}
.hover\:bg-gray-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
@ -2534,11 +2494,6 @@ select {
background-color: rgb(67 56 202 / var(--tw-bg-opacity));
}
.hover\:bg-orange-500:hover {
--tw-bg-opacity: 1;
background-color: rgb(249 115 22 / var(--tw-bg-opacity));
}
.hover\:bg-primary-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(205 222 227 / var(--tw-bg-opacity));
@ -2554,11 +2509,6 @@ select {
background-color: rgb(2 73 90 / var(--tw-bg-opacity));
}
.hover\:bg-red-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(153 0 0 / var(--tw-bg-opacity));
}
.hover\:bg-yellow-500:hover {
--tw-bg-opacity: 1;
background-color: rgb(255 255 0 / var(--tw-bg-opacity));
@ -2569,6 +2519,10 @@ select {
background-color: rgb(3 91 113 / var(--tw-bg-opacity));
}
.hover\:fill-white:hover {
fill: #fff;
}
.hover\:text-gray-500:hover {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
@ -2594,6 +2548,11 @@ select {
color: rgb(2 73 90 / var(--tw-text-opacity));
}
.hover\:text-white:hover {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.focus\:border-0:focus {
border-width: 0px;
}
@ -2658,16 +2617,16 @@ select {
--tw-ring-inset: inset;
}
.focus\:ring-blue-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
}
.focus\:ring-indigo-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity));
}
.focus\:ring-primary-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(3 91 113 / var(--tw-ring-opacity));
}
.focus\:ring-vtd-primary-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(3 91 113 / var(--tw-ring-opacity));
@ -2678,11 +2637,6 @@ select {
--tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity));
}
.focus\:ring-primary-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(3 91 113 / var(--tw-ring-opacity));
}
.focus\:ring-opacity-10:focus {
--tw-ring-opacity: 0.1;
}
@ -2721,14 +2675,23 @@ select {
background-color: rgb(205 222 227 / var(--tw-bg-opacity));
}
.group:hover .group-hover\:fill-gray-600 {
fill: #4b5563;
.group:hover .group-hover\:bg-primary-500 {
--tw-bg-opacity: 1;
background-color: rgb(3 91 113 / var(--tw-bg-opacity));
}
.group:hover .group-hover\:fill-gray-500 {
fill: #6b7280;
}
.group:hover .group-hover\:fill-white {
fill: #fff;
}
.group:hover .group-hover\:stroke-white {
stroke: #fff;
}
.group:hover .group-hover\:text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
@ -2744,6 +2707,16 @@ select {
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.group:hover .group-hover\:text-gray-600 {
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
}
.group:hover .group-hover\:text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
}
@media (prefers-color-scheme: dark) {
.dark\:bg-opacity-50 {
--tw-bg-opacity: 0.5;
@ -3060,10 +3033,6 @@ select {
padding-right: 1.5rem;
}
.sm\:pb-6 {
padding-bottom: 1.5rem;
}
.sm\:text-left {
text-align: left;
}

View File

@ -1,4 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g id="DotOutline">
<path id="Vector" opacity="0.2" d="M9.5 8C9.5 8.29667 9.41203 8.58668 9.24721 8.83336C9.08238 9.08003 8.84812 9.27229 8.57403 9.38582C8.29994 9.49935 7.99834 9.52906 7.70737 9.47118C7.41639 9.4133 7.14912 9.27044 6.93934 9.06066C6.72956 8.85088 6.5867 8.58361 6.52882 8.29264C6.47094 8.00166 6.50065 7.70006 6.61418 7.42597C6.72771 7.15189 6.91997 6.91762 7.16665 6.7528C7.41332 6.58797 7.70333 6.5 8 6.5C8.39783 6.5 8.77936 6.65804 9.06066 6.93934C9.34197 7.22064 9.5 7.60218 9.5 8Z" fill="#4B5563"/>
<path id="Vector_2" d="M8 6C7.60444 6 7.21776 6.1173 6.88886 6.33706C6.55996 6.55682 6.30362 6.86918 6.15224 7.23463C6.00087 7.60009 5.96126 8.00222 6.03843 8.39018C6.1156 8.77814 6.30608 9.13451 6.58579 9.41421C6.86549 9.69392 7.22186 9.8844 7.60982 9.96157C7.99778 10.0387 8.39992 9.99913 8.76537 9.84776C9.13082 9.69638 9.44318 9.44004 9.66294 9.11114C9.8827 8.78224 10 8.39556 10 8C10 7.46957 9.78929 6.96086 9.41421 6.58579C9.03914 6.21071 8.53043 6 8 6ZM8 9C7.80222 9 7.60888 8.94135 7.44443 8.83147C7.27998 8.72159 7.15181 8.56541 7.07612 8.38268C7.00043 8.19996 6.98063 7.99889 7.01922 7.80491C7.0578 7.61093 7.15304 7.43275 7.29289 7.29289C7.43275 7.15304 7.61093 7.0578 7.80491 7.01921C7.99889 6.98063 8.19996 7.00043 8.38268 7.07612C8.56541 7.15181 8.72159 7.27998 8.83147 7.44443C8.94135 7.60888 9 7.80222 9 8C9 8.26522 8.89464 8.51957 8.70711 8.70711C8.51957 8.89464 8.26522 9 8 9Z" fill="#4B5563"/>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -15,22 +15,22 @@ import {
import { XMarkIcon } from '@heroicons/vue/24/outline'
import { useMenuStore } from '@/stores/menu'
import { IconApp } from '@/utils/icons'
import AsideMenuSingle from './AsideMenuSingle.vue'
import AsideMenuSingle from '@/components/Aside/AsideMenuSingle.vue'
import AsideMenuMultiple from '@/components/Aside/AsideMenuMultiple.vue'
import type { MenuItemModel } from '@/utils/interfaces'
const menu = useMenuStore()
const route = useRoute()
const navigation = ref<MenuItemModel[]>(menu.navigation)
const menuSelected = ref(route.fullPath)
watch(route, (to, _) => {
menuSelected.value = to.fullPath
menu.menuSelected = to.fullPath
closeSideBar()
})
const isMenu = (name: string) => {
return menuSelected.value === name
return menu.menuSelected === name
}
const closeSideBar = () => menu.toggleSidebar()
@ -73,7 +73,7 @@ const closeSideBar = () => menu.toggleSidebar()
<nav class="px-2 space-y-1">
<template v-for="item in navigation" :key="item.name">
<div v-if="!item.children || item.children.length === 0">
<AsideMenuSingle :item="item" :is-menu-selected="isMenu(item.href)" />
<AsideMenuSingle :item="item" :selected="isMenu(item.href)" />
<!-- Single-level item -->
<!-- <RouterLink :to="item.href"
:class="[isMenu(item.href) ? 'bg-primary-500 text-white font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-full flex items-center pl-2 py-2 text-xs rounded-lg']">
@ -85,22 +85,22 @@ const closeSideBar = () => menu.toggleSidebar()
</div>
<Disclosure v-else
v-bind:default-open="item.children.find((d) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? true : false">
v-bind:default-open="item.children.find((d) => d.href === menu.menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menu.menuSelected)) ? true : false">
<!-- Nested item with children -->
<template v-slot="{ open }">
<DisclosureButton
:class="[item.children.find((d) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? 'text-primary-500 font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-full flex items-center pl-2 pr-1 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0 focus:ring-indigo-500']">
:class="[item.children.find((d) => d.href === menu.menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menu.menuSelected)) ? 'text-primary-500 font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-full flex items-center pl-2 pr-1 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0 focus:ring-indigo-500']">
<embed :data="item.icon"
:class="[item.children.find((d: any) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? 'text-primary-500' : 'text-gray-400 group-hover:text-gray-500', 'flex-shrink-0 w-6 h-6 mr-3']"
:class="[item.children.find((d: any) => d.href === menu.menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menu.menuSelected)) ? 'text-primary-500' : 'text-gray-400 group-hover:text-gray-500', 'flex-shrink-0 w-6 h-6 mr-3']"
type="image/svg+xml" />
<span class="flex-1">{{ item.name }}</span>
<svg :class="[item.children.find((d: any) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
<svg :class="[item.children.find((d: any) => d.href === menu.menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menu.menuSelected)) ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
width="16" height="16" viewBox="0 0 24 24" fill="none"
aria-hidden="true">
<path
d="M4.44002 8.9399C4.72127 8.659 5.10252 8.50122 5.50002 8.50122C5.89752 8.50122 6.27877 8.659 6.56002 8.9399L12 14.3799L17.44 8.9399C17.7244 8.67494 18.1005 8.53069 18.4891 8.53755C18.8777 8.54441 19.2484 8.70183 19.5233 8.97666C19.7981 9.25148 19.9555 9.62225 19.9624 10.0109C19.9692 10.3995 19.825 10.7756 19.56 11.0599L13.06 17.5599C12.7788 17.8408 12.3975 17.9986 12 17.9986C11.6025 17.9986 11.2213 17.8408 10.94 17.5599L4.44002 11.0599C4.15912 10.7787 4.00134 10.3974 4.00134 9.9999C4.00134 9.6024 4.15912 9.22115 4.44002 8.9399Z"
:fill="item.children.find((d: any) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? '#14A2BA' : '#647375'" />
:fill="item.children.find((d: any) => d.href === menu.menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menu.menuSelected)) ? '#14A2BA' : '#647375'" />
</svg>
</DisclosureButton>
@ -113,25 +113,25 @@ const closeSideBar = () => menu.toggleSidebar()
:class="[isMenu(subItem.href) ? 'text-white font-bold bg-primary-500' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'flex items-center w-11/12 py-2 px-2 text-xs rounded-lg group ml-auto']">
{{ subItem.name }}
</RouterLink> -->
<AsideMenuSingle :item="subItem"
:is-menu-selected="isMenu(subItem.href)" :is-children="true" />
<AsideMenuSingle :item="subItem" :selected="isMenu(subItem.href)"
:is-children="true" />
</div>
<Disclosure v-else
:default-open="subItem.children.find((d: any) => d.href === menuSelected) ? true : false">
:default-open="subItem.children.find((d: any) => d.href === menu.menuSelected) ? true : false">
<!-- Nested child with children -->
<template v-slot="{ open }">
<DisclosureButton
:class="[subItem.children.find((d: any) => d.href === menuSelected) ? 'text-primary-500 font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-11/12 flex items-center px-2 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0 focus:ring-indigo-500 ml-auto']">
:class="[subItem.children.find((d: any) => d.href === menu.menuSelected) ? 'text-primary-500 font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-11/12 flex items-center px-2 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0 focus:ring-indigo-500 ml-auto']">
<span class="flex-1">{{ subItem.name }}</span>
<svg :class="[subItem.children.find((d: any) => d.href === menuSelected) ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
<svg :class="[subItem.children.find((d: any) => d.href === menu.menuSelected) ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
width="16" height="16" viewBox="0 0 24 24" fill="none"
aria-hidden="true">
<path
d="M4.44002 8.9399C4.72127 8.659 5.10252 8.50122 5.50002 8.50122C5.89752 8.50122 6.27877 8.659 6.56002 8.9399L12 14.3799L17.44 8.9399C17.7244 8.67494 18.1005 8.53069 18.4891 8.53755C18.8777 8.54441 19.2484 8.70183 19.5233 8.97666C19.7981 9.25148 19.9555 9.62225 19.9624 10.0109C19.9692 10.3995 19.825 10.7756 19.56 11.0599L13.06 17.5599C12.7788 17.8408 12.3975 17.9986 12 17.9986C11.6025 17.9986 11.2213 17.8408 10.94 17.5599L4.44002 11.0599C4.15912 10.7787 4.00134 10.3974 4.00134 9.9999C4.00134 9.6024 4.15912 9.22115 4.44002 8.9399Z"
:fill="subItem.children.find((d: any) => d.href === menuSelected) ? '#14A2BA' : '#647375'" />
:fill="subItem.children.find((d: any) => d.href === menu.menuSelected) ? '#14A2BA' : '#647375'" />
</svg>
</DisclosureButton>
<DisclosurePanel class="space-y-1 pl-11">
@ -143,7 +143,7 @@ const closeSideBar = () => menu.toggleSidebar()
</RouterLink> -->
<AsideMenuSingle v-for="nestedSubItem in subItem.children"
:key="nestedSubItem.name" :item="nestedSubItem"
:is-menu-selected="isMenu(nestedSubItem.href)"
:selected="isMenu(nestedSubItem.href)"
:is-children="true" />
</DisclosurePanel>
</template>
@ -178,74 +178,11 @@ const closeSideBar = () => menu.toggleSidebar()
<div class="flex flex-col flex-grow mt-5">
<nav class="flex-1 px-2 pb-4 space-y-1">
<template v-for="item in navigation" :key="item.name">
<div v-if="item.children.length === 0">
<!-- Single-level item -->
<AsideMenuSingle :item="item" :is-menu-selected="isMenu(item.href)" />
</div>
<!-- Single-level item -->
<AsideMenuSingle v-if="item.children.length === 0" :item="item" :selected="isMenu(item.href)" />
<Disclosure v-slot="{ open }" v-else
v-bind:default-open="item.children.find((d) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? true : false">
<!-- Nested item with children -->
<DisclosureButton
:class="[item.children.find((d) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? 'text-primary-500 font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-full flex items-center pl-2 pr-1 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0 focus:ring-indigo-500']">
<embed :src="item.icon"
:class="[item.children.find((d: any) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? 'fill-primary-500' : 'fill-gray-400 group-hover:fill-gray-500', 'flex-shrink-0 w-6 h-6 mr-3']"
type="image/svg+xml" />
<span class="flex-1">{{ item.name }}</span>
<svg :class="[item.children.find((d: any) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4.44002 8.9399C4.72127 8.659 5.10252 8.50122 5.50002 8.50122C5.89752 8.50122 6.27877 8.659 6.56002 8.9399L12 14.3799L17.44 8.9399C17.7244 8.67494 18.1005 8.53069 18.4891 8.53755C18.8777 8.54441 19.2484 8.70183 19.5233 8.97666C19.7981 9.25148 19.9555 9.62225 19.9624 10.0109C19.9692 10.3995 19.825 10.7756 19.56 11.0599L13.06 17.5599C12.7788 17.8408 12.3975 17.9986 12 17.9986C11.6025 17.9986 11.2213 17.8408 10.94 17.5599L4.44002 11.0599C4.15912 10.7787 4.00134 10.3974 4.00134 9.9999C4.00134 9.6024 4.15912 9.22115 4.44002 8.9399Z"
:fill="item.children.find((d: any) => d.href === menuSelected) || item.children.find((d) => d.children.find((e) => e.href === menuSelected)) ? '#14A2BA' : '#647375'" />
</svg>
</DisclosureButton>
<transition enter-active-class="overflow-hidden transition-all duration-300"
enter-from-class="transform scale-95 opacity-0 max-h-0"
enter-to-class="transform scale-300 opacity-300 max-h-[1000px]"
leave-active-class="overflow-hidden transition-all duration-300"
leave-from-class="transform scale-300 opacity-300 max-h-[1000px]"
leave-to-class="transform scale-95 opacity-0 max-h-0">
<DisclosurePanel class="space-y-1">
<!-- Nested children -->
<template v-for="(subItem, index) in item.children" :key="subItem.href">
<div v-if="!subItem.children || subItem.children.length === 0">
<!-- Single-level child -->
<AsideMenuSingle :item="subItem" :is-children="true"
:is-menu-selected="isMenu(subItem.href)" />
</div>
<Disclosure :key="subItem.href + index" v-slot="{ open }" v-else
:default-open="subItem.children.find((d: any) => d.href === menuSelected) ? true : false">
<!-- Nested child with children -->
<DisclosureButton
:class="[subItem.children.find((d: any) => d.href === menuSelected) ? 'text-primary-500 font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-11/12 flex items-center px-2 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0 focus:ring-indigo-500 ml-auto']">
<span class="flex-1">{{ subItem.name }}</span>
<svg :class="[subItem.children.find((d: any) => d.href === menuSelected) ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
width="16" height="16" viewBox="0 0 24 24" fill="none"
aria-hidden="true">
<path
d="M4.44002 8.9399C4.72127 8.659 5.10252 8.50122 5.50002 8.50122C5.89752 8.50122 6.27877 8.659 6.56002 8.9399L12 14.3799L17.44 8.9399C17.7244 8.67494 18.1005 8.53069 18.4891 8.53755C18.8777 8.54441 19.2484 8.70183 19.5233 8.97666C19.7981 9.25148 19.9555 9.62225 19.9624 10.0109C19.9692 10.3995 19.825 10.7756 19.56 11.0599L13.06 17.5599C12.7788 17.8408 12.3975 17.9986 12 17.9986C11.6025 17.9986 11.2213 17.8408 10.94 17.5599L4.44002 11.0599C4.15912 10.7787 4.00134 10.3974 4.00134 9.9999C4.00134 9.6024 4.15912 9.22115 4.44002 8.9399Z"
:fill="subItem.children.find((d: any) => d.href === menuSelected) ? '#14A2BA' : '#647375'" />
</svg>
</DisclosureButton>
<transition enter-active-class="overflow-hidden transition-all duration-300"
enter-from-class="transform scale-95 opacity-0 max-h-0"
enter-to-class="transform scale-300 opacity-300 max-h-[1000px]"
leave-active-class="overflow-hidden transition-all duration-300"
leave-from-class="transform scale-300 opacity-300 max-h-[1000px]"
leave-to-class="transform scale-95 opacity-0 max-h-0">
<DisclosurePanel class="space-y-1 pl-11">
<!-- Nested children of nested child -->
<AsideMenuSingle v-for="nestedSubItem in subItem.children"
:item="nestedSubItem" :is-children="true"
:is-menu-selected="isMenu(subItem.href)" />
</DisclosurePanel>
</transition>
</Disclosure>
</template>
</DisclosurePanel>
</transition>
</Disclosure>
<!-- Nested item with children -->
<AsideMenuMultiple v-else :item="item" :selected="isMenu(item.href)" />
</template>
</nav>
</div>

View File

@ -0,0 +1,74 @@
<script setup lang="ts">
import { computed, defineProps } from 'vue'
import type { MenuItemModel } from '@/utils/interfaces'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
import { useMenuStore } from '@/stores/menu'
import { DotOutline } from '@/utils/icons'
import AsideMenuSingle from '@/components/Aside/AsideMenuSingle.vue'
const menu = useMenuStore()
const props = defineProps({
item: {
type: Object as () => MenuItemModel,
required: true
},
selected: {
type: Boolean,
required: true
},
isChildren: {
type: Boolean,
default: false
}
})
const isMenu = (name: string) => {
return menu.menuSelected === name
}
const isMenuSelected = computed(() => {
return props.item.children.find((d) => d.href === menu.menuSelected) || props.item.children.find((d) => d.children.find((e) => e.href === menu.menuSelected))
})
</script>
<template>
<div :class="[isChildren ? 'ml-4 mt-1 bg-primary-100 rounded-xl' : '']">
<Disclosure v-slot="{ open }" v-bind:default-open="isMenuSelected ? true : false">
<!-- Nested item with children -->
<DisclosureButton
:class="[(isMenuSelected || open || isChildren) ? 'bg-primary-100 text-primary-500 font-bold' : 'text-gray-600 font-semibold text-aside hover:bg-primary-100 hover:text-primary-500', 'group w-full flex items-center pl-2 pr-1 py-2 text-left text-xs rounded-lg focus:outline-none focus:ring-0']">
<embed :src="isChildren ? DotOutline : item.icon"
:class="[isMenuSelected ? 'fill-primary-500' : 'fill-gray-400 group-hover:fill-gray-500', isChildren ? '' : 'mr-2', 'flex-shrink-0 w-6 h-6']"
type="image/svg+xml" />
<span class="flex-1">{{ item.name }}</span>
<svg :class="[isMenuSelected ? 'text-primary-500' : 'text-gray-300 group-hover:text-gray-500', open ? 'rotate-180' : '', 'ml-3 flex-shrink-0 transform transition-colors duration-150 ease-in-out ']"
width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M4.44002 8.9399C4.72127 8.659 5.10252 8.50122 5.50002 8.50122C5.89752 8.50122 6.27877 8.659 6.56002 8.9399L12 14.3799L17.44 8.9399C17.7244 8.67494 18.1005 8.53069 18.4891 8.53755C18.8777 8.54441 19.2484 8.70183 19.5233 8.97666C19.7981 9.25148 19.9555 9.62225 19.9624 10.0109C19.9692 10.3995 19.825 10.7756 19.56 11.0599L13.06 17.5599C12.7788 17.8408 12.3975 17.9986 12 17.9986C11.6025 17.9986 11.2213 17.8408 10.94 17.5599L4.44002 11.0599C4.15912 10.7787 4.00134 10.3974 4.00134 9.9999C4.00134 9.6024 4.15912 9.22115 4.44002 8.9399Z"
:fill="isMenuSelected ? '#14A2BA' : '#647375'" />
</svg>
</DisclosureButton>
<transition enter-active-class="overflow-hidden transition-all duration-300"
enter-from-class="transform scale-95 opacity-0 max-h-0"
enter-to-class="transform scale-300 opacity-300 max-h-[1000px]"
leave-active-class="overflow-hidden transition-all duration-300"
leave-from-class="transform scale-300 opacity-300 max-h-[1000px]"
leave-to-class="transform scale-95 opacity-0 max-h-0">
<DisclosurePanel :class="[(isChildren) ? 'bg-primary-100 rounded-xl ml-4' : '', 'space-y-1']">
<!-- Nested children -->
<template v-for="(subItem, index) in item.children" :key="subItem.href">
<!-- Single-level child -->
<div v-if="subItem.children.length === 0" :class="[isChildren ? '' : '']">
<AsideMenuSingle :item="subItem" :is-children="true" :selected="isMenu(subItem.href)" />
</div>
<AsideMenuMultiple v-else :item="subItem" :selected="subItem.href === menu.menuSelected"
:is-children="true" />
</template>
</DisclosurePanel>
</transition>
</Disclosure>
</div>
</template>

View File

@ -1,14 +1,14 @@
<script setup lang="ts">
import { defineProps } from 'vue'
import type { MenuItemModel } from '@/utils/interfaces'
import { DotOutline } from '@/utils/icons';
import { DotOutline } from '@/utils/icons'
defineProps({
item: {
type: Object as () => MenuItemModel,
required: true
},
isMenuSelected: {
selected: {
type: Boolean,
required: true
},
@ -20,10 +20,26 @@ defineProps({
</script>
<template>
<RouterLink :to="item.href"
:class="[isMenuSelected ? 'bg-primary-500 text-white font-bold' : 'font-semibold text-aside hover:bg-primary-100 hover:text-gray-900', 'group w-full flex items-center pl-2 py-2 text-xs rounded-lg']">
<embed :src="isChildren ? DotOutline : item.icon" type="image/svg+xml"
:class="[isMenuSelected ? 'text-white' : 'text-aside group-hover:text-gray-900', 'mr-3 flex-shrink-0 h-6 w-6']">
{{ item.name }}
</RouterLink>
<div class="group">
<RouterLink :to="item.href"
:class="[selected ? 'bg-primary-500 text-white font-bold' : 'font-semibold text-aside group-hover:bg-primary-100 text-gray-600 group-hover:text-white group-hover:bg-primary-500', 'w-full flex items-center pl-2 py-2 text-xs rounded-xl']">
<svg v-if="isChildren" :class="[selected ? 'stroke-white' : 'text-aside group-hover:stroke-white', 'h-6 w-6']"
width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g id="DotOutline">
<path id="Vector" opacity="0.2"
d="M9.5 8C9.5 8.29667 9.41203 8.58668 9.24721 8.83336C9.08238 9.08003 8.84812 9.27229 8.57403 9.38582C8.29994 9.49935 7.99834 9.52906 7.70737 9.47118C7.41639 9.4133 7.14912 9.27044 6.93934 9.06066C6.72956 8.85088 6.5867 8.58361 6.52882 8.29264C6.47094 8.00166 6.50065 7.70006 6.61418 7.42597C6.72771 7.15189 6.91997 6.91762 7.16665 6.7528C7.41332 6.58797 7.70333 6.5 8 6.5C8.39783 6.5 8.77936 6.65804 9.06066 6.93934C9.34197 7.22064 9.5 7.60218 9.5 8Z"
fill="#4B5563" />
<path id="Vector_2"
d="M8 6C7.60444 6 7.21776 6.1173 6.88886 6.33706C6.55996 6.55682 6.30362 6.86918 6.15224 7.23463C6.00087 7.60009 5.96126 8.00222 6.03843 8.39018C6.1156 8.77814 6.30608 9.13451 6.58579 9.41421C6.86549 9.69392 7.22186 9.8844 7.60982 9.96157C7.99778 10.0387 8.39992 9.99913 8.76537 9.84776C9.13082 9.69638 9.44318 9.44004 9.66294 9.11114C9.8827 8.78224 10 8.39556 10 8C10 7.46957 9.78929 6.96086 9.41421 6.58579C9.03914 6.21071 8.53043 6 8 6ZM8 9C7.80222 9 7.60888 8.94135 7.44443 8.83147C7.27998 8.72159 7.15181 8.56541 7.07612 8.38268C7.00043 8.19996 6.98063 7.99889 7.01922 7.80491C7.0578 7.61093 7.15304 7.43275 7.29289 7.29289C7.43275 7.15304 7.61093 7.0578 7.80491 7.01921C7.99889 6.98063 8.19996 7.00043 8.38268 7.07612C8.56541 7.15181 8.72159 7.27998 8.83147 7.44443C8.94135 7.60888 9 7.80222 9 8C9 8.26522 8.89464 8.51957 8.70711 8.70711C8.51957 8.89464 8.26522 9 8 9Z"
fill="#4B5563" />
</g>
</svg>
<embed v-else :src="item.icon" type="image/svg+xml"
:class="[selected ? 'text-white fill-white' : 'text-aside group-hover:text-white group-hover:fill-white', 'mr-2 flex-shrink-0 h-6 w-6']">
{{ item.name }}
</RouterLink>
</div>
</template>

View File

@ -1,18 +0,0 @@
<script setup lang="ts">
import { defineProps } from 'vue'
import type { MenuItemModel } from '@/utils/interfaces'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@headlessui/vue'
defineProps({
item: {
type: Object as () => MenuItemModel,
required: true
},
isMenuSelected: {
type: Boolean,
required: true
}
})
</script>
<template></template>

View File

@ -8,6 +8,7 @@ import {
Swap
} from '@/utils/icons'
import type { MenuItemModel } from '@/utils/interfaces'
import { useRoute } from 'vue-router'
export const useMenuStore = defineStore('menu', () => {
const navigation: MenuItemModel[] = [
@ -461,11 +462,14 @@ export const useMenuStore = defineStore('menu', () => {
},
]
const sidebarOpen = ref(false)
const route = useRoute()
const menuSelected = ref(route.fullPath)
const toggleSidebar = () => (sidebarOpen.value = !sidebarOpen.value)
return {
navigation,
toggleSidebar,
sidebarOpen
sidebarOpen,
menuSelected
}
})