From 68dc225c5e5ebffe8fee53f92e61825dda21c39d Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 02:03:33 +0100 Subject: [PATCH 01/25] Refactor font appearance fallbacks --- .../global-styles/typography-panel.js | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) 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 12ceadeb758df2..7a1dbc9f1be954 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -257,7 +257,7 @@ export default function TypographyPanel( { // Check if previous font style and weight values are available in the new font family useEffect( () => { - const { fontStyles, fontWeights, isSystemFont } = + const { fontStyles, fontWeights, combinedStyleAndWeightOptions } = getFontStylesAndWeights( fontFamilyFaces ); const hasFontStyle = fontStyles?.some( ( { value: fs } ) => fs === fontStyle @@ -266,24 +266,49 @@ export default function TypographyPanel( { ( { value: fw } ) => fw === fontWeight ); - // Try to set nearest available font weight - if ( ! hasFontWeight && fontWeight ) { - setFontAppearance( { - fontStyle, - fontWeight: findNearestFontWeight( fontWeights, fontWeight ), - } ); + // Default to previous values if they are available + let newFontStyle = fontStyle; + let newFontWeight = fontWeight; + + if ( ! hasFontStyle ) { + if ( ! fontStyle && fontWeight ) { + newFontStyle = combinedStyleAndWeightOptions?.find( + ( option ) => option.style.fontWeight === fontWeight + )?.style?.fontStyle; + } + + if ( ! fontWeight && ! fontStyle ) { + newFontStyle = undefined; + } } - // Set the same weight and style values if the font family is a system font or if both are the same - if ( isSystemFont || ( hasFontStyle && hasFontWeight ) ) { - setFontAppearance( { - fontStyle, - fontWeight, - } ); + if ( ! hasFontWeight ) { + if ( fontWeight ) { + newFontWeight = findNearestFontWeight( + fontWeights, + fontWeight + ); + } + + if ( ! fontWeight && fontStyle ) { + newFontWeight = newFontWeight = + combinedStyleAndWeightOptions?.find( + ( option ) => option.style.fontStyle === fontStyle + )?.style?.fontWeight; + } + + if ( ! fontWeight && ! fontStyle ) { + newFontWeight = undefined; + } } - // Reset font appearance if the font family does not have the selected font style - if ( ! hasFontStyle ) { + if ( newFontStyle && newFontWeight ) { + setFontAppearance( { + fontStyle: newFontStyle, + fontWeight: newFontWeight, + } ); + } else { + // Reset font appearance if there are no available styles or weights resetFontAppearance(); } }, [ fontFamily ] ); From 3b434b1d6c97605563b6329c442a67659f663ad4 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 15:39:06 +0100 Subject: [PATCH 02/25] Create new findNearestStyleAndWeight function --- .../global-styles/typography-panel.js | 55 ++---------------- .../global-styles/typography-utils.js | 58 +++++++++++++++++++ 2 files changed, 64 insertions(+), 49 deletions(-) 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 7a1dbc9f1be954..cf586c87ae3926 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -25,9 +25,8 @@ import { getValueFromVariable, useToolsPanelDropdownMenuProps } from './utils'; import { setImmutably } from '../../utils/object'; import { getMergedFontFamiliesAndFontFamilyFaces, - findNearestFontWeight, + findNearestStyleAndWeight, } from './typography-utils'; -import { getFontStylesAndWeights } from '../../utils/get-font-styles-and-weights'; const MIN_TEXT_COLUMNS = 1; const MAX_TEXT_COLUMNS = 6; @@ -257,55 +256,13 @@ export default function TypographyPanel( { // Check if previous font style and weight values are available in the new font family useEffect( () => { - const { fontStyles, fontWeights, combinedStyleAndWeightOptions } = - getFontStylesAndWeights( fontFamilyFaces ); - const hasFontStyle = fontStyles?.some( - ( { value: fs } ) => fs === fontStyle - ); - const hasFontWeight = fontWeights?.some( - ( { value: fw } ) => fw === fontWeight - ); - - // Default to previous values if they are available - let newFontStyle = fontStyle; - let newFontWeight = fontWeight; - - if ( ! hasFontStyle ) { - if ( ! fontStyle && fontWeight ) { - newFontStyle = combinedStyleAndWeightOptions?.find( - ( option ) => option.style.fontWeight === fontWeight - )?.style?.fontStyle; - } - - if ( ! fontWeight && ! fontStyle ) { - newFontStyle = undefined; - } - } - - if ( ! hasFontWeight ) { - if ( fontWeight ) { - newFontWeight = findNearestFontWeight( - fontWeights, - fontWeight - ); - } - - if ( ! fontWeight && fontStyle ) { - newFontWeight = newFontWeight = - combinedStyleAndWeightOptions?.find( - ( option ) => option.style.fontStyle === fontStyle - )?.style?.fontWeight; - } - - if ( ! fontWeight && ! fontStyle ) { - newFontWeight = undefined; - } - } + const { nearestFontStyle, nearestFontWeight } = + findNearestStyleAndWeight( fontFamilyFaces, fontStyle, fontWeight ); - if ( newFontStyle && newFontWeight ) { + if ( nearestFontStyle && nearestFontWeight ) { setFontAppearance( { - fontStyle: newFontStyle, - fontWeight: newFontWeight, + fontStyle: nearestFontStyle, + fontWeight: nearestFontWeight, } ); } else { // Reset font appearance if there are no available styles or weights diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index 0d4c1b29b8b662..9d98905c848d59 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -11,6 +11,7 @@ import { getComputedFluidTypographyValue, getTypographyValueAndUnit, } from '../font-sizes/fluid-utils'; +import { getFontStylesAndWeights } from '../../utils/get-font-styles-and-weights'; /** * @typedef {Object} FluidPreset @@ -185,3 +186,60 @@ export function findNearestFontWeight( return nearestFontWeight; } + +/** + * Returns the nearest font style and weight based on the available font family faces and the new font style and weight. + * + * @param {Array} fontFamilyFaces Array of available font family faces + * @param {string} fontStyle New font style + * @param {string} fontWeight New font weight + * @return {Object} Nearest font style and weight + */ +export function findNearestStyleAndWeight( + fontFamilyFaces, + fontStyle, + fontWeight +) { + if ( ! fontStyle && ! fontWeight ) { + return { nearestFontStyle: undefined, nearestFontWeight: undefined }; + } + + // Default to previous values if they are available + let nearestFontStyle = fontStyle ?? undefined; + let nearestFontWeight = fontWeight ?? undefined; + + const { fontStyles, fontWeights, combinedStyleAndWeightOptions } = + getFontStylesAndWeights( fontFamilyFaces ); + + const hasFontStyle = fontStyles?.some( + ( { value: fs } ) => fs === fontStyle + ); + const hasFontWeight = fontWeights?.some( + ( { value: fw } ) => fw === fontWeight + ); + + if ( ! hasFontStyle ) { + if ( fontWeight ) { + nearestFontStyle = combinedStyleAndWeightOptions?.find( + ( option ) => option.style.fontWeight === fontWeight + )?.style?.fontStyle; + } + } + + if ( ! hasFontWeight ) { + if ( fontWeight ) { + nearestFontWeight = findNearestFontWeight( + fontWeights, + fontWeight + ); + } + + if ( ! fontWeight && fontStyle ) { + nearestFontWeight = combinedStyleAndWeightOptions?.find( + ( option ) => option.style.fontStyle === fontStyle + )?.style?.fontWeight; + } + } + + return { nearestFontStyle, nearestFontWeight }; +} From dacc850597d2152c1ca6072568d1a34d23eea202 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 15:39:50 +0100 Subject: [PATCH 03/25] Add tests for findNearestStyleAndWeight --- .../global-styles/test/typography-utils.js | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 115de8cdf2563d..09b7bcf21522b3 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -6,6 +6,7 @@ import { getFluidTypographyOptionsFromSettings, getMergedFontFamiliesAndFontFamilyFaces, findNearestFontWeight, + findNearestStyleAndWeight, } from '../typography-utils'; describe( 'typography utils', () => { @@ -951,6 +952,223 @@ describe( 'typography utils', () => { ); } ); + describe( 'findNearestStyleAndWeight', () => { + [ + { + message: 'should return empty object when all values are empty', + fontFamilyFaces: [], + fontStyle: undefined, + fontWeight: undefined, + expected: {}, + }, + { + message: + 'should return original fontStyle and fontWeight when fontFamilyFaces is empty', + fontFamilyFaces: [], + fontStyle: 'italic', + fontWeight: '700', + expected: { + nearestFontStyle: 'italic', + nearestFontWeight: '700', + }, + }, + { + message: + 'should return undefined values if fontStyle and fontWeight are not available', + fontFamilyFaces: [ + { + fontFamily: 'ABeeZee', + fontStyle: 'italic', + fontWeight: '400', + src: [ + 'file:./assets/fonts/esDT31xSG-6AGleN2tCkkJUCGpG-GQ.woff2', + ], + }, + ], + fontStyle: undefined, + fontWeight: undefined, + expected: { + nearestFontStyle: undefined, + nearestFontWeight: undefined, + }, + }, + { + message: + 'should return nearest fontStyle and fontWeight for normal/400', + fontFamilyFaces: [ + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'italic', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Italic.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '700', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2', + ], + }, + ], + fontStyle: 'normal', + fontWeight: '100', + expected: { + nearestFontStyle: 'normal', + nearestFontWeight: '400', + }, + }, + { + message: + 'should return nearest fontStyle and fontWeight for italic/700', + fontFamilyFaces: [ + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'italic', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Italic.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '700', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2', + ], + }, + ], + fontStyle: 'italic', + fontWeight: '900', + expected: { + nearestFontStyle: 'italic', + nearestFontWeight: '700', + }, + }, + { + message: + 'should return nearest fontStyle and fontWeight for oblique/600', + fontFamilyFaces: [ + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'italic', + fontWeight: '700', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2', + ], + }, + ], + fontStyle: 'oblique', + fontWeight: '600', + expected: { + nearestFontStyle: 'italic', + nearestFontWeight: '700', + }, + }, + { + message: + 'should return nearest fontStyle and fontWeight for just 300', + fontFamilyFaces: [ + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'italic', + fontWeight: '700', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2', + ], + }, + ], + fontStyle: undefined, + fontWeight: '300', + expected: { + nearestFontStyle: 'normal', + nearestFontWeight: '400', + }, + }, + { + message: + 'should return nearest fontStyle and fontWeight for just oblique', + fontFamilyFaces: [ + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'italic', + fontWeight: '700', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2', + ], + }, + ], + fontStyle: 'oblique', + fontWeight: undefined, + expected: { + nearestFontStyle: 'italic', + nearestFontWeight: '400', + }, + }, + ].forEach( + ( { + message, + fontFamilyFaces, + fontStyle, + fontWeight, + expected, + } ) => { + it( `${ message }`, () => { + expect( + findNearestStyleAndWeight( + fontFamilyFaces, + fontStyle, + fontWeight + ) + ).toEqual( expected ); + } ); + } + ); + } ); + describe( 'typography utils', () => { [ { From 23a8fa25dfb85a4672e4207f8c08d0a85d5dd5b2 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 17:31:34 +0100 Subject: [PATCH 04/25] Refactor findNearestStyleAndWeight --- .../global-styles/typography-utils.js | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index 9d98905c848d59..dc8f419fdb469d 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -191,26 +191,22 @@ export function findNearestFontWeight( * Returns the nearest font style and weight based on the available font family faces and the new font style and weight. * * @param {Array} fontFamilyFaces Array of available font family faces - * @param {string} fontStyle New font style - * @param {string} fontWeight New font weight - * @return {Object} Nearest font style and weight + * @param {string} fontStyle New font style. Defaults to previous value. + * @param {string} fontWeight New font weight. Defaults to previous value. + * @return {Object} Nearest font style and font weight */ export function findNearestStyleAndWeight( fontFamilyFaces, fontStyle, fontWeight ) { - if ( ! fontStyle && ! fontWeight ) { - return { nearestFontStyle: undefined, nearestFontWeight: undefined }; - } - - // Default to previous values if they are available - let nearestFontStyle = fontStyle ?? undefined; - let nearestFontWeight = fontWeight ?? undefined; + let nearestFontStyle = fontStyle; + let nearestFontWeight = fontWeight; const { fontStyles, fontWeights, combinedStyleAndWeightOptions } = getFontStylesAndWeights( fontFamilyFaces ); + // Check if the new font style and weight are available in the font family faces const hasFontStyle = fontStyles?.some( ( { value: fs } ) => fs === fontStyle ); @@ -219,26 +215,24 @@ export function findNearestStyleAndWeight( ); if ( ! hasFontStyle ) { - if ( fontWeight ) { - nearestFontStyle = combinedStyleAndWeightOptions?.find( - ( option ) => option.style.fontWeight === fontWeight - )?.style?.fontStyle; - } + nearestFontStyle = + fontStyle === 'oblique' + ? 'italic' + : combinedStyleAndWeightOptions?.find( + ( option ) => + option.style.fontWeight === + findNearestFontWeight( fontWeights, fontWeight ) + )?.style?.fontStyle; } if ( ! hasFontWeight ) { - if ( fontWeight ) { - nearestFontWeight = findNearestFontWeight( - fontWeights, - fontWeight - ); - } - - if ( ! fontWeight && fontStyle ) { - nearestFontWeight = combinedStyleAndWeightOptions?.find( - ( option ) => option.style.fontStyle === fontStyle - )?.style?.fontWeight; - } + nearestFontWeight = fontWeight + ? findNearestFontWeight( fontWeights, fontWeight ) + : combinedStyleAndWeightOptions?.find( + ( option ) => + option.style.fontStyle === + ( nearestFontStyle || fontStyle ) + )?.style?.fontWeight; } return { nearestFontStyle, nearestFontWeight }; From 2e0e9c54dd241e44083eee871bc37afcbfaa50a9 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 20:20:07 +0100 Subject: [PATCH 05/25] Add a test for normal/100 --- .../global-styles/test/typography-utils.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 09b7bcf21522b3..96605ce2e817df 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -1022,6 +1022,42 @@ describe( 'typography utils', () => { }, ], fontStyle: 'normal', + fontWeight: '400', + expected: { + nearestFontStyle: 'normal', + nearestFontWeight: '400', + }, + }, + { + message: + 'should return nearest fontStyle and fontWeight for normal/100', + fontFamilyFaces: [ + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'italic', + fontWeight: '400', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Italic.woff2', + ], + }, + { + fontFamily: 'IBM Plex Mono', + fontStyle: 'normal', + fontWeight: '700', + src: [ + 'file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2', + ], + }, + ], + fontStyle: 'normal', fontWeight: '100', expected: { nearestFontStyle: 'normal', From 5a22028cee2108ebdc34229ac089995a09be1a8f Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 20:31:57 +0100 Subject: [PATCH 06/25] Add comments --- .../src/components/global-styles/typography-utils.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index dc8f419fdb469d..686c74369a4982 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -215,6 +215,8 @@ export function findNearestStyleAndWeight( ); if ( ! hasFontStyle ) { + // Default to italic if oblique is not available + // Or find the nearest font style based on the nearest font weight nearestFontStyle = fontStyle === 'oblique' ? 'italic' @@ -226,6 +228,8 @@ export function findNearestStyleAndWeight( } if ( ! hasFontWeight ) { + // Find the nearest font weight based on available weights + // Or find the nearest font weight based on the nearest font style nearestFontWeight = fontWeight ? findNearestFontWeight( fontWeights, fontWeight ) : combinedStyleAndWeightOptions?.find( From 981334763200d34b984ee34af22a9443abcbd691 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 20:52:16 +0100 Subject: [PATCH 07/25] Tidy up comments --- .../src/components/global-styles/typography-utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index 686c74369a4982..eb2fa8a71f1917 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -190,10 +190,10 @@ export function findNearestFontWeight( /** * Returns the nearest font style and weight based on the available font family faces and the new font style and weight. * - * @param {Array} fontFamilyFaces Array of available font family faces + * @param {Array} fontFamilyFaces Array of available font family faces. * @param {string} fontStyle New font style. Defaults to previous value. * @param {string} fontWeight New font weight. Defaults to previous value. - * @return {Object} Nearest font style and font weight + * @return {Object} Nearest font style and font weight. */ export function findNearestStyleAndWeight( fontFamilyFaces, From 23567d5561795a08398408572ad5a3d992082ba9 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 20:54:17 +0100 Subject: [PATCH 08/25] Fix test description --- .../src/components/global-styles/test/typography-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 96605ce2e817df..07393c6e89acfb 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -1066,7 +1066,7 @@ describe( 'typography utils', () => { }, { message: - 'should return nearest fontStyle and fontWeight for italic/700', + 'should return nearest fontStyle and fontWeight for italic/900', fontFamilyFaces: [ { fontFamily: 'IBM Plex Mono', From 1f102c694e725f3f3c1bd1ea39b7c9bd48e194e5 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sat, 6 Jul 2024 21:02:35 +0100 Subject: [PATCH 09/25] Update test descriptions --- .../src/components/global-styles/test/typography-utils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 07393c6e89acfb..2079d76fd6f408 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -974,7 +974,7 @@ describe( 'typography utils', () => { }, { message: - 'should return undefined values if fontStyle and fontWeight are not available', + 'should return undefined values if both fontStyle and fontWeight are not available', fontFamilyFaces: [ { fontFamily: 'ABeeZee', @@ -1130,7 +1130,7 @@ describe( 'typography utils', () => { }, { message: - 'should return nearest fontStyle and fontWeight for just 300', + 'should return nearest fontStyle and fontWeight for 300 font weight and empty font style', fontFamilyFaces: [ { fontFamily: 'IBM Plex Mono', @@ -1158,7 +1158,7 @@ describe( 'typography utils', () => { }, { message: - 'should return nearest fontStyle and fontWeight for just oblique', + 'should return nearest fontStyle and fontWeight for oblique font style and empty font weight', fontFamilyFaces: [ { fontFamily: 'IBM Plex Mono', From c74daebd9a8b8b3b505df96c8a4765f059f76261 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 11:53:59 +0100 Subject: [PATCH 10/25] Update deps and wrap setFontAppearance and resetFontAppearance in useCallback --- .../global-styles/typography-panel.js | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) 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 cf586c87ae3926..33116a74c09e76 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -235,24 +235,24 @@ export default function TypographyPanel( { const hasFontWeights = settings?.typography?.fontWeight; const fontStyle = decodeValue( inheritedValue?.typography?.fontStyle ); const fontWeight = decodeValue( inheritedValue?.typography?.fontWeight ); - const setFontAppearance = ( { - fontStyle: newFontStyle, - fontWeight: newFontWeight, - } ) => { - onChange( { - ...value, - typography: { - ...value?.typography, - fontStyle: newFontStyle || undefined, - fontWeight: newFontWeight || undefined, - }, - } ); - }; + const setFontAppearance = useCallback( + ( { fontStyle: newFontStyle, fontWeight: newFontWeight } ) => { + onChange( { + ...value, + typography: { + ...value?.typography, + fontStyle: newFontStyle || undefined, + fontWeight: newFontWeight || undefined, + }, + } ); + }, + [ value, onChange ] + ); const hasFontAppearance = () => !! value?.typography?.fontStyle || !! value?.typography?.fontWeight; - const resetFontAppearance = () => { + const resetFontAppearance = useCallback( () => { setFontAppearance( {} ); - }; + }, [ setFontAppearance ] ); // Check if previous font style and weight values are available in the new font family useEffect( () => { @@ -268,7 +268,14 @@ export default function TypographyPanel( { // Reset font appearance if there are no available styles or weights resetFontAppearance(); } - }, [ fontFamily ] ); + }, [ + fontFamily, + fontFamilyFaces, + fontStyle, + fontWeight, + resetFontAppearance, + setFontAppearance, + ] ); // Line Height const hasLineHeightEnabled = useHasLineHeightControl( settings ); From 7e027b4588e48715fd2d7475800d32b63396e1b1 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 12:51:29 +0100 Subject: [PATCH 11/25] Add e2e test for appearance control dropdown menu --- .../various/font-appearance-control.spec.js | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 test/e2e/specs/editor/various/font-appearance-control.spec.js diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js new file mode 100644 index 00000000000000..9084ec88e0cd23 --- /dev/null +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -0,0 +1,91 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'Font Appearance Control dropdown menu', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activateTheme( 'twentytwentythree' ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + + test( 'should apply available font weight and styles from active font family', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: 'Regular', + style: { + typography: { fontWeight: '400', fontStyle: 'normal' }, + }, + }, + } ); + await page + .getByRole( 'button', { name: 'Typography options' } ) + .click(); + await expect( + page.getByRole( 'button', { name: 'Appearance' } ) + ).toContainText( 'Regular' ); + + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: 'Extra Light Italic', + style: { + typography: { fontWeight: '200', fontStyle: 'italic' }, + }, + }, + } ); + await page + .getByRole( 'button', { name: 'Typography options' } ) + .click(); + await expect( + page.getByRole( 'button', { name: 'Appearance' } ) + ).toContainText( 'Extra Light Italic' ); + + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: 'Bold Italic', + style: { + typography: { fontWeight: '700', fontStyle: 'italic' }, + }, + }, + } ); + await page + .getByRole( 'button', { name: 'Typography options' } ) + .click(); + await expect( + page.getByRole( 'button', { name: 'Appearance' } ) + ).toContainText( 'Bold Italic' ); + } ); + + test( 'should apply Default appearance if weight and style are invalid', async ( { + editor, + page, + } ) => { + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: 'Default', + style: { + typography: { fontWeight: '', fontStyle: '' }, + }, + }, + } ); + await page + .getByRole( 'button', { name: 'Typography options' } ) + .click(); + await page + .getByRole( 'menuitemcheckbox', { name: 'Show Appearance' } ) + .click(); + await expect( + page.getByRole( 'button', { name: 'Appearance' } ) + ).toContainText( 'Default' ); + } ); +} ); From ef7350b8783a520eb508ab75f2a8fa2ca35c1cff Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 12:59:22 +0100 Subject: [PATCH 12/25] Add periods to end of comments --- .../global-styles/typography-panel.js | 4 +-- .../global-styles/typography-utils.js | 26 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) 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 33116a74c09e76..11b6efcd692712 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -254,7 +254,7 @@ export default function TypographyPanel( { setFontAppearance( {} ); }, [ setFontAppearance ] ); - // Check if previous font style and weight values are available in the new font family + // Check if previous font style and weight values are available in the new font family. useEffect( () => { const { nearestFontStyle, nearestFontWeight } = findNearestStyleAndWeight( fontFamilyFaces, fontStyle, fontWeight ); @@ -265,7 +265,7 @@ export default function TypographyPanel( { fontWeight: nearestFontWeight, } ); } else { - // Reset font appearance if there are no available styles or weights + // Reset font appearance if there are no available styles or weights. resetFontAppearance(); } }, [ diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index eb2fa8a71f1917..e96751afad3391 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -128,9 +128,9 @@ export function getFluidTypographyOptionsFromSettings( settings ) { * Returns an object of merged font families and the font faces from the selected font family * based on the theme.json settings object and the currently selected font family. * - * @param {Object} settings Theme.json settings - * @param {string} selectedFontFamily Decoded font family string - * @return {Object} Merged font families and font faces from the selected font family + * @param {Object} settings Theme.json settings. + * @param {string} selectedFontFamily Decoded font family string. + * @return {Object} Merged font families and font faces from the selected font family. */ export function getMergedFontFamiliesAndFontFamilyFaces( settings, @@ -154,9 +154,9 @@ export function getMergedFontFamiliesAndFontFamilyFaces( * Returns the nearest font weight value from the available font weight list based on the new font weight. * The nearest font weight is the one with the smallest difference from the new font weight. * - * @param {Array} availableFontWeights Array of available font weights - * @param {string} newFontWeightValue New font weight value - * @return {string} Nearest font weight + * @param {Array} availableFontWeights Array of available font weights. + * @param {string} newFontWeightValue New font weight value. + * @return {string} Nearest font weight. */ export function findNearestFontWeight( @@ -206,7 +206,7 @@ export function findNearestStyleAndWeight( const { fontStyles, fontWeights, combinedStyleAndWeightOptions } = getFontStylesAndWeights( fontFamilyFaces ); - // Check if the new font style and weight are available in the font family faces + // Check if the new font style and weight are available in the font family faces. const hasFontStyle = fontStyles?.some( ( { value: fs } ) => fs === fontStyle ); @@ -215,8 +215,10 @@ export function findNearestStyleAndWeight( ); if ( ! hasFontStyle ) { - // Default to italic if oblique is not available - // Or find the nearest font style based on the nearest font weight + /* + * Default to italic if oblique is not available. + * Or find the nearest font style based on the nearest font weight. + */ nearestFontStyle = fontStyle === 'oblique' ? 'italic' @@ -228,8 +230,10 @@ export function findNearestStyleAndWeight( } if ( ! hasFontWeight ) { - // Find the nearest font weight based on available weights - // Or find the nearest font weight based on the nearest font style + /* + * Find the nearest font weight based on available weights. + * Or find the nearest font weight based on the nearest font style. + */ nearestFontWeight = fontWeight ? findNearestFontWeight( fontWeights, fontWeight ) : combinedStyleAndWeightOptions?.find( From a796d1392b8258739fef40a3bf895650be7289a1 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 14:01:07 +0100 Subject: [PATCH 13/25] Use better test data for font appearance e2e default test --- .../e2e/specs/editor/various/font-appearance-control.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 9084ec88e0cd23..8c54502a7d1bed 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -74,7 +74,10 @@ test.describe( 'Font Appearance Control dropdown menu', () => { attributes: { content: 'Default', style: { - typography: { fontWeight: '', fontStyle: '' }, + typography: { + fontWeight: '', + fontStyle: 'invalid-style', + }, }, }, } ); From 72199ccaa807f0f3a138e1bcb68a45b70b67a9a9 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 14:02:47 +0100 Subject: [PATCH 14/25] Add findNearestFontStyle function with tests --- .../global-styles/test/typography-utils.js | 52 ++++++++++++++++ .../global-styles/typography-utils.js | 61 ++++++++++++++++--- 2 files changed, 104 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 2079d76fd6f408..8f0c738498e8ef 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -6,6 +6,7 @@ import { getFluidTypographyOptionsFromSettings, getMergedFontFamiliesAndFontFamilyFaces, findNearestFontWeight, + findNearestFontStyle, findNearestStyleAndWeight, } from '../typography-utils'; @@ -952,6 +953,57 @@ describe( 'typography utils', () => { ); } ); + describe( 'findNearestFontStyle', () => { + [ + { + message: + 'should return empty string when newFontStyleValue is `undefined`', + availableFontStyles: undefined, + newFontStyleValue: undefined, + expected: '', + }, + { + message: + 'should return newFontStyleValue value when availableFontStyles is empty', + availableFontStyles: [], + newFontStyleValue: 'italic', + expected: 'italic', + }, + { + message: + 'should return empty string if there is no new font style available', + availableFontStyles: [ { name: 'Normal', value: 'normal' } ], + newFontStyleValue: 'italic', + expected: '', + }, + { + message: 'should return italic if oblique is not available', + availableFontStyles: [ + { name: 'Regular', value: 'normal' }, + { name: 'Italic', value: 'italic' }, + ], + newFontStyleValue: 'oblique', + expected: 'italic', + }, + ].forEach( + ( { + message, + availableFontStyles, + newFontStyleValue, + expected, + } ) => { + it( `${ message }`, () => { + expect( + findNearestFontStyle( + availableFontStyles, + newFontStyleValue + ) + ).toEqual( expected ); + } ); + } + ); + } ); + describe( 'findNearestStyleAndWeight', () => { [ { diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index e96751afad3391..c2a49f0a04fc94 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -158,7 +158,6 @@ export function getMergedFontFamiliesAndFontFamilyFaces( * @param {string} newFontWeightValue New font weight value. * @return {string} Nearest font weight. */ - export function findNearestFontWeight( availableFontWeights, newFontWeightValue @@ -187,6 +186,51 @@ export function findNearestFontWeight( return nearestFontWeight; } +/** + * Returns the nearest font style based on the new font style. + * Defaults to an empty string if the new font style is not valid or available. + * + * @param {Array} availableFontStyles Array of available font weights. + * @param {string} newFontStyleValue New font style value. + * @return {string} Nearest font style. + */ +export function findNearestFontStyle( availableFontStyles, newFontStyleValue ) { + if ( typeof newFontStyleValue !== 'string' || ! newFontStyleValue ) { + return ''; + } + + if ( + ! availableFontStyles || + availableFontStyles.length === 0 || + availableFontStyles.find( + ( style ) => style.value === newFontStyleValue + ) + ) { + return newFontStyleValue; + } + + let nearestFontStyle; + const validStyles = [ 'normal', 'italic', 'oblique' ]; + + if ( + ! validStyles.includes( newFontStyleValue ) || + ! availableFontStyles.find( + ( style ) => style.value === newFontStyleValue + ) + ) { + nearestFontStyle = ''; + } + + if ( + newFontStyleValue === 'oblique' && + ! availableFontStyles.find( ( style ) => style.value === 'oblique' ) + ) { + nearestFontStyle = 'italic'; + } + + return nearestFontStyle; +} + /** * Returns the nearest font style and weight based on the available font family faces and the new font style and weight. * @@ -219,14 +263,13 @@ export function findNearestStyleAndWeight( * Default to italic if oblique is not available. * Or find the nearest font style based on the nearest font weight. */ - nearestFontStyle = - fontStyle === 'oblique' - ? 'italic' - : combinedStyleAndWeightOptions?.find( - ( option ) => - option.style.fontWeight === - findNearestFontWeight( fontWeights, fontWeight ) - )?.style?.fontStyle; + nearestFontStyle = fontStyle + ? findNearestFontStyle( fontStyles, fontStyle ) + : combinedStyleAndWeightOptions?.find( + ( option ) => + option.style.fontWeight === + findNearestFontWeight( fontWeights, fontWeight ) + )?.style?.fontStyle; } if ( ! hasFontWeight ) { From 37963050aebcb6b0da3b42cf3139c5795421732d Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 15:09:36 +0100 Subject: [PATCH 15/25] Limit the dependency array to just fontFamily --- .../src/components/global-styles/typography-panel.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) 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 11b6efcd692712..4b59587efd89f0 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -268,14 +268,9 @@ export default function TypographyPanel( { // Reset font appearance if there are no available styles or weights. resetFontAppearance(); } - }, [ - fontFamily, - fontFamilyFaces, - fontStyle, - fontWeight, - resetFontAppearance, - setFontAppearance, - ] ); + // We need to limit the dependency array to just `fontFamily` to avoid infinite loops. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ fontFamily ] ); // Line Height const hasLineHeightEnabled = useHasLineHeightControl( settings ); From 64b13cc657ce1c7c4437a50b52e08b72b9a926e1 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 15:23:54 +0100 Subject: [PATCH 16/25] Add normal font style test --- .../components/global-styles/test/typography-utils.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 8f0c738498e8ef..1127859125fa0a 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -985,6 +985,15 @@ describe( 'typography utils', () => { newFontStyleValue: 'oblique', expected: 'italic', }, + { + message: 'should return normal if normal is available', + availableFontStyles: [ + { name: 'Regular', value: 'normal' }, + { name: 'Italic', value: 'italic' }, + ], + newFontStyleValue: 'normal', + expected: 'normal', + }, ].forEach( ( { message, From fc209a6e520a837b618da3f40d96e7a66d0ecf4c Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 15:43:09 +0100 Subject: [PATCH 17/25] Add invalid font style test --- .../components/global-styles/test/typography-utils.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/block-editor/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js index 1127859125fa0a..41a7d6b5e37b8b 100644 --- a/packages/block-editor/src/components/global-styles/test/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/test/typography-utils.js @@ -976,6 +976,16 @@ describe( 'typography utils', () => { newFontStyleValue: 'italic', expected: '', }, + { + message: + 'should return empty string if the new font style is invalid', + availableFontStyles: [ + { name: 'Regular', value: 'normal' }, + { name: 'Italic', value: 'italic' }, + ], + newFontStyleValue: 'not-valid', + expected: '', + }, { message: 'should return italic if oblique is not available', availableFontStyles: [ From 1f69824ccd97fa813b633ebcf4377c97b2b1843b Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 18:31:39 +0100 Subject: [PATCH 18/25] Try toHaveText instead of toContainText --- .../specs/editor/various/font-appearance-control.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 8c54502a7d1bed..4dd533b84a4f51 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -30,7 +30,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .click(); await expect( page.getByRole( 'button', { name: 'Appearance' } ) - ).toContainText( 'Regular' ); + ).toHaveText( 'Regular' ); await editor.insertBlock( { name: 'core/paragraph', @@ -46,7 +46,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .click(); await expect( page.getByRole( 'button', { name: 'Appearance' } ) - ).toContainText( 'Extra Light Italic' ); + ).toHaveText( 'Extra Light Italic' ); await editor.insertBlock( { name: 'core/paragraph', @@ -62,7 +62,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .click(); await expect( page.getByRole( 'button', { name: 'Appearance' } ) - ).toContainText( 'Bold Italic' ); + ).toHaveText( 'Bold Italic' ); } ); test( 'should apply Default appearance if weight and style are invalid', async ( { @@ -89,6 +89,6 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .click(); await expect( page.getByRole( 'button', { name: 'Appearance' } ) - ).toContainText( 'Default' ); + ).toHaveText( 'Default' ); } ); } ); From a7a3b6a04f438fd08522ee452798269363ebcaa8 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 19:03:19 +0100 Subject: [PATCH 19/25] Try using TT4 for e2e test rather than TT3 --- test/e2e/specs/editor/various/font-appearance-control.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 4dd533b84a4f51..4955f693394359 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -5,7 +5,7 @@ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); test.describe( 'Font Appearance Control dropdown menu', () => { test.beforeAll( async ( { requestUtils } ) => { - await requestUtils.activateTheme( 'twentytwentythree' ); + await requestUtils.activateTheme( 'twentytwentyfour' ); } ); test.beforeEach( async ( { admin } ) => { From cec7d9d7b3db4e0742ada0c0afe66b09460e5421 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Mon, 8 Jul 2024 19:12:46 +0100 Subject: [PATCH 20/25] Use combobox role rather than button in e2e test --- .../specs/editor/various/font-appearance-control.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 4955f693394359..5118d3a606a777 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -29,7 +29,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .getByRole( 'button', { name: 'Typography options' } ) .click(); await expect( - page.getByRole( 'button', { name: 'Appearance' } ) + page.getByRole( 'combobox', { name: 'Appearance' } ) ).toHaveText( 'Regular' ); await editor.insertBlock( { @@ -45,7 +45,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .getByRole( 'button', { name: 'Typography options' } ) .click(); await expect( - page.getByRole( 'button', { name: 'Appearance' } ) + page.getByRole( 'combobox', { name: 'Appearance' } ) ).toHaveText( 'Extra Light Italic' ); await editor.insertBlock( { @@ -61,7 +61,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .getByRole( 'button', { name: 'Typography options' } ) .click(); await expect( - page.getByRole( 'button', { name: 'Appearance' } ) + page.getByRole( 'combobox', { name: 'Appearance' } ) ).toHaveText( 'Bold Italic' ); } ); @@ -88,7 +88,7 @@ test.describe( 'Font Appearance Control dropdown menu', () => { .getByRole( 'menuitemcheckbox', { name: 'Show Appearance' } ) .click(); await expect( - page.getByRole( 'button', { name: 'Appearance' } ) + page.getByRole( 'combobox', { name: 'Appearance' } ) ).toHaveText( 'Default' ); } ); } ); From b06c4e4716a71a88297bb521ec4607679fc8eb67 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Tue, 9 Jul 2024 16:41:26 +0100 Subject: [PATCH 21/25] Set nearestFontStyle to an empty string by default --- .../src/components/global-styles/typography-utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index c2a49f0a04fc94..b060d87d0984b0 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -192,7 +192,7 @@ export function findNearestFontWeight( * * @param {Array} availableFontStyles Array of available font weights. * @param {string} newFontStyleValue New font style value. - * @return {string} Nearest font style. + * @return {string} Nearest font style or an empty string. */ export function findNearestFontStyle( availableFontStyles, newFontStyleValue ) { if ( typeof newFontStyleValue !== 'string' || ! newFontStyleValue ) { @@ -209,7 +209,7 @@ export function findNearestFontStyle( availableFontStyles, newFontStyleValue ) { return newFontStyleValue; } - let nearestFontStyle; + let nearestFontStyle = ''; const validStyles = [ 'normal', 'italic', 'oblique' ]; if ( From b407be1654b1ce6851b5a72e155180c39f27e9dd Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Tue, 9 Jul 2024 16:55:29 +0100 Subject: [PATCH 22/25] Refactor findNearestFontStyle --- .../global-styles/typography-utils.js | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js index b060d87d0984b0..59ff04bf21ebcb 100644 --- a/packages/block-editor/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -199,6 +199,11 @@ export function findNearestFontStyle( availableFontStyles, newFontStyleValue ) { return ''; } + const validStyles = [ 'normal', 'italic', 'oblique' ]; + if ( ! validStyles.includes( newFontStyleValue ) ) { + return ''; + } + if ( ! availableFontStyles || availableFontStyles.length === 0 || @@ -209,26 +214,14 @@ export function findNearestFontStyle( availableFontStyles, newFontStyleValue ) { return newFontStyleValue; } - let nearestFontStyle = ''; - const validStyles = [ 'normal', 'italic', 'oblique' ]; - - if ( - ! validStyles.includes( newFontStyleValue ) || - ! availableFontStyles.find( - ( style ) => style.value === newFontStyleValue - ) - ) { - nearestFontStyle = ''; - } - if ( newFontStyleValue === 'oblique' && ! availableFontStyles.find( ( style ) => style.value === 'oblique' ) ) { - nearestFontStyle = 'italic'; + return 'italic'; } - return nearestFontStyle; + return ''; } /** From 9d7dfc4624eba3ea9e7825901efbb9f532560254 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Tue, 9 Jul 2024 17:33:47 +0100 Subject: [PATCH 23/25] Do not activate a theme in font appearance e2e test --- test/e2e/specs/editor/various/font-appearance-control.spec.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 5118d3a606a777..4b148b6dd8587c 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -4,10 +4,6 @@ const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); test.describe( 'Font Appearance Control dropdown menu', () => { - test.beforeAll( async ( { requestUtils } ) => { - await requestUtils.activateTheme( 'twentytwentyfour' ); - } ); - test.beforeEach( async ( { admin } ) => { await admin.createNewPost(); } ); From 18e1bfebf9b50cae3bb9fc81d1bf3814681b7922 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Fri, 12 Jul 2024 00:07:19 +0100 Subject: [PATCH 24/25] Run findNearestStyleAndWeight only when fontFamily has changed --- .../global-styles/typography-panel.js | 44 ++++++++++++------- .../various/font-appearance-control.spec.js | 3 -- 2 files changed, 29 insertions(+), 18 deletions(-) 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 2c6522938036b4..869e1acb4c69bb 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -8,7 +8,7 @@ import { __experimentalToolsPanelItem as ToolsPanelItem, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useCallback, useMemo, useEffect } from '@wordpress/element'; +import { useCallback, useMemo, useEffect, useRef } from '@wordpress/element'; /** * Internal dependencies @@ -185,6 +185,7 @@ export default function TypographyPanel( { // Font Family const hasFontFamilyEnabled = useHasFontFamilyControl( settings ); const fontFamily = decodeValue( inheritedValue?.typography?.fontFamily ); + const previousFontFamily = useRef( fontFamily ); const { fontFamilies, fontFamilyFaces } = useMemo( () => { return getMergedFontFamiliesAndFontFamilyFaces( settings, fontFamily ); }, [ settings, fontFamily ] ); @@ -256,21 +257,34 @@ export default function TypographyPanel( { // Check if previous font style and weight values are available in the new font family. useEffect( () => { - const { nearestFontStyle, nearestFontWeight } = - findNearestStyleAndWeight( fontFamilyFaces, fontStyle, fontWeight ); - - if ( nearestFontStyle && nearestFontWeight ) { - setFontAppearance( { - fontStyle: nearestFontStyle, - fontWeight: nearestFontWeight, - } ); - } else { - // Reset font appearance if there are no available styles or weights. - resetFontAppearance(); + if ( fontFamily !== previousFontFamily.current ) { + const { nearestFontStyle, nearestFontWeight } = + findNearestStyleAndWeight( + fontFamilyFaces, + fontStyle, + fontWeight + ); + + if ( nearestFontStyle && nearestFontWeight ) { + setFontAppearance( { + fontStyle: nearestFontStyle, + fontWeight: nearestFontWeight, + } ); + } else { + // Reset font appearance if there are no available styles or weights. + resetFontAppearance(); + } + + previousFontFamily.current = fontFamily; } - // We need to limit the dependency array to just `fontFamily` to avoid infinite loops. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ fontFamily ] ); + }, [ + fontFamily, + fontFamilyFaces, + fontStyle, + fontWeight, + resetFontAppearance, + setFontAppearance, + ] ); // Line Height const hasLineHeightEnabled = useHasLineHeightControl( settings ); diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 4b148b6dd8587c..050f06020f178e 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -80,9 +80,6 @@ test.describe( 'Font Appearance Control dropdown menu', () => { await page .getByRole( 'button', { name: 'Typography options' } ) .click(); - await page - .getByRole( 'menuitemcheckbox', { name: 'Show Appearance' } ) - .click(); await expect( page.getByRole( 'combobox', { name: 'Appearance' } ) ).toHaveText( 'Default' ); From 8288dd40a8eecf0be54ef06f2919540bd3687420 Mon Sep 17 00:00:00 2001 From: Sarah Norris Date: Sun, 14 Jul 2024 00:10:55 +0100 Subject: [PATCH 25/25] Only trigger appearance onChange if values are different --- .../global-styles/typography-panel.js | 62 +++++++++---------- .../various/font-appearance-control.spec.js | 3 + 2 files changed, 31 insertions(+), 34 deletions(-) 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 869e1acb4c69bb..f6a389a5bc96d9 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -8,7 +8,7 @@ import { __experimentalToolsPanelItem as ToolsPanelItem, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useCallback, useMemo, useEffect, useRef } from '@wordpress/element'; +import { useCallback, useMemo, useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -185,7 +185,6 @@ export default function TypographyPanel( { // Font Family const hasFontFamilyEnabled = useHasFontFamilyControl( settings ); const fontFamily = decodeValue( inheritedValue?.typography?.fontFamily ); - const previousFontFamily = useRef( fontFamily ); const { fontFamilies, fontFamilyFaces } = useMemo( () => { return getMergedFontFamiliesAndFontFamilyFaces( settings, fontFamily ); }, [ settings, fontFamily ] ); @@ -236,18 +235,26 @@ export default function TypographyPanel( { const hasFontWeights = settings?.typography?.fontWeight; const fontStyle = decodeValue( inheritedValue?.typography?.fontStyle ); const fontWeight = decodeValue( inheritedValue?.typography?.fontWeight ); + const { nearestFontStyle, nearestFontWeight } = findNearestStyleAndWeight( + fontFamilyFaces, + fontStyle, + fontWeight + ); const setFontAppearance = useCallback( ( { fontStyle: newFontStyle, fontWeight: newFontWeight } ) => { - onChange( { - ...value, - typography: { - ...value?.typography, - fontStyle: newFontStyle || undefined, - fontWeight: newFontWeight || undefined, - }, - } ); + // Only update the font style and weight if they have changed. + if ( newFontStyle !== fontStyle || newFontWeight !== fontWeight ) { + onChange( { + ...value, + typography: { + ...value?.typography, + fontStyle: newFontStyle || undefined, + fontWeight: newFontWeight || undefined, + }, + } ); + } }, - [ value, onChange ] + [ fontStyle, fontWeight, onChange, value ] ); const hasFontAppearance = () => !! value?.typography?.fontStyle || !! value?.typography?.fontWeight; @@ -257,31 +264,18 @@ export default function TypographyPanel( { // Check if previous font style and weight values are available in the new font family. useEffect( () => { - if ( fontFamily !== previousFontFamily.current ) { - const { nearestFontStyle, nearestFontWeight } = - findNearestStyleAndWeight( - fontFamilyFaces, - fontStyle, - fontWeight - ); - - if ( nearestFontStyle && nearestFontWeight ) { - setFontAppearance( { - fontStyle: nearestFontStyle, - fontWeight: nearestFontWeight, - } ); - } else { - // Reset font appearance if there are no available styles or weights. - resetFontAppearance(); - } - - previousFontFamily.current = fontFamily; + if ( nearestFontStyle && nearestFontWeight ) { + setFontAppearance( { + fontStyle: nearestFontStyle, + fontWeight: nearestFontWeight, + } ); + } else { + // Reset font appearance if there are no available styles or weights. + resetFontAppearance(); } }, [ - fontFamily, - fontFamilyFaces, - fontStyle, - fontWeight, + nearestFontStyle, + nearestFontWeight, resetFontAppearance, setFontAppearance, ] ); diff --git a/test/e2e/specs/editor/various/font-appearance-control.spec.js b/test/e2e/specs/editor/various/font-appearance-control.spec.js index 050f06020f178e..4b148b6dd8587c 100644 --- a/test/e2e/specs/editor/various/font-appearance-control.spec.js +++ b/test/e2e/specs/editor/various/font-appearance-control.spec.js @@ -80,6 +80,9 @@ test.describe( 'Font Appearance Control dropdown menu', () => { await page .getByRole( 'button', { name: 'Typography options' } ) .click(); + await page + .getByRole( 'menuitemcheckbox', { name: 'Show Appearance' } ) + .click(); await expect( page.getByRole( 'combobox', { name: 'Appearance' } ) ).toHaveText( 'Default' );