Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 116 additions & 91 deletions src/components/SidebarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import * as Collapsible from "@radix-ui/react-collapsible";
import { cn } from "@utils/helpers";
import classNames from "classnames";
import { ChevronDownIcon, ChevronUpIcon, DotIcon } from "lucide-react";
import { usePathname, useRouter } from "next/navigation";
import { usePathname } from "next/navigation";
import Link from "next/link";
import React, { useEffect, useMemo } from "react";
import { useApplicationContext } from "@/contexts/ApplicationProvider";

Expand Down Expand Up @@ -52,106 +52,131 @@ export default function SidebarItem({
setOpen(true);
}
}, [hasActiveChild]);
const router = useRouter();
const { mobileNavOpen, toggleMobileNav, isNavigationCollapsed } =
useApplicationContext();

const handleClick = () => {
const preventRedirect = href
const isActive = useMemo(() => {
if (collapsible) return false;
return href
? exactPathMatch
? path == href
? path === href
: path.includes(href)
: false;
if (collapsible && href) return;
if (collapsible && mobileNavOpen) return;
if (collapsible && open) return;
if (preventRedirect) return;
if (target == "_blank") return window.open(href, "_blank");
}, [path, href, exactPathMatch, collapsible]);

const handleClick = (e: React.MouseEvent) => {
if (collapsible) return;

if (isActive) {
return e.preventDefault();
}

if (target === "_blank") return;

Comment thread
miyaji255 marked this conversation as resolved.
if (mobileNavOpen) toggleMobileNav();
router.push(href);
};

const isActive = useMemo(() => {
if (collapsible) return false;
return href ? (exactPathMatch ? path == href : path.includes(href)) : false;
}, [path, href, exactPathMatch, collapsible]);

if (!visible) return;

return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Collapsible.Trigger asChild>
<li className={"px-3 cursor-pointer list-none"}>
<button
className={classNames(
"rounded-lg text-[.87rem] w-full relative font-normal",
className,
isChild
? "pl-7 pr-2 py-[.45rem] mt-1 mb-0.5"
: "py-[.45rem] px-3",
isActive
? "text-gray-900 bg-gray-200 dark:text-white dark:bg-nb-gray-900"
: "text-gray-600 hover:bg-gray-200 dark:text-nb-gray-400 dark:hover:bg-nb-gray-900/50",
)}
onClick={handleClick}
data-cy={"left-navigation-item"}
>
{isChild && isNavigationCollapsed && !mobileNavOpen && (
<div
className={
"absolute left-0 top-0 w-full h-full flex items-center justify-center group-hover/navigation:hidden text-[10px]"
}
>
<DotIcon size={14} className={"shrink-0"} />
</div>
)}
<div
className={classNames(
"flex w-full items-center shrink-0 ",
href == "" ? "disabled pointer-events-none" : "",
const content = (
<div
className={cn(
"rounded-lg text-[.87rem] w-full relative font-normal",
className,
isChild ? "pl-7 pr-2 py-[.45rem] mt-1 mb-0.5" : "py-[.45rem] px-3",
isActive
? "text-gray-900 bg-gray-200 dark:text-white dark:bg-nb-gray-900"
: "text-gray-600 hover:bg-gray-200 dark:text-nb-gray-400 dark:hover:bg-nb-gray-900/50",
)}
data-cy={"left-navigation-item"}
>
{isChild && isNavigationCollapsed && !mobileNavOpen && (
<div
className={
"absolute left-0 top-0 w-full h-full flex items-center justify-center group-hover/navigation:hidden text-[10px]"
}
>
<DotIcon size={14} className={"shrink-0"} />
</div>
)}
<div
className={cn(
"flex w-full items-center shrink-0 ",
href === "" ? "disabled pointer-events-none" : "",
)}
>
<span className="peer/icon" data-active={isActive} />
{icon}

<span
className={cn(
"px-3 whitespace-nowrap flex-1 w-full text-left",
labelClassName,
isNavigationCollapsed &&
!mobileNavOpen &&
"opacity-0 group-hover/navigation:opacity-100",
)}
>
{label}
</span>
{collapsible &&
(open ? (
<ChevronUpIcon
size={18}
className={cn(
"shrink-0",
isNavigationCollapsed &&
!mobileNavOpen &&
"opacity-0 group-hover/navigation:opacity-100",
)}
/>
) : (
<ChevronDownIcon
size={18}
className={cn(
"shrink-0",
isNavigationCollapsed &&
!mobileNavOpen &&
"opacity-0 group-hover/navigation:opacity-100",
)}
>
<span className="peer/icon" data-active={isActive} />
{icon}

<span
className={cn(
"px-3 whitespace-nowrap flex-1 w-full text-left",
labelClassName,
isNavigationCollapsed &&
!mobileNavOpen &&
"opacity-0 group-hover/navigation:opacity-100",
)}
>
{label}
</span>
{collapsible &&
(open ? (
<ChevronUpIcon
size={18}
className={cn(
"shrink-0",
isNavigationCollapsed &&
!mobileNavOpen &&
"opacity-0 group-hover/navigation:opacity-100",
)}
/>
) : (
<ChevronDownIcon
size={18}
className={cn(
"shrink-0",
isNavigationCollapsed &&
!mobileNavOpen &&
"opacity-0 group-hover/navigation:opacity-100",
)}
/>
))}
</div>
</button>
</li>
</Collapsible.Trigger>
{collapsible && <Collapsible.Content>{children}</Collapsible.Content>}
</Collapsible.Root>
/>
))}
</div>
</div>
);

const itemContent = (
<li className={"px-3 cursor-pointer list-none"}>
{href && !collapsible ? (
<Link
href={href}
target={target}
rel={target === "_blank" ? "noopener noreferrer" : undefined}
onClick={handleClick}
>
{content}
</Link>
) : (
<button
type="button"
className={"w-full"}
onClick={handleClick}
disabled={!collapsible && href === ""}
>
{content}
</button>
)}
</li>
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

if (collapsible) {
return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Collapsible.Trigger asChild>{itemContent}</Collapsible.Trigger>
<Collapsible.Content>{children}</Collapsible.Content>
</Collapsible.Root>
);
}

return itemContent;
}