header.tsx 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { useEffect, useState } from 'react'
  2. import { cn } from '@/lib/utils'
  3. import { Separator } from '@/components/ui/separator'
  4. import { SidebarTrigger } from '@/components/ui/sidebar'
  5. type HeaderProps = React.HTMLAttributes<HTMLElement> & {
  6. fixed?: boolean
  7. ref?: React.Ref<HTMLElement>
  8. }
  9. export function Header({ className, fixed, children, ...props }: HeaderProps) {
  10. const [offset, setOffset] = useState(0)
  11. useEffect(() => {
  12. const onScroll = () => {
  13. setOffset(document.body.scrollTop || document.documentElement.scrollTop)
  14. }
  15. // Add scroll listener to the body
  16. document.addEventListener('scroll', onScroll, { passive: true })
  17. // Clean up the event listener on unmount
  18. return () => document.removeEventListener('scroll', onScroll)
  19. }, [])
  20. return (
  21. <header
  22. className={cn(
  23. 'z-50 h-16',
  24. fixed && 'header-fixed peer/header sticky top-0 w-[inherit]',
  25. offset > 10 && fixed ? 'shadow' : 'shadow-none',
  26. className
  27. )}
  28. {...props}
  29. >
  30. <div
  31. className={cn(
  32. 'relative flex h-full items-center gap-3 p-4 sm:gap-4',
  33. offset > 10 &&
  34. fixed &&
  35. 'after:absolute after:inset-0 after:-z-10 after:bg-background/20 after:backdrop-blur-lg'
  36. )}
  37. >
  38. <SidebarTrigger variant='outline' className='max-md:scale-125' />
  39. <Separator orientation='vertical' className='h-6' />
  40. {children}
  41. </div>
  42. </header>
  43. )
  44. }