From 5ce624d7f2df48992dd9e4df00c25659151a8e63 Mon Sep 17 00:00:00 2001 From: Javier Reyes Date: Sat, 1 Nov 2025 13:06:40 +0100 Subject: [PATCH 1/3] feat: add useActiveUrl composable for active URL management --- resources/js/composables/useActiveUrl.ts | 26 ++++++++++++++++++++++++ resources/js/lib/utils.ts | 12 ----------- 2 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 resources/js/composables/useActiveUrl.ts diff --git a/resources/js/composables/useActiveUrl.ts b/resources/js/composables/useActiveUrl.ts new file mode 100644 index 00000000..11626bc7 --- /dev/null +++ b/resources/js/composables/useActiveUrl.ts @@ -0,0 +1,26 @@ +import { usePage } from '@inertiajs/vue3'; +import type { InertiaLinkProps } from '@inertiajs/vue3'; +import { computed, readonly } from 'vue'; + +const page = usePage() +const currentUrlReactive = computed(()=> new URL(page.url, window?.location.origin).pathname); + +function toUrl(href: NonNullable) { + return typeof href === 'string' ? href : href?.url; +} + +export function useActiveUrl(){ + function urlIsActive( + urlToCheck: NonNullable, + currentUrl?: string, + ) { + const urlToCompare = currentUrl ?? currentUrlReactive.value; + return toUrl(urlToCheck) === urlToCompare; + } + + return { + currentUrl: readonly(currentUrlReactive), + urlIsActive, + toUrl + } + } diff --git a/resources/js/lib/utils.ts b/resources/js/lib/utils.ts index fdee36a6..3877c89f 100644 --- a/resources/js/lib/utils.ts +++ b/resources/js/lib/utils.ts @@ -1,18 +1,6 @@ -import { InertiaLinkProps } from '@inertiajs/vue3'; import { clsx, type ClassValue } from 'clsx'; import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } - -export function urlIsActive( - urlToCheck: NonNullable, - currentUrl: string, -) { - return toUrl(urlToCheck) === currentUrl; -} - -export function toUrl(href: NonNullable) { - return typeof href === 'string' ? href : href?.url; -} From 7773ef896a889d03a89744ebf0664278f07e3cb5 Mon Sep 17 00:00:00 2001 From: Javier Reyes Date: Sat, 1 Nov 2025 13:26:40 +0100 Subject: [PATCH 2/3] feat: refactor navigation components to use useActiveUrl composable for URL management --- resources/js/components/AppHeader.vue | 24 ++++++++++-------------- resources/js/components/NavFooter.vue | 4 +++- resources/js/components/NavMain.vue | 8 ++++---- resources/js/layouts/settings/Layout.vue | 6 +++--- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/resources/js/components/AppHeader.vue b/resources/js/components/AppHeader.vue index 40e454f8..0dc05e43 100644 --- a/resources/js/components/AppHeader.vue +++ b/resources/js/components/AppHeader.vue @@ -29,11 +29,12 @@ import { TooltipTrigger, } from '@/components/ui/tooltip'; import UserMenuContent from '@/components/UserMenuContent.vue'; +import { useActiveUrl } from '@/composables/useActiveUrl'; import { getInitials } from '@/composables/useInitials'; -import { toUrl, urlIsActive } from '@/lib/utils'; import { dashboard } from '@/routes'; import type { BreadcrumbItem, NavItem } from '@/types'; -import { InertiaLinkProps, Link, usePage } from '@inertiajs/vue3'; +import type { InertiaLinkProps } from '@inertiajs/vue3'; +import { Link, usePage } from '@inertiajs/vue3'; import { BookOpen, Folder, LayoutGrid, Menu, Search } from 'lucide-vue-next'; import { computed } from 'vue'; @@ -47,18 +48,13 @@ const props = withDefaults(defineProps(), { const page = usePage(); const auth = computed(() => page.props.auth); +const { urlIsActive, toUrl } = useActiveUrl(); -const isCurrentRoute = computed( - () => (url: NonNullable) => - urlIsActive(url, page.url), -); - -const activeItemStyles = computed( - () => (url: NonNullable) => - isCurrentRoute.value(toUrl(url)) - ? 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100' - : '', -); +function activeItemStyles(url: NonNullable) { + return urlIsActive(url) + ? 'text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100' + : ''; +} const mainNavItems: NavItem[] = [ { @@ -179,7 +175,7 @@ const rightNavItems: NavItem[] = [ {{ item.title }}
diff --git a/resources/js/components/NavFooter.vue b/resources/js/components/NavFooter.vue index 6ae1d5f2..4bf2ceca 100644 --- a/resources/js/components/NavFooter.vue +++ b/resources/js/components/NavFooter.vue @@ -6,7 +6,7 @@ import { SidebarMenuButton, SidebarMenuItem, } from '@/components/ui/sidebar'; -import { toUrl } from '@/lib/utils'; +import { useActiveUrl } from '@/composables/useActiveUrl'; import { type NavItem } from '@/types'; interface Props { @@ -15,6 +15,8 @@ interface Props { } defineProps(); + +const { toUrl } = useActiveUrl();