Commit f0605d156df for woocommerce
commit f0605d156df136b3c87a4feffa9f2f9e2c063aab
Author: Yuliyan Slavchev <yuliyan.slavchev@gmail.com>
Date: Wed Aug 26 12:46:16 2026 +0300
Fix email editor back button detection on WordPress 7.1 (#68017)
diff --git a/packages/js/email-editor/changelog/fix-back-button-wp71-detection b/packages/js/email-editor/changelog/fix-back-button-wp71-detection
new file mode 100644
index 00000000000..47fe336fb8b
--- /dev/null
+++ b/packages/js/email-editor/changelog/fix-back-button-wp71-detection
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Render the compact back button on WordPress 7.1 again, where the header sizes the back button column by its content
diff --git a/packages/js/email-editor/src/components/header/back-button-content.tsx b/packages/js/email-editor/src/components/header/back-button-content.tsx
index 97ea14ae61c..d43fc3b0068 100644
--- a/packages/js/email-editor/src/components/header/back-button-content.tsx
+++ b/packages/js/email-editor/src/components/header/back-button-content.tsx
@@ -21,10 +21,8 @@ import { BackButton } from '../../private-apis';
import { recordEvent } from '../../events';
import { storeName } from '../../store';
-// The WordPress 7.1+ header reserves a compact 32px slot for the back button
-// and renders it as a plain chevron; older versions reserve a 64px slot filled
-// with a fullscreen-style logo button. The slot width is what our button must
-// fit into, so detect it instead of the WordPress version.
+// We measure the header column while it is still empty. WordPress 7.1 lets it
+// shrink to 0px there, while older versions always keep it 64px wide.
const COMPACT_SLOT_MAX_WIDTH = 48;
const toggleHomeIconVariants = {
@@ -166,9 +164,10 @@ const DefaultBackButtonContent = () => {
const slot = measureRef.current?.closest< HTMLElement >(
'.editor-header__back-button'
);
- const slotWidth = slot?.getBoundingClientRect().width ?? 0;
+ const reservedWidth = slot?.getBoundingClientRect().width;
setIsCompactSlot(
- slotWidth > 0 && slotWidth <= COMPACT_SLOT_MAX_WIDTH
+ reservedWidth !== undefined &&
+ reservedWidth <= COMPACT_SLOT_MAX_WIDTH
);
}, [] );
diff --git a/packages/js/email-editor/src/components/header/test/back-button-content.spec.tsx b/packages/js/email-editor/src/components/header/test/back-button-content.spec.tsx
index 16ccbabedd8..8419e220596 100644
--- a/packages/js/email-editor/src/components/header/test/back-button-content.spec.tsx
+++ b/packages/js/email-editor/src/components/header/test/back-button-content.spec.tsx
@@ -49,13 +49,25 @@ const mockUrls = {
send: 'https://example.com/send',
};
-// Renders the component inside the editor header's back button slot with the
-// given width. jsdom has no layout, so getBoundingClientRect is stubbed.
-const renderInSlot = ( slotWidth: number ) => {
+// jsdom does not do layout, so we fake the slot width the way each WordPress
+// version sizes that column.
+type SizeSlot = ( slot: HTMLElement ) => number;
+
+const fixedColumn: SizeSlot = () => 64;
+
+const contentSizedColumn: SizeSlot = ( slot ) =>
+ slot.querySelector( 'button' ) ? 74 : 0;
+
+const renderInSlot = ( sizeSlot: SizeSlot ) => {
jest.spyOn(
HTMLElement.prototype,
'getBoundingClientRect'
- ).mockReturnValue( { width: slotWidth } as DOMRect );
+ ).mockImplementation( function ( this: HTMLElement ) {
+ const width = this.classList.contains( 'editor-header__back-button' )
+ ? sizeSlot( this )
+ : 0;
+ return { width } as DOMRect;
+ } );
return render(
<div className="editor-header__back-button">
@@ -114,8 +126,8 @@ describe( 'BackButtonContent', () => {
expect( button.onclick ).not.toBeNull();
} );
- it( 'should render the fullscreen-style button in a wide slot (WordPress ≤ 7.0 header)', () => {
- const { container } = renderInSlot( 64 );
+ it( 'should render the fullscreen-style button in a fixed 64px slot (WordPress ≤ 7.0 header)', () => {
+ const { container } = renderInSlot( fixedColumn );
expect(
container.querySelector(
'.woocommerce-email-editor__view-mode-toggle'
@@ -123,8 +135,8 @@ describe( 'BackButtonContent', () => {
).toBeInTheDocument();
} );
- it( 'should render the compact button in a narrow slot (WordPress 7.1+ header)', () => {
- const { container, getByRole } = renderInSlot( 32 );
+ it( 'should render the compact button in a content-sized slot (WordPress 7.1+ header)', () => {
+ const { container, getByRole } = renderInSlot( contentSizedColumn );
expect(
container.querySelector(
'.woocommerce-email-editor__view-mode-toggle'
@@ -135,14 +147,23 @@ describe( 'BackButtonContent', () => {
).toHaveAttribute( 'data-icon', 'chevronLeft' );
} );
- it( 'should render the right chevron in a narrow slot in RTL', () => {
+ it( 'should render the right chevron in a content-sized slot in RTL', () => {
( isRTL as jest.Mock ).mockReturnValueOnce( true );
- const { getByRole } = renderInSlot( 32 );
+ const { getByRole } = renderInSlot( contentSizedColumn );
expect(
getByRole( 'button', { name: 'Close editor' } )
).toHaveAttribute( 'data-icon', 'chevronRight' );
} );
+ it( 'should fall back to the fullscreen-style button when there is no header slot', () => {
+ const { container } = render( <BackButtonContent /> );
+ expect(
+ container.querySelector(
+ '.woocommerce-email-editor__view-mode-toggle'
+ )
+ ).toBeInTheDocument();
+ } );
+
it( 'should apply woocommerce_email_editor_close_content filter to render custom component', () => {
// Mock the filter to return a custom component
const CustomComponent = () => (