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

theme.json: Setting block fontStyle to inherit/initial results in error when changing block font family in the Site Editor #68491

Open
3 of 6 tasks
andersnoren opened this issue Jan 5, 2025 · 5 comments
Labels
[Feature] Typography Font and typography-related issues and PRs [Type] Bug An existing feature does not function as intended

Comments

@andersnoren
Copy link

Description

In theme.json, if you set typography.fontStyle for a specific block to inherit or initial, changing the font family of that block in the Styles tab of the Site Editor crashes the editor with the error message "The editor has encountered an unexpected error.".

Changing the font family of one instance of the block doesn't give the error.

Originally reported in this theme specific issue, then reproduced in Twenty Twenty-Four.

Step-by-step reproduction instructions

  1. In Twenty Twenty-Four (or any block theme), add the following to styles.blocks (replacing the existing core/site-title – any specific block will work though):
"core/site-title": {
	"typography": {
		"fontStyle": "inherit"
	}
}
  1. In the Site Editor, click the Styles tab, then Blocks, then select Site Title.
  2. Click the Font dropdown, and select any option in the list.
  3. The site editor will freeze, and after a few seconds, give the error message.

Screenshots, screen recording, code snippet

Image

Error message:

al@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:82566
enqueueForceUpdate@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:117185
@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react.min.js:10:4691
forceUpdate@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/components.min.js:26:212463
@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/components.min.js:26:211850
Ur@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:73390
Jr@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:80623
Zr@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:80469
Gr@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:80003
@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:91506
xl@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:92017
fl@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:85788
Nn@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:32475
pl@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:86083
V@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:9907
Je@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:24964
pe@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:15784
fe@https://c0.wp.com/c/6.7.1/wp-includes/js/dist/vendor/react-dom.min.js:10:15568

Environment info

WordPress 6.7.1
Without or without Gutenberg
Twenty Twenty-Four

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure
@andersnoren andersnoren added the [Type] Bug An existing feature does not function as intended label Jan 5, 2025
@himanshupathak95
Copy link
Contributor

Hi @andersnoren, Thanks for bringing this up.

After a little digging, I found out that the crash occurs due to React's reconciliation issues when updating nested style properties individually.
Here's a proposed fix that modifies how we update the font family in the typography-panel.js -

// Current implementation
const setFontFamily = ( newValue ) => {
    const slug = fontFamilies?.find(
        ( { fontFamily: f } ) => f === newValue
    )?.slug;

    onChange(
        setImmutably(
            value,
            [ 'typography', 'fontFamily' ],
            slug
                ? `var:preset|font-family|${ slug }`
                : newValue || undefined
        )
    );
};

// fix
const setFontFamily = ( newValue ) => {
    const slug = fontFamilies?.find(
        ( { fontFamily: f } ) => f === newValue
    )?.slug;

    const fontFamilyValue = slug ? `var:preset|font-family|${ slug }` : newValue || undefined;

    onChange({
        ...value,
        typography: {
            ...value?.typography,
            fontFamily: fontFamilyValue
        }
    });
};

This fix updates the entire typography object at once instead of using setImmutably and maintains proper style inheritance
and while this happens, the editor doesn't crash.

Would love to hear your thoughts on this approach before proceeding with a PR.

@Mamaduka Mamaduka added the [Feature] Typography Font and typography-related issues and PRs label Jan 6, 2025
@Mamaduka
Copy link
Member

Mamaduka commented Jan 6, 2025

@himanshupathak95,

Do you have more details on why setImmutably conflicts with React's Reconciliation? I found it odd.

The setImmutably utility method is widely used, especially for block and global styles. We should try to find the source of the issue.

cc @tyxla, @mcsf

P.S. Can you also share the full error you're getting in Dev mode?

@himanshupathak95
Copy link
Contributor

Thanks @Mamaduka for the reply,

The error I am seeing is this -

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    at checkForNestedUpdates (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:27341:13)
    at scheduleUpdateOnFiber (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:25524:5)
    at Object.enqueueForceUpdate (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:17988:9)
    at Component.forceUpdate (http://671.local/wp-includes/js/dist/vendor/react.js?ver=18.3.1:363:18)
    at SlotComponent.forceUpdate (http://671.local/wp-includes/js/dist/components.js?ver=490baf094e76d91dd234:33448:11)
    at http://671.local/wp-includes/js/dist/components.js?ver=490baf094e76d91dd234:33368:12
    at commitHookEffectListMount (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:23199:28)
    at commitLayoutEffectOnFiber (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:23317:19)
    at commitLayoutMountEffects_complete (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:24737:11)
    at commitLayoutEffects_begin (http://671.local/wp-includes/js/dist/vendor/react-dom.js?ver=18.3.1:24723:9)

Image

@t-hamano
Copy link
Contributor

t-hamano commented Jan 7, 2025

As far as I can tell, it's this useEffect() hook that's causing the problem:

useEffect( () => {
if ( nearestFontStyle && nearestFontWeight ) {
setFontAppearance( {
fontStyle: nearestFontStyle,
fontWeight: nearestFontWeight,
} );
} else {
// Reset font appearance if there are no available styles or weights.
resetFontAppearance();
}
}, [
nearestFontStyle,
nearestFontWeight,
resetFontAppearance,
setFontAppearance,
] );

For example, excluding the dependency like this will prevent the infinite loop (Note: this is not an actual solution):

diff --git a/packages/block-editor/src/components/global-styles/typography-panel.js b/packages/block-editor/src/components/global-styles/typography-panel.js
index 9bc875cdc0..940d5ce040 100644
--- a/packages/block-editor/src/components/global-styles/typography-panel.js
+++ b/packages/block-editor/src/components/global-styles/typography-panel.js
@@ -273,12 +273,7 @@ export default function TypographyPanel( {
                        // Reset font appearance if there are no available styles or weights.
                        resetFontAppearance();
                }
-       }, [
-               nearestFontStyle,
-               nearestFontWeight,
-               resetFontAppearance,
-               setFontAppearance,
-       ] );
+       }, [] );

It looks similar to the issue reported here: https://github.com/WordPress/gutenberg/pull/61915/files#r1673421903

cc @mikachan @vcanales @creativecoder

@tyxla
Copy link
Member

tyxla commented Jan 7, 2025

If the cause is the useEffect, since it only conditionally calls setState(), it might be a case where we don't really need an effect, see https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Typography Font and typography-related issues and PRs [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

No branches or pull requests

5 participants