diff --git a/wp-modules/app/js/src/components/PatternPreview/index.tsx b/wp-modules/app/js/src/components/PatternPreview/index.tsx index 016895e31..93e50c595 100644 --- a/wp-modules/app/js/src/components/PatternPreview/index.tsx +++ b/wp-modules/app/js/src/components/PatternPreview/index.tsx @@ -1,5 +1,5 @@ // WP dependencies -import { useState, useRef, useEffect } from '@wordpress/element'; +import { useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; // External dependencies @@ -21,20 +21,13 @@ export default function PatternPreview( { url, viewportWidth, }: PatternPreviewProps ) { - const [ previewContainerSize, setPreviewContainerSize ] = - useState< BoundingClientRect >(); const previewContainer = useRef< HTMLDivElement | null >( null ); const { lazyHasIntersected } = useLazyRender( previewContainer, { threshold: [ 0.3, 0.6, 1.0 ], } ); - useEffect( () => { - if ( previewContainer?.current ) { - setPreviewContainerSize( - previewContainer?.current?.getBoundingClientRect() - ); - } - }, [ previewContainer ] ); + const previewContainerSize: BoundingClientRect | undefined = + previewContainer?.current?.getBoundingClientRect(); const scale = previewContainerSize ? previewContainerSize?.width / viewportWidth diff --git a/wp-modules/app/js/src/components/Patterns/PatternGrid.tsx b/wp-modules/app/js/src/components/Patterns/PatternGrid.tsx index 8e37a4f27..c2697c193 100644 --- a/wp-modules/app/js/src/components/Patterns/PatternGrid.tsx +++ b/wp-modules/app/js/src/components/Patterns/PatternGrid.tsx @@ -7,6 +7,9 @@ import loadable from '@loadable/component'; // Globals import { patternManager } from '../../globals'; +// Hooks +import useWindowResize from '../../hooks/useWindowResize'; + // Components const PatternPreview: PatternPreviewType = loadable( async () => import( '../PatternPreview' ) @@ -26,6 +29,10 @@ type Props = { /** Render the patterns in a grid, or a message if no patterns are found. */ export default function PatternGrid( { themePatterns }: Props ) { + // If the window is resized, trigger a fresh render of the grid. + // Helps ensure PatternPreview iFrames are the right size. + useWindowResize(); + return ( <> { ! Object.entries( themePatterns ?? {} ).length ? ( diff --git a/wp-modules/app/js/src/hooks/useWindowResize.ts b/wp-modules/app/js/src/hooks/useWindowResize.ts new file mode 100644 index 000000000..a97079217 --- /dev/null +++ b/wp-modules/app/js/src/hooks/useWindowResize.ts @@ -0,0 +1,16 @@ +import { useLayoutEffect, useState } from '@wordpress/element'; + +/** Rerender the calling component when the window is resized. */ +export default function useWindowResize() { + const [ , setWindowSize ] = useState( [ 0, 0 ] ); + + useLayoutEffect( () => { + function updateSizeAndRerender() { + setWindowSize( [ window.innerWidth, window.innerHeight ] ); + } + + window.addEventListener( 'resize', updateSizeAndRerender ); + return () => + window.removeEventListener( 'resize', updateSizeAndRerender ); + }, [] ); +}