From 25e0ffc521603eeb71353e96ecccf3340e4fc8c3 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Tue, 18 May 2021 21:08:38 +0200 Subject: [PATCH] Move into separate fontFamily attribute --- .../block-editor/src/hooks/font-family.js | 119 +++++++++++++++--- 1 file changed, 101 insertions(+), 18 deletions(-) diff --git a/packages/block-editor/src/hooks/font-family.js b/packages/block-editor/src/hooks/font-family.js index 6f9b512fb6a609..491647d8e86d88 100644 --- a/packages/block-editor/src/hooks/font-family.js +++ b/packages/block-editor/src/hooks/font-family.js @@ -9,16 +9,40 @@ import { find } from 'lodash'; import { addFilter } from '@wordpress/hooks'; import { hasBlockSupport } from '@wordpress/blocks'; import TokenList from '@wordpress/token-list'; +import { createHigherOrderComponent } from '@wordpress/compose'; /** * Internal dependencies */ -import { cleanEmptyObject } from './utils'; import useSetting from '../components/use-setting'; import FontFamilyControl from '../components/font-family'; export const FONT_FAMILY_SUPPORT_KEY = '__experimentalFontFamily'; +/** + * Filters registered block settings, extending attributes to include + * the `fontFamily` attribute. + * + * @param {Object} settings Original block settings + * @return {Object} Filtered block settings + */ +function addAttributes( settings ) { + if ( ! hasBlockSupport( settings, FONT_FAMILY_SUPPORT_KEY ) ) { + return settings; + } + + // Allow blocks to specify a default value if needed. + if ( ! settings.attributes.fontFamily ) { + Object.assign( settings.attributes, { + fontFamily: { + type: 'string', + }, + } ); + } + + return settings; +} + /** * Override props assigned to save component to inject font family. * @@ -41,11 +65,13 @@ function addSaveProps( props, blockType, attributes ) { return props; } + if ( ! attributes?.fontFamily ) { + return props; + } + // Use TokenList to dedupe classes. const classes = new TokenList( props.className ); - classes.add( - `has-${ attributes.style?.typography?.fontFamily }-font-family` - ); + classes.add( `has-${ attributes?.fontFamily }-font-family` ); const newClassName = classes.value; props.className = newClassName ? newClassName : undefined; @@ -55,7 +81,7 @@ function addSaveProps( props, blockType, attributes ) { export function FontFamilyEdit( { name, setAttributes, - attributes: { style = {} }, + attributes: { fontFamily }, } ) { const fontFamilies = useSetting( 'typography.fontFamilies' ); const isDisable = useIsFontFamilyDisabled( { name } ); @@ -64,25 +90,16 @@ export function FontFamilyEdit( { return null; } - const value = find( - fontFamilies, - ( { slug } ) => style.typography?.fontFamily === slug - )?.fontFamily; + const value = find( fontFamilies, ( { slug } ) => fontFamily === slug ) + ?.fontFamily; function onChange( newValue ) { const predefinedFontFamily = find( fontFamilies, - ( { fontFamily } ) => fontFamily === newValue + ( { fontFamily: f } ) => f === newValue ); setAttributes( { - style: cleanEmptyObject( { - ...style, - typography: { - ...( style.typography || {} ), - fontFamily: - predefinedFontFamily?.slug || newValue || undefined, - }, - } ), + fontFamily: predefinedFontFamily?.slug, } ); } @@ -111,8 +128,74 @@ export function useIsFontFamilyDisabled( { name } ) { ); } +/** + * Add inline styles for font families. + * Ideally, this is not needed and themes load the font-family classes on the + * editor. + * + * @param {Function} BlockListBlock Original component + * @return {Function} Wrapped component + */ +const withFontFamilyInlineStyles = createHigherOrderComponent( + ( BlockListBlock ) => ( props ) => { + const fontFamilies = useSetting( 'typography.fontFamilies' ); + const { + name: blockName, + attributes: { fontFamily, style }, + wrapperProps, + } = props; + + // Only add inline styles if the block supports font families, + // doesn't skip serialization of font families, + // doesn't already have an inline font family, + // and does have a class to extract the font family from. + if ( + ! hasBlockSupport( blockName, FONT_FAMILY_SUPPORT_KEY ) || + hasBlockSupport( + blockName, + '__experimentalSkipTypographySerialization' + ) || + ! fontFamily || + style?.typography?.fontFamily + ) { + return ; + } + + const fontFamilyValue = find( + fontFamilies, + ( { slug } ) => slug === fontFamily + )?.fontFamily; + + const newProps = { + ...props, + wrapperProps: { + ...wrapperProps, + style: { + fontFamily: fontFamilyValue, + ...wrapperProps?.style, + }, + }, + }; + + return ; + }, + 'withFontFamilyInlineStyles' +); + +addFilter( + 'blocks.registerBlockType', + 'core/font/addAttribute', + addAttributes +); + addFilter( 'blocks.getSaveContent.extraProps', 'core/fontFamily/addSaveProps', addSaveProps ); + +addFilter( + 'editor.BlockListBlock', + 'core/font-family/with-font-family-inline-styles', + withFontFamilyInlineStyles +);