From 13df7098a483bfe874799f835a747716c5459210 Mon Sep 17 00:00:00 2001 From: xiejay97 Date: Thu, 9 Mar 2023 15:43:23 +0800 Subject: [PATCH] fix(ui): fix `ResizeObserver` miss borderBoxSize with some browsers --- packages/hooks/src/useResize.ts | 35 +++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/hooks/src/useResize.ts b/packages/hooks/src/useResize.ts index 3d79d9af..92279c0c 100644 --- a/packages/hooks/src/useResize.ts +++ b/packages/hooks/src/useResize.ts @@ -4,25 +4,40 @@ import { flushSync } from 'react-dom'; export function useResize(target: React.RefObject, cb?: ResizeObserverCallback, disabled = false, skipEmpty = true): void { const dataRef = useRef<{ - prevBorderBoxSize?: ResizeObserverSize; + prevContentRect?: { width: number; height: number }; }>({}); if (disabled) { - dataRef.current.prevBorderBoxSize = undefined; + dataRef.current.prevContentRect = undefined; } useEffect(() => { if (target.current && !disabled) { const observer = new ResizeObserver((entries, observer) => { - if ( - !isUndefined(dataRef.current.prevBorderBoxSize) && - !(skipEmpty && entries[0].borderBoxSize[0].blockSize === 0 && entries[0].borderBoxSize[0].inlineSize === 0) && - (dataRef.current.prevBorderBoxSize.blockSize !== entries[0].borderBoxSize[0].blockSize || - dataRef.current.prevBorderBoxSize.inlineSize !== entries[0].borderBoxSize[0].inlineSize) - ) { - flushSync(() => cb?.(entries, observer)); + let entry = entries[0]; + + if ('borderBoxSize' in entry) { + if ( + !isUndefined(dataRef.current.prevContentRect) && + !(skipEmpty && entry.borderBoxSize[0].blockSize === 0 && entry.borderBoxSize[0].inlineSize === 0) && + (dataRef.current.prevContentRect.width !== entry.borderBoxSize[0].inlineSize || + dataRef.current.prevContentRect.height !== entry.borderBoxSize[0].blockSize) + ) { + flushSync(() => cb?.(entries, observer)); + } + dataRef.current.prevContentRect = { width: entry.borderBoxSize[0].inlineSize, height: entry.borderBoxSize[0].blockSize }; + } else { + entry = entries[0]; + if ( + !isUndefined(dataRef.current.prevContentRect) && + !(skipEmpty && entry.contentRect.width === 0 && entry.contentRect.height === 0) && + (dataRef.current.prevContentRect.width !== entry.contentRect.width || + dataRef.current.prevContentRect.height !== entry.contentRect.height) + ) { + flushSync(() => cb?.(entries, observer)); + } + dataRef.current.prevContentRect = { width: entry.contentRect.width, height: entry.contentRect.height }; } - dataRef.current.prevBorderBoxSize = entries[0].borderBoxSize[0]; }); observer.observe(target.current); return () => {