Skip to content

Commit

Permalink
Font family: switch from CSS Custom Property to classes (#31910)
Browse files Browse the repository at this point in the history
This PR switches the font-family property to use class names instead of CSS Custom Properties, following what the other properties do.

Co-authored-by: André <andres.maneiro@automattic.com>
Co-authored-by: André <583546+oandregal@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 20, 2021
1 parent 2b91d6d commit 1e17b5a
Show file tree
Hide file tree
Showing 75 changed files with 1,469 additions and 104 deletions.
24 changes: 14 additions & 10 deletions lib/block-supports/typography.php
Expand Up @@ -105,17 +105,21 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}

if ( $has_font_family_support ) {
$has_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );
if ( $has_font_family ) {
$font_family = $block_attributes['style']['typography']['fontFamily'];
if ( strpos( $font_family, 'var:preset|font-family' ) !== false ) {
// Get the name from the string and add proper styles.
$index_to_splice = strrpos( $font_family, '|' ) + 1;
$font_family_name = substr( $font_family, $index_to_splice );
$styles[] = sprintf( 'font-family: var(--wp--preset--font-family--%s);', $font_family_name );
} else {
$styles[] = sprintf( 'font-family: %s;', $block_attributes['style']['typography']['fontFamily'] );
$has_named_font_family = array_key_exists( 'fontFamily', $block_attributes );
$has_custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );

if ( $has_named_font_family ) {
$classes[] = sprintf( 'has-%s-font-family', gutenberg_experimental_to_kebab_case( $block_attributes['fontFamily'] ) );
} elseif ( $has_custom_font_family ) {
// Before using classes, the value was serialized as a CSS Custom Property.
// We don't need this code path when it lands in core.
$font_family_custom = $block_attributes['style']['typography']['fontFamily'];
if ( strpos( $font_family_custom, 'var:preset|font-family' ) !== false ) {
$index_to_splice = strrpos( $font_family_custom, '|' ) + 1;
$font_family_slug = gutenberg_experimental_to_kebab_case( substr( $font_family_custom, $index_to_splice ) );
$font_family_custom = sprintf( 'var(--wp--preset--font-family--%s)', $font_family_slug );
}
$styles[] = sprintf( 'font-family: %s;', $font_family_custom );
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/class-wp-theme-json-gutenberg.php
Expand Up @@ -205,7 +205,7 @@ class WP_Theme_JSON_Gutenberg {
'path' => array( 'typography', 'fontFamilies' ),
'value_key' => 'fontFamily',
'css_vars' => '--wp--preset--font-family--$slug',
'classes' => array(),
'classes' => array( '.has-$slug-font-family' => 'font-family' ),
'properties' => array( 'font-family' ),
),
);
Expand Down
134 changes: 107 additions & 27 deletions packages/block-editor/src/hooks/font-family.js
@@ -1,39 +1,111 @@
/**
* External dependencies
*/
import { find } from 'lodash';
import { find, kebabCase } from 'lodash';

/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { hasBlockSupport } from '@wordpress/blocks';
import TokenList from '@wordpress/token-list';

/**
* Internal dependencies
*/
import { cleanEmptyObject } from './utils';
import useSetting from '../components/use-setting';
import FontFamilyControl from '../components/font-family';

export const FONT_FAMILY_SUPPORT_KEY = 'typography.__experimentalFontFamily';

const getFontFamilyFromAttributeValue = ( fontFamilies, value ) => {
const attributeParsed = /var:preset\|font-family\|(.+)/.exec( value );
if ( attributeParsed && attributeParsed[ 1 ] ) {
const fontFamilyObject = find( fontFamilies, ( { slug } ) => {
return slug === attributeParsed[ 1 ];
/**
* 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',
},
} );
if ( fontFamilyObject ) {
return fontFamilyObject.fontFamily;
}
}
return value;
};

return settings;
}

/**
* Override props assigned to save component to inject font family.
*
* @param {Object} props Additional props applied to save element
* @param {Object} blockType Block type
* @param {Object} attributes Block attributes
* @return {Object} Filtered props applied to save element
*/
function addSaveProps( props, blockType, attributes ) {
if ( ! hasBlockSupport( blockType, FONT_FAMILY_SUPPORT_KEY ) ) {
return props;
}

if (
hasBlockSupport(
blockType,
'__experimentalSkipTypographySerialization'
)
) {
return props;
}

if ( ! attributes?.fontFamily ) {
return props;
}

// Use TokenList to dedupe classes.
const classes = new TokenList( props.className );
classes.add( `has-${ kebabCase( attributes?.fontFamily ) }-font-family` );
const newClassName = classes.value;
props.className = newClassName ? newClassName : undefined;

return props;
}

/**
* Filters registered block settings to expand the block edit wrapper
* by applying the desired styles and classnames.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function addEditProps( settings ) {
if ( ! hasBlockSupport( settings, FONT_FAMILY_SUPPORT_KEY ) ) {
return settings;
}

const existingGetEditWrapperProps = settings.getEditWrapperProps;
settings.getEditWrapperProps = ( attributes ) => {
let props = {};
if ( existingGetEditWrapperProps ) {
props = existingGetEditWrapperProps( attributes );
}
return addSaveProps( props, settings, attributes );
};

return settings;
}

export function FontFamilyEdit( {
name,
setAttributes,
attributes: { style = {} },
attributes: { fontFamily },
} ) {
const fontFamilies = useSetting( 'typography.fontFamilies' );
const isDisable = useIsFontFamilyDisabled( { name } );
Expand All @@ -42,26 +114,16 @@ export function FontFamilyEdit( {
return null;
}

const value = getFontFamilyFromAttributeValue(
fontFamilies,
style.typography?.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
? `var:preset|font-family|${ predefinedFontFamily.slug }`
: newValue || undefined,
},
} ),
fontFamily: predefinedFontFamily?.slug,
} );
}

Expand Down Expand Up @@ -89,3 +151,21 @@ export function useIsFontFamilyDisabled( { name } ) {
! hasBlockSupport( name, FONT_FAMILY_SUPPORT_KEY )
);
}

addFilter(
'blocks.registerBlockType',
'core/fontFamily/addAttribute',
addAttributes
);

addFilter(
'blocks.getSaveContent.extraProps',
'core/fontFamily/addSaveProps',
addSaveProps
);

addFilter(
'blocks.registerBlockType',
'core/fontFamily/addEditProps',
addEditProps
);

0 comments on commit 1e17b5a

Please sign in to comment.