From 3767bc29bfcd743ca66b9b1a2f28f09003127686 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Wed, 10 Sep 2025 14:08:48 -0400 Subject: [PATCH 1/7] feat: Set default colors and gradients for sites without settings If a site does not have the Gutenberg plugin enabled, the editor settings endpoint is unavailable. We set a default color palette and gradients to enable customizing block styles. --- src/utils/editor-settings.js | 41 ++++++++++++++++++++++++++++++++++++ src/utils/editor.jsx | 10 ++------- 2 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 src/utils/editor-settings.js diff --git a/src/utils/editor-settings.js b/src/utils/editor-settings.js new file mode 100644 index 00000000..cea458c2 --- /dev/null +++ b/src/utils/editor-settings.js @@ -0,0 +1,41 @@ +/** + * WordPress dependencies + */ +import defaultEditorStyles from '@wordpress/block-editor/build-style/default-editor-styles.css?inline'; +import { store as editorStore } from '@wordpress/editor'; +import { select } from '@wordpress/data'; + +/** + * Returns a default editor settings object to use when a site cannot provide + * its own editor settings due to lacking the necessary experimental REST API + * endpoint provided by the Gutenberg plugin + * + * @see https://github.com/WordPress/gutenberg/blob/d97807b50f756126798a04a5ae94745aee19356d/lib/experimental/class-wp-rest-block-editor-settings-controller.php + * @see https://github.com/WordPress/gutenberg/pull/64448 + * + * @return {Object} The default editor settings object + */ +export function getDefaultEditorSettings() { + const settings = select( editorStore ).getEditorSettings(); + const defaultEditorColors = settings?.colors; + const defaultEditorGradients = settings?.gradients; + + return { + defaultEditorStyles: [ { css: defaultEditorStyles } ], + __experimentalFeatures: { + blocks: {}, // Avoid errors from blocks relying upon block settings + color: { + text: true, + background: true, + palette: { + default: defaultEditorColors, + }, + gradients: { + default: defaultEditorGradients, + }, + defaultPalette: defaultEditorColors?.length > 0, + defaultGradients: defaultEditorGradients?.length > 0, + }, + }, + }; +} diff --git a/src/utils/editor.jsx b/src/utils/editor.jsx index 52d28b13..195cadac 100644 --- a/src/utils/editor.jsx +++ b/src/utils/editor.jsx @@ -1,8 +1,3 @@ -/** - * WordPress dependencies - */ -import defaultEditorStyles from '@wordpress/block-editor/build-style/default-editor-styles.css?inline'; - /** * Internal dependencies */ @@ -14,6 +9,7 @@ import { store as preferencesStore } from '@wordpress/preferences'; import { registerCoreBlocks } from '@wordpress/block-library'; import { unregisterDisallowedBlocks } from './blocks'; import { getGBKit, getPost } from './bridge'; +import { getDefaultEditorSettings } from './editor-settings'; /** * Configure editor settings and styles, and render the editor. @@ -28,9 +24,7 @@ import { getGBKit, getPost } from './bridge'; export function initializeEditor( { allowedBlockTypes } = {} ) { const { themeStyles, hideTitle, editorSettings } = getGBKit(); - const settings = editorSettings || { - defaultEditorStyles: [ { css: defaultEditorStyles } ], - }; + const settings = editorSettings || getDefaultEditorSettings(); dispatch( editorStore ).updateEditorSettings( settings ); const preferenceDispatch = dispatch( preferencesStore ); From f219d46623c4ab8ab5775235a3699d5e89321680 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 11 Sep 2025 15:16:55 -0400 Subject: [PATCH 2/7] fix: Include preset editor styles Ensures preset styles are loaded--e.g., utility classes for colors. --- src/components/visual-editor/use-editor-styles.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/visual-editor/use-editor-styles.js b/src/components/visual-editor/use-editor-styles.js index 738770fd..778725de 100644 --- a/src/components/visual-editor/use-editor-styles.js +++ b/src/components/visual-editor/use-editor-styles.js @@ -36,8 +36,15 @@ export function useEditorStyles() { }, [] ); return useMemo( () => { + const presetStyles = + editorSettings.styles?.filter( + ( style ) => + style.__unstableType && style.__unstableType !== 'theme' + ) ?? []; + const defaultEditorStyles = [ ...( editorSettings?.defaultEditorStyles ?? [] ), + ...presetStyles, ]; if ( ! editorSettings.disableLayoutStyles && ! hasThemeStyleSupport ) { From 52776c3f22a48cf6cacb433ff10773e9766d5dac Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 11 Sep 2025 15:18:25 -0400 Subject: [PATCH 3/7] chore: Update `useEditorStyles` copy with latest from Gutenberg core Bring our copy of this private utility up to date. --- .../visual-editor/use-editor-styles.js | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/components/visual-editor/use-editor-styles.js b/src/components/visual-editor/use-editor-styles.js index 778725de..55236308 100644 --- a/src/components/visual-editor/use-editor-styles.js +++ b/src/components/visual-editor/use-editor-styles.js @@ -22,11 +22,14 @@ const { getLayoutStyles } = unlock( blockEditorPrivateApis ); /** * Custom hook to retrieve and memoize editor styles. * + * @param {...any} additionalStyles Additional styles to add to the default styles. + * * @todo This should be exported from Core so no reimplementation is needed. + * @see https://github.com/WordPress/gutenberg/blob/a4d79e85a06e06b9123778e6991ac27b0bbe351d/packages/edit-post/src/components/layout/index.js#L86 * * @return {any[]} An array of editor styles. */ -export function useEditorStyles() { +export function useEditorStyles( ...additionalStyles ) { const { hasThemeStyleSupport, editorSettings } = useSelect( ( select ) => { return { hasThemeStyleSupport: @@ -35,6 +38,9 @@ export function useEditorStyles() { }; }, [] ); + const addedStyles = additionalStyles.join( '\n' ); + + // Compute the default styles. return useMemo( () => { const presetStyles = editorSettings.styles?.filter( @@ -47,7 +53,14 @@ export function useEditorStyles() { ...presetStyles, ]; - if ( ! editorSettings.disableLayoutStyles && ! hasThemeStyleSupport ) { + // Has theme styles if the theme supports them and if some styles were not preset styles (in which case they're theme styles). + const hasThemeStyles = + hasThemeStyleSupport && + presetStyles.length !== ( editorSettings.styles?.length ?? 0 ); + + // If theme styles are not present or displayed, ensure that + // base layout styles are still present in the editor. + if ( ! editorSettings.disableLayoutStyles && ! hasThemeStyles ) { defaultEditorStyles.push( { css: getLayoutStyles( { style: {}, @@ -59,16 +72,21 @@ export function useEditorStyles() { } ); } - if ( ! hasThemeStyleSupport ) { + // Add sensible default styles if theme styles are not present. + if ( ! hasThemeStyles ) { defaultEditorStyles.push( { css: defaultThemeStyles, } ); } - const baseStyles = hasThemeStyleSupport + const baseStyles = hasThemeStyles ? editorSettings.styles ?? [] : defaultEditorStyles; + if ( addedStyles ) { + return [ ...baseStyles, { css: addedStyles } ]; + } + // `commonStyles` represent manually added notable styles that are missing. // The styles likely absent due to them being injected by the WP Admin // context. @@ -78,5 +96,6 @@ export function useEditorStyles() { editorSettings.disableLayoutStyles, editorSettings.styles, hasThemeStyleSupport, + addedStyles, ] ); } From 26cde69ee416e74f8f5b46d7baa2456cc61bb523 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 11 Sep 2025 15:36:48 -0400 Subject: [PATCH 4/7] refactor: Utilize `useEditorSetting` added styles parameter Embrace new abilities of this private function copy. --- src/components/visual-editor/index.jsx | 14 +++++++++++++- .../visual-editor/use-editor-styles.js | 17 +---------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/components/visual-editor/index.jsx b/src/components/visual-editor/index.jsx index b4b7f9f5..83435c41 100644 --- a/src/components/visual-editor/index.jsx +++ b/src/components/visual-editor/index.jsx @@ -26,6 +26,11 @@ import { useEditorStyles } from './use-editor-styles'; import { unlock } from '../../lock-unlock'; import DefaultBlockAppender from '../default-block-appender'; import { useEditorVisible } from './use-editor-visible'; +// The Vite query parameter breaks the linter's import resolution +// eslint-disable-next-line import/no-unresolved +import defaultThemeStyles from './default-theme-styles.scss?inline'; +// eslint-disable-next-line import/no-unresolved +import commonStyles from './wp-common-styles.scss?inline'; const { ExperimentalBlockCanvas: BlockCanvas, @@ -75,7 +80,14 @@ function VisualEditor( { hideTitle } ) { }; }, [] ); - const styles = useEditorStyles(); + const styles = useEditorStyles( + // `commonStyles` represent manually added notable styles that are missing. + // The styles likely absent due to them being injected by the WP Admin + // context. + commonStyles, + // Add sensible default styles if theme styles are not present. + hasThemeStyleSupport ? '' : defaultThemeStyles + ); const editorClasses = clsx( 'gutenberg-kit-visual-editor', { 'has-root-padding': diff --git a/src/components/visual-editor/use-editor-styles.js b/src/components/visual-editor/use-editor-styles.js index 55236308..3c744b04 100644 --- a/src/components/visual-editor/use-editor-styles.js +++ b/src/components/visual-editor/use-editor-styles.js @@ -11,11 +11,6 @@ import { useMemo } from '@wordpress/element'; * Internal dependencies */ import { unlock } from '../../lock-unlock'; -// The Vite query parameter breaks the linter's import resolution -// eslint-disable-next-line import/no-unresolved -import defaultThemeStyles from './default-theme-styles.scss?inline'; -// eslint-disable-next-line import/no-unresolved -import commonStyles from './wp-common-styles.scss?inline'; const { getLayoutStyles } = unlock( blockEditorPrivateApis ); @@ -72,13 +67,6 @@ export function useEditorStyles( ...additionalStyles ) { } ); } - // Add sensible default styles if theme styles are not present. - if ( ! hasThemeStyles ) { - defaultEditorStyles.push( { - css: defaultThemeStyles, - } ); - } - const baseStyles = hasThemeStyles ? editorSettings.styles ?? [] : defaultEditorStyles; @@ -87,10 +75,7 @@ export function useEditorStyles( ...additionalStyles ) { return [ ...baseStyles, { css: addedStyles } ]; } - // `commonStyles` represent manually added notable styles that are missing. - // The styles likely absent due to them being injected by the WP Admin - // context. - return [ { css: commonStyles }, ...baseStyles ]; + return baseStyles; }, [ editorSettings.defaultEditorStyles, editorSettings.disableLayoutStyles, From 85b38305c1b11c486e5dfbc55d33d338076baa9b Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 11 Sep 2025 16:45:44 -0400 Subject: [PATCH 5/7] fix: Default colors render for separators Include default color utility classes. This is typically added by WordPress' admin via PHP. The manual addition is necessary for sites without the GutenbergKit plugin, which do not provide editor settings and theme styles. --- .../visual-editor/wp-common-styles.scss | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) diff --git a/src/components/visual-editor/wp-common-styles.scss b/src/components/visual-editor/wp-common-styles.scss index 6b8f6060..c867161d 100644 --- a/src/components/visual-editor/wp-common-styles.scss +++ b/src/components/visual-editor/wp-common-styles.scss @@ -1,6 +1,8 @@ // Manually added styles that are missing from the editor settings, likely // because the styles are injected by the WP Admin context, which is not present // in the REST API endpoint. +// +// @todo: Research a different approach that keeps these styles up to date. // Constraints for the post title. .editor-visual-editor__post-title-wrapper @@ -44,3 +46,333 @@ margin-block-start: 1.2rem; margin-block-end: 0; } + +// Default colors and presets. +:root { + --wp--preset--aspect-ratio--square: 1; + --wp--preset--aspect-ratio--4-3: 4/3; + --wp--preset--aspect-ratio--3-4: 3/4; + --wp--preset--aspect-ratio--3-2: 3/2; + --wp--preset--aspect-ratio--2-3: 2/3; + --wp--preset--aspect-ratio--16-9: 16/9; + --wp--preset--aspect-ratio--9-16: 9/16; + --wp--preset--color--black: #000000; + --wp--preset--color--cyan-bluish-gray: #abb8c3; + --wp--preset--color--white: #ffffff; + --wp--preset--color--pale-pink: #f78da7; + --wp--preset--color--vivid-red: #cf2e2e; + --wp--preset--color--luminous-vivid-orange: #ff6900; + --wp--preset--color--luminous-vivid-amber: #fcb900; + --wp--preset--color--light-green-cyan: #7bdcb5; + --wp--preset--color--vivid-green-cyan: #00d084; + --wp--preset--color--pale-cyan-blue: #8ed1fc; + --wp--preset--color--vivid-cyan-blue: #0693e3; + --wp--preset--color--vivid-purple: #9b51e0; + --wp--preset--color--dark-gray: #28303d; + --wp--preset--color--gray: #39414d; + --wp--preset--color--green: #d1e4dd; + --wp--preset--color--blue: #d1dfe4; + --wp--preset--color--purple: #d1d1e4; + --wp--preset--color--red: #e4d1d1; + --wp--preset--color--orange: #e4dad1; + --wp--preset--color--yellow: #eeeadd; + --wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient( + 135deg, + rgba(6, 147, 227, 1) 0%, + rgb(155, 81, 224) 100% + ); + --wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient( + 135deg, + rgb(122, 220, 180) 0%, + rgb(0, 208, 130) 100% + ); + --wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient( + 135deg, + rgba(252, 185, 0, 1) 0%, + rgba(255, 105, 0, 1) 100% + ); + --wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient( + 135deg, + rgba(255, 105, 0, 1) 0%, + rgb(207, 46, 46) 100% + ); + --wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient( + 135deg, + rgb(238, 238, 238) 0%, + rgb(169, 184, 195) 100% + ); + --wp--preset--gradient--cool-to-warm-spectrum: linear-gradient( + 135deg, + rgb(74, 234, 220) 0%, + rgb(151, 120, 209) 20%, + rgb(207, 42, 186) 40%, + rgb(238, 44, 130) 60%, + rgb(251, 105, 98) 80%, + rgb(254, 248, 76) 100% + ); + --wp--preset--gradient--blush-light-purple: linear-gradient( + 135deg, + rgb(255, 206, 236) 0%, + rgb(152, 150, 240) 100% + ); + --wp--preset--gradient--blush-bordeaux: linear-gradient( + 135deg, + rgb(254, 205, 165) 0%, + rgb(254, 45, 45) 50%, + rgb(107, 0, 62) 100% + ); + --wp--preset--gradient--luminous-dusk: linear-gradient( + 135deg, + rgb(255, 203, 112) 0%, + rgb(199, 81, 192) 50%, + rgb(65, 88, 208) 100% + ); + --wp--preset--gradient--pale-ocean: linear-gradient( + 135deg, + rgb(255, 245, 203) 0%, + rgb(182, 227, 212) 50%, + rgb(51, 167, 181) 100% + ); + --wp--preset--gradient--electric-grass: linear-gradient( + 135deg, + rgb(202, 248, 128) 0%, + rgb(113, 206, 126) 100% + ); + --wp--preset--gradient--midnight: linear-gradient( + 135deg, + rgb(2, 3, 129) 0%, + rgb(40, 116, 252) 100% + ); + --wp--preset--gradient--purple-to-yellow: linear-gradient( + 160deg, + #d1d1e4 0%, + #eeeadd 100% + ); + --wp--preset--gradient--yellow-to-purple: linear-gradient( + 160deg, + #eeeadd 0%, + #d1d1e4 100% + ); + --wp--preset--gradient--green-to-yellow: linear-gradient( + 160deg, + #d1e4dd 0%, + #eeeadd 100% + ); + --wp--preset--gradient--yellow-to-green: linear-gradient( + 160deg, + #eeeadd 0%, + #d1e4dd 100% + ); + --wp--preset--gradient--red-to-yellow: linear-gradient( + 160deg, + #e4d1d1 0%, + #eeeadd 100% + ); + --wp--preset--gradient--yellow-to-red: linear-gradient( + 160deg, + #eeeadd 0%, + #e4d1d1 100% + ); + --wp--preset--gradient--purple-to-red: linear-gradient( + 160deg, + #d1d1e4 0%, + #e4d1d1 100% + ); + --wp--preset--gradient--red-to-purple: linear-gradient( + 160deg, + #e4d1d1 0%, + #d1d1e4 100% + ); + --wp--preset--font-size--small: 18px; + --wp--preset--font-size--medium: 20px; + --wp--preset--font-size--large: 24px; + --wp--preset--font-size--x-large: 42px; + --wp--preset--font-size--extra-small: 16px; + --wp--preset--font-size--normal: 20px; + --wp--preset--font-size--extra-large: 40px; + --wp--preset--font-size--huge: 96px; + --wp--preset--font-size--gigantic: 144px; + --wp--preset--spacing--20: 0.44rem; + --wp--preset--spacing--30: 0.67rem; + --wp--preset--spacing--40: 1rem; + --wp--preset--spacing--50: 1.5rem; + --wp--preset--spacing--60: 2.25rem; + --wp--preset--spacing--70: 3.38rem; + --wp--preset--spacing--80: 5.06rem; + --wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2); + --wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4); + --wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2); + --wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), + 6px 6px rgba(0, 0, 0, 1); + --wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1); +} + +// Color utilities. +.has-black-color { + color: var(--wp--preset--color--black) !important; +} +.has-cyan-bluish-gray-color { + color: var(--wp--preset--color--cyan-bluish-gray) !important; +} +.has-white-color { + color: var(--wp--preset--color--white) !important; +} +.has-pale-pink-color { + color: var(--wp--preset--color--pale-pink) !important; +} +.has-vivid-red-color { + color: var(--wp--preset--color--vivid-red) !important; +} +.has-luminous-vivid-orange-color { + color: var(--wp--preset--color--luminous-vivid-orange) !important; +} +.has-luminous-vivid-amber-color { + color: var(--wp--preset--color--luminous-vivid-amber) !important; +} +.has-light-green-cyan-color { + color: var(--wp--preset--color--light-green-cyan) !important; +} +.has-vivid-green-cyan-color { + color: var(--wp--preset--color--vivid-green-cyan) !important; +} +.has-pale-cyan-blue-color { + color: var(--wp--preset--color--pale-cyan-blue) !important; +} +.has-vivid-cyan-blue-color { + color: var(--wp--preset--color--vivid-cyan-blue) !important; +} +.has-vivid-purple-color { + color: var(--wp--preset--color--vivid-purple) !important; +} +.has-black-background-color { + background-color: var(--wp--preset--color--black) !important; +} +.has-cyan-bluish-gray-background-color { + background-color: var(--wp--preset--color--cyan-bluish-gray) !important; +} +.has-white-background-color { + background-color: var(--wp--preset--color--white) !important; +} +.has-pale-pink-background-color { + background-color: var(--wp--preset--color--pale-pink) !important; +} +.has-vivid-red-background-color { + background-color: var(--wp--preset--color--vivid-red) !important; +} +.has-luminous-vivid-orange-background-color { + background-color: var( + --wp--preset--color--luminous-vivid-orange + ) !important; +} +.has-luminous-vivid-amber-background-color { + background-color: var(--wp--preset--color--luminous-vivid-amber) !important; +} +.has-light-green-cyan-background-color { + background-color: var(--wp--preset--color--light-green-cyan) !important; +} +.has-vivid-green-cyan-background-color { + background-color: var(--wp--preset--color--vivid-green-cyan) !important; +} +.has-pale-cyan-blue-background-color { + background-color: var(--wp--preset--color--pale-cyan-blue) !important; +} +.has-vivid-cyan-blue-background-color { + background-color: var(--wp--preset--color--vivid-cyan-blue) !important; +} +.has-vivid-purple-background-color { + background-color: var(--wp--preset--color--vivid-purple) !important; +} +.has-black-border-color { + border-color: var(--wp--preset--color--black) !important; +} +.has-cyan-bluish-gray-border-color { + border-color: var(--wp--preset--color--cyan-bluish-gray) !important; +} +.has-white-border-color { + border-color: var(--wp--preset--color--white) !important; +} +.has-pale-pink-border-color { + border-color: var(--wp--preset--color--pale-pink) !important; +} +.has-vivid-red-border-color { + border-color: var(--wp--preset--color--vivid-red) !important; +} +.has-luminous-vivid-orange-border-color { + border-color: var(--wp--preset--color--luminous-vivid-orange) !important; +} +.has-luminous-vivid-amber-border-color { + border-color: var(--wp--preset--color--luminous-vivid-amber) !important; +} +.has-light-green-cyan-border-color { + border-color: var(--wp--preset--color--light-green-cyan) !important; +} +.has-vivid-green-cyan-border-color { + border-color: var(--wp--preset--color--vivid-green-cyan) !important; +} +.has-pale-cyan-blue-border-color { + border-color: var(--wp--preset--color--pale-cyan-blue) !important; +} +.has-vivid-cyan-blue-border-color { + border-color: var(--wp--preset--color--vivid-cyan-blue) !important; +} +.has-vivid-purple-border-color { + border-color: var(--wp--preset--color--vivid-purple) !important; +} +.has-vivid-cyan-blue-to-vivid-purple-gradient-background { + background: var( + --wp--preset--gradient--vivid-cyan-blue-to-vivid-purple + ) !important; +} +.has-light-green-cyan-to-vivid-green-cyan-gradient-background { + background: var( + --wp--preset--gradient--light-green-cyan-to-vivid-green-cyan + ) !important; +} +.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background { + background: var( + --wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange + ) !important; +} +.has-luminous-vivid-orange-to-vivid-red-gradient-background { + background: var( + --wp--preset--gradient--luminous-vivid-orange-to-vivid-red + ) !important; +} +.has-very-light-gray-to-cyan-bluish-gray-gradient-background { + background: var( + --wp--preset--gradient--very-light-gray-to-cyan-bluish-gray + ) !important; +} +.has-cool-to-warm-spectrum-gradient-background { + background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important; +} +.has-blush-light-purple-gradient-background { + background: var(--wp--preset--gradient--blush-light-purple) !important; +} +.has-blush-bordeaux-gradient-background { + background: var(--wp--preset--gradient--blush-bordeaux) !important; +} +.has-luminous-dusk-gradient-background { + background: var(--wp--preset--gradient--luminous-dusk) !important; +} +.has-pale-ocean-gradient-background { + background: var(--wp--preset--gradient--pale-ocean) !important; +} +.has-electric-grass-gradient-background { + background: var(--wp--preset--gradient--electric-grass) !important; +} +.has-midnight-gradient-background { + background: var(--wp--preset--gradient--midnight) !important; +} +.has-small-font-size { + font-size: var(--wp--preset--font-size--small) !important; +} +.has-medium-font-size { + font-size: var(--wp--preset--font-size--medium) !important; +} +.has-large-font-size { + font-size: var(--wp--preset--font-size--large) !important; +} +.has-x-large-font-size { + font-size: var(--wp--preset--font-size--x-large) !important; +} From d090121d288dfdaeab7a58b08b637ebd0e01f712 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 11 Sep 2025 16:47:28 -0400 Subject: [PATCH 6/7] fix: Apply default styles when editor settings provide none Even if the theme style preferences is enabled, we must apply the default styles if: 1. The theme provides no style via a block.json; 2. Or the site lacks the experimental Gutenberg REST API endpoint providing editor settings and styles. --- src/components/visual-editor/index.jsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/visual-editor/index.jsx b/src/components/visual-editor/index.jsx index 83435c41..b464dc92 100644 --- a/src/components/visual-editor/index.jsx +++ b/src/components/visual-editor/index.jsx @@ -59,7 +59,7 @@ function VisualEditor( { hideTitle } ) { const { renderingMode, - hasThemeStyleSupport, + hasThemeStyles, themeHasDisabledLayoutStyles, themeSupportsLayout, hasRootPaddingAwareAlignments, @@ -68,11 +68,14 @@ function VisualEditor( { hideTitle } ) { const _renderingMode = getRenderingMode(); const { getSettings } = unlock( select( blockEditorStore ) ); const _settings = getSettings(); + // Implies editor settings provided theme styles via the REST API. + const settingsHasStyles = _settings.styles?.length > 0; return { renderingMode: _renderingMode, - hasThemeStyleSupport: - select( editPostStore ).isFeatureActive( 'themeStyles' ), + hasThemeStyles: + select( editPostStore ).isFeatureActive( 'themeStyles' ) && + settingsHasStyles, themeSupportsLayout: _settings.supportsLayout, themeHasDisabledLayoutStyles: _settings.disableLayoutStyles, hasRootPaddingAwareAlignments: @@ -86,12 +89,11 @@ function VisualEditor( { hideTitle } ) { // context. commonStyles, // Add sensible default styles if theme styles are not present. - hasThemeStyleSupport ? '' : defaultThemeStyles + hasThemeStyles ? '' : defaultThemeStyles ); const editorClasses = clsx( 'gutenberg-kit-visual-editor', { - 'has-root-padding': - ! hasThemeStyleSupport || ! hasRootPaddingAwareAlignments, + 'has-root-padding': ! hasThemeStyles || ! hasRootPaddingAwareAlignments, } ); const titleClasses = clsx( @@ -99,7 +101,7 @@ function VisualEditor( { hideTitle } ) { 'editor-visual-editor__post-title-wrapper', { 'has-global-padding': - hasThemeStyleSupport && hasRootPaddingAwareAlignments, + hasThemeStyles && hasRootPaddingAwareAlignments, } ); @@ -126,7 +128,7 @@ function VisualEditor( { hideTitle } ) { { 'is-layout-flow': ! themeSupportsLayout, 'has-global-padding': - hasThemeStyleSupport && hasRootPaddingAwareAlignments, + hasThemeStyles && hasRootPaddingAwareAlignments, } ); From 6406b8cbb8fa1937dddd1974e0a689b8c90051f4 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 11 Sep 2025 21:26:55 -0400 Subject: [PATCH 7/7] docs: Further document nuanced editor settings fall back logic --- src/utils/editor-settings.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/utils/editor-settings.js b/src/utils/editor-settings.js index cea458c2..b83a322b 100644 --- a/src/utils/editor-settings.js +++ b/src/utils/editor-settings.js @@ -8,10 +8,9 @@ import { select } from '@wordpress/data'; /** * Returns a default editor settings object to use when a site cannot provide * its own editor settings due to lacking the necessary experimental REST API - * endpoint provided by the Gutenberg plugin + * endpoint provided by the Gutenberg plugin. * * @see https://github.com/WordPress/gutenberg/blob/d97807b50f756126798a04a5ae94745aee19356d/lib/experimental/class-wp-rest-block-editor-settings-controller.php - * @see https://github.com/WordPress/gutenberg/pull/64448 * * @return {Object} The default editor settings object */ @@ -21,9 +20,27 @@ export function getDefaultEditorSettings() { const defaultEditorGradients = settings?.gradients; return { + /** + * These styles are used if the "no theme styles" options is triggered or on + * themes without their own editor styles. + * + * @see https://github.com/WordPress/wordpress-develop/blob/db9654e6d386c2c69401b9c77c6ce1ae7460a6e4/src/wp-includes/block-editor.php#L218C4-L218C23 + */ defaultEditorStyles: [ { css: defaultEditorStyles } ], __experimentalFeatures: { - blocks: {}, // Avoid errors from blocks relying upon block settings + /** + * Avoid errors from blocks relying upon block settings. + * + * @see https://github.com/WordPress/gutenberg/pull/64448 + */ + blocks: {}, + /** + * Ensure themes lacking their own theme styles can customize blocks using + * the default editor colors and gradients. Mirrors the approach taken by + * the Gutenberg Mobile editor. + * + * @see https://github.com/WordPress/gutenberg/blob/d97807b50f756126798a04a5ae94745aee19356d/packages/block-editor/src/components/global-styles/use-global-styles-context.native.js#L410-L433 + */ color: { text: true, background: true,