"use client" import React, { ComponentProps, ComponentRef, forwardRef, useContext, useState, } from "react" import { tv } from "tailwind-variants" import { classNames } from "../../utils" import { isInteractiveElement } from "../../utils/element" import { Collapsible, CollapsibleProps } from "../Collapsible" import { Flex } from "../Flex" import { FlexColumn } from "../FlexColumn" import { Item, ItemProps } from "../Item" import { Separator } from "../Separator" import { SidebarContext } from "./SidebarContext" import { SidebarOpen } from "./SidebarOpen" type SidebarItemProps = { active?: boolean renderItem?: React.ComponentType size?: "sm" | "md" } & ItemProps const sidebarItemVariants = tv({ base: "flex w-full flex-nowrap items-center gap-2 rounded-md bg-transparent p-2", variants: { interactive: { true: "text-text-secondary transition-colors duration-200 ease-out-quint hover:bg-bg-additional-2 hover:text-text-primary", }, active: { true: "bg-bg-additional-2 text-text-primary [&[data-state=open]]:text-text-primary", }, size: { sm: "h-7 px-2 py-1", md: "h-9", }, }, }) const SidebarItemBase = forwardRef, SidebarItemProps>( function SidebarItem( { active, children, renderItem, className, interactive, onClick, size = "md", ...rest }, ref, ) { const { setDisableExpand } = useContext(SidebarContext) const Comp = renderItem ?? Item const isInteractive = interactive ?? isInteractiveElement({ ...rest, onClick }) return ( { onClick?.(e) setDisableExpand(true) }} {...rest} > {children} ) }, ) type SidebarCollapsibleItemProps = CollapsibleProps & { active?: boolean } export const SidebarCollapsibleItem = forwardRef< ComponentRef, SidebarCollapsibleItemProps >(function SidebarCollapsibleItem( { children, className, active, content, toggleClosedDirection = "right", overrides, onOpenChange, ...rest }, ref, ) { const [open, setOpen] = useState(rest.open) const { disableExpand, setDisableExpand } = useContext(SidebarContext) return ( {content} } overrides={{ ...overrides, Icon: { className: classNames("order-3"), ...overrides?.Icon, }, }} ref={ref} toggleClosedDirection={toggleClosedDirection} onClick={e => { if (disableExpand) { setDisableExpand(false) if (open) { e.preventDefault() } } }} onOpenChange={newOpen => { setOpen(newOpen) onOpenChange?.(newOpen) }} > {/* div prevents Collapsible's selector rotating Item avatar */}
{children}
) }) export const SidebarAvatar = ({ className, ...rest }: ComponentProps) => { return ( ) } export const SidebarItemTitle = ({ children, className, size = "md", }: { children: React.ReactNode className?: string size?: "sm" | "md" }) => { return ( {children} ) } export const SidebarItem = Object.assign(SidebarItemBase, { Avatar: SidebarAvatar, Title: SidebarItemTitle, })