49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
|
|
'use client'
|
||
|
|
|
||
|
|
import * as React from 'react'
|
||
|
|
import { ArrowDown } from 'lucide-react'
|
||
|
|
|
||
|
|
import { cn } from '@/lib/utils'
|
||
|
|
import { Button, type ButtonProps } from '@/components/ui/button'
|
||
|
|
|
||
|
|
export function ButtonScrollToBottom({ className, ...props }: ButtonProps) {
|
||
|
|
const [isAtBottom, setIsAtBottom] = React.useState(false)
|
||
|
|
|
||
|
|
React.useEffect(() => {
|
||
|
|
const handleScroll = () => {
|
||
|
|
setIsAtBottom(
|
||
|
|
window.innerHeight + window.scrollY > document.body.offsetHeight - 100
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
||
|
|
handleScroll()
|
||
|
|
|
||
|
|
return () => {
|
||
|
|
window.removeEventListener('scroll', handleScroll)
|
||
|
|
}
|
||
|
|
}, [])
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Button
|
||
|
|
variant="outline"
|
||
|
|
size="icon"
|
||
|
|
className={cn(
|
||
|
|
'absolute right-4 top-1 z-10 bg-background transition-opacity duration-300 sm:right-8 md:top-2',
|
||
|
|
isAtBottom ? 'opacity-0' : 'opacity-100',
|
||
|
|
className
|
||
|
|
)}
|
||
|
|
onClick={() =>
|
||
|
|
window.scrollTo({
|
||
|
|
top: document.body.offsetHeight,
|
||
|
|
behavior: 'smooth'
|
||
|
|
})
|
||
|
|
}
|
||
|
|
{...props}
|
||
|
|
>
|
||
|
|
<ArrowDown className="h-4 w-4" />
|
||
|
|
<span className="sr-only">Scroll to bottom</span>
|
||
|
|
</Button>
|
||
|
|
)
|
||
|
|
}
|