/** * Copyright (c) 2023-present Plane Software, Inc. and contributors * SPDX-License-Identifier: AGPL-3.0-only * See the LICENSE file for details. */ import Link from "next/link"; import { cn } from "@plane/utils"; // ============================================================================ // TYPES // ============================================================================ interface AppSidebarItemData { href?: string; label?: string; icon?: React.ReactNode; isActive?: boolean; onClick?: () => void; disabled?: boolean; showLabel?: boolean; } interface AppSidebarItemProps { variant?: "link" | "button"; item?: AppSidebarItemData; } interface AppSidebarItemLabelProps { highlight?: boolean; label?: string; } interface AppSidebarItemIconProps { icon?: React.ReactNode; highlight?: boolean; } interface AppSidebarLinkItemProps { href?: string; children: React.ReactNode; className?: string; } interface AppSidebarButtonItemProps { children: React.ReactNode; onClick?: () => void; disabled?: boolean; className?: string; } // ============================================================================ // STYLES // ============================================================================ const styles = { base: "group flex flex-col gap-0.5 items-center justify-center text-tertiary", icon: "flex items-center justify-center gap-2 size-8 rounded-md text-tertiary", iconActive: "bg-layer-transparent-selected text-secondary !text-icon-primary", iconInactive: "group-hover:text-icon-secondary group-hover:bg-layer-transparent-hover !text-icon-tertiary", label: "text-11 font-medium", labelActive: "text-secondary", labelInactive: "group-hover:text-secondary text-tertiary", } as const; // ============================================================================ // SUB-COMPONENTS // ============================================================================ function AppSidebarItemLabel({ highlight = false, label }: AppSidebarItemLabelProps) { if (!label) return null; return ( {label} ); } function AppSidebarItemIcon({ icon, highlight }: AppSidebarItemIconProps) { if (!icon) return null; return (
{icon}
); } function AppSidebarLinkItem({ href, children, className }: AppSidebarLinkItemProps) { if (!href) return null; return ( {children} ); } function AppSidebarButtonItem({ children, onClick, disabled = false, className }: AppSidebarButtonItemProps) { return ( ); } // ============================================================================ // MAIN COMPONENT // ============================================================================ export type AppSidebarItemComponent = React.FC & { Label: React.FC; Icon: React.FC; Link: React.FC; Button: React.FC; }; function AppSidebarItem({ variant = "link", item }: AppSidebarItemProps) { if (!item) return null; const { icon, isActive, label, href, onClick, disabled, showLabel = true } = item; const commonItems = ( <> {showLabel && } ); if (variant === "link") { return {commonItems}; } return ( {commonItems} ); } // ============================================================================ // COMPOUND COMPONENT ASSIGNMENT // ============================================================================ AppSidebarItem.Label = AppSidebarItemLabel; AppSidebarItem.Icon = AppSidebarItemIcon; AppSidebarItem.Link = AppSidebarLinkItem; AppSidebarItem.Button = AppSidebarButtonItem; export { AppSidebarItem }; export type { AppSidebarItemData, AppSidebarItemProps };