diff --git a/packages/block-editor/src/components/global-styles/hooks.js b/packages/block-editor/src/components/global-styles/hooks.js index 5b2151dbfaba4..b843b978bbd4b 100644 --- a/packages/block-editor/src/components/global-styles/hooks.js +++ b/packages/block-editor/src/components/global-styles/hooks.js @@ -218,3 +218,48 @@ export function useSupportedStyles( name, element ) { return supportedPanels; } + +/** + * Given a settings object and a list of supported panels, + * returns a new settings object with the unsupported panels removed. + * + * @param {Object} settings Settings object. + * @param {string[]} supports Supported style panels. + * + * @return {Object} Merge of settings and supports. + */ +export function overrideSettingsWithSupports( settings, supports ) { + const updatedSettings = { ...settings }; + + if ( ! supports.includes( 'fontSize' ) ) { + updatedSettings.typography = { + ...updatedSettings.typography, + fontSizes: {}, + customFontSize: false, + }; + } + + if ( ! supports.includes( 'fontFamily' ) ) { + updatedSettings.typography = { + ...updatedSettings.typography, + fontFamilies: {}, + }; + } + + [ + 'lineHeight', + 'fontStyle', + 'fontWeight', + 'letterSpacing', + 'textTransform', + ].forEach( ( key ) => { + if ( ! supports.includes( key ) ) { + updatedSettings.typography = { + ...updatedSettings.typography, + [ key ]: false, + }; + } + } ); + + return updatedSettings; +} diff --git a/packages/block-editor/src/components/global-styles/index.js b/packages/block-editor/src/components/global-styles/index.js index 6581f46254985..77582d2f05415 100644 --- a/packages/block-editor/src/components/global-styles/index.js +++ b/packages/block-editor/src/components/global-styles/index.js @@ -2,6 +2,7 @@ export { useGlobalStylesReset, useGlobalSetting, useGlobalStyle, + overrideSettingsWithSupports, } from './hooks'; export { useGlobalStylesOutput } from './use-global-styles-output'; export { GlobalStylesContext } from './context'; diff --git a/packages/block-editor/src/components/global-styles/typography-panel.js b/packages/block-editor/src/components/global-styles/typography-panel.js index 471055be391f7..15ebf70da93a8 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -17,29 +17,16 @@ import LineHeightControl from '../line-height-control'; import LetterSpacingControl from '../letter-spacing-control'; import TextTransformControl from '../text-transform-control'; import TextDecorationControl from '../text-decoration-control'; -import { useSupportedStyles } from './hooks'; import { getValueFromVariable } from './utils'; -export function useHasTypographyPanel( name, element, settings ) { - const hasFontFamily = useHasFontFamilyControl( name, element, settings ); - const hasLineHeight = useHasLineHeightControl( name, element, settings ); - const hasFontAppearance = useHasAppearanceControl( - name, - element, - settings - ); - const hasLetterSpacing = useHasLetterSpacingControl( - name, - element, - settings - ); - const hasTextTransform = useHasTextTransformControl( - name, - element, - settings - ); - const hasTextDecoration = useHasTextDecorationControl( name, element ); - const hasFontSize = useHasFontSizeControl( name, element, settings ); +export function useHasTypographyPanel( settings ) { + const hasFontFamily = useHasFontFamilyControl( settings ); + const hasLineHeight = useHasLineHeightControl( settings ); + const hasFontAppearance = useHasAppearanceControl( settings ); + const hasLetterSpacing = useHasLetterSpacingControl( settings ); + const hasTextTransform = useHasTextTransformControl( settings ); + const hasTextDecoration = useHasTextDecorationControl( settings ); + const hasFontSize = useHasFontSizeControl( settings ); return ( hasFontFamily || @@ -52,52 +39,38 @@ export function useHasTypographyPanel( name, element, settings ) { ); } -function useHasFontSizeControl( name, element, settings ) { - const supports = useSupportedStyles( name, element ); +function useHasFontSizeControl( settings ) { const disableCustomFontSizes = ! settings?.typography?.customFontSize; const fontSizesPerOrigin = settings?.typography?.fontSizes ?? {}; const fontSizes = fontSizesPerOrigin?.custom ?? fontSizesPerOrigin?.theme ?? fontSizesPerOrigin.default; - return ( - supports.includes( 'fontSize' ) && - ( !! fontSizes?.length || ! disableCustomFontSizes ) - ); + return !! fontSizes?.length || ! disableCustomFontSizes; } -function useHasFontFamilyControl( name, element, settings ) { - const supports = useSupportedStyles( name, element ); +function useHasFontFamilyControl( settings ) { const fontFamiliesPerOrigin = settings?.typography?.fontFamilies; const fontFamilies = fontFamiliesPerOrigin?.custom ?? fontFamiliesPerOrigin?.theme ?? fontFamiliesPerOrigin?.default; - return supports.includes( 'fontFamily' ) && !! fontFamilies?.length; + return !! fontFamilies?.length; } -function useHasLineHeightControl( name, element, settings ) { - const supports = useSupportedStyles( name, element ); - return ( - settings?.typography?.lineHeight && supports.includes( 'lineHeight' ) - ); +function useHasLineHeightControl( settings ) { + return settings?.typography?.lineHeight; } -function useHasAppearanceControl( name, element, settings ) { - const supports = useSupportedStyles( name, element ); - const hasFontStyles = - settings?.typography?.fontStyle && supports.includes( 'fontStyle' ); - const hasFontWeights = - settings?.typography?.fontWeight && supports.includes( 'fontWeight' ); +function useHasAppearanceControl( settings ) { + const hasFontStyles = settings?.typography?.fontStyle; + const hasFontWeights = settings?.typography?.fontWeight; return hasFontStyles || hasFontWeights; } -function useAppearanceControlLabel( name, element, settings ) { - const supports = useSupportedStyles( name, element ); - const hasFontStyles = - settings?.typography?.fontStyle && supports.includes( 'fontStyle' ); - const hasFontWeights = - settings?.typography?.fontWeight && supports.includes( 'fontWeight' ); +function useAppearanceControlLabel( settings ) { + const hasFontStyles = settings?.typography?.fontStyle; + const hasFontWeights = settings?.typography?.fontWeight; if ( ! hasFontStyles ) { return __( 'Font weight' ); } @@ -107,27 +80,16 @@ function useAppearanceControlLabel( name, element, settings ) { return __( 'Appearance' ); } -function useHasLetterSpacingControl( name, element, settings ) { - const setting = settings?.typography?.letterSpacing; - const supports = useSupportedStyles( name, element ); - if ( ! setting ) { - return false; - } - return supports.includes( 'letterSpacing' ); +function useHasLetterSpacingControl( settings ) { + return settings?.typography?.letterSpacing; } -function useHasTextTransformControl( name, element, settings ) { - const setting = settings?.typography?.textTransform; - const supports = useSupportedStyles( name, element ); - if ( ! setting ) { - return false; - } - return supports.includes( 'textTransform' ); +function useHasTextTransformControl( settings ) { + return settings?.typography?.textTransform; } -function useHasTextDecorationControl( name, element ) { - const supports = useSupportedStyles( name, element ); - return supports.includes( 'textDecoration' ); +function useHasTextDecorationControl( settings ) { + return settings?.typography?.textDecoration; } function TypographyToolsPanel( { ...props } ) { @@ -146,8 +108,6 @@ const DEFAULT_CONTROLS = { export default function TypographyPanel( { as: Wrapper = TypographyToolsPanel, - name, - element, value, onChange, inheritedValue = value, @@ -159,11 +119,7 @@ export default function TypographyPanel( { getValueFromVariable( { settings }, '', rawValue ); // Font Family - const hasFontFamilyEnabled = useHasFontFamilyControl( - name, - element, - settings - ); + const hasFontFamilyEnabled = useHasFontFamilyControl( settings ); const fontFamiliesPerOrigin = settings?.typography?.fontFamilies; const fontFamilies = fontFamiliesPerOrigin?.custom ?? @@ -188,7 +144,7 @@ export default function TypographyPanel( { const resetFontFamily = () => setFontFamily( undefined ); // Font Size - const hasFontSizeEnabled = useHasFontSizeControl( name, element, settings ); + const hasFontSizeEnabled = useHasFontSizeControl( settings ); const disableCustomFontSizes = ! settings?.typography?.customFontSize; const fontSizesPerOrigin = settings?.typography?.fontSizes ?? {}; const fontSizes = @@ -213,16 +169,8 @@ export default function TypographyPanel( { const resetFontSize = () => setFontSize( undefined ); // Appearance - const hasAppearanceControl = useHasAppearanceControl( - name, - element, - settings - ); - const appearanceControlLabel = useAppearanceControlLabel( - name, - element, - settings - ); + const hasAppearanceControl = useHasAppearanceControl( settings ); + const appearanceControlLabel = useAppearanceControlLabel( settings ); const hasFontStyles = settings?.typography?.fontStyle; const hasFontWeights = settings?.typography?.fontWeight; const fontStyle = decodeValue( inheritedValue?.typography?.fontStyle ); @@ -247,11 +195,7 @@ export default function TypographyPanel( { }; // Line Height - const hasLineHeightEnabled = useHasLineHeightControl( - name, - element, - settings - ); + const hasLineHeightEnabled = useHasLineHeightControl( settings ); const lineHeight = decodeValue( inheritedValue?.typography?.lineHeight ); const setLineHeight = ( newValue ) => { onChange( { @@ -266,11 +210,7 @@ export default function TypographyPanel( { const resetLineHeight = () => setLineHeight( undefined ); // Letter Spacing - const hasLetterSpacingControl = useHasLetterSpacingControl( - name, - element, - settings - ); + const hasLetterSpacingControl = useHasLetterSpacingControl( settings ); const letterSpacing = decodeValue( inheritedValue?.typography?.letterSpacing ); @@ -287,11 +227,7 @@ export default function TypographyPanel( { const resetLetterSpacing = () => setLetterSpacing( undefined ); // Text Transform - const hasTextTransformControl = useHasTextTransformControl( - name, - element, - settings - ); + const hasTextTransformControl = useHasTextTransformControl( settings ); const textTransform = decodeValue( inheritedValue?.typography?.textTransform ); @@ -308,10 +244,7 @@ export default function TypographyPanel( { const resetTextTransform = () => setTextTransform( undefined ); // Text Decoration - const hasTextDecorationControl = useHasTextDecorationControl( - name, - element - ); + const hasTextDecorationControl = useHasTextDecorationControl( settings ); const textDecoration = decodeValue( inheritedValue?.typography?.textDecoration ); diff --git a/packages/block-editor/src/hooks/typography.js b/packages/block-editor/src/hooks/typography.js index 87e734b00667c..a5aac0cb2d312 100644 --- a/packages/block-editor/src/hooks/typography.js +++ b/packages/block-editor/src/hooks/typography.js @@ -18,6 +18,10 @@ import { FONT_FAMILY_SUPPORT_KEY } from './font-family'; import { FONT_SIZE_SUPPORT_KEY } from './font-size'; import { useSetting } from '../components'; import { cleanEmptyObject } from './utils'; +import { + overrideSettingsWithSupports, + useSupportedStyles, +} from '../components/global-styles/hooks'; function omit( object, keys ) { return Object.fromEntries( @@ -48,33 +52,59 @@ function TypographyInspectorControl( { children } ) { ); } +function useBlockSettings( name ) { + const fontFamilies = useSetting( 'typography.fontFamilies' ); + const fontSizes = useSetting( 'typography.fontSizes' ); + const customFontSize = useSetting( 'typography.customFontSize' ); + const fontStyle = useSetting( 'typography.fontStyle' ); + const fontWeight = useSetting( 'typography.fontWeight' ); + const lineHeight = useSetting( 'typography.lineHeight' ); + const textDecoration = useSetting( 'typography.textDecoration' ); + const textTransform = useSetting( 'typography.textTransform' ); + const letterSpacing = useSetting( 'typography.letterSpacing' ); + const supports = useSupportedStyles( name, null ); + + return useMemo( () => { + const rawSettings = { + typography: { + fontFamilies: { + custom: fontFamilies, + }, + fontSizes: { + custom: fontSizes, + }, + customFontSize, + fontStyle, + fontWeight, + lineHeight, + textDecoration, + textTransform, + letterSpacing, + }, + }; + return overrideSettingsWithSupports( rawSettings, supports ); + }, [ + fontFamilies, + fontSizes, + customFontSize, + fontStyle, + fontWeight, + lineHeight, + textDecoration, + textTransform, + letterSpacing, + supports, + ] ); +} + export function TypographyPanel( { clientId, name, attributes, setAttributes, } ) { - const settings = { - typography: { - fontFamilies: { - custom: useSetting( 'typography.fontFamilies' ), - }, - fontSizes: { - custom: useSetting( 'typography.fontSizes' ), - }, - customFontSize: useSetting( 'typography.customFontSize' ), - fontStyle: useSetting( 'typography.fontStyle' ), - fontWeight: useSetting( 'typography.fontWeight' ), - lineHeight: useSetting( 'typography.lineHeight' ), - textDecoration: useSetting( 'typography.textDecoration' ), - textTransform: useSetting( 'typography.textTransform' ), - letterSpacing: useSetting( 'typography.letterSpacing' ), - }, - }; - - const isSupported = hasTypographySupport( name ); - const isEnabled = useHasTypographyPanel( name, null, settings ); - + const settings = useBlockSettings( name ); + const isEnabled = useHasTypographyPanel( settings ); const value = useMemo( () => { return { ...attributes.style, @@ -115,7 +145,7 @@ export function TypographyPanel( { } ); }; - if ( ! isEnabled || ! isSupported ) { + if ( ! isEnabled ) { return null; } diff --git a/packages/edit-site/src/components/global-styles/context-menu.js b/packages/edit-site/src/components/global-styles/context-menu.js index 04ab8e65f403f..d2753e48774e8 100644 --- a/packages/edit-site/src/components/global-styles/context-menu.js +++ b/packages/edit-site/src/components/global-styles/context-menu.js @@ -22,6 +22,7 @@ import { isRTL, __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; +import { useMemo } from '@wordpress/element'; /** * Internal dependencies @@ -35,14 +36,22 @@ import { IconWithCurrentColor } from './icon-with-current-color'; import { ScreenVariations } from './screen-variations'; import { useHasShadowControl } from './shadow-panel'; import { unlock } from '../../private-apis'; +import { useSupportedStyles } from './hooks'; -const { useHasTypographyPanel, useGlobalSetting } = unlock( - blockEditorPrivateApis -); +const { + useHasTypographyPanel, + useGlobalSetting, + overrideSettingsWithSupports, +} = unlock( blockEditorPrivateApis ); function ContextMenu( { name, parentMenu = '' } ) { - const [ settings ] = useGlobalSetting( '', name ); - const hasTypographyPanel = useHasTypographyPanel( name, null, settings ); + const [ rawSettings ] = useGlobalSetting( '', name ); + const supports = useSupportedStyles( name ); + const settings = useMemo( + () => overrideSettingsWithSupports( rawSettings, supports ), + [ rawSettings, supports ] + ); + const hasTypographyPanel = useHasTypographyPanel( settings ); const hasColorPanel = useHasColorPanel( name ); const hasBorderPanel = useHasBorderPanel( name ); const hasEffectsPanel = useHasShadowControl( name ); diff --git a/packages/edit-site/src/components/global-styles/screen-block-list.js b/packages/edit-site/src/components/global-styles/screen-block-list.js index cba1455333898..0bfbe96f23b60 100644 --- a/packages/edit-site/src/components/global-styles/screen-block-list.js +++ b/packages/edit-site/src/components/global-styles/screen-block-list.js @@ -27,10 +27,13 @@ import { useHasVariationsPanel } from './variations-panel'; import ScreenHeader from './header'; import { NavigationButtonAsItem } from './navigation-button'; import { unlock } from '../../private-apis'; +import { useSupportedStyles } from './hooks'; -const { useHasTypographyPanel, useGlobalSetting } = unlock( - blockEditorPrivateApis -); +const { + useHasTypographyPanel, + useGlobalSetting, + overrideSettingsWithSupports, +} = unlock( blockEditorPrivateApis ); function useSortedBlockTypes() { const blockItems = useSelect( @@ -56,12 +59,13 @@ function useSortedBlockTypes() { } function BlockMenuItem( { block } ) { - const [ settings ] = useGlobalSetting( '', block.name ); - const hasTypographyPanel = useHasTypographyPanel( - block.name, - null, - settings + const [ rawSettings ] = useGlobalSetting( '', block.name ); + const supports = useSupportedStyles( block.name ); + const settings = useMemo( + () => overrideSettingsWithSupports( rawSettings, supports ), + [ rawSettings, supports ] ); + const hasTypographyPanel = useHasTypographyPanel( settings ); const hasColorPanel = useHasColorPanel( block.name ); const hasBorderPanel = useHasBorderPanel( block.name ); const hasDimensionsPanel = useHasDimensionsPanel( block.name ); diff --git a/packages/edit-site/src/components/global-styles/typography-panel.js b/packages/edit-site/src/components/global-styles/typography-panel.js index d77594b13663f..da2429432d795 100644 --- a/packages/edit-site/src/components/global-styles/typography-panel.js +++ b/packages/edit-site/src/components/global-styles/typography-panel.js @@ -2,15 +2,18 @@ * WordPress dependencies */ import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; +import { useMemo } from '@wordpress/element'; /** * Internal dependencies */ import { unlock } from '../../private-apis'; +import { useSupportedStyles } from './hooks'; const { useGlobalStyle, useGlobalSetting, + overrideSettingsWithSupports, TypographyPanel: StylesTypographyPanel, } = unlock( blockEditorPrivateApis ); @@ -35,12 +38,16 @@ export default function TypographyPanel( { const [ inheritedStyle, setStyle ] = useGlobalStyle( prefix, name, 'all', { shouldDecodeEncode: false, } ); - const [ settings ] = useGlobalSetting( '', name ); + const [ rawSettings ] = useGlobalSetting( '', name ); + const usedElement = element === 'heading' ? headingLevel : element; + const supports = useSupportedStyles( name, usedElement ); + const settings = useMemo( + () => overrideSettingsWithSupports( rawSettings, supports ), + [ rawSettings, supports ] + ); return (