notification-scrolled-to.tsx 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import Notification, {
  2. NotificationProps,
  3. } from '@/shared/components/notification'
  4. import { useEffect } from 'react'
  5. function elementIsInView(el: HTMLElement) {
  6. const scroll = window.scrollY
  7. const boundsTop = el.getBoundingClientRect().top + scroll
  8. const viewport = {
  9. top: scroll,
  10. bottom: scroll + window.innerHeight,
  11. }
  12. const bounds = {
  13. top: boundsTop,
  14. bottom: boundsTop + el.clientHeight,
  15. }
  16. return (
  17. (bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom) ||
  18. (bounds.top <= viewport.bottom && bounds.top >= viewport.top)
  19. )
  20. }
  21. function NotificationScrolledTo({ ...props }: NotificationProps) {
  22. useEffect(() => {
  23. if (props.id) {
  24. const alert = document.getElementById(props.id)
  25. if (alert && !elementIsInView(alert)) {
  26. alert.scrollIntoView({ behavior: 'smooth' })
  27. }
  28. }
  29. }, [props])
  30. const notificationProps = { ...props }
  31. if (!notificationProps.className) {
  32. notificationProps.className = ''
  33. }
  34. notificationProps.className = `${notificationProps.className} notification-with-scroll-margin`
  35. return (
  36. <div className="notification-list">
  37. <Notification {...notificationProps} />
  38. </div>
  39. )
  40. }
  41. export default NotificationScrolledTo