diff --git a/packages/edit-site/src/components/global-styles/highlighted-colors.js b/packages/edit-site/src/components/global-styles/highlighted-colors.js
new file mode 100644
index 00000000000000..35f5574f185a5a
--- /dev/null
+++ b/packages/edit-site/src/components/global-styles/highlighted-colors.js
@@ -0,0 +1,39 @@
+/**
+ * WordPress dependencies
+ */
+import { __unstableMotion as motion } from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { useStylesPreviewColors } from './hooks';
+
+export default function HighlightedColors( {
+ normalizedColorSwatchSize,
+ ratio,
+} ) {
+ const { highlightedColors } = useStylesPreviewColors();
+ const scaledSwatchSize = normalizedColorSwatchSize * ratio;
+ return highlightedColors.map( ( { slug, color }, index ) => (
+
+ ) );
+}
diff --git a/packages/edit-site/src/components/global-styles/preview-colors.js b/packages/edit-site/src/components/global-styles/preview-colors.js
index 88885baf300626..08a372ed83cf90 100644
--- a/packages/edit-site/src/components/global-styles/preview-colors.js
+++ b/packages/edit-site/src/components/global-styles/preview-colors.js
@@ -2,32 +2,17 @@
* WordPress dependencies
*/
import {
- __unstableIframe as Iframe,
- __unstableEditorStyles as EditorStyles,
- privateApis as blockEditorPrivateApis,
-} from '@wordpress/block-editor';
-import {
- __unstableMotion as motion,
__experimentalHStack as HStack,
+ __unstableMotion as motion,
} from '@wordpress/components';
-import {
- useThrottle,
- useReducedMotion,
- useResizeObserver,
-} from '@wordpress/compose';
-import { useLayoutEffect, useState, useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
-import { unlock } from '../../lock-unlock';
-import { useStylesPreviewColors } from './hooks';
-
-const { useGlobalStyle, useGlobalStylesOutput } = unlock(
- blockEditorPrivateApis
-);
+import HighlightedColors from './highlighted-colors';
+import PreviewIframe from './preview-iframe';
-const firstFrame = {
+const firstFrameVariants = {
start: {
scale: 1,
opacity: 1,
@@ -38,178 +23,38 @@ const firstFrame = {
},
};
-const normalizedWidth = 248;
-const normalizedHeight = 152;
-
-const normalizedColorSwatchSize = 66;
-
-// Throttle options for useThrottle. Must be defined outside of the component,
-// so that the object reference is the same on each render.
-const THROTTLE_OPTIONS = {
- leading: true,
- trailing: true,
-};
-
const StylesPreviewColors = ( { label, isFocused, withHoverView } ) => {
- const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
- const [ gradientValue ] = useGlobalStyle( 'color.gradient' );
- const [ styles ] = useGlobalStylesOutput();
- const disableMotion = useReducedMotion();
- const [ isHovered, setIsHovered ] = useState( false );
- const [ containerResizeListener, { width } ] = useResizeObserver();
- const [ throttledWidth, setThrottledWidthState ] = useState( width );
- const [ ratioState, setRatioState ] = useState();
-
- const setThrottledWidth = useThrottle(
- setThrottledWidthState,
- 250,
- THROTTLE_OPTIONS
- );
-
- // Must use useLayoutEffect to avoid a flash of the iframe at the wrong
- // size before the width is set.
- useLayoutEffect( () => {
- if ( width ) {
- setThrottledWidth( width );
- }
- }, [ width, setThrottledWidth ] );
-
- // Must use useLayoutEffect to avoid a flash of the iframe at the wrong
- // size before the width is set.
- useLayoutEffect( () => {
- const newRatio = throttledWidth ? throttledWidth / normalizedWidth : 1;
- const ratioDiff = newRatio - ( ratioState || 0 );
-
- // Only update the ratio state if the difference is big enough
- // or if the ratio state is not yet set. This is to avoid an
- // endless loop of updates at particular viewport heights when the
- // presence of a scrollbar causes the width to change slightly.
- const isRatioDiffBigEnough = Math.abs( ratioDiff ) > 0.1;
-
- if ( isRatioDiffBigEnough || ! ratioState ) {
- setRatioState( newRatio );
- }
- }, [ throttledWidth, ratioState ] );
-
- // Set a fallbackRatio to use before the throttled ratio has been set.
- const fallbackRatio = width ? width / normalizedWidth : 1;
- /*
- * Use the throttled ratio if it has been calculated, otherwise
- * use the fallback ratio. The throttled ratio is used to avoid
- * an endless loop of updates at particular viewport heights.
- * See: https://github.com/WordPress/gutenberg/issues/55112
- */
- const ratio = ratioState ? ratioState : fallbackRatio;
-
- const { highlightedColors } = useStylesPreviewColors();
-
- /*
- * Reset leaked styles from WP common.css and remove main content layout padding and border.
- * Add pointer cursor to the body to indicate the iframe is interactive,
- * similar to Typography variation previews.
- */
- const editorStyles = useMemo( () => {
- if ( styles ) {
- return [
- ...styles,
- {
- css: 'html{overflow:hidden}body{min-width: 0;padding: 0;border: none;cursor: pointer;}',
- isGlobalStyles: true,
- },
- ];
- }
-
- return styles;
- }, [ styles ] );
- const isReady = !! width;
-
return (
- <>
-
- { containerResizeListener }
-
- { isReady && (
-
+
+
+
) }
- >
+
);
};
diff --git a/packages/edit-site/src/components/global-styles/preview-iframe.js b/packages/edit-site/src/components/global-styles/preview-iframe.js
new file mode 100644
index 00000000000000..ea4207e35a113d
--- /dev/null
+++ b/packages/edit-site/src/components/global-styles/preview-iframe.js
@@ -0,0 +1,153 @@
+/**
+ * WordPress dependencies
+ */
+import {
+ __unstableIframe as Iframe,
+ __unstableEditorStyles as EditorStyles,
+ privateApis as blockEditorPrivateApis,
+} from '@wordpress/block-editor';
+import { __unstableMotion as motion } from '@wordpress/components';
+import {
+ useThrottle,
+ useReducedMotion,
+ useResizeObserver,
+} from '@wordpress/compose';
+import { useLayoutEffect, useState, useMemo } from '@wordpress/element';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../../lock-unlock';
+
+const { useGlobalStyle, useGlobalStylesOutput } = unlock(
+ blockEditorPrivateApis
+);
+
+const normalizedWidth = 248;
+const normalizedHeight = 152;
+
+// Throttle options for useThrottle. Must be defined outside of the component,
+// so that the object reference is the same on each render.
+const THROTTLE_OPTIONS = {
+ leading: true,
+ trailing: true,
+};
+
+export default function PreviewIframe( {
+ children,
+ label,
+ isFocused,
+ withHoverView,
+} ) {
+ const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
+ const [ gradientValue ] = useGlobalStyle( 'color.gradient' );
+ const [ styles ] = useGlobalStylesOutput();
+ const disableMotion = useReducedMotion();
+ const [ isHovered, setIsHovered ] = useState( false );
+ const [ containerResizeListener, { width } ] = useResizeObserver();
+ const [ throttledWidth, setThrottledWidthState ] = useState( width );
+ const [ ratioState, setRatioState ] = useState();
+
+ const setThrottledWidth = useThrottle(
+ setThrottledWidthState,
+ 250,
+ THROTTLE_OPTIONS
+ );
+
+ // Must use useLayoutEffect to avoid a flash of the iframe at the wrong
+ // size before the width is set.
+ useLayoutEffect( () => {
+ if ( width ) {
+ setThrottledWidth( width );
+ }
+ }, [ width, setThrottledWidth ] );
+
+ // Must use useLayoutEffect to avoid a flash of the iframe at the wrong
+ // size before the width is set.
+ useLayoutEffect( () => {
+ const newRatio = throttledWidth ? throttledWidth / normalizedWidth : 1;
+ const ratioDiff = newRatio - ( ratioState || 0 );
+
+ // Only update the ratio state if the difference is big enough
+ // or if the ratio state is not yet set. This is to avoid an
+ // endless loop of updates at particular viewport heights when the
+ // presence of a scrollbar causes the width to change slightly.
+ const isRatioDiffBigEnough = Math.abs( ratioDiff ) > 0.1;
+
+ if ( isRatioDiffBigEnough || ! ratioState ) {
+ setRatioState( newRatio );
+ }
+ }, [ throttledWidth, ratioState ] );
+
+ // Set a fallbackRatio to use before the throttled ratio has been set.
+ const fallbackRatio = width ? width / normalizedWidth : 1;
+ /*
+ * Use the throttled ratio if it has been calculated, otherwise
+ * use the fallback ratio. The throttled ratio is used to avoid
+ * an endless loop of updates at particular viewport heights.
+ * See: https://github.com/WordPress/gutenberg/issues/55112
+ */
+ const ratio = ratioState ? ratioState : fallbackRatio;
+
+ /*
+ * Reset leaked styles from WP common.css and remove main content layout padding and border.
+ * Add pointer cursor to the body to indicate the iframe is interactive,
+ * similar to Typography variation previews.
+ */
+ const editorStyles = useMemo( () => {
+ if ( styles ) {
+ return [
+ ...styles,
+ {
+ css: 'html{overflow:hidden}body{min-width: 0;padding: 0;border: none;cursor: pointer;}',
+ isGlobalStyles: true,
+ },
+ ];
+ }
+
+ return styles;
+ }, [ styles ] );
+ const isReady = !! width;
+
+ return (
+ <>
+
+ { containerResizeListener }
+
+ { isReady && (
+
+ ) }
+ >
+ );
+}
diff --git a/packages/edit-site/src/components/global-styles/preview-styles.js b/packages/edit-site/src/components/global-styles/preview-styles.js
new file mode 100644
index 00000000000000..f4566ca32d6784
--- /dev/null
+++ b/packages/edit-site/src/components/global-styles/preview-styles.js
@@ -0,0 +1,185 @@
+/**
+ * WordPress dependencies
+ */
+import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
+import {
+ __experimentalHStack as HStack,
+ __experimentalVStack as VStack,
+ __unstableMotion as motion,
+} from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { unlock } from '../../lock-unlock';
+import { useStylesPreviewColors } from './hooks';
+import PreviewTypography from './preview-typography';
+import HighlightedColors from './highlighted-colors';
+import PreviewIframe from './preview-iframe';
+
+const { useGlobalStyle } = unlock( blockEditorPrivateApis );
+
+const firstFrameVariants = {
+ start: {
+ scale: 1,
+ opacity: 1,
+ },
+ hover: {
+ scale: 0,
+ opacity: 0,
+ },
+};
+
+const midFrameVariants = {
+ hover: {
+ opacity: 1,
+ },
+ start: {
+ opacity: 0.5,
+ },
+};
+
+const secondFrameVariants = {
+ hover: {
+ scale: 1,
+ opacity: 1,
+ },
+ start: {
+ scale: 0,
+ opacity: 0,
+ },
+};
+
+const PreviewStyles = ( { label, isFocused, withHoverView, variation } ) => {
+ const [ fontWeight ] = useGlobalStyle( 'typography.fontWeight' );
+ const [ fontFamily = 'serif' ] = useGlobalStyle( 'typography.fontFamily' );
+ const [ headingFontFamily = fontFamily ] = useGlobalStyle(
+ 'elements.h1.typography.fontFamily'
+ );
+ const [ headingFontWeight = fontWeight ] = useGlobalStyle(
+ 'elements.h1.typography.fontWeight'
+ );
+ const [ textColor = 'black' ] = useGlobalStyle( 'color.text' );
+ const [ headingColor = textColor ] = useGlobalStyle(
+ 'elements.h1.color.text'
+ );
+
+ const { paletteColors } = useStylesPreviewColors();
+
+ return (
+
+ { ( { ratio, key } ) => (
+
+
+
+
+
+
+
+
+ ) }
+ { ( { key } ) => (
+
+
+ { paletteColors
+ .slice( 0, 4 )
+ .map( ( { color }, index ) => (
+
+ ) ) }
+
+
+ ) }
+ { ( { ratio, key } ) => (
+
+
+ { label && (
+
+ { label }
+
+ ) }
+
+
+ ) }
+
+ );
+};
+
+export default PreviewStyles;
diff --git a/packages/edit-site/src/components/global-styles/preview.js b/packages/edit-site/src/components/global-styles/preview.js
deleted file mode 100644
index eb58419ccec6bf..00000000000000
--- a/packages/edit-site/src/components/global-styles/preview.js
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * WordPress dependencies
- */
-import {
- __unstableIframe as Iframe,
- __unstableEditorStyles as EditorStyles,
- privateApis as blockEditorPrivateApis,
-} from '@wordpress/block-editor';
-import {
- __unstableMotion as motion,
- __experimentalHStack as HStack,
- __experimentalVStack as VStack,
-} from '@wordpress/components';
-import {
- useThrottle,
- useReducedMotion,
- useResizeObserver,
-} from '@wordpress/compose';
-import { useLayoutEffect, useState, useMemo } from '@wordpress/element';
-
-/**
- * Internal dependencies
- */
-import { unlock } from '../../lock-unlock';
-import { useStylesPreviewColors } from './hooks';
-import PreviewTypography from './preview-typography';
-
-const { useGlobalStyle, useGlobalStylesOutput } = unlock(
- blockEditorPrivateApis
-);
-
-const firstFrame = {
- start: {
- scale: 1,
- opacity: 1,
- },
- hover: {
- scale: 0,
- opacity: 0,
- },
-};
-
-const midFrame = {
- hover: {
- opacity: 1,
- },
- start: {
- opacity: 0.5,
- },
-};
-
-const secondFrame = {
- hover: {
- scale: 1,
- opacity: 1,
- },
- start: {
- scale: 0,
- opacity: 0,
- },
-};
-
-const normalizedWidth = 248;
-const normalizedHeight = 152;
-
-const normalizedColorSwatchSize = 32;
-
-// Throttle options for useThrottle. Must be defined outside of the component,
-// so that the object reference is the same on each render.
-const THROTTLE_OPTIONS = {
- leading: true,
- trailing: true,
-};
-
-const StylesPreview = ( { label, isFocused, withHoverView, variation } ) => {
- const [ fontWeight ] = useGlobalStyle( 'typography.fontWeight' );
- const [ fontFamily = 'serif' ] = useGlobalStyle( 'typography.fontFamily' );
- const [ headingFontFamily = fontFamily ] = useGlobalStyle(
- 'elements.h1.typography.fontFamily'
- );
- const [ headingFontWeight = fontWeight ] = useGlobalStyle(
- 'elements.h1.typography.fontWeight'
- );
- const [ textColor = 'black' ] = useGlobalStyle( 'color.text' );
- const [ headingColor = textColor ] = useGlobalStyle(
- 'elements.h1.color.text'
- );
- const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
- const [ gradientValue ] = useGlobalStyle( 'color.gradient' );
- const [ styles ] = useGlobalStylesOutput();
- const disableMotion = useReducedMotion();
- const [ isHovered, setIsHovered ] = useState( false );
- const [ containerResizeListener, { width } ] = useResizeObserver();
- const [ throttledWidth, setThrottledWidthState ] = useState( width );
- const [ ratioState, setRatioState ] = useState();
-
- const setThrottledWidth = useThrottle(
- setThrottledWidthState,
- 250,
- THROTTLE_OPTIONS
- );
-
- // Must use useLayoutEffect to avoid a flash of the iframe at the wrong
- // size before the width is set.
- useLayoutEffect( () => {
- if ( width ) {
- setThrottledWidth( width );
- }
- }, [ width, setThrottledWidth ] );
-
- // Must use useLayoutEffect to avoid a flash of the iframe at the wrong
- // size before the width is set.
- useLayoutEffect( () => {
- const newRatio = throttledWidth ? throttledWidth / normalizedWidth : 1;
- const ratioDiff = newRatio - ( ratioState || 0 );
-
- // Only update the ratio state if the difference is big enough
- // or if the ratio state is not yet set. This is to avoid an
- // endless loop of updates at particular viewport heights when the
- // presence of a scrollbar causes the width to change slightly.
- const isRatioDiffBigEnough = Math.abs( ratioDiff ) > 0.1;
-
- if ( isRatioDiffBigEnough || ! ratioState ) {
- setRatioState( newRatio );
- }
- }, [ throttledWidth, ratioState ] );
-
- // Set a fallbackRatio to use before the throttled ratio has been set.
- const fallbackRatio = width ? width / normalizedWidth : 1;
- // Use the throttled ratio if it has been calculated, otherwise
- // use the fallback ratio. The throttled ratio is used to avoid
- // an endless loop of updates at particular viewport heights.
- // See: https://github.com/WordPress/gutenberg/issues/55112
- const ratio = ratioState ? ratioState : fallbackRatio;
-
- const { paletteColors, highlightedColors } = useStylesPreviewColors();
-
- // Reset leaked styles from WP common.css and remove main content layout padding and border.
- const editorStyles = useMemo( () => {
- if ( styles ) {
- return [
- ...styles,
- {
- css: 'html{overflow:hidden}body{min-width: 0;padding: 0;border: none;}',
- isGlobalStyles: true,
- },
- ];
- }
-
- return styles;
- }, [ styles ] );
- const isReady = !! width;
-
- return (
- <>
-
- { containerResizeListener }
-
- { isReady && (
-
- ) }
- >
- );
-};
-
-export default StylesPreview;
diff --git a/packages/edit-site/src/components/global-styles/screen-root.js b/packages/edit-site/src/components/global-styles/screen-root.js
index 28b3642ac09b45..4146b32b57e3db 100644
--- a/packages/edit-site/src/components/global-styles/screen-root.js
+++ b/packages/edit-site/src/components/global-styles/screen-root.js
@@ -24,7 +24,7 @@ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
import { IconWithCurrentColor } from './icon-with-current-color';
import { NavigationButtonAsItem } from './navigation-button';
import RootMenu from './root-menu';
-import StylesPreview from './preview';
+import PreviewStyles from './preview-styles';
import { unlock } from '../../lock-unlock';
const { useGlobalStyle } = unlock( blockEditorPrivateApis );
@@ -58,7 +58,7 @@ function ScreenRoot() {
-
+
{ hasVariations && (
diff --git a/packages/edit-site/src/components/global-styles/style-variations-container.js b/packages/edit-site/src/components/global-styles/style-variations-container.js
index bcc0b940de4b26..69aff3e5be415a 100644
--- a/packages/edit-site/src/components/global-styles/style-variations-container.js
+++ b/packages/edit-site/src/components/global-styles/style-variations-container.js
@@ -10,7 +10,7 @@ import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
-import StylesPreview from './preview';
+import PreviewStyles from './preview-styles';
import Variation from './variations/variation';
export default function StyleVariationsContainer() {
@@ -43,7 +43,7 @@ export default function StyleVariationsContainer() {
{ withEmptyVariation.map( ( variation, index ) => (
{ ( isFocused ) => (
-