From e791e77de36febc0b0d224000374cc285ab50470 Mon Sep 17 00:00:00 2001 From: Jorge Date: Thu, 27 Aug 2020 16:58:54 +0100 Subject: [PATCH] Add: Font Family picking mechanism --- lib/experimental-default-theme.json | 55 ++++++++ lib/global-styles.php | 2 + .../block-editor/src/hooks/font-family.js | 130 ++++++++++++++++++ .../block-editor/src/hooks/font-family.scss | 4 + packages/block-editor/src/hooks/style.js | 1 + packages/block-editor/src/hooks/typography.js | 8 ++ packages/block-editor/src/style.scss | 1 + .../block-library/src/paragraph/block.json | 1 + 8 files changed, 202 insertions(+) create mode 100644 packages/block-editor/src/hooks/font-family.js create mode 100644 packages/block-editor/src/hooks/font-family.scss diff --git a/lib/experimental-default-theme.json b/lib/experimental-default-theme.json index 23357d05d29f2..dec66b7e09b7d 100644 --- a/lib/experimental-default-theme.json +++ b/lib/experimental-default-theme.json @@ -73,6 +73,61 @@ "value": 48 } ], + "font-family": [ + { + "value": "Georgia, serif", + "slug": "georgia", + "name": "Georgia, serif" + }, + { + "value": "\"Palatino Linotype\", \"Book Antiqua\", Palatino, serif", + "slug": "palatino-linotype" + }, + { + "value": "\"Times New Roman\", Times, serif", + "slug": "times-new-roman" + }, + { + "value": "Arial, Helvetica, sans-serif", + "slug": "arial" + }, + { + "value": "\"Arial Black\", Gadget, sans-serif", + "slug": "arial-block" + }, + { + "value": "\"Comic Sans MS\", cursive, sans-serif", + "slug": "comic-sans-ms" + }, + { + "value": "Impact, Charcoal, sans-serif", + "slug": "impact" + }, + { + "value": "\"Lucida Sans Unicode\", \"Lucida Grande\", sans-serif", + "slug": "lucida-sans-unicode" + }, + { + "value": "Tahoma, Geneva, sans-serif", + "slug": "tahoma" + }, + { + "value": "\"Trebuchet MS\", Helvetica, sans-serif", + "slug": "trebuchet-ms" + }, + { + "value": "Verdana, Geneva, sans-serif", + "slug": "verdana" + }, + { + "value": "\"Courier New\", Courier, monospace", + "slug": "courier-new" + }, + { + "value": "\"Lucida Console\", Monaco, monospace", + "slug": "lucida-console" + } + ], "gradient": [ { "slug": "blush-bordeaux", diff --git a/lib/global-styles.php b/lib/global-styles.php index b4d916555f172..2e4598be89215 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -276,6 +276,7 @@ function gutenberg_experimental_global_styles_get_supported_styles( $supports ) 'color' => array( '__experimentalColor' ), 'font-size' => array( '__experimentalFontSize' ), 'line-height' => array( '__experimentalLineHeight' ), + 'font-family' => array( '__experimentalFontFamily' ), ); $supported_features = array(); @@ -385,6 +386,7 @@ function gutenberg_experimental_global_styles_flatten_styles_tree( $styles ) { $mappings = array( 'line-height' => array( 'typography', 'lineHeight' ), 'font-size' => array( 'typography', 'fontSize' ), + 'font-family' => array( 'typography', 'fontFamily' ), 'background' => array( 'color', 'gradient' ), 'background-color' => array( 'color', 'background' ), 'color' => array( 'color', 'text' ), diff --git a/packages/block-editor/src/hooks/font-family.js b/packages/block-editor/src/hooks/font-family.js new file mode 100644 index 0000000000000..13b716a5dfcad --- /dev/null +++ b/packages/block-editor/src/hooks/font-family.js @@ -0,0 +1,130 @@ +/** + * External dependencies + */ +import { find } from 'lodash'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { hasBlockSupport } from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; +import { CustomSelectControl } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { cleanEmptyObject } from './utils'; + +export const FONT_FAMILY_SUPPORT_KEY = '__experimentalFontFamily'; + +const EMPTY_ARRAY = []; + +function FontFamilyControl( { + fontFamilies = [], + value = '', + onChange, + ...props +} ) { + const options = [ + { key: '', name: __( 'Default' ) }, + ...fontFamilies.map( ( { value: fontFamily, name } ) => { + return { + key: fontFamily, + name: name || fontFamily, + style: { fontFamily }, + }; + } ), + ]; + return ( + option.key === value ) } + onChange={ ( { selectedItem: { key } } ) => onChange( key ) } + { ...props } + /> + ); +} + +const getFontFamilyFromAttributeValue = ( fontFamilies, value ) => { + const attributeParsed = /var:preset\|font-family\|(.+)/.exec( value ); + if ( attributeParsed && attributeParsed[ 1 ] ) { + return find( fontFamilies, ( { slug } ) => { + return slug === attributeParsed[ 1 ]; + } ).value; + } + return value; +}; + +export function FontFamilyEdit( { + name, + setAttributes, + attributes: { style = {} }, +} ) { + const isDisable = useIsFontFamilyDisabled( { name } ); + const fontFamilies = useSelect( ( select ) => { + const editorSettings = select( 'core/block-editor' ).getSettings(); + return ( + editorSettings.__experimentalGlobalStylesBase?.global.presets[ + 'font-family' + ] || EMPTY_ARRAY + ); + } ); + + if ( isDisable ) { + return null; + } + + const fontFamily = getFontFamilyFromAttributeValue( + fontFamilies, + style.typography?.fontFamily + ); + + function onChange( newValue ) { + const predefinedFontFamily = find( + fontFamilies, + ( { value } ) => value === newValue + ); + setAttributes( { + style: cleanEmptyObject( { + ...style, + typography: { + ...( style.typography || {} ), + fontFamily: predefinedFontFamily + ? `var:preset|font-family|${ predefinedFontFamily.slug }` + : newValue || undefined, + }, + } ), + } ); + } + + return ( + + ); +} + +/** + * 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 } ) { + return ( + useSelect( ( select ) => { + const editorSettings = select( 'core/block-editor' ).getSettings(); + return ( + ( + editorSettings.__experimentalGlobalStylesBase?.global + .presets[ 'font-family' ] || EMPTY_ARRAY + ).length === 0 + ); + } ) || ! hasBlockSupport( name, FONT_FAMILY_SUPPORT_KEY ) + ); +} diff --git a/packages/block-editor/src/hooks/font-family.scss b/packages/block-editor/src/hooks/font-family.scss new file mode 100644 index 0000000000000..7695385a4f8a0 --- /dev/null +++ b/packages/block-editor/src/hooks/font-family.scss @@ -0,0 +1,4 @@ +.block-editor-hooks-font-family-control > button { + width: 100%; + margin-bottom: $grid-unit-10; +} diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index de5de6c278951..f5dfd4afd2636 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -56,6 +56,7 @@ export function getInlineStyles( styles = {} ) { ...paddingStyleMappings, lineHeight: [ 'typography', 'lineHeight' ], fontSize: [ 'typography', 'fontSize' ], + fontFamily: [ 'typography', 'fontFamily' ], background: [ 'color', 'gradient' ], backgroundColor: [ 'color', 'background' ], color: [ 'color', 'text' ], diff --git a/packages/block-editor/src/hooks/typography.js b/packages/block-editor/src/hooks/typography.js index 49a281cb219ea..e219d50b2f3ee 100644 --- a/packages/block-editor/src/hooks/typography.js +++ b/packages/block-editor/src/hooks/typography.js @@ -16,6 +16,11 @@ import { LineHeightEdit, useIsLineHeightDisabled, } from './line-height'; +import { + FONT_FAMILY_SUPPORT_KEY, + FontFamilyEdit, + useIsFontFamilyDisabled, +} from './font-family'; import { FONT_SIZE_SUPPORT_KEY, FontSizeEdit, @@ -25,6 +30,7 @@ import { export const TYPOGRAPHY_SUPPORT_KEYS = [ LINE_HEIGHT_SUPPORT_KEY, FONT_SIZE_SUPPORT_KEY, + FONT_FAMILY_SUPPORT_KEY, ]; export function TypographyPanel( props ) { @@ -36,6 +42,7 @@ export function TypographyPanel( props ) { return ( + @@ -56,6 +63,7 @@ function useIsTypographyDisabled( props = {} ) { const configs = [ useIsFontSizeDisabled( props ), useIsLineHeightDisabled( props ), + useIsFontFamilyDisabled( props ), ]; return configs.filter( Boolean ).length === configs.length; diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 096eb3bacb796..808d58fd7c1e4 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -49,6 +49,7 @@ @import "./components/warning/style.scss"; @import "./components/writing-flow/style.scss"; @import "./hooks/anchor.scss"; +@import "./hooks/font-family.scss"; // This tag marks the end of the styles that apply to editing canvas contents and need to be manipulated when we resize the editor. #end-resizable-editor-section { diff --git a/packages/block-library/src/paragraph/block.json b/packages/block-library/src/paragraph/block.json index 91d8ad357f7eb..50e089d2ce434 100644 --- a/packages/block-library/src/paragraph/block.json +++ b/packages/block-library/src/paragraph/block.json @@ -34,6 +34,7 @@ "linkColor": true }, "__experimentalFontSize": true, + "__experimentalFontFamily": true, "__experimentalLineHeight": true, "__experimentalSelector": "p", "__unstablePasteTextInline": true