From 1bb27791da0c61b7528fe7fbf754a828178cf03b Mon Sep 17 00:00:00 2001 From: Renatho De Carli Rosa Date: Thu, 17 Oct 2024 00:33:08 -0300 Subject: [PATCH] Fix the navigation issue inside cover blocks (#66093) Co-authored-by: renatho Co-authored-by: kevin940726 Co-authored-by: aaronrobertshaw Co-authored-by: getdave Co-authored-by: andrewserong --- packages/block-library/src/cover/style.scss | 6 ++ .../src/navigation/edit/index.js | 33 ++++++++- test/e2e/specs/editor/blocks/cover.spec.js | 71 +++++++++++++++++++ 3 files changed, 107 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/cover/style.scss b/packages/block-library/src/cover/style.scss index 41b3acf1833fc0..b2c1fe88440235 100644 --- a/packages/block-library/src/cover/style.scss +++ b/packages/block-library/src/cover/style.scss @@ -100,6 +100,12 @@ color: inherit; // Reset the fixed LTR direction at the root of the block in RTL languages. /*rtl:raw: direction: rtl; */ + + // Reset the z-index to auto when the body has a modal open. So when the + // modal is inside the cover, it doesn't create a stacking context. + @at-root .has-modal-open & { + z-index: auto; + } } // Position: Top diff --git a/packages/block-library/src/navigation/edit/index.js b/packages/block-library/src/navigation/edit/index.js index ae7dd60bd0c5ba..d961f0d8fc93b9 100644 --- a/packages/block-library/src/navigation/edit/index.js +++ b/packages/block-library/src/navigation/edit/index.js @@ -73,6 +73,33 @@ import AccessibleDescription from './accessible-description'; import AccessibleMenuDescription from './accessible-menu-description'; import { unlock } from '../../lock-unlock'; +function useResponsiveMenu( navRef ) { + const [ isResponsiveMenuOpen, setResponsiveMenuVisibility ] = + useState( false ); + + useEffect( () => { + if ( ! navRef.current ) { + return; + } + + const htmlElement = navRef.current.ownerDocument.documentElement; + + // Add a `has-modal-open` class to the when the responsive + // menu is open. This reproduces the same behavior of the frontend. + if ( isResponsiveMenuOpen ) { + htmlElement.classList.add( 'has-modal-open' ); + } else { + htmlElement.classList.remove( 'has-modal-open' ); + } + + return () => { + htmlElement?.classList.remove( 'has-modal-open' ); + }; + }, [ navRef, isResponsiveMenuOpen ] ); + + return [ isResponsiveMenuOpen, setResponsiveMenuVisibility ]; +} + function ColorTools( { textColor, setTextColor, @@ -284,8 +311,10 @@ function Navigation( { __unstableMarkNextChangeAsNotPersistent, } = useDispatch( blockEditorStore ); + const navRef = useRef(); + const [ isResponsiveMenuOpen, setResponsiveMenuVisibility ] = - useState( false ); + useResponsiveMenu( navRef ); const [ overlayMenuPreview, setOverlayMenuPreview ] = useState( false ); @@ -367,8 +396,6 @@ function Navigation( { __unstableMarkNextChangeAsNotPersistent, ] ); - const navRef = useRef(); - // The standard HTML5 tag for the block wrapper. const TagName = 'nav'; diff --git a/test/e2e/specs/editor/blocks/cover.spec.js b/test/e2e/specs/editor/blocks/cover.spec.js index cf3005c9eaa18f..a9a93caa4f4341 100644 --- a/test/e2e/specs/editor/blocks/cover.spec.js +++ b/test/e2e/specs/editor/blocks/cover.spec.js @@ -226,6 +226,77 @@ test.describe( 'Cover', () => { await expect( overlay ).toHaveCSS( 'background-color', 'rgb(0, 0, 0)' ); await expect( overlay ).toHaveCSS( 'opacity', '0.5' ); } ); + + test( 'other cover blocks are not over the navigation block when the menu is open', async ( { + editor, + page, + } ) => { + // Insert a Cover block + await editor.insertBlock( { name: 'core/cover' } ); + const coverBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Cover', + } ); + + // Choose a color swatch to transform the placeholder block into + // a functioning block. + await coverBlock + .getByRole( 'option', { + name: 'Color: Black', + } ) + .click(); + + // Insert a Navigation block inside the Cover block + await editor.selectBlocks( coverBlock ); + await coverBlock.getByRole( 'button', { name: 'Add block' } ).click(); + await page.keyboard.type( 'Navigation' ); + const blockResults = page.getByRole( 'listbox', { + name: 'Blocks', + } ); + const blockResultOptions = blockResults.getByRole( 'option' ); + await blockResultOptions.nth( 0 ).click(); + + // Insert a second Cover block. + await editor.insertBlock( { name: 'core/cover' } ); + const secondCoverBlock = editor.canvas + .getByRole( 'document', { + name: 'Block: Cover', + } ) + .last(); + + // Choose a color swatch to transform the placeholder block into + // a functioning block. + await secondCoverBlock + .getByRole( 'option', { + name: 'Color: Black', + } ) + .click(); + + // Set the viewport to a small screen and open menu. + await page.setViewportSize( { width: 375, height: 1000 } ); + const navigationBlock = editor.canvas.getByRole( 'document', { + name: 'Block: Navigation', + } ); + await editor.selectBlocks( navigationBlock ); + await editor.canvas + .getByRole( 'button', { name: 'Open menu' } ) + .click(); + + // Check if inner container of the second cover is clickable. + const secondInnerContainer = secondCoverBlock.locator( + '.wp-block-cover__inner-container' + ); + let isClickable; + try { + isClickable = await secondInnerContainer.click( { + trial: true, + timeout: 1000, // This test will always take 1 second to run. + } ); + } catch ( error ) { + isClickable = false; + } + + expect( isClickable ).toBe( false ); + } ); } ); class CoverBlockUtils {