-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Fix: Fit text not working in site editor preview #73020
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
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +146 B (+0.01%) Total Size: 2.45 MB
ℹ️ View Unchanged
|
|
Flaky tests detected in 21b3f74. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/19110786584
|
|
Nice, thank you for the fix, I think all this needs is a code review. |
| function useFitText( { fitText, name, clientId } ) { | ||
| const hasFitTextSupport = hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY ); | ||
| const blockElement = useBlockElement( clientId ); | ||
| const refBlockElement = useBlockElement( clientId ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if we try to find why useBlockElement is failing to work in this context. Maybe @ellatrix knows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I will give another try at finding the cause, this was like a desesperate attemp for a fix 😅
I'm also considering if an alternative like, render a style element after the block get its ref never rerender again and then just inject on that element ref the styles you need may not be a better alternative to what we have. We would never need to query the dom directly and would just use a ref for an element we rendered and control.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took me a while to fish it out, but it's a RichText-specific issue. I believe it's been around since #60544. When the block editor context has isPreviewMode set, RichText will render little more than just the basic content element, and in the process it omits the ref that it received:
This solves it for me:
diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js
index 13188d49fcc..f0c6e756307 100644
--- a/packages/block-editor/src/components/rich-text/index.js
+++ b/packages/block-editor/src/components/rich-text/index.js
@@ -569,6 +569,7 @@ const PublicForwardedRichTextContainer = forwardRef( ( props, ref ) => {
} = removeNativeProps( props );
return (
<Tag
+ ref={ ref }
{ ...contentProps }
dangerouslySetInnerHTML={ {
__html: valueToHTMLString( value, multiline ),I'll check with Ella to make sure there's no reason not to add the ref.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason, sounds good. Sounds like an oversight
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // If not found, check the editor canvas iframe | ||
| if ( ! element ) { | ||
| const iframe = document.querySelector( | ||
| 'iframe[name="editor-canvas"]' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we go with this approach, this is fragile. We'd need an e2e test to communicate this works the way it does, catch regressions in case something changes, etc.
| // that probably is an existing bug but the fix is not obvious so for now lets | ||
| // try this workaround on fit text only. | ||
| const [ fallbackElement, setFallbackElement ] = useState( null ); | ||
| useLayoutEffect( () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block painting, but the operation is cheap (finding a couple of DOM nodes), so it should be fine.
| } | ||
|
|
||
| if ( element ) { | ||
| setFallbackElement( element ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sets the elements if some was found, but how do we unset it in the preview context? Imagine an element is set, but the next time the hook runs, we don't find an element. Wouldn't be risk using a stale element as fallback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pre-approving on the interest of having a fix ready.
This works, and I couldn't make it fail in my testing. It also doesn't introduce any major changes, API, impact, etc.
Lefts some comments that'd be nice to address, and I also see we're still investigating an alternative fix.
Fixes any kind of bug arising from the fact that refs passed to RichText were ignored when the block editor is in preview mode. Particularly, `useBlockProps`, with its many merged refs, was systematically ignored. This was revealed while debugging the bug that #73020 sought to fix: `useBlockElement` could never return elements because the ref callback of `useBlockElementRef` was never called.
Let RichText forward the ref that it receives to the element it returns, even when this element is the lightweight alternative returned when the block editor is in preview mode. Fixes any kind of bug arising from the fact that refs passed to RichText were ignored when the block editor is in preview mode. Particularly, `useBlockProps`, with its many merged refs, was systematically ignored. This was revealed while debugging the bug that #73020 sought to fix: `useBlockElement` could never return elements because the ref callback of `useBlockElementRef` was never called.
|
Closed in favor of #73062. |
Let RichText forward the ref that it receives to the element it returns, even when this element is the lightweight alternative returned when the block editor is in preview mode. Fixes any kind of bug arising from the fact that refs passed to RichText were ignored when the block editor is in preview mode. Particularly, `useBlockProps`, with its many merged refs, was systematically ignored. This was revealed while debugging the bug that #73020 sought to fix: `useBlockElement` could never return elements because the ref callback of `useBlockElementRef` was never called. Co-authored-by: mcsf <mcsf@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
Let RichText forward the ref that it receives to the element it returns, even when this element is the lightweight alternative returned when the block editor is in preview mode. Fixes any kind of bug arising from the fact that refs passed to RichText were ignored when the block editor is in preview mode. Particularly, `useBlockProps`, with its many merged refs, was systematically ignored. This was revealed while debugging the bug that #73020 sought to fix: `useBlockElement` could never return elements because the ref callback of `useBlockElementRef` was never called. Co-authored-by: mcsf <mcsf@git.wordpress.org> Co-authored-by: jorgefilipecosta <jorgefilipecosta@git.wordpress.org>
The fit text feature wasn't working in site editor preview mode because
useBlockElement()returnsnullwhen blocks are rendered there I think that's a bug but I was not having luck finding a fix in a very short time frame for 6.9. So I added a fit text specific work around.Solution
useFitText()that queries the DOM directly when the ref-baseduseBlockElement()returnsnull. The fallback checks both the main document and the editor canvas iframe (iframe[name="editor-canvas"]) to find the block element.cc: @jasmussen, @henriqueiamarino
Testing
Technical Details
The fix uses
useLayoutEffectto query the DOM whenblockElementis null:document.getElementById()in the main documentiframe[name="editor-canvas"]actualElement = blockElement || fallbackElementThis ensures fit text works both in the normal editor (using refs) and in preview mode (using DOM queries).
Screenshot
Screen.Recording.2025-11-05.at.16.33.35.mov