mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
d0ea931f5a
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>
61 lines
1.4 KiB
TypeScript
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;
|