From 5ba5769339aee49f07b5942adfd786e324b0fe0d Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 16 Sep 2023 20:43:16 +0200 Subject: [PATCH] add one more test case --- .../TextareaAutosize.test.tsx | 37 +++++++++++++++++++ .../src/TextareaAutosize/TextareaAutosize.tsx | 16 +++++++- packages/mui-lab/src/Masonry/Masonry.js | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx index 8b4d2777919e17..703ee0bbc1fe6b 100644 --- a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx +++ b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx @@ -103,6 +103,43 @@ describe('', () => { }); }); + // For https://github.com/mui/material-ui/pull/37135 + it('should update height without delay', async function test() { + if (/jsdom/.test(window.navigator.userAgent)) { + // It depends on ResizeObserver + this.skip(); + } + + function App() { + const ref = React.useRef(null); + return ( +
+ +
+ +
+
+ ); + } + const { container } = render(); + const input = container.querySelector('textarea')!; + const button = screen.getByRole('button'); + expect(input.style).to.have.property('height', '30px'); + fireEvent.click(button); + await sleep(10); + expect(input.style).to.have.property('height', '15px'); + }); + describe('layout', () => { const getComputedStyleStub = new Map>(); function setLayout( diff --git a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx index 0d8606914db45f..9f582765f6e932 100644 --- a/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx +++ b/packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx @@ -188,6 +188,17 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize( renders.current = 0; syncHeightWithFlushSync(); }; + // Workaround a "ResizeObserver loop completed with undelivered notifications" error + // in test. + // Note that we might need to use this logic in production per https://github.com/WICG/resize-observer/issues/38 + // Also see https://github.com/mui/mui-x/issues/8733 + let rAF: any; + const rAFHandleResize = () => { + cancelAnimationFrame(rAF); + rAF = requestAnimationFrame(() => { + handleResize(); + }); + }; const debounceHandleResize = debounce(handleResize); const input = inputRef.current!; const containerWindow = ownerWindow(input); @@ -197,12 +208,15 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize( let resizeObserver: ResizeObserver; if (typeof ResizeObserver !== 'undefined') { - resizeObserver = new ResizeObserver(handleResize); + resizeObserver = new ResizeObserver( + process.env.NODE_ENV === 'test' ? rAFHandleResize : handleResize, + ); resizeObserver.observe(input); } return () => { debounceHandleResize.clear(); + cancelAnimationFrame(rAF); containerWindow.removeEventListener('resize', debounceHandleResize); if (resizeObserver) { resizeObserver.disconnect(); diff --git a/packages/mui-lab/src/Masonry/Masonry.js b/packages/mui-lab/src/Masonry/Masonry.js index b29c236c3f4cfe..c48e32772f9170 100644 --- a/packages/mui-lab/src/Masonry/Masonry.js +++ b/packages/mui-lab/src/Masonry/Masonry.js @@ -287,7 +287,7 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) { const resizeObserver = new ResizeObserver(() => { // see https://github.com/mui/material-ui/issues/36909 - animationFrame = window.requestAnimationFrame(handleResize); + animationFrame = requestAnimationFrame(handleResize); }); if (masonryRef.current) {