SidebarItem.tsx raw

   1  import { Button, ButtonProps } from '@/components/ui/button'
   2  import { useKeyboardNavigable } from '@/hooks/useKeyboardNavigable'
   3  import { cn } from '@/lib/utils'
   4  import { forwardRef, useCallback, useRef } from 'react'
   5  import { useTranslation } from 'react-i18next'
   6  
   7  const SidebarItem = forwardRef<
   8    HTMLButtonElement,
   9    ButtonProps & {
  10      title: string
  11      collapse: boolean
  12      description?: string
  13      active?: boolean
  14      navIndex?: number
  15    }
  16  >(({ children, title, description, className, active, collapse, navIndex, onClick, ...props }, _ref) => {
  17    const { t } = useTranslation()
  18    const buttonRef = useRef<HTMLButtonElement>(null)
  19  
  20    const handleActivate = useCallback(() => {
  21      buttonRef.current?.click()
  22    }, [])
  23  
  24    const { ref: navRef, isSelected } = useKeyboardNavigable(0, navIndex ?? 0, {
  25      meta: { type: 'sidebar', onActivate: handleActivate }
  26    })
  27  
  28    return (
  29      <div ref={navRef}>
  30        <Button
  31          className={cn(
  32            'flex shadow-none items-center transition-colors duration-500 bg-transparent m-0 rounded-lg gap-4 text-lg font-semibold',
  33            collapse
  34              ? 'w-12 h-12 p-3 [&_svg]:size-full'
  35              : 'justify-start w-full h-auto py-2 px-3 [&_svg]:size-5',
  36            active && 'text-primary hover:text-primary bg-primary/10 hover:bg-primary/10',
  37            isSelected && 'ring-2 ring-primary ring-offset-2 ring-offset-background',
  38            className
  39          )}
  40          variant="ghost"
  41          title={t(title)}
  42          ref={buttonRef}
  43          onClick={onClick}
  44          {...props}
  45        >
  46          {children}
  47          {!collapse && <div>{t(description ?? title)}</div>}
  48        </Button>
  49      </div>
  50    )
  51  })
  52  SidebarItem.displayName = 'SidebarItem'
  53  export default SidebarItem
  54