diff --git a/packages/block-editor/src/hooks/fit-text.js b/packages/block-editor/src/hooks/fit-text.js index aa6a92348318de..2524680dce70ef 100644 --- a/packages/block-editor/src/hooks/fit-text.js +++ b/packages/block-editor/src/hooks/fit-text.js @@ -180,12 +180,16 @@ function useFitText( { fitText, name, clientId } ) { * @param {Function} props.setAttributes Function to set block attributes. * @param {string} props.name Block name. * @param {boolean} props.fitText Whether fit text is enabled. + * @param {string} props.fontSize Font size slug. + * @param {Object} props.style Block style object. */ export function FitTextControl( { clientId, fitText = false, setAttributes, name, + fontSize, + style, } ) { if ( ! hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY ) ) { return null; @@ -203,9 +207,28 @@ export function FitTextControl( { __nextHasNoMarginBottom label={ __( 'Fit text' ) } checked={ fitText } - onChange={ () => - setAttributes( { fitText: ! fitText || undefined } ) - } + onChange={ () => { + const newFitText = ! fitText || undefined; + const updates = { fitText: newFitText }; + + // When enabling fit text, clear font size if it has a value + if ( newFitText ) { + if ( fontSize ) { + updates.fontSize = undefined; + } + if ( style?.typography?.fontSize ) { + updates.style = { + ...style, + typography: { + ...style?.typography, + fontSize: undefined, + }, + }; + } + } + + setAttributes( updates ); + } } help={ fitText ? __( 'Text will resize to fit its container.' ) @@ -278,7 +301,7 @@ const hasFitTextSupport = ( blockNameOrType ) => { export default { useBlockProps, addSaveProps, - attributeKeys: [ 'fitText' ], + attributeKeys: [ 'fitText', 'fontSize', 'style' ], hasSupport: hasFitTextSupport, edit: FitTextControl, }; diff --git a/packages/block-editor/src/hooks/typography.js b/packages/block-editor/src/hooks/typography.js index 066211c15aafe9..5c551a4bb35761 100644 --- a/packages/block-editor/src/hooks/typography.js +++ b/packages/block-editor/src/hooks/typography.js @@ -116,11 +116,13 @@ function TypographyInspectorControl( { children, resetAllFilter } ) { export function TypographyPanel( { clientId, name, setAttributes, settings } ) { function selector( select ) { - const { style, fontFamily, fontSize } = + const { style, fontFamily, fontSize, fitText } = select( blockEditorStore ).getBlockAttributes( clientId ) || {}; - return { style, fontFamily, fontSize }; + return { style, fontFamily, fontSize, fitText }; } - const { style, fontFamily, fontSize } = useSelect( selector, [ clientId ] ); + const { style, fontFamily, fontSize, fitText } = useSelect( selector, [ + clientId, + ] ); const isEnabled = useHasTypographyPanel( settings ); const value = useMemo( () => attributesToStyle( { style, fontFamily, fontSize } ), @@ -128,7 +130,16 @@ export function TypographyPanel( { clientId, name, setAttributes, settings } ) { ); const onChange = ( newStyle ) => { - setAttributes( styleToAttributes( newStyle ) ); + const newAttributes = styleToAttributes( newStyle ); + + // If setting a font size and fitText is currently enabled, disable it + const hasFontSize = + newAttributes.fontSize || newAttributes.style?.typography?.fontSize; + if ( hasFontSize && fitText ) { + newAttributes.fitText = undefined; + } + + setAttributes( newAttributes ); }; if ( ! isEnabled ) { diff --git a/test/e2e/specs/editor/blocks/fit-text.spec.js b/test/e2e/specs/editor/blocks/fit-text.spec.js index ce9f22a561c81d..5dd045d844587e 100644 --- a/test/e2e/specs/editor/blocks/fit-text.spec.js +++ b/test/e2e/specs/editor/blocks/fit-text.spec.js @@ -221,6 +221,89 @@ test.describe( 'Fit Text', () => { // Fit text should scale up significantly for short content expect( fitTextSize ).toBeGreaterThan( normalSize * 2 ); } ); + + test( 'should disable fit text when a font size is selected', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'core/heading', + attributes: { + content: 'Test Heading', + level: 2, + fitText: true, + }, + } ); + + await editor.openDocumentSettingsSidebar(); + + // Set a custom font size + await page.click( + 'role=region[name="Editor settings"i] >> role=button[name="Set custom size"i]' + ); + await page.click( 'role=spinbutton[name="Font size"i]' ); + await page.keyboard.type( '24' ); + + // fitText should be cleared + await expect.poll( editor.getBlocks ).toMatchObject( [ + { + name: 'core/heading', + attributes: expect.objectContaining( { + content: 'Test Heading', + level: 2, + style: { + typography: { + fontSize: '24px', + }, + }, + } ), + }, + ] ); + } ); + + test( 'should clear font size when fit text is enabled', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'core/heading', + attributes: { + content: 'Test Heading', + level: 2, + fontSize: 'large', + }, + } ); + + await editor.openDocumentSettingsSidebar(); + + // Enable Fit text control via Typography options menu + await page + .getByRole( 'region', { name: 'Editor settings' } ) + .getByRole( 'button', { name: 'Typography options' } ) + .click(); + await page + .getByRole( 'menu', { name: 'Typography options' } ) + .getByRole( 'menuitemcheckbox', { name: 'Show Fit text' } ) + .click(); + + const fitTextToggle = page.getByRole( 'checkbox', { + name: 'Fit text', + } ); + + await fitTextToggle.click(); + + // fontSize should be cleared + await expect.poll( editor.getBlocks ).toMatchObject( [ + { + name: 'core/heading', + attributes: expect.objectContaining( { + content: 'Test Heading', + level: 2, + fitText: true, + } ), + }, + ] ); + } ); } ); test.describe( 'Frontend functionality', () => {