Updates
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import Row from "../layout/Row";
|
||||
import HeaderNavLinkComponent from "./HeaderNavLinkComponent";
|
||||
|
||||
export type TWUI_HEADER_NAV_PROPS = DetailedHTMLProps<
|
||||
HTMLAttributes<HTMLElement>,
|
||||
HTMLElement
|
||||
> & {
|
||||
headerLinks: TwuiHeaderLink[];
|
||||
customDropdowns?: {
|
||||
url: string;
|
||||
content: ReactNode;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type TwuiHeaderLink = {
|
||||
title: string;
|
||||
url: string;
|
||||
strict?: boolean;
|
||||
dropdown?: ReactNode;
|
||||
children?: TwuiHeaderLink[];
|
||||
icon?: ReactNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* # Header Nav Component
|
||||
* @className twui-header-nav
|
||||
* @className twui-header-nav-link-component
|
||||
* @className twui-header-nav-link-icon
|
||||
* @className twui-header-nav-link-dropdown
|
||||
*/
|
||||
export default function HeaderNav({
|
||||
headerLinks,
|
||||
customDropdowns,
|
||||
...props
|
||||
}: TWUI_HEADER_NAV_PROPS) {
|
||||
React.useEffect(() => {
|
||||
twuiAddActiveLinksFn({ selector: ".twui-header-nav-link-component a" });
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<nav
|
||||
{...props}
|
||||
className={twMerge(
|
||||
"twui-header-nav w-full xl:w-auto",
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
<Row className="gap-x-2 gap-y-2 flex-col xl:flex-row items-start xl:items-stretch">
|
||||
{headerLinks.map((link, index) => {
|
||||
const targetCustomDropdown = customDropdowns?.find(
|
||||
(d) => d.url == link.url
|
||||
);
|
||||
return (
|
||||
<HeaderNavLinkComponent
|
||||
link={link}
|
||||
key={index}
|
||||
dropdown={targetCustomDropdown?.content}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
type AddActiveLinkParams = {
|
||||
selector?: string;
|
||||
wrapperEl?: HTMLElement;
|
||||
};
|
||||
|
||||
export function twuiAddActiveLinksFn({
|
||||
selector,
|
||||
wrapperEl,
|
||||
}: AddActiveLinkParams) {
|
||||
(wrapperEl || document).querySelectorAll(selector || "a").forEach((ln) => {
|
||||
const linkEl = ln as HTMLAnchorElement;
|
||||
const isLinkStrict = linkEl.dataset.strict;
|
||||
|
||||
const linkAttr = linkEl.getAttribute("href");
|
||||
|
||||
if (window.location.pathname === "/" && linkAttr == "/") {
|
||||
linkEl.classList.add("active");
|
||||
} else if (
|
||||
isLinkStrict &&
|
||||
linkEl.getAttribute("href") === window.location.pathname
|
||||
) {
|
||||
linkEl.classList.add("active");
|
||||
} else if (
|
||||
linkAttr &&
|
||||
window.location.pathname.startsWith(linkAttr) &&
|
||||
!isLinkStrict
|
||||
) {
|
||||
linkEl.classList.add("active");
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user