Skip to content

Instantly share code, notes, and snippets.

@smashercosmo
Last active September 22, 2023 15:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smashercosmo/fbc0169030c6a7a713443a9cf06d992e to your computer and use it in GitHub Desktop.
Save smashercosmo/fbc0169030c6a7a713443a9cf06d992e to your computer and use it in GitHub Desktop.
Table.tsx
import React from 'react'
import cx from 'classnames'
import { useTableScrollObserver } from './useTableScrollObserver'
import styles from './Table.css'
type TableProps = {
children: React.ReactNode
}
export const Table = (props: TableProps) => {
const { children } = props
const {
rootRef,
leftBorderRef,
rightBorderRef,
hasScroll,
} = useTableScrollObserver()
const classes = cx(styles.root, {
[styles.hasScroll]: hasScroll,
})
return (
<div className={classes} ref={rootRef}>
<div ref={leftBorderRef} />
<table className={styles.table}>{children}</table>
<div ref={rightBorderRef} />
</div>
)
}
import { useEffect, useRef, useState } from 'react'
export function useTableScrollObserver() {
const rootRef = useRef(null)
const leftBorderRef = useRef(null)
const rightBorderRef = useRef(null)
const [hasScroll, setHasScroll] = useState(false)
const targets: React.RefObject<HTMLElement>[] = [
leftBorderRef,
rightBorderRef,
]
useEffect(
() => {
if (!rootRef.current) {
return undefined
}
const observer = new IntersectionObserver(
entries => {
const { isIntersecting } = entries[0]
const rootNode = rootRef.current
if (!isIntersecting && !hasScroll) {
setHasScroll(true)
} else if (
isIntersecting &&
hasScroll &&
rootNode &&
(rootNode as HTMLElement).clientWidth ===
(rootNode as HTMLElement).scrollWidth
) {
setHasScroll(false)
}
},
{
root: rootRef.current,
},
)
targets.forEach(target => {
if (target.current) {
observer.observe(target.current)
}
})
return () => {
targets.forEach(target => {
if (target.current) {
observer.unobserve(target.current)
}
})
}
},
[hasScroll],
)
return {
rootRef,
leftBorderRef,
rightBorderRef,
hasScroll,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment