Files
Hemanshu Upadhyay d0ea931f5a Migrated the active-class-name Example to App router (#67622)
Updated/Migrated the active-class-name example to the App router

This PR contains the Following Changes. 
Pages folder Converted into App Folder. 
Updated file Structure according to the App Router convention
Updated ActiveLink Component as per App router.

---------

Co-authored-by: samcx <sam@vercel.com>
2024-07-15 11:25:33 +00:00

61 lines
1.4 KiB
TypeScript

"use client";
import Link, { LinkProps } from "next/link";
import React, { PropsWithChildren, useEffect, useState } from "react";
import { usePathname } from "next/navigation";
const getLinkUrl = (href: LinkProps["href"], as?: LinkProps["as"]): string => {
// Dynamic route will be matched via props.as
// Static route will be matched via props.href
if (as) return as.toString();
return href.toString();
};
type ActiveLinkProps = LinkProps & {
className?: string;
activeClassName: string;
};
const ActiveLink = ({
children,
activeClassName,
className,
...props
}: PropsWithChildren<ActiveLinkProps>) => {
const pathname = usePathname();
const [computedClassName, setComputedClassName] = useState(className);
useEffect(() => {
if (pathname) {
const linkUrl = getLinkUrl(props.href, props.as);
const linkPathname = new URL(linkUrl, location.href).pathname;
const activePathname = new URL(pathname, location.href).pathname;
const newClassName =
linkPathname === activePathname
? `${className} ${activeClassName}`.trim()
: className;
if (newClassName !== computedClassName) {
setComputedClassName(newClassName);
}
}
}, [
pathname,
props.as,
props.href,
activeClassName,
className,
computedClassName,
]);
return (
<Link className={computedClassName} {...props}>
{children}
</Link>
);
};
export default ActiveLink;