Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add layout styles from Post Content block to post editor #44258

Merged
merged 14 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/block-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import './metadata';
import './metadata-name';

export { useCustomSides } from './dimensions';
export { useLayoutClasses, useLayoutStyles } from './layout';
export { getBorderClassesAndStyles, useBorderProps } from './use-border-props';
export { getColorClassesAndStyles, useColorProps } from './use-color-props';
export { getSpacingClassesAndStyles } from './use-spacing-props';
Expand Down
85 changes: 64 additions & 21 deletions packages/block-editor/src/hooks/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,58 +37,101 @@ import { getLayoutType, getLayoutTypes } from '../layouts';
const layoutBlockSupportKey = '__experimentalLayout';

/**
* Generates the utility classnames for the given blocks layout attributes.
* This method was primarily added to reintroduce classnames that were removed
* in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719), rather
* than providing an extensive list of all possible layout classes. The plan is to
* have the style engine generate a more extensive list of utility classnames which
* will then replace this method.
* Generates the utility classnames for the given block's layout attributes.
*
* @param { Object } layout Layout object.
* @param { Object } layoutDefinitions An object containing layout definitions, stored in theme.json.
* @param { Object } block Block object.
*
* @return { Array } Array of CSS classname strings.
*/
function useLayoutClasses( layout, layoutDefinitions ) {
export function useLayoutClasses( block = {} ) {
const rootPaddingAlignment = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
return getSettings().__experimentalFeatures
?.useRootPaddingAwareAlignments;
}, [] );
const globalLayoutSettings = useSetting( 'layout' ) || {};

const { attributes = {}, name } = block;
const { layout } = attributes;

const { default: defaultBlockLayout } =
getBlockSupport( name, layoutBlockSupportKey ) || {};
const usedLayout =
layout?.inherit || layout?.contentSize || layout?.wideSize
? { ...layout, type: 'constrained' }
: layout || defaultBlockLayout || {};

const layoutClassnames = [];

if ( layoutDefinitions?.[ layout?.type || 'default' ]?.className ) {
if (
globalLayoutSettings?.definitions?.[ usedLayout?.type || 'default' ]
?.className
) {
layoutClassnames.push(
layoutDefinitions?.[ layout?.type || 'default' ]?.className
globalLayoutSettings?.definitions?.[ usedLayout?.type || 'default' ]
?.className
);
}

if (
( layout?.inherit ||
layout?.contentSize ||
layout?.type === 'constrained' ) &&
( usedLayout?.inherit ||
usedLayout?.contentSize ||
usedLayout?.type === 'constrained' ) &&
rootPaddingAlignment
) {
layoutClassnames.push( 'has-global-padding' );
}

if ( layout?.orientation ) {
layoutClassnames.push( `is-${ kebabCase( layout.orientation ) }` );
if ( usedLayout?.orientation ) {
layoutClassnames.push( `is-${ kebabCase( usedLayout.orientation ) }` );
}

if ( layout?.justifyContent ) {
if ( usedLayout?.justifyContent ) {
layoutClassnames.push(
`is-content-justification-${ kebabCase( layout.justifyContent ) }`
`is-content-justification-${ kebabCase(
usedLayout.justifyContent
) }`
);
}

if ( layout?.flexWrap && layout.flexWrap === 'nowrap' ) {
if ( usedLayout?.flexWrap && usedLayout.flexWrap === 'nowrap' ) {
layoutClassnames.push( 'is-nowrap' );
}

return layoutClassnames;
}

/**
* Generates a CSS rule with the given block's layout styles.
*
* @param { Object } block Block object.
* @param { string } selector A selector to use in generating the CSS rule.
*
* @return { string } CSS rule.
*/
export function useLayoutStyles( block = {}, selector ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice abstraction here!

const { attributes = {}, name } = block;
const { layout = {}, style = {} } = attributes;
// Update type for blocks using legacy layouts.
const usedLayout =
layout?.inherit || layout?.contentSize || layout?.wideSize
? { ...layout, type: 'constrained' }
: layout || {};
const fullLayoutType = getLayoutType( usedLayout?.type || 'default' );
const globalLayoutSettings = useSetting( 'layout' ) || {};
const blockGapSupport = useSetting( 'spacing.blockGap' );
const hasBlockGapSupport = blockGapSupport !== null;
const css = fullLayoutType?.getLayoutStyle?.( {
blockName: name,
selector,
layout,
layoutDefinitions: globalLayoutSettings?.definitions,
style,
hasBlockGapSupport,
} );
return css;
}

function LayoutPanel( { setAttributes, attributes, name: blockName } ) {
const { layout } = attributes;
const defaultThemeLayout = useSetting( 'layout' );
Expand Down Expand Up @@ -299,7 +342,7 @@ export const withInspectorControls = createHigherOrderComponent(
*/
export const withLayoutStyles = createHigherOrderComponent(
( BlockListBlock ) => ( props ) => {
const { name, attributes } = props;
const { name, attributes, block } = props;
const hasLayoutBlockSupport = hasBlockSupport(
name,
layoutBlockSupportKey
Expand All @@ -321,7 +364,7 @@ export const withLayoutStyles = createHigherOrderComponent(
? { ...layout, type: 'constrained' }
: layout || defaultBlockLayout || {};
const layoutClasses = hasLayoutBlockSupport
? useLayoutClasses( usedLayout, defaultThemeLayout?.definitions )
? useLayoutClasses( block )
: null;
const selector = `.${ getBlockDefaultClassName(
name
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export {
getSpacingClassesAndStyles as __experimentalGetSpacingClassesAndStyles,
getGapCSSValue as __experimentalGetGapCSSValue,
useCachedTruthy,
useLayoutClasses as __experimentaluseLayoutClasses,
useLayoutStyles as __experimentaluseLayoutStyles,
} from './hooks';
export * from './components';
export * from './elements';
Expand Down
4 changes: 3 additions & 1 deletion packages/block-library/src/post-content/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ function EditableContent( { layout, context = {} } ) {
return getSettings()?.supportsLayout;
}, [] );
const defaultLayout = useSetting( 'layout' ) || {};
const usedLayout = !! layout && layout.inherit ? defaultLayout : layout;
const usedLayout = ! layout?.type
? { ...defaultLayout, ...layout, type: 'default' }
: { ...defaultLayout, ...layout };
const [ blocks, onInput, onChange ] = useEntityBlockEditor(
'postType',
postType,
Expand Down
131 changes: 110 additions & 21 deletions packages/edit-post/src/components/visual-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ import {
__unstableUseMouseMoveTypingReset as useMouseMoveTypingReset,
__unstableIframe as Iframe,
__experimentalRecursionProvider as RecursionProvider,
__experimentaluseLayoutClasses as useLayoutClasses,
__experimentaluseLayoutStyles as useLayoutStyles,
} from '@wordpress/block-editor';
import { useEffect, useRef, useMemo } from '@wordpress/element';
import { Button, __unstableMotion as motion } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { useMergeRefs } from '@wordpress/compose';
import { arrowLeft } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { parse } from '@wordpress/blocks';

/**
* Internal dependencies
Expand Down Expand Up @@ -82,20 +85,48 @@ function MaybeIframe( {
);
}

/**
* Given an array of nested blocks, find the first Post Content
* block inside it, recursing through any nesting levels.
*
* @param {Array} blocks A list of blocks.
*
* @return {Object} The Post Content block.
*/
function findPostContent( blocks ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we help our future selves here and add a JS doc comment?

for ( let i = 0; i < blocks.length; i++ ) {
if ( blocks[ i ].name === 'core/post-content' ) {
return blocks[ i ];
}
if ( blocks[ i ].innerBlocks.length ) {
const nestedPostContent = findPostContent(
blocks[ i ].innerBlocks
);

if ( nestedPostContent ) {
return nestedPostContent;
}
}
}
}

export default function VisualEditor( { styles } ) {
const {
deviceType,
isWelcomeGuideVisible,
isTemplateMode,
editedPostTemplate = {},
wrapperBlockName,
wrapperUniqueId,
} = useSelect( ( select ) => {
const {
isFeatureActive,
isEditingTemplate,
__experimentalGetPreviewDeviceType,
getEditedPostTemplate,
} = select( editPostStore );
const { getCurrentPostId, getCurrentPostType } = select( editorStore );
const { getCurrentPostId, getCurrentPostType, getEditorSettings } =
select( editorStore );
const _isTemplateMode = isEditingTemplate();
let _wrapperBlockName;

Expand All @@ -105,10 +136,17 @@ export default function VisualEditor( { styles } ) {
_wrapperBlockName = 'core/post-content';
}

const supportsTemplateMode = getEditorSettings().supportsTemplateMode;

return {
deviceType: __experimentalGetPreviewDeviceType(),
isWelcomeGuideVisible: isFeatureActive( 'welcomeGuide' ),
isTemplateMode: _isTemplateMode,
// Post template fetch returns a 404 on classic themes, which
// messes with e2e tests, so we check it's a block theme first.
editedPostTemplate: supportsTemplateMode
? getEditedPostTemplate()
: {},
wrapperBlockName: _wrapperBlockName,
wrapperUniqueId: getCurrentPostId(),
};
Expand All @@ -122,16 +160,13 @@ export default function VisualEditor( { styles } ) {
themeHasDisabledLayoutStyles,
themeSupportsLayout,
assets,
useRootPaddingAwareAlignments,
isFocusMode,
} = useSelect( ( select ) => {
const _settings = select( blockEditorStore ).getSettings();
return {
themeHasDisabledLayoutStyles: _settings.disableLayoutStyles,
themeSupportsLayout: _settings.supportsLayout,
assets: _settings.__unstableResolvedAssets,
useRootPaddingAwareAlignments:
_settings.__experimentalFeatures?.useRootPaddingAwareAlignments,
isFocusMode: _settings.focusMode,
};
}, [] );
Expand All @@ -154,7 +189,7 @@ export default function VisualEditor( { styles } ) {
borderBottom: 0,
};
const resizedCanvasStyles = useResizeCanvas( deviceType, isTemplateMode );
const defaultLayout = useSetting( 'layout' );
const globalLayoutSettings = useSetting( 'layout' );
const previewMode = 'is-' + deviceType.toLowerCase() + '-preview';

let animatedStyles = isTemplateMode
Expand Down Expand Up @@ -183,25 +218,68 @@ export default function VisualEditor( { styles } ) {

const blockSelectionClearerRef = useBlockSelectionClearer();

const layout = useMemo( () => {
// fallbackLayout is used if there is no Post Content,
// and for Post Title.
const fallbackLayout = useMemo( () => {
if ( isTemplateMode ) {
return { type: 'default' };
}

if ( themeSupportsLayout ) {
// We need to ensure support for wide and full alignments,
// so we add the constrained type.
return { ...defaultLayout, type: 'constrained' };
return { ...globalLayoutSettings, type: 'constrained' };
}
// Set default layout for classic themes so all alignments are supported.
return { type: 'default' };
}, [ isTemplateMode, themeSupportsLayout, defaultLayout ] );
}, [ isTemplateMode, themeSupportsLayout, globalLayoutSettings ] );

const postContentBlock = useMemo( () => {
// When in template editing mode, we can access the blocks directly.
if ( editedPostTemplate?.blocks ) {
return findPostContent( editedPostTemplate?.blocks );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can reproduce error that @andrewserong noticed but only sometimes.

Most of the times it works for me.

When it does fail I suspect it's because postContentBlock is undefined (and therefore trying to access the attributes below fails).

Replacing with return findPostContent( editedPostTemplate?.blocks ) || {}; seems to get around that,

2022-09-26 12 39 39

But it exposes another error triggered by the component 🤣

Uncaught TypeError: Cannot read properties of null (reading 'removeEventListener')

previousElement.ownerDocument.defaultView.removeEventListener(

Not sure why yet. I can't reproduce either error in trunk.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I've only managed to repro the error once on TT2, and not at all on Empty theme. But I think something's messed up because previous customisations are now appearing as the default template state 😅
Will continue investigating.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I fixed the failure if Post Content block is removed from the template by accessing layout from attributes via optional chaining instead of destructuring. The reason returning empty object from findPostContent won't work correctly is some logic further down is dependent on checking if postContentBlock exists, and empty object will always be true 😅

}
// If there are no blocks, we have to parse the content string.
// Best double-check it's a string otherwise the parse function gets unhappy.
const parseableContent =
typeof editedPostTemplate?.content === 'string'
? editedPostTemplate?.content
: '';

return findPostContent( parse( parseableContent ) ) || {};
}, [ editedPostTemplate?.content, editedPostTemplate?.blocks ] );

const postContentLayoutClasses = useLayoutClasses( postContentBlock );

const blockListLayoutClass = classnames(
{
'is-layout-flow': ! themeSupportsLayout,
},
themeSupportsLayout && postContentLayoutClasses
);

const blockListLayoutClass = classnames( {
'is-layout-constrained': themeSupportsLayout,
'is-layout-flow': ! themeSupportsLayout,
'has-global-padding': useRootPaddingAwareAlignments,
} );
const postContentLayoutStyles = useLayoutStyles(
postContentBlock,
'.block-editor-block-list__layout.is-root-container'
);
Comment on lines +261 to +264
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there appears to be a difference in the rules that are being output here versus trunk 🤔 I noticed that there's an issue with the middle content justification with the Cover block set to wide alignment in TwentyTwentyTwo:

Trunk This PR
image image

This appears to be the rule that isn't present / winning out:

image

Copy link
Contributor

@andrewserong andrewserong Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if the issue is that useLayoutStyles generates the layout styles for the individual post content block, but not the base layout styles that need to be attached to this more specific selector in order for it to win out? Or to put it differently, prior to this PR, it looks like we might have depended on the output of base layout rules with this more specific selector for this middle content justification. Apologies if I'm way off!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those styles that are overriding the middle justification are the TT2 root padding logic that I thought were going to be removed after the Core root padding styles became available.

I'm reluctant to either increase specificity of the default layout styles or add wp-container rules for the default justification state, because any theme can conceivably still override them with higher specificity rules 😅

This should probably be fixed in TT2 instead cc @carolinan @scruffian

Copy link
Contributor

@andrewserong andrewserong Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reluctant to either increase specificity of the default layout styles or add wp-container rules for the default justification state

Agreed, it'd be better not to have to add container rules, or explicit rules for the default justification state 🤔

This should probably be fixed in TT2 instead

It's a tricky one... because TT2 has been used as a base for many other themes, it might not just TT2 out in the wild that has this issue. (E.g. the rule appears to be part of BlockBase https://github.com/Automattic/themes/blob/23b9090090279c95788357bb634fd2e57c3973db/blockbase/sass/base/_alignment.scss#L58 which many themes have been built on top of, too).

Just trying to think of other options... would it work to update the change to this line in this PR

selector=".edit-post-visual-editor__post-title-wrapper"
to include .block-editor-block-list__layout.is-root-container as well (as on trunk)? Or did we we need to remove it for the postContentLayoutStyles to work? Since they already have the selector attached, I was wondering if they can coexist. From quickly adding it back in in my local environment, it appears to get all three content justifications working in TT2 for me, but it's highly likely I'm missing some context 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just trying to think of other options... would it work to update the change to this line in this PR to include .block-editor-block-list__layout.is-root-container as well (as on trunk)? Or did we we need to remove it for the postContentLayoutStyles to work?

I did remove it initially so that custom content widths would work, but because we since increased the specificity of the default rules it seems to be working ok. I just tried pushing that change now, hopefully it doesn't break anything else 😅

It's a tricky one... because TT2 has been used as a base for many other themes, it might not just TT2 out in the wild that has this issue.

I'm not sure how much of a concern that should be to us, because the temporary status of these rules is explicitly called out in the TT2 stylesheet.


const layout = postContentBlock?.attributes?.layout || {};

// Update type for blocks using legacy layouts.
const postContentLayout =
layout &&
( layout?.type === 'constrained' ||
layout?.inherit ||
layout?.contentSize ||
layout?.wideSize )
? { ...globalLayoutSettings, ...layout, type: 'constrained' }
: { ...globalLayoutSettings, ...layout, type: 'default' };

// If there is a Post Content block we use its layout for the block list;
// if not, this must be a classic theme, in which case we use the fallback layout.
const blockListLayout = postContentBlock
? postContentLayout
: fallbackLayout;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi there! I stumbled on this code while doing some performance debugging. While right now, it's not clear to me that this code (I mean all the figuring out of the layout) is introducing performance regression (specially loading) but I noticed that the value of the layout changes three times for a regular post loaded in the post editor.

Screen Shot 2022-10-24 at 11 08 48 PM

  • A few things stand out to me here. Can we just compute the right layout only once to avoid unnecessary re-renders?
  • Why does the layout object contains this "definitions" key? Seems weird? (probably unrelated to this PR but maybe you have an idea)
  • Also the logic here is over-complexifying this component. Is there a possibility of some kind of cleanup like a dedicated hook useBlockEditorLayout or something (I have no idea, just wild suggesting)?

Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have access to the post template straightaway on load, so we need to do a little checking to see when it becomes available. But we should probably be checking whether postContentBlock is an empty object rather than just checking whether it exists, as then blockListLayout would only change once.

The definitions object appeared in #40875; it's where we store base styles for each layout type. When we get the layout settings with useSetting the definitions will always be included.

Is there a possibility of some kind of cleanup like a dedicated hook useBlockEditorLayout or something

That's a good point, I can't say offhand but it's worth looking into!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The definitions object appeared in #40875; it's where we store base styles for each layout type. When we get the layout settings with useSetting the definitions will always be included.

What's seems not correct here is that the "definition" are included in the "default layout" object. I'm fine having "definitions" but I don't they should be part of the default layout object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably be checking whether postContentBlock is an empty object rather than just checking whether it exists, as then blockListLayout would only change once.

Yeah, is there a way to have no changes at all, this is to avoid rendering anything if the correct layout object is not available yet. As I guess otherwise, we'd just be doing unnecessary computation and potentially causing layout shifts in the UI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine having "definitions" but I don't they should be part of the default layout object.

I'm not sure I understand. The default layout type has default styles too, so we need to access those definitions sometimes. Do you mean we shouldn't be returning the definitions from useSetting( 'layout' ) or am I missing your point altogether? 😅

Yeah, is there a way to have no changes at all, this is to avoid rendering anything if the correct layout object is not available yet. As I guess otherwise, we'd just be doing unnecessary computation and potentially causing layout shifts in the UI.

Yeah, there will be a layout shift if the layout is anything other than center-aligned and constrained to default theme width. The problem is, if we wait for the post template data to be available before rendering the post content, users will be looking at a white screen for a little bit, which seems to me a worse experience than the layout shift. Unless we can find a faster way to access the Post Content block layout? The thing is we need the Post Content block from the specific template being used with the post, because it might have custom settings. It's not enough to get the data from global styles.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking through this a bit, also in light of #45262, would it be terrible to get the Post Content layout and add it to the block editor settings here? I haven't tried it out yet but happy to do so as I think we're going to need a solution that renders the correct layout for all types of users, not just the ones with the right permissions 😬

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in general we're trying to move away from server-side provided settings in order to make the editor more portable (outside wordpress, other contexts...) but in this case, I wouldn't mind it. The original idea of the "layout" properly in theme.json was to avoid this problem exactly: the layout in theme.json would always correspond (as a convention) to the post content block one and we'd avoid any complex computations. (statically defined)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the context! Yeah, the issue is precisely that folks wanted to customize the Post Content layout, and with features such as #44065 it makes sense for the post editor to reflect whatever layout is set.


const titleRef = useRef();
useEffect( () => {
Expand Down Expand Up @@ -257,13 +335,24 @@ export default function VisualEditor( { styles } ) {
{ themeSupportsLayout &&
! themeHasDisabledLayoutStyles &&
! isTemplateMode && (
<LayoutStyle
selector=".edit-post-visual-editor__post-title-wrapper, .block-editor-block-list__layout.is-root-container"
layout={ layout }
layoutDefinitions={
defaultLayout?.definitions
}
/>
<>
<LayoutStyle
selector=".edit-post-visual-editor__post-title-wrapper, .block-editor-block-list__layout.is-root-container"
layout={ fallbackLayout }
layoutDefinitions={
globalLayoutSettings?.definitions
}
/>
{ postContentLayoutStyles && (
<LayoutStyle
layout={ postContentLayout }
css={ postContentLayoutStyles }
layoutDefinitions={
globalLayoutSettings?.definitions
}
/>
) }
</>
) }
{ ! isTemplateMode && (
<div
Expand All @@ -288,7 +377,7 @@ export default function VisualEditor( { styles } ) {
? 'wp-site-blocks'
: `${ blockListLayoutClass } wp-block-post-content` // Ensure root level blocks receive default/flow blockGap styling rules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if we might still need the wp-block-post-content classname to be added, so that we can hook into styles that are set at the core/post-content block in global styles? (It looks like the layout classnames don't output the block classname, so I think we might still need to add it in manually 🤔)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit hazy on how the global styles stuff works in the post editor, so if you think it's needed I'll just add it back. Won't do any harm to have the class there 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit hazy on how the global styles stuff works in the post editor

I was looking at this the other day while reviewing other PRs, so in case the breadcrumbs here are helpful: it's pretty naive when it comes to global styles. The server-rendered global styles are added to the block editor settings in PHP here, and then the post editor figures out whether or not to use them here. The styles are then passed down to the post editor's Layout component on this line. That component then passes the styles to VisualEditor here. And in VisualEditor, the styles are passed to MaybeIframe which finally passes it along to EditorStyles, which ultimately outputs styles in a style tag on this line: https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/components/editor-styles/index.js#L81

The TL;DR is that it's nearly as if the global styles stylesheet had been enqueued, only those styles get transformed a bit by the EditorStyles component to play nicely in the editor.

I mostly just wanted to write that out somewhere because it finally clicked for me how it's hooked together 😀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's really helpful!

}
__experimentalLayout={ layout }
__experimentalLayout={ blockListLayout }
/>
</RecursionProvider>
</MaybeIframe>
Expand Down