diff --git a/packages/edit-site/src/components/global-styles/screen-typography-element.js b/packages/edit-site/src/components/global-styles/screen-typography-element.js index a14801c43a3b0..76d7d6de5df90 100644 --- a/packages/edit-site/src/components/global-styles/screen-typography-element.js +++ b/packages/edit-site/src/components/global-styles/screen-typography-element.js @@ -2,12 +2,19 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; +import { + __experimentalToggleGroupControl as ToggleGroupControl, + __experimentalToggleGroupControlOption as ToggleGroupControlOption, + __experimentalSpacer as Spacer, +} from '@wordpress/components'; +import { useState } from '@wordpress/element'; /** * Internal dependencies */ import TypographyPanel from './typography-panel'; import ScreenHeader from './header'; +import TypographyPreview from './typography-preview'; const elements = { text: { @@ -29,13 +36,70 @@ const elements = { }; function ScreenTypographyElement( { name, element } ) { + const [ headingLevel, setHeadingLevel ] = useState( 'heading' ); + return ( <> - + + + + { element === 'heading' && ( + + + + + + + + + + + + ) } + ); } diff --git a/packages/edit-site/src/components/global-styles/style.scss b/packages/edit-site/src/components/global-styles/style.scss index 1731fea74c969..21ddb8a8c02d9 100644 --- a/packages/edit-site/src/components/global-styles/style.scss +++ b/packages/edit-site/src/components/global-styles/style.scss @@ -11,7 +11,7 @@ display: block; } -.edit-site-typography-panel__preview { +.edit-site-typography-preview { display: flex; align-items: center; justify-content: center; 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 f4c77abf0fd71..a632f532a174f 100644 --- a/packages/edit-site/src/components/global-styles/typography-panel.js +++ b/packages/edit-site/src/components/global-styles/typography-panel.js @@ -9,25 +9,25 @@ import { __experimentalTextTransformControl as TextTransformControl, } from '@wordpress/block-editor'; import { - PanelBody, FontSizePicker, - __experimentalToggleGroupControl as ToggleGroupControl, - __experimentalToggleGroupControlOption as ToggleGroupControlOption, - __experimentalGrid as Grid, + __experimentalToolsPanel as ToolsPanel, + __experimentalToolsPanelItem as ToolsPanelItem, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useState } from '@wordpress/element'; + /** * Internal dependencies */ import { getSupportedGlobalStylesPanels, useSetting, useStyle } from './hooks'; export function useHasTypographyPanel( name ) { + const hasFontFamily = useHasFontFamilyControl( name ); const hasLineHeight = useHasLineHeightControl( name ); const hasFontAppearance = useHasAppearanceControl( name ); const hasLetterSpacing = useHasLetterSpacingControl( name ); const supports = getSupportedGlobalStylesPanels( name ); return ( + hasFontFamily || hasLineHeight || hasFontAppearance || hasLetterSpacing || @@ -35,6 +35,12 @@ export function useHasTypographyPanel( name ) { ); } +function useHasFontFamilyControl( name ) { + const supports = getSupportedGlobalStylesPanels( name ); + const [ fontFamilies ] = useSetting( 'typography.fontFamilies', name ); + return supports.includes( 'fontFamily' ) && !! fontFamilies?.length; +} + function useHasLineHeightControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); return ( @@ -54,6 +60,23 @@ function useHasAppearanceControl( name ) { return hasFontStyles || hasFontWeights; } +function useAppearanceControlLabel( name ) { + const supports = getSupportedGlobalStylesPanels( name ); + const hasFontStyles = + useSetting( 'typography.fontStyle', name )[ 0 ] && + supports.includes( 'fontStyle' ); + const hasFontWeights = + useSetting( 'typography.fontWeight', name )[ 0 ] && + supports.includes( 'fontWeight' ); + if ( ! hasFontStyles ) { + return __( 'Font weight' ); + } + if ( ! hasFontWeights ) { + return __( 'Font style' ); + } + return __( 'Appearance' ); +} + function useHasLetterSpacingControl( name, element ) { const setting = useSetting( 'typography.letterSpacing', name )[ 0 ]; if ( ! setting ) { @@ -78,12 +101,53 @@ function useHasTextTransformControl( name, element ) { return supports.includes( 'textTransform' ); } -export default function TypographyPanel( { name, element } ) { - const [ selectedLevel, setCurrentTab ] = useState( 'heading' ); +function useStyleWithReset( path, blockName ) { + const [ style, setStyle ] = useStyle( path, blockName ); + const [ userStyle ] = useStyle( path, blockName, 'user' ); + const hasStyle = () => !! userStyle; + const resetStyle = () => setStyle( undefined ); + return [ style, setStyle, hasStyle, resetStyle ]; +} + +function useFontAppearance( prefix, name ) { + const [ fontStyle, setFontStyle ] = useStyle( + prefix + 'typography.fontStyle', + name + ); + const [ userFontStyle ] = useStyle( + prefix + 'typography.fontStyle', + name, + 'user' + ); + const [ fontWeight, setFontWeight ] = useStyle( + prefix + 'typography.fontWeight', + name + ); + const [ userFontWeight ] = useStyle( + prefix + 'typography.fontWeight', + name, + 'user' + ); + const hasFontAppearance = () => !! userFontStyle || !! userFontWeight; + const resetFontAppearance = () => { + setFontStyle( undefined ); + setFontWeight( undefined ); + }; + return { + fontStyle, + setFontStyle, + fontWeight, + setFontWeight, + hasFontAppearance, + resetFontAppearance, + }; +} + +export default function TypographyPanel( { name, element, headingLevel } ) { const supports = getSupportedGlobalStylesPanels( name ); let prefix = ''; if ( element === 'heading' ) { - prefix = `elements.${ selectedLevel }.`; + prefix = `elements.${ headingLevel }.`; } else if ( element && element !== 'text' ) { prefix = `elements.${ element }.`; } @@ -99,142 +163,99 @@ export default function TypographyPanel( { name, element } ) { const hasFontWeights = useSetting( 'typography.fontWeight', name )[ 0 ] && supports.includes( 'fontWeight' ); + const hasFontFamilyEnabled = useHasFontFamilyControl( name ); const hasLineHeightEnabled = useHasLineHeightControl( name ); const hasAppearanceControl = useHasAppearanceControl( name ); + const appearanceControlLabel = useAppearanceControlLabel( name ); const hasLetterSpacingControl = useHasLetterSpacingControl( name, element ); const hasTextTransformControl = useHasTextTransformControl( name, element ); /* Disable font size controls when the option to style all headings is selected. */ let hasFontSizeEnabled = supports.includes( 'fontSize' ); - if ( element === 'heading' && selectedLevel === 'heading' ) { + if ( element === 'heading' && headingLevel === 'heading' ) { hasFontSizeEnabled = false; } - const [ fontFamily, setFontFamily ] = useStyle( - prefix + 'typography.fontFamily', - name - ); - const [ fontSize, setFontSize ] = useStyle( - prefix + 'typography.fontSize', - name - ); + const [ fontFamily, setFontFamily, hasFontFamily, resetFontFamily ] = + useStyleWithReset( prefix + 'typography.fontFamily', name ); + const [ fontSize, setFontSize, hasFontSize, resetFontSize ] = + useStyleWithReset( prefix + 'typography.fontSize', name ); + const { + fontStyle, + setFontStyle, + fontWeight, + setFontWeight, + hasFontAppearance, + resetFontAppearance, + } = useFontAppearance( prefix, name ); + const [ lineHeight, setLineHeight, hasLineHeight, resetLineHeight ] = + useStyleWithReset( prefix + 'typography.lineHeight', name ); + const [ + letterSpacing, + setLetterSpacing, + hasLetterSpacing, + resetLetterSpacing, + ] = useStyleWithReset( prefix + 'typography.letterSpacing', name ); + const [ + textTransform, + setTextTransform, + hasTextTransform, + resetTextTransform, + ] = useStyleWithReset( prefix + 'typography.textTransform', name ); - const [ fontStyle, setFontStyle ] = useStyle( - prefix + 'typography.fontStyle', - name - ); - const [ fontWeight, setFontWeight ] = useStyle( - prefix + 'typography.fontWeight', - name - ); - const [ lineHeight, setLineHeight ] = useStyle( - prefix + 'typography.lineHeight', - name - ); - const [ letterSpacing, setLetterSpacing ] = useStyle( - prefix + 'typography.letterSpacing', - name - ); - const [ textTransform, setTextTransform ] = useStyle( - prefix + 'typography.textTransform', - name - ); - const [ backgroundColor ] = useStyle( prefix + 'color.background', name ); - const [ gradientValue ] = useStyle( prefix + 'color.gradient', name ); - const [ color ] = useStyle( prefix + 'color.text', name ); - const extraStyles = - element === 'link' - ? { - textDecoration: 'underline', - } - : {}; + const resetAll = () => { + resetFontFamily(); + resetFontSize(); + resetFontAppearance(); + resetLineHeight(); + resetLetterSpacing(); + resetTextTransform(); + }; return ( - -
- Aa -
- - { element === 'heading' && ( -
- - - - - - - - - -
- ) } - { supports.includes( 'fontFamily' ) && ( -
- -
- ) } - { hasFontSizeEnabled && ( -
- -
- ) } - { hasAppearanceControl && ( + + { hasFontFamilyEnabled && ( + + + + ) } + { hasFontSizeEnabled && ( + + + + ) } + { hasAppearanceControl && ( + - ) } - { hasLineHeightEnabled && ( + + ) } + { hasLineHeightEnabled && ( + - ) } - { hasLetterSpacingControl && ( + + ) } + { hasLetterSpacingControl && ( + - ) } - { hasTextTransformControl && ( -
- -
- ) } -
-
+ + ) } + { hasTextTransformControl && ( + + + + ) } + ); } diff --git a/packages/edit-site/src/components/global-styles/typography-preview.js b/packages/edit-site/src/components/global-styles/typography-preview.js new file mode 100644 index 0000000000000..b0e134ab0cce5 --- /dev/null +++ b/packages/edit-site/src/components/global-styles/typography-preview.js @@ -0,0 +1,49 @@ +/** + * Internal dependencies + */ +import { useStyle } from './hooks'; + +export default function TypographyPreview( { name, element, headingLevel } ) { + let prefix = ''; + if ( element === 'heading' ) { + prefix = `elements.${ headingLevel }.`; + } else if ( element && element !== 'text' ) { + prefix = `elements.${ element }.`; + } + + const [ fontFamily ] = useStyle( prefix + 'typography.fontFamily', name ); + const [ gradientValue ] = useStyle( prefix + 'color.gradient', name ); + const [ backgroundColor ] = useStyle( prefix + 'color.background', name ); + const [ color ] = useStyle( prefix + 'color.text', name ); + const [ fontSize ] = useStyle( prefix + 'typography.fontSize', name ); + const [ fontStyle ] = useStyle( prefix + 'typography.fontStyle', name ); + const [ fontWeight ] = useStyle( prefix + 'typography.fontWeight', name ); + const [ letterSpacing ] = useStyle( + prefix + 'typography.letterSpacing', + name + ); + const extraStyles = + element === 'link' + ? { + textDecoration: 'underline', + } + : {}; + + return ( +
+ Aa +
+ ); +} diff --git a/packages/edit-site/src/components/sidebar/style.scss b/packages/edit-site/src/components/sidebar/style.scss index b4527736273e8..181740907c09a 100644 --- a/packages/edit-site/src/components/sidebar/style.scss +++ b/packages/edit-site/src/components/sidebar/style.scss @@ -56,7 +56,7 @@ border: 0; } -.edit-site-global-styles-sidebar .components-tools-panel-item.single-column { +.edit-site-global-styles-sidebar .single-column { grid-column: span 1; }