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

Add: Font Family picking mechanism #24868

Merged
merged 2 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions lib/block-supports/typography.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
$has_line_height_support = gutenberg_experimental_get( $block_type->supports, array( 'lineHeight' ), false );
$has_text_transform_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalTextTransform' ), false );

$has_font_family_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$has_font_family_support = gutenberg_experimental_get( $block_type->supports, array( '__experimentalFontFamily' ), false );
}

// Font Size.
if ( $has_font_size_support ) {
$has_named_font_size = array_key_exists( 'fontSize', $block_attributes );
Expand All @@ -77,6 +82,23 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
}
}

// Font Family.
if ( $has_font_family_support ) {
$has_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );
// Apply required class and style.
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']['color']['fontFamily'] );
Copy link
Member

@oandregal oandregal Jul 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under which situations a font-family value is not in the form of var:preset|font-family|etc?

Unlike other style properties, users can't provide custom values, so I don't see how this path is reached. I presume we can remove it. The fact that this has been using style.COLOR.fontFamily without a bug being reported seems to confirm this is a code path we don't need. cc @jorgefilipecosta @aristath

For context, this question comes from a PR I'm working on at #31910 to use classes instead of CSS Custom Properties for font-family. I'm looking at removing this code path there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a situation where font-family may not be preset is in the case of a block pattern where the pattern is excitedly using a specific font family in a block.

Regarding the usage of classes for font-family presets I think we can use variables for now it is not clear classes bring any advantage in that use case. For the colors, we are outputting CSS vars anyway so a block could use the vars directly and we need to support that. For the font family, I guess we can keep with just vars for now and see what feedback we get.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a situation where font-family may not be preset is in the case of a block pattern

Nice thinking, thanks! I'll keep that use case then.

Regarding the usage of classes for font-family presets I think we can use variables for now it is not clear classes bring any advantage in that use case

I'd think we want to do it the other way around: what's the advantage of font-family using custom properties instead of classes, as the other style properties do?

}
}
}

// Line Height.
if ( $has_line_height_support ) {
$has_line_height = isset( $block_attributes['style']['typography']['lineHeight'] );
Expand Down
9 changes: 9 additions & 0 deletions lib/global-styles.php
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ function gutenberg_experimental_global_styles_get_css_property( $style_property
return 'font-size';
case 'lineHeight':
return 'line-height';
case 'fontFamily':
return 'font-family';
case 'textTransform':
return 'text-transform';
default:
Expand All @@ -414,6 +416,7 @@ function gutenberg_experimental_global_styles_get_style_property() {
'backgroundColor' => array( 'color', 'background' ),
'color' => array( 'color', 'text' ),
'fontSize' => array( 'typography', 'fontSize' ),
'fontFamily' => array( 'typography', 'fontFamily' ),
'lineHeight' => array( 'typography', 'lineHeight' ),
'textTransform' => array( 'typography', 'textTransform' ),
);
Expand All @@ -432,6 +435,7 @@ function gutenberg_experimental_global_styles_get_support_keys() {
'color' => array( 'color' ),
'fontSize' => array( 'fontSize' ),
'lineHeight' => array( 'lineHeight' ),
'fontFamily' => array( '__experimentalFontFamily' ),
'textTransform' => array( '__experimentalTextTransform' ),
);
}
Expand All @@ -455,6 +459,10 @@ function gutenberg_experimental_global_styles_get_presets_structure() {
'path' => array( 'typography', 'fontSizes' ),
'key' => 'size',
),
'fontFamily' => array(
'path' => array( 'typography', 'fontFamilies' ),
'key' => 'fontFamily',
),
'textTransform' => array(
'path' => array( 'typography', 'textTransforms' ),
'key' => 'slug',
Expand Down Expand Up @@ -498,6 +506,7 @@ function gutenberg_experimental_global_styles_get_block_data() {
array(
'supports' => array(
'__experimentalSelector' => ':root',
'__experimentalFontFamily' => true,
'fontSize' => true,
'__experimentalTextTransform' => true,
'color' => array(
Expand Down
53 changes: 53 additions & 0 deletions packages/block-editor/src/components/font-family/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* External dependencies
*/
import { isEmpty } from 'lodash';

/**
* WordPress dependencies
*/
import { SelectControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import useEditorFeature from '../use-editor-feature';

export default function FontFamilyControl( {
value = '',
onChange,
fontFamilies,
...props
} ) {
const blockLevelFontFamilies = useEditorFeature(
'typography.fontFamilies'
);
if ( ! fontFamilies ) {
fontFamilies = blockLevelFontFamilies;
}

if ( isEmpty( fontFamilies ) ) {
return null;
}

const options = [
{ value: '', label: __( 'Default' ) },
...fontFamilies.map( ( { fontFamily, name } ) => {
return {
value: fontFamily,
label: name || fontFamily,
};
} ),
];
return (
<SelectControl
label={ __( 'Font family' ) }
options={ options }
value={ value }
onChange={ onChange }
labelPosition="top"
{ ...props }
/>
);
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export { default as ContrastChecker } from './contrast-checker';
export { default as __experimentalGradientPicker } from './gradient-picker';
export { default as __experimentalGradientPickerControl } from './gradient-picker/control';
export { default as __experimentalGradientPickerPanel } from './gradient-picker/panel';
export { default as __experimentalFontFamilyControl } from './font-family';
export { default as __experimentalColorGradientControl } from './colors-gradients/control';
export { default as __experimentalPanelColorGradientSettings } from './colors-gradients/panel-color-gradient-settings';
export { default as __experimentalImageSizeControl } from './image-size-control';
Expand Down
88 changes: 88 additions & 0 deletions packages/block-editor/src/hooks/font-family.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* External dependencies
*/
import { find } from 'lodash';

/**
* WordPress dependencies
*/
import { hasBlockSupport } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { cleanEmptyObject } from './utils';
import useEditorFeature from '../components/use-editor-feature';
import FontFamilyControl from '../components/font-family';

export const FONT_FAMILY_SUPPORT_KEY = '__experimentalFontFamily';

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

export function FontFamilyEdit( {
name,
setAttributes,
attributes: { style = {} },
} ) {
const fontFamilies = useEditorFeature( 'typography.fontFamilies' );
const isDisable = useIsFontFamilyDisabled( { name } );

if ( isDisable ) {
return null;
}

const value = getFontFamilyFromAttributeValue(
fontFamilies,
style.typography?.fontFamily
);

function onChange( newValue ) {
const predefinedFontFamily = find(
fontFamilies,
( { fontFamily } ) => fontFamily === newValue
);
setAttributes( {
style: cleanEmptyObject( {
...style,
typography: {
...( style.typography || {} ),
fontFamily: predefinedFontFamily
? `var:preset|font-family|${ predefinedFontFamily.slug }`
: newValue || undefined,
},
} ),
} );
}

return (
<FontFamilyControl
className="block-editor-hooks-font-family-control"
fontFamilies={ fontFamilies }
value={ value }
onChange={ onChange }
/>
);
}

/**
* Custom hook that checks if font-family functionality is disabled.
*
* @param {string} name The name of the block.
* @return {boolean} Whether setting is disabled.
*/
export function useIsFontFamilyDisabled( { name } ) {
const fontFamilies = useEditorFeature( 'typography.fontFamilies' );
return (
! fontFamilies ||
fontFamilies.length === 0 ||
! hasBlockSupport( name, FONT_FAMILY_SUPPORT_KEY )
);
}
8 changes: 8 additions & 0 deletions packages/block-editor/src/hooks/typography.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import {
LineHeightEdit,
useIsLineHeightDisabled,
} from './line-height';
import {
FONT_FAMILY_SUPPORT_KEY,
FontFamilyEdit,
useIsFontFamilyDisabled,
} from './font-family';
import {
FONT_SIZE_SUPPORT_KEY,
FontSizeEdit,
Expand All @@ -30,6 +35,7 @@ import {
export const TYPOGRAPHY_SUPPORT_KEYS = [
LINE_HEIGHT_SUPPORT_KEY,
FONT_SIZE_SUPPORT_KEY,
FONT_FAMILY_SUPPORT_KEY,
TEXT_TRANSFORM_SUPPORT_KEY,
];

Expand All @@ -42,6 +48,7 @@ export function TypographyPanel( props ) {
return (
<InspectorControls>
<PanelBody title={ __( 'Typography' ) }>
<FontFamilyEdit { ...props } />
<FontSizeEdit { ...props } />
<LineHeightEdit { ...props } />
<TextDecorationAndTransformEdit { ...props } />
Expand All @@ -63,6 +70,7 @@ function useIsTypographyDisabled( props = {} ) {
const configs = [
useIsFontSizeDisabled( props ),
useIsLineHeightDisabled( props ),
useIsFontFamilyDisabled( props ),
useIsTextTransformDisabled( props ),
];

Expand Down
3 changes: 2 additions & 1 deletion packages/block-library/src/navigation/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"color": {
"textColor": true,
"backgroundColor": true
}
},
"__experimentalFontFamily": true
}
}
1 change: 1 addition & 0 deletions packages/block-library/src/post-title/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalSelector": {
"core/post-title/h1": "h1",
"core/post-title/h2": "h2",
Expand Down
3 changes: 2 additions & 1 deletion packages/block-library/src/site-tagline/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"gradients": true
},
"fontSize": true,
"lineHeight": true
"lineHeight": true,
"__experimentalFontFamily": true
}
}
3 changes: 2 additions & 1 deletion packages/block-library/src/site-title/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"gradients": true
},
"fontSize": true,
"lineHeight": true
"lineHeight": true,
"__experimentalFontFamily": true
}
}
1 change: 1 addition & 0 deletions packages/blocks/src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = {
paddingLeft: [ 'spacing', 'padding', 'left' ],
paddingRight: [ 'spacing', 'padding', 'right' ],
paddingTop: [ 'spacing', 'padding', 'top' ],
fontFamily: [ 'typography', 'fontFamily' ],
};
1 change: 1 addition & 0 deletions packages/edit-site/src/components/editor/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const PRESET_CATEGORIES = {
color: { path: [ 'color', 'palette' ], key: 'color' },
gradient: { path: [ 'color', 'gradients' ], key: 'gradient' },
fontSize: { path: [ 'typography', 'fontSizes' ], key: 'size' },
fontFamily: { path: [ 'typography', 'fontFamilies' ], key: 'fontFamily' },
textTransform: { path: [ 'typography', 'textTransforms' ], key: 'slug' },
};
export const LINK_COLOR = '--wp--style--color--link';
Expand Down
15 changes: 14 additions & 1 deletion packages/edit-site/src/components/sidebar/typography-panel.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/**
* WordPress dependencies
*/
import { LineHeightControl } from '@wordpress/block-editor';
import {
LineHeightControl,
__experimentalFontFamilyControl as FontFamilyControl,
} from '@wordpress/block-editor';
import { PanelBody, FontSizePicker } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

Expand All @@ -24,9 +27,18 @@ export default function TypographyPanel( {
'typography.customFontSize',
name
);
const fontFamilies = useEditorFeature( 'typography.fontFamilies', name );

return (
<PanelBody title={ __( 'Typography' ) } initialOpen={ true }>
{ supports.includes( 'fontFamily' ) && (
<FontFamilyControl
value={ getStyleProperty( name, 'fontFamily' ) }
onChange={ ( value ) =>
setStyleProperty( name, 'fontFamily', value )
}
/>
) }
{ supports.includes( 'fontSize' ) && (
<FontSizePicker
value={ getStyleProperty( name, 'fontSize' ) }
Expand All @@ -39,6 +51,7 @@ export default function TypographyPanel( {
) }
{ supports.includes( 'lineHeight' ) && (
<LineHeightControl
fontFamilies={ fontFamilies }
value={ getStyleProperty( name, 'lineHeight' ) }
onChange={ ( value ) =>
setStyleProperty( name, 'lineHeight', value )
Expand Down