Skip to content

Commit 08df299

Browse files
Merge pull request #185 from hcancelik/hotfix-navmain-active
Fix active state logic for sidebar menu items
2 parents 98e83b9 + 2b6d96d commit 08df299

File tree

5 files changed

+21
-15
lines changed

5 files changed

+21
-15
lines changed

resources/js/components/AppHeader.vue

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/co
1010
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
1111
import UserMenuContent from '@/components/UserMenuContent.vue';
1212
import { getInitials } from '@/composables/useInitials';
13+
import { toUrl, urlIsActive } from '@/lib/utils';
1314
import { dashboard } from '@/routes';
1415
import type { BreadcrumbItem, NavItem } from '@/types';
1516
import { InertiaLinkProps, Link, usePage } from '@inertiajs/vue3';
@@ -27,11 +28,11 @@ const props = withDefaults(defineProps<Props>(), {
2728
const page = usePage();
2829
const auth = computed(() => page.props.auth);
2930
30-
const isCurrentRoute = computed(() => (url: NonNullable<InertiaLinkProps['href']>) => page.url === (typeof url === 'string' ? url : url.url));
31+
const isCurrentRoute = computed(() => (url: NonNullable<InertiaLinkProps['href']>) => urlIsActive(url, page.url));
3132
3233
const activeItemStyles = computed(
3334
() => (url: NonNullable<InertiaLinkProps['href']>) =>
34-
isCurrentRoute.value(typeof url === 'string' ? url : url.url) ? 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100' : '',
35+
isCurrentRoute.value(toUrl(url)) ? 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100' : '',
3536
);
3637
3738
const mainNavItems: NavItem[] = [
@@ -90,7 +91,7 @@ const rightNavItems: NavItem[] = [
9091
<a
9192
v-for="item in rightNavItems"
9293
:key="item.title"
93-
:href="typeof item.href === 'string' ? item.href : item.href?.url"
94+
:href="toUrl(item.href)"
9495
target="_blank"
9596
rel="noopener noreferrer"
9697
class="flex items-center space-x-2 text-sm font-medium"
@@ -141,11 +142,7 @@ const rightNavItems: NavItem[] = [
141142
<Tooltip>
142143
<TooltipTrigger>
143144
<Button variant="ghost" size="icon" as-child class="group h-9 w-9 cursor-pointer">
144-
<a
145-
:href="typeof item.href === 'string' ? item.href : item.href?.url"
146-
target="_blank"
147-
rel="noopener noreferrer"
148-
>
145+
<a :href="toUrl(item.href)" target="_blank" rel="noopener noreferrer">
149146
<span class="sr-only">{{ item.title }}</span>
150147
<component :is="item.icon" class="size-5 opacity-80 group-hover:opacity-100" />
151148
</a>

resources/js/components/NavFooter.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { SidebarGroup, SidebarGroupContent, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
3+
import { toUrl } from '@/lib/utils';
34
import { type NavItem } from '@/types';
45
56
interface Props {
@@ -16,7 +17,7 @@ defineProps<Props>();
1617
<SidebarMenu>
1718
<SidebarMenuItem v-for="item in items" :key="item.title">
1819
<SidebarMenuButton class="text-neutral-600 hover:text-neutral-800 dark:text-neutral-300 dark:hover:text-neutral-100" as-child>
19-
<a :href="typeof item.href === 'string' ? item.href : item.href.url" target="_blank" rel="noopener noreferrer">
20+
<a :href="toUrl(item.href)" target="_blank" rel="noopener noreferrer">
2021
<component :is="item.icon" />
2122
<span>{{ item.title }}</span>
2223
</a>

resources/js/components/NavMain.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
3+
import { urlIsActive } from '@/lib/utils';
34
import { type NavItem } from '@/types';
45
import { Link, usePage } from '@inertiajs/vue3';
56
@@ -15,7 +16,7 @@ const page = usePage();
1516
<SidebarGroupLabel>Platform</SidebarGroupLabel>
1617
<SidebarMenu>
1718
<SidebarMenuItem v-for="item in items" :key="item.title">
18-
<SidebarMenuButton as-child :is-active="item.href === page.url" :tooltip="item.title">
19+
<SidebarMenuButton as-child :is-active="urlIsActive(item.href, page.url)" :tooltip="item.title">
1920
<Link :href="item.href">
2021
<component :is="item.icon" />
2122
<span>{{ item.title }}</span>

resources/js/layouts/settings/Layout.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import Heading from '@/components/Heading.vue';
33
import { Button } from '@/components/ui/button';
44
import { Separator } from '@/components/ui/separator';
5+
import { toUrl, urlIsActive } from '@/lib/utils';
56
import { appearance } from '@/routes';
67
import { edit as editPassword } from '@/routes/password';
78
import { edit } from '@/routes/profile';
@@ -35,12 +36,9 @@ const currentPath = typeof window !== undefined ? window.location.pathname : '';
3536
<nav class="flex flex-col space-y-1 space-x-0">
3637
<Button
3738
v-for="item in sidebarNavItems"
38-
:key="typeof item.href === 'string' ? item.href : item.href?.url"
39+
:key="toUrl(item.href)"
3940
variant="ghost"
40-
:class="[
41-
'w-full justify-start',
42-
{ 'bg-muted': currentPath === (typeof item.href === 'string' ? item.href : item.href?.url) },
43-
]"
41+
:class="['w-full justify-start', { 'bg-muted': urlIsActive(item.href, currentPath) }]"
4442
as-child
4543
>
4644
<Link :href="item.href">

resources/js/lib/utils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1+
import { InertiaLinkProps } from '@inertiajs/vue3';
12
import { clsx, type ClassValue } from 'clsx';
23
import { twMerge } from 'tailwind-merge';
34

45
export function cn(...inputs: ClassValue[]) {
56
return twMerge(clsx(inputs));
67
}
8+
9+
export function urlIsActive(urlToCheck: NonNullable<InertiaLinkProps['href']>, currentUrl: string) {
10+
return toUrl(urlToCheck) === currentUrl;
11+
}
12+
13+
export function toUrl(href: NonNullable<InertiaLinkProps['href']>) {
14+
return typeof href === 'string' ? href : href?.url;
15+
}

0 commit comments

Comments
 (0)