Commit e630b68b21 for woocommerce

commit e630b68b2103fd31ae5549dd677acb15378074c5
Author: Rostislav Wolný <1082140+costasovo@users.noreply.github.com>
Date:   Thu Dec 11 13:56:05 2025 +0100

    Email editor Gutenberg 22/WP 6.9 compatibility fixes (#61964)

    * Add custom hook for generating styles and re-enable use-email-css hook

    WOOPRD-1278

    * Update admin client build to bundle the @wordpress/global-styles-engine

    The package is exposed via wp global variable so we need to bundle it
    WOOPRD-1278

    * Cleanup private APIs exports

    * Update types for email theme

    * Add overrides deactivation

    This is needed when the editor is used in an app that allows
    editing emails and also regular posts
    WOOPRD-1278

    * Fix appearance of styles panel

    WOOPRD-1278

    * Fix back button styles

    The header height changed from 60 to 64px.
    This fix optimizes for ideal appearance in WP6.9+
    For WP 6.8 there is still small misalignment in hover state on the button.
    WOOPRD-1278

    * Add changelog

    * Fix linter warnings

    * Remove outdated comment

    * Remove optional getBlockStyles from global styles hook

    * Update email styles directly via editor settings property

    Gutenberg 22+ supports passing styles via editor settings.
    This approach is similar to what we did previously and will
    allow us to get rid of the core editor store overrides, which might
    be problematic because there is no 100% reliable mechanism for disabling
    them.

    * Remove Editor store overrides

    * Update changelog

    * Add a note about bundling the global styles package

    * Address nitpicks, comments and fix types for global styles post

diff --git a/packages/js/email-editor/README.md b/packages/js/email-editor/README.md
index e239cb726e..d7e1f5d9de 100644
--- a/packages/js/email-editor/README.md
+++ b/packages/js/email-editor/README.md
@@ -74,6 +74,26 @@ To ensure the correct functionality of the Email Editor and its features, you mu
 The required minimum version of this package is stored in the assets directory.
 If your WordPress installation does not use the Gutenberg plugin or does not include the required version, replace the existing `@wordpress/rich-text` package with the one provided in the assets directory.

+#### Global Styles Engine
+
+The email editor depends on `@wordpress/global-styles-engine`, which is **not enqueued by WordPress core**. Unlike most `@wordpress/*` packages, this package is not available globally in WordPress environments and must be bundled.
+
+**Impact**: If your build configuration marks all `@wordpress/*` packages as externals (common in webpack configs), you will encounter runtime errors: `"Cannot find module '@wordpress/global-styles-engine'"`.
+
+**Solution**: Configure your webpack dependency extraction plugin to bundle this package instead of treating it as an external:
+
+```javascript
+new DependencyExtractionWebpackPlugin( {
+    requestToExternal( request ) {
+        if ( request === '@wordpress/global-styles-engine' ) {
+            // Return null to bundle this package instead of treating it as external
+            return null;
+        }
+        // ... handle other dependencies
+    }
+} )
+```
+
 ### Email Editor

 -   Bootstrapped in the plugin in the [email editor controller](https://github.com/mailpoet/mailpoet/blob/13bf305aeb29bbadd0695ee02a3735e62cc4f21f/mailpoet/lib/EmailEditor/Integrations/MailPoet/EmailEditor.php)
diff --git a/packages/js/email-editor/changelog/wooprd-1278-compatibility-with-gutenberg-220 b/packages/js/email-editor/changelog/wooprd-1278-compatibility-with-gutenberg-220
new file mode 100644
index 0000000000..9cb01e9fa3
--- /dev/null
+++ b/packages/js/email-editor/changelog/wooprd-1278-compatibility-with-gutenberg-220
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Compatibility update for Gutenberg 22.0. useEmailCss now returns styles correctly with Gutenberg 22.0+.
diff --git a/packages/js/email-editor/src/components/block-editor/editor.tsx b/packages/js/email-editor/src/components/block-editor/editor.tsx
index 9e9ac56d3f..31d20c11b8 100644
--- a/packages/js/email-editor/src/components/block-editor/editor.tsx
+++ b/packages/js/email-editor/src/components/block-editor/editor.tsx
@@ -109,12 +109,14 @@ export function InnerEditor( {
 					? 'post-only'
 					: 'template-locked',
 			supportsTemplateMode: true,
+			styles,
 		} ),
 		[
 			settings,
 			onNavigateToEntityRecord,
 			onNavigateToPreviousEntityRecord,
 			currentPost.postType,
+			styles,
 		]
 	);
 	const canRenderEditor =
@@ -145,8 +147,8 @@ export function InnerEditor( {
 					postType={ currentPost.postType }
 					settings={ editorSettings }
 					templateId={ template && template.id }
-					styles={ styles }
 					contentRef={ contentRef }
+					styles={ styles } // This is needed for BC for Gutenberg below v22
 				>
 					<AutosaveMonitor />
 					<LocalAutosaveMonitor />
diff --git a/packages/js/email-editor/src/components/header/style.scss b/packages/js/email-editor/src/components/header/style.scss
index bc8d184d41..b55df2fa5d 100644
--- a/packages/js/email-editor/src/components/header/style.scss
+++ b/packages/js/email-editor/src/components/header/style.scss
@@ -17,8 +17,6 @@
 	/* stylelint-enable */
 	top: 0;
 	left: 0;
-	height: 60px;
-	width: 60px;
 	z-index: 100;

 	.components-button {
@@ -54,8 +52,8 @@
 	position: absolute;
 	top: 0;
 	left: 0;
-	width: 60px;
-	height: 60px;
+	width: 64px;
+	height: 64px;
 	display: flex;
 	align-items: center;
 	justify-content: center;
diff --git a/packages/js/email-editor/src/components/styles-sidebar/style.scss b/packages/js/email-editor/src/components/styles-sidebar/style.scss
index b4102d703e..0f3e823345 100644
--- a/packages/js/email-editor/src/components/styles-sidebar/style.scss
+++ b/packages/js/email-editor/src/components/styles-sidebar/style.scss
@@ -8,6 +8,7 @@
 	.components-navigator-provider,
 	.components-navigator-screen {
 		height: 100%;
+		padding: 0;
 	}

 	.components-navigator-screen {
@@ -57,4 +58,9 @@
 	.interface-complementary-area-header__small {
 		display: none;
 	}
+
+	// Hide border around styles screen root.
+	.edit-site-global-styles-screen-root {
+		box-shadow: none;
+	}
 }
diff --git a/packages/js/email-editor/src/editor.tsx b/packages/js/email-editor/src/editor.tsx
index 6aa0aa49ae..3efc295aee 100644
--- a/packages/js/email-editor/src/editor.tsx
+++ b/packages/js/email-editor/src/editor.tsx
@@ -21,7 +21,7 @@ import '@wordpress/format-library'; // Enables text formatting capabilities
 import { getAllowedBlockNames, initBlocks } from './blocks';
 import { initializeLayout } from './layouts/flex-email';
 import { InnerEditor } from './components/block-editor';
-import { createStore, storeName, initStoreOverrides } from './store';
+import { createStore, storeName } from './store';
 import { initTextHooks } from './text-hooks';
 import {
 	initEventCollector,
@@ -95,7 +95,7 @@ function Editor( {
 	);
 }

-function onInit( config: EmailEditorConfig ) {
+function onInit() {
 	initEventCollector();
 	initStoreTracking();
 	initDomTracking();
@@ -104,7 +104,6 @@ function onInit( config: EmailEditorConfig ) {
 	initializeLayout();
 	initBlocks();
 	initTextHooks();
-	initStoreOverrides( config );
 }

 export function initialize( elementId: string ) {
@@ -128,7 +127,7 @@ export function initialize( elementId: string ) {
 		Editor
 	) as typeof Editor;

-	onInit( getEditorConfigFromWindow() );
+	onInit();

 	// Set configuration to store from window object for backward compatibility
 	const editorConfig = getEditorConfigFromWindow();
@@ -162,7 +161,7 @@ export function ExperimentalEmailEditor( {
 		const backupEditorSettings = select( editorStore ).getEditorSettings();
 		// Set configuration to store from window object for backward compatibility
 		const editorConfig = config || getEditorConfigFromWindow();
-		onInit( editorConfig );
+		onInit();

 		dispatch( storeName ).setEditorConfig( editorConfig );
 		setIsInitialized( true );
diff --git a/packages/js/email-editor/src/hooks/use-email-css.ts b/packages/js/email-editor/src/hooks/use-email-css.ts
index a3abc170d1..0848a7c5e5 100644
--- a/packages/js/email-editor/src/hooks/use-email-css.ts
+++ b/packages/js/email-editor/src/hooks/use-email-css.ts
@@ -11,10 +11,7 @@ import deepmerge from 'deepmerge';
  */
 import { EmailTheme, EmailBuiltStyles, storeName } from '../store';
 import { useUserTheme } from './use-user-theme';
-import {
-	useGlobalStylesOutputWithConfig,
-	areExternalStylesSupported,
-} from '../private-apis';
+import { useGlobalStylesOutputWithConfig } from './use-global-styles-output';
 import { unwrapCompressedPresetStyleVariable } from '../style-variables';

 // Empty array to avoid re-rendering the component when the array is empty
@@ -22,8 +19,8 @@ const EMPTY_ARRAY = [];

 export function useEmailCss() {
 	const { userTheme } = useUserTheme();
-	const { editorTheme, layout, deviceType, editorSettingsStyles } = useSelect(
-		( select ) => {
+	const { editorTheme, layout, deviceType, initialEditorSettingsStyles } =
+		useSelect( ( select ) => {
 			const {
 				getEditorSettings,
 				// @ts-expect-error getDeviceType is not in types.
@@ -32,17 +29,20 @@ export function useEmailCss() {

 			const editorSettings = getEditorSettings();

+			// Get initial styles from our email editor store to avoid circular dependency
+			// when we add our generated styles back to settings
+			const initialSettings =
+				select( storeName ).getInitialEditorSettings();
+
 			return {
 				editorTheme: select( storeName ).getTheme(),
 				// @ts-expect-error There are no types for the experimental features settings.
 				// eslint-disable-next-line no-underscore-dangle
 				layout: editorSettings?.__experimentalFeatures?.layout,
 				deviceType: getDeviceType(),
-				editorSettingsStyles: editorSettings?.styles,
+				initialEditorSettingsStyles: initialSettings?.styles,
 			};
-		},
-		[]
-	);
+		}, [] );

 	const mergedConfig = useMemo(
 		() =>
@@ -54,8 +54,6 @@ export function useEmailCss() {
 		[ editorTheme, userTheme ]
 	);

-	// In the Gutenberg version 22.0+ the useGlobalStylesOutputWithConfig hook is not available and we return empty array.
-	// We keep this for now to support WP 6.9 and lower.
 	const [ styles ] = useGlobalStylesOutputWithConfig( mergedConfig );

 	let rootContainerStyles = '';
@@ -64,7 +62,11 @@ export function useEmailCss() {
 			layout?.contentSize || '660px'
 		}; margin: 0 auto;box-sizing: border-box;max-width: 100%;`;
 	}
-	const padding = mergedConfig.styles?.spacing?.padding;
+	const padding = mergedConfig.styles?.spacing?.padding as {
+		left: string;
+		right: string;
+	};
+
 	if ( padding ) {
 		rootContainerStyles += `padding-left:${ unwrapCompressedPresetStyleVariable(
 			padding.left
@@ -75,17 +77,14 @@ export function useEmailCss() {
 	}

 	const finalStyles = useMemo( () => {
-		if ( ! areExternalStylesSupported ) {
-			return EMPTY_ARRAY;
-		}
 		return [
 			...( ( styles as EmailBuiltStyles[] ) ?? [] ),
 			{
 				css: `.is-root-container{ ${ rootContainerStyles } }`,
 			},
-			...( editorSettingsStyles ?? [] ),
+			...( initialEditorSettingsStyles ?? [] ),
 		];
-	}, [ styles, editorSettingsStyles, rootContainerStyles ] );
+	}, [ styles, initialEditorSettingsStyles, rootContainerStyles ] );

 	// eslint-disable-next-line @typescript-eslint/no-unsafe-return
 	return [ finalStyles || EMPTY_ARRAY ];
diff --git a/packages/js/email-editor/src/hooks/use-email-styles.ts b/packages/js/email-editor/src/hooks/use-email-styles.ts
index b0b8f4f8b9..75aabd7f31 100644
--- a/packages/js/email-editor/src/hooks/use-email-styles.ts
+++ b/packages/js/email-editor/src/hooks/use-email-styles.ts
@@ -125,7 +125,7 @@ function cleanupUserStyles( obj ) {
 			}

 			for ( const key in current ) {
-				if ( current.hasOwnProperty( key ) ) {
+				if ( Object.prototype.hasOwnProperty.call( current, key ) ) {
 					const cleanedValue = cleanObject( current[ key ] );
 					if (
 						cleanedValue === undefined ||
@@ -165,7 +165,7 @@ export const useEmailStyles = (): EmailStylesData => {
 		( newStyles ) => {
 			const newTheme = {
 				...userTheme,
-				styles: cleanupUserStyles( newStyles ),
+				styles: cleanupUserStyles( newStyles ) as EmailStyles,
 			};
 			updateUserTheme( newTheme );
 		},
diff --git a/packages/js/email-editor/src/hooks/use-global-styles-output.ts b/packages/js/email-editor/src/hooks/use-global-styles-output.ts
new file mode 100644
index 0000000000..d42508a3d9
--- /dev/null
+++ b/packages/js/email-editor/src/hooks/use-global-styles-output.ts
@@ -0,0 +1,29 @@
+/**
+ * External dependencies
+ */
+import {
+	generateGlobalStyles,
+	type GlobalStylesConfig,
+} from '@wordpress/global-styles-engine';
+import { useMemo } from '@wordpress/element';
+
+const EMPTY_OBJECT = {};
+const EMPTY_ARRAY = [];
+
+export const useGlobalStylesOutputWithConfig = (
+	mergedConfig: GlobalStylesConfig = {}
+) => {
+	return useMemo( () => {
+		if ( ! mergedConfig?.styles || ! mergedConfig?.settings ) {
+			return [ EMPTY_ARRAY, EMPTY_OBJECT ];
+		}
+		const blockTypes = [];
+		const styles = generateGlobalStyles( mergedConfig, blockTypes, {
+			hasBlockGapSupport: true,
+			hasFallbackGapSupport: false,
+			disableLayoutStyles: false,
+			disableRootPadding: false,
+		} );
+		return styles;
+	}, [ mergedConfig ] );
+};
diff --git a/packages/js/email-editor/src/hooks/use-user-theme.ts b/packages/js/email-editor/src/hooks/use-user-theme.ts
index b240bae1dc..665a519056 100644
--- a/packages/js/email-editor/src/hooks/use-user-theme.ts
+++ b/packages/js/email-editor/src/hooks/use-user-theme.ts
@@ -12,10 +12,7 @@ import { EmailTheme, storeName } from '../store';

 export function useUserTheme() {
 	const { globalStylePost } = useSelect( ( select ) => {
-		const post =
-			( select( storeName ).getGlobalEmailStylesPost() as EmailTheme & {
-				id: number;
-			} ) || null;
+		const post = select( storeName ).getGlobalEmailStylesPost() || null;
 		return {
 			globalStylePost: post,
 		};
diff --git a/packages/js/email-editor/src/private-apis/index.ts b/packages/js/email-editor/src/private-apis/index.ts
index b49cf47a30..d6f5667cb4 100644
--- a/packages/js/email-editor/src/private-apis/index.ts
+++ b/packages/js/email-editor/src/private-apis/index.ts
@@ -24,26 +24,12 @@ const { unlock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules(
  */
 const { ColorPanel: StylesColorPanel } = unlock( blockEditorPrivateApis );

-/**
- * The useGlobalStylesOutputWithConfig is used to generate the CSS for the email editor content from the style settings.
- */
-const {
-	useGlobalStylesOutputWithConfig: useGlobalStylesOutputWithConfigOriginal,
-} = unlock( blockEditorPrivateApis );
-
 /**
  * The Editor is the main component for the email editor.
  */
 const { Editor, FullscreenMode, ViewMoreMenuGroup, BackButton } =
 	unlock( editorPrivateApis );

-/**
- * Feature detection whether the active version of Gutenberg supports external styles being passed to Editor component.
- * useGlobalStylesOutputWithConfig function was removed with this change.
- */
-const areExternalStylesSupported =
-	useGlobalStylesOutputWithConfigOriginal !== undefined;
-
 /**
  * The registerEntityAction and unregisterEntityAction are used to register and unregister entity actions.
  * This is used in the move-to-trash.tsx file to modify the move to trash action.
@@ -53,18 +39,12 @@ const { registerEntityAction, unregisterEntityAction } = unlock(
 	dispatch( editorStore )
 );

-const useGlobalStylesOutputWithConfig = useGlobalStylesOutputWithConfigOriginal
-	? useGlobalStylesOutputWithConfigOriginal
-	: () => [ [], {} ];
-
 export {
 	StylesColorPanel,
-	useGlobalStylesOutputWithConfig,
 	Editor,
 	FullscreenMode,
 	ViewMoreMenuGroup,
 	BackButton,
 	registerEntityAction,
 	unregisterEntityAction,
-	areExternalStylesSupported,
 };
diff --git a/packages/js/email-editor/src/store/index.ts b/packages/js/email-editor/src/store/index.ts
index d1fb8a6265..f88d61f942 100644
--- a/packages/js/email-editor/src/store/index.ts
+++ b/packages/js/email-editor/src/store/index.ts
@@ -4,4 +4,3 @@
 export * from './constants';
 export * from './store';
 export * from './types';
-export * from './overrides';
diff --git a/packages/js/email-editor/src/store/overrides.ts b/packages/js/email-editor/src/store/overrides.ts
deleted file mode 100644
index 17734c1fbc..0000000000
--- a/packages/js/email-editor/src/store/overrides.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * External dependencies
- */
-import { use, select } from '@wordpress/data';
-import deepmerge from 'deepmerge';
-
-/**
- * Internal dependencies
- */
-import { EmailStyles, EmailTheme, storeName } from './index';
-import { unwrapCompressedPresetStyleVariable } from '../style-variables';
-import { areExternalStylesSupported } from '../private-apis';
-
-/**
- * Function to generate the root container styles based on the config.
- * As of Gutenberg 22.0 we can no longer override styles directly so we are sending additional dynamic CSS via theme's css property
- */
-const generateRootContainerStyles = ( config ) => {
-	const layout = config.editorSettings?.__experimentalFeatures?.layout;
-	const baseTheme = config.theme;
-	const userTheme = select(
-		storeName
-	).getGlobalEmailStylesPost() as EmailTheme;
-	const userStyles = userTheme?.styles;
-	const mergedStyles = deepmerge.all( [
-		{},
-		baseTheme.styles,
-		userStyles,
-	] ) as EmailStyles;
-	const maxWidth = layout?.contentSize || '100%';
-	let rootContainerStyles = `display:flow-root; max-width: ${ maxWidth }; margin: 0 auto;box-sizing: border-box;`;
-	const padding = mergedStyles?.spacing?.padding;
-	if ( padding ) {
-		rootContainerStyles += `padding-left:${ unwrapCompressedPresetStyleVariable(
-			padding.left
-		) };`;
-		rootContainerStyles += `padding-right:${ unwrapCompressedPresetStyleVariable(
-			padding.right
-		) };`;
-	}
-	return `.is-root-container{ ${ rootContainerStyles } }`;
-};
-
-/**
- * We wrap the core store selectors to return the global styles post id and email base theme from the email editor config.
- * As of Gutenberg 22.0 we can no longer override styles directly via a prop see https://github.com/WordPress/gutenberg/pull/72681/files#diff-da0dfea2139990db95c1ff4cae9f222aef66ae8d3dafb6237953d0c98c63fb64
- *
- * @param config - The configuration object containing the global styles post id and email base theme.
- */
-export const initStoreOverrides = ( config ) => {
-	// If the active version of Gutenberg supports external styles being passed to Editor component, we don't need to override the store.
-	if ( areExternalStylesSupported ) {
-		return;
-	}
-	use( ( registry ) => ( {
-		select( store ) {
-			const base = registry.select( store );
-			if ( store.name === 'core' ) {
-				return {
-					...base,
-					// Override the base function to return the global styles post id from the config
-					__experimentalGetCurrentGlobalStylesId() {
-						// Run the original function to run resolver and return overridden value after resolution is done
-						const baseGlobalStylesId =
-							base.__experimentalGetCurrentGlobalStylesId();
-						if ( ! baseGlobalStylesId ) {
-							return null;
-						}
-						return config.globalStylesPostId;
-					},
-					// Override the base function to return email base theme
-					__experimentalGetCurrentThemeBaseGlobalStyles() {
-						// Run the original function to run resolver and return overridden value after resolution is done
-						const baseTheme =
-							base.__experimentalGetCurrentThemeBaseGlobalStyles();
-						if ( ! baseTheme ) {
-							return null;
-						}
-						const theme = {
-							...config.theme,
-							styles: {
-								...config.theme.styles,
-								css: generateRootContainerStyles( config ),
-							},
-						};
-						return theme;
-					},
-				};
-			}
-			return base;
-		},
-	} ) );
-};
diff --git a/packages/js/email-editor/src/store/selectors.ts b/packages/js/email-editor/src/store/selectors.ts
index 226683d30f..ffcafbada3 100644
--- a/packages/js/email-editor/src/store/selectors.ts
+++ b/packages/js/email-editor/src/store/selectors.ts
@@ -6,7 +6,6 @@ import { store as coreDataStore } from '@wordpress/core-data';
 import { store as editorStore } from '@wordpress/editor';
 import { store as preferencesStore } from '@wordpress/preferences';
 import { serialize, parse, BlockInstance } from '@wordpress/blocks';
-import { Post } from '@wordpress/core-data/build-types/entity-types/post';

 /**
  * Internal dependencies
@@ -18,6 +17,7 @@ import {
 	EmailEditorPostType,
 	Feature,
 	PersonalizationTag,
+	GlobalEmailStylesPost,
 } from './types';

 function getContentFromEntity( entity ): string {
@@ -304,7 +304,7 @@ export const getGlobalEmailStylesPost = createRegistrySelector(
 					'root',
 					'globalStyles',
 					postId
-				) as unknown as Post;
+				) as GlobalEmailStylesPost;
 			}
 			return regularizedGetEntityRecord(
 				select( coreDataStore ).getEntityRecord(
@@ -313,7 +313,7 @@ export const getGlobalEmailStylesPost = createRegistrySelector(
 					postId,
 					{ context: 'view' }
 				)
-			) as unknown as Post;
+			) as GlobalEmailStylesPost;
 		}
 		return null;
 	}
diff --git a/packages/js/email-editor/src/store/types.ts b/packages/js/email-editor/src/store/types.ts
index 5ca65e5c97..18e9784f73 100644
--- a/packages/js/email-editor/src/store/types.ts
+++ b/packages/js/email-editor/src/store/types.ts
@@ -5,6 +5,7 @@ import { EditorSettings, EditorColor } from '@wordpress/block-editor/index';
 import { BlockInstance } from '@wordpress/blocks/index';
 import { Post } from '@wordpress/core-data/build-types/entity-types/post';
 import type { WpTemplate } from '@wordpress/core-data';
+import type { GlobalStylesConfig } from '@wordpress/global-styles-engine';

 export interface EmailTemplate extends Omit< WpTemplate, 'title' > {
 	post_types: string[];
@@ -39,93 +40,15 @@ export type EmailEditorSettings = EditorSettings &
 	ExperimentalSettings & {
 		isPreviewMode: boolean;
 		allowedIframeStyleHandles?: string[];
+		styles?: EmailBuiltStyles[];
 	};

-export type EmailTheme = {
-	version?: number;
-	styles?: EmailStyles;
-	// Ref: https://github.com/WordPress/gutenberg/blob/38d0a4351105e6ba4b72c4dcb90985305aacf921/packages/block-editor/src/components/global-styles/hooks.js#L24C7-L24C21
-	settings?: {
-		appearanceTools?: boolean;
-		useRootPaddingAwareAlignments?: boolean;
-		background?: {
-			backgroundImage?: boolean;
-			backgroundRepeat?: boolean;
-			backgroundSize?: boolean;
-			backgroundPosition?: boolean;
-		};
-		border?: {
-			radius?: boolean;
-			width?: boolean;
-			style?: boolean;
-			color?: boolean;
-		};
-		shadow?: {
-			presets?: boolean;
-			defaultPresets?: boolean;
-		};
-		color?: {
-			background?: boolean;
-			button?: boolean;
-			caption?: boolean;
-			custom?: boolean;
-			customDuotone?: boolean;
-			customGradient?: boolean;
-			defaultDuotone?: boolean;
-			defaultGradients?: boolean;
-			defaultPalette?: boolean;
-			duotone?: boolean;
-			gradients?: {
-				default?: boolean;
-				theme?: boolean;
-				custom?: boolean;
-			};
-			heading?: boolean;
-			link?: boolean;
-			palette?: boolean;
-			text?: boolean;
-		};
-		dimensions?: {
-			aspectRatio?: boolean;
-			minHeight?: boolean;
-		};
-		layout?: {
-			contentSize?: string;
-			wideSize?: string;
-		};
-		spacing?: {
-			customSpacingSize?: number;
-			blockGap?: number;
-			margin?: boolean;
-			padding?: boolean;
-			spacingSizes?: number[];
-			spacingScale?: number;
-			units?: string[];
-		};
-		position?: {
-			fixed?: boolean;
-			sticky?: boolean;
-		};
-		typography?: {
-			customFontSize?: boolean;
-			defaultFontSizes?: boolean;
-			dropCap?: boolean;
-			fontFamilies?: boolean;
-			fontSizes?: boolean;
-			fontStyle?: boolean;
-			fontWeight?: boolean;
-			letterSpacing?: boolean;
-			lineHeight?: boolean;
-			textColumns?: boolean;
-			textDecoration?: boolean;
-			textTransform?: boolean;
-			writingMode?: boolean;
-		};
-		lightbox?: {
-			enabled?: boolean;
-			allowEditing?: boolean;
-		};
-	};
+export type EmailTheme = Omit< GlobalStylesConfig, 'styles' > & {
+	styles: EmailStyles;
+};
+
+export type GlobalEmailStylesPost = EmailTheme & {
+	id: number;
 };

 export interface TypographyProperties {
diff --git a/plugins/woocommerce/changelog/wooprd-1278-compatibility-with-gutenberg-220 b/plugins/woocommerce/changelog/wooprd-1278-compatibility-with-gutenberg-220
new file mode 100644
index 0000000000..25dc314c28
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooprd-1278-compatibility-with-gutenberg-220
@@ -0,0 +1,5 @@
+Significance: patch
+Type: tweak
+Comment: Update admin client build to bundle @wordpress/global-styles-engine
+
+
diff --git a/plugins/woocommerce/client/admin/webpack.config.js b/plugins/woocommerce/client/admin/webpack.config.js
index 5ac04cc7e6..8dba2a38d1 100644
--- a/plugins/woocommerce/client/admin/webpack.config.js
+++ b/plugins/woocommerce/client/admin/webpack.config.js
@@ -250,6 +250,10 @@ const webpackConfig = {
 							// See https://github.com/WordPress/gutenberg/pull/61692 for more details about the dependency in general.
 							// For backward compatibility reasons we need to skip requesting to external here.
 							return null;
+						case '@wordpress/global-styles-engine':
+							// @wordpress/global-styles-engine is not a standard WordPress package available globally,
+							// so we need to bundle it instead of treating it as an external.
+							return null;
 					}

 					if ( request.startsWith( '@wordpress/dataviews' ) ) {