Files
2026-04-09 16:06:44 -06:00

83 lines
2.3 KiB
TypeScript

import type { InertiaLinkProps } from '@inertiajs/vue3';
import { usePage } from '@inertiajs/vue3';
import type { ComputedRef, DeepReadonly } from 'vue';
import { computed, readonly } from 'vue';
import { toUrl } from '@/lib/utils';
export type UseCurrentUrlReturn = {
currentUrl: DeepReadonly<ComputedRef<string>>;
isCurrentUrl: (
urlToCheck: NonNullable<InertiaLinkProps['href']>,
currentUrl?: string,
startsWith?: boolean,
) => boolean;
isCurrentOrParentUrl: (
urlToCheck: NonNullable<InertiaLinkProps['href']>,
currentUrl?: string,
) => boolean;
whenCurrentUrl: <T, F = null>(
urlToCheck: NonNullable<InertiaLinkProps['href']>,
ifTrue: T,
ifFalse?: F,
) => T | F;
};
const page = usePage();
const currentUrlReactive = computed(
() =>
new URL(
page.url,
typeof window !== 'undefined'
? window.location.origin
: 'http://localhost',
).pathname,
);
export function useCurrentUrl(): UseCurrentUrlReturn {
function isCurrentUrl(
urlToCheck: NonNullable<InertiaLinkProps['href']>,
currentUrl?: string,
startsWith: boolean = false,
) {
const urlToCompare = currentUrl ?? currentUrlReactive.value;
const urlString = toUrl(urlToCheck);
const comparePath = (path: string): boolean =>
startsWith ? urlToCompare.startsWith(path) : path === urlToCompare;
if (!urlString.startsWith('http')) {
return comparePath(urlString);
}
try {
const absoluteUrl = new URL(urlString);
return comparePath(absoluteUrl.pathname);
} catch {
return false;
}
}
function isCurrentOrParentUrl(
urlToCheck: NonNullable<InertiaLinkProps['href']>,
currentUrl?: string,
) {
return isCurrentUrl(urlToCheck, currentUrl, true);
}
function whenCurrentUrl(
urlToCheck: NonNullable<InertiaLinkProps['href']>,
ifTrue: any,
ifFalse: any = null,
) {
return isCurrentUrl(urlToCheck) ? ifTrue : ifFalse;
}
return {
currentUrl: readonly(currentUrlReactive),
isCurrentUrl,
isCurrentOrParentUrl,
whenCurrentUrl,
};
}