Stirling-PDF/frontend/src/core/hooks/useIsOverflowing.ts
James Brunton d2b38ef4b8
Restructure frontend code to allow for extensions (#4721)
# Description of Changes
Move frontend code into `core` folder and add infrastructure for
`proprietary` folder to include premium, non-OSS features
2025-10-28 10:29:36 +00:00

73 lines
2.1 KiB
TypeScript

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 = useIsOverflowing(scrollableRef);
Fallback example (for browsers without ResizeObserver):
return (
<div ref={scrollableRef} className="h-64 overflow-y-auto">
{Content that might overflow}
</div>
);
*/
export const useIsOverflowing = (ref: React.RefObject<HTMLElement | null>, callback?: (isOverflow: boolean) => void) => {
// State to track overflow status
const [isOverflow, setIsOverflow] = React.useState<boolean | undefined>(undefined);
React.useLayoutEffect(() => {
const { current } = ref;
// Function to check if element is overflowing
const trigger = () => {
if (!current) return;
// Compare scroll height (total content height) vs client height (visible height)
const hasOverflow = current.scrollHeight > current.clientHeight;
setIsOverflow(hasOverflow);
// Call optional callback with overflow state
if (callback) callback(hasOverflow);
};
if (current) {
// Use ResizeObserver for modern browsers (real-time detection)
if ('ResizeObserver' in window) {
const resizeObserver = new ResizeObserver(trigger);
resizeObserver.observe(current);
// Cleanup function to disconnect observer
return () => {
resizeObserver.disconnect();
};
}
// Fallback for browsers without ResizeObserver support
// Add a small delay to ensure the element is fully rendered
setTimeout(trigger, 0);
}
}, [callback, ref]);
return isOverflow;
};