add some comments to useIsOverflowing

This commit is contained in:
EthanHealy01 2025-07-24 21:21:46 +01:00
parent 227ed2de08
commit 8d96d0d31a

View File

@ -1,31 +1,69 @@
import * as React from 'react'; import * as React from 'react';
/**
Hook to detect if an element's content overflows its container
Parameters:
- ref: React ref to the element to monitor
- callback: Optional callback function called when overflow state changes
Returns: boolean | undefined - true if overflowing, false if not, undefined before first check
Usage example:
useEffect(() => {
if (isOverflow) {
// Do something
}
}, [isOverflow]);
const scrollableRef = useRef<HTMLDivElement>(null);
const isOverflow = useIsOverflow(scrollableRef);
Fallback example (for browsers without ResizeObserver):
return (
<div ref={scrollableRef} className="h-64 overflow-y-auto">
{Content that might overflow}
</div>
);
*/
export const useIsOverflow = (ref: React.RefObject<HTMLElement | null>, callback?: (isOverflow: boolean) => void) => { export const useIsOverflow = (ref: React.RefObject<HTMLElement | null>, callback?: (isOverflow: boolean) => void) => {
// State to track overflow status
const [isOverflow, setIsOverflow] = React.useState<boolean | undefined>(undefined); const [isOverflow, setIsOverflow] = React.useState<boolean | undefined>(undefined);
React.useLayoutEffect(() => { React.useLayoutEffect(() => {
const { current } = ref; const { current } = ref;
// Function to check if element is overflowing
const trigger = () => { const trigger = () => {
if (!current) return; if (!current) return;
// Compare scroll height (total content height) vs client height (visible height)
const hasOverflow = current.scrollHeight > current.clientHeight; const hasOverflow = current.scrollHeight > current.clientHeight;
setIsOverflow(hasOverflow); setIsOverflow(hasOverflow);
// Call optional callback with overflow state
if (callback) callback(hasOverflow); if (callback) callback(hasOverflow);
}; };
if (current) { if (current) {
// Use ResizeObserver for modern browsers (real-time detection)
if ('ResizeObserver' in window) { if ('ResizeObserver' in window) {
const resizeObserver = new ResizeObserver(trigger); const resizeObserver = new ResizeObserver(trigger);
resizeObserver.observe(current); resizeObserver.observe(current);
// Cleanup function // Cleanup function to disconnect observer
return () => { return () => {
resizeObserver.disconnect(); resizeObserver.disconnect();
}; };
} }
// Fallback for browsers without ResizeObserver support
// Add a small delay to ensure the element is fully rendered // Add a small delay to ensure the element is fully rendered
setTimeout(trigger, 0); setTimeout(trigger, 0);
} }