Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fluid Typography: Fix bug in global styles where fluid clamp rules were not calculated for custom values #44761

Merged
merged 9 commits into from
Oct 10, 2022
12 changes: 12 additions & 0 deletions lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,18 @@ protected static function compute_style_properties( $styles, $settings = array()
continue;
}

// Calculates fluid typography rules where available.
if ( 'font-size' === $css_property ) {
/*
* gutenberg_get_typography_font_size_value() will check
* if fluid typography has been activated and also
* whether the incoming value can be converted to a fluid value.
* Values that already have a "clamp()" function will not pass the test,
* and therefore the original $value will be returned.
*/
$value = gutenberg_get_typography_font_size_value( array( 'size' => $value ) );
}

$declarations[] = array(
'name' => $css_property,
'value' => $value,
Expand Down
3 changes: 3 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Bug Fix
- `FontSizePicker`: Ensure that fluid font size presets appear correctly in the UI controls ([#44791](https://github.com/WordPress/gutenberg/pull/44791))

## 21.2.0 (2022-10-05)

### Enhancements
Expand Down
10 changes: 5 additions & 5 deletions packages/components/src/font-size-picker/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,33 +120,33 @@ describe( 'getToggleGroupOptions', () => {
).toEqual( [
{
key: '1',
value: '1',
label: 'S',
name: '1',
value: '1',
},
{
key: '2',
value: '2',
label: 'M',
name: '2',
value: '2',
},
{
key: '3',
value: '3',
label: 'L',
name: '3',
value: '3',
},
{
key: '4',
value: '4',
label: 'XL',
name: '4',
value: '4',
},
{
key: '5',
value: '5',
label: 'XXL',
name: 'XXL',
value: '5',
},
] );
} );
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/font-size-picker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function getSelectOptions(
];
return options.map( ( { slug, name, size } ) => ( {
key: slug,
name,
name: name || slug,
size,
__experimentalHint:
size && isSimpleCssValue( size ) && parseFloat( String( size ) ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,41 @@ describe( 'typography utils', () => {
},
expected: '28px',
},
// Should coerce number to `px` and return non-fluid value.
// Should coerce number to `px` and return fluid value.
{
preset: {
size: 33,
fluid: true,
},
typographySettings: {
fluid: true,
},
expected:
'clamp(24.75px, 1.546875rem + ((1vw - 7.68px) * 2.975), 49.5px)',
},
// Should return incoming value when already clamped.
{
preset: {
size: 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)',
fluid: false,
},
typographySettings: {
fluid: true,
},
expected:
'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)',
},
// Should return incoming value with unsupported unit.
{
preset: {
size: '1000%',
fluid: false,
},
typographySettings: {
fluid: true,
},
expected: '1000%',
},
// Should return fluid value.
{
preset: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -711,10 +711,11 @@ describe( 'global styles renderer', () => {
},
typography: {
fontFamily: 'sans-serif',
fontSize: '14px',
},
};

it( 'Should output padding variables and other properties if useRootPaddingAwareAlignments is enabled', () => {
it( 'should output padding variables and other properties if useRootPaddingAwareAlignments is enabled', () => {
expect(
getStylesDeclarations( blockStyles, 'body', true )
).toEqual( [
Expand All @@ -724,10 +725,11 @@ describe( 'global styles renderer', () => {
'--wp--style--root--padding-left: 33px',
'background-color: var(--wp--preset--color--light-green-cyan)',
'font-family: sans-serif',
'font-size: 14px',
] );
} );

it( 'Should output padding and other properties if useRootPaddingAwareAlignments is disabled', () => {
it( 'should output padding and other properties if useRootPaddingAwareAlignments is disabled', () => {
expect(
getStylesDeclarations( blockStyles, 'body', false )
).toEqual( [
Expand All @@ -737,10 +739,11 @@ describe( 'global styles renderer', () => {
'padding-bottom: 33px',
'padding-left: 33px',
'font-family: sans-serif',
'font-size: 14px',
] );
} );

it( 'Should not output padding variables if selector is not root', () => {
it( 'should not output padding variables if selector is not root', () => {
expect(
getStylesDeclarations(
blockStyles,
Expand All @@ -754,6 +757,57 @@ describe( 'global styles renderer', () => {
'padding-bottom: 33px',
'padding-left: 33px',
'font-family: sans-serif',
'font-size: 14px',
] );
} );

it( 'should output clamp values for font-size when fluid typography is enabled', () => {
expect(
getStylesDeclarations(
blockStyles,
'.wp-block-site-title',
true,
{
settings: {
typography: {
fluid: true,
},
},
}
)
).toEqual( [
'background-color: var(--wp--preset--color--light-green-cyan)',
'padding-top: 33px',
'padding-right: 33px',
'padding-bottom: 33px',
'padding-left: 33px',
'font-family: sans-serif',
'font-size: clamp(10.5px, 0.65625rem + ((1vw - 7.68px) * 1.262), 21px)',
] );
} );

it( 'should output direct values for font-size when fluid typography is disabled', () => {
expect(
getStylesDeclarations(
blockStyles,
'.wp-block-site-title',
true,
{
settings: {
typography: {
fluid: false,
},
},
}
)
).toEqual( [
'background-color: var(--wp--preset--color--light-green-cyan)',
'padding-top: 33px',
'padding-right: 33px',
'padding-bottom: 33px',
'padding-left: 33px',
'font-family: sans-serif',
'font-size: 14px',
] );
} );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { __ } from '@wordpress/i18n';
* Internal dependencies
*/
import { getSupportedGlobalStylesPanels, useSetting, useStyle } from './hooks';
import { getTypographyFontSizeValue } from './typography-utils';

export function useHasTypographyPanel( name ) {
const hasFontFamily = useHasFontFamilyControl( name );
Expand Down Expand Up @@ -151,7 +152,19 @@ export default function TypographyPanel( { name, element, headingLevel } ) {
} else if ( element && element !== 'text' ) {
prefix = `elements.${ element }.`;
}
const [ fluidTypography ] = useSetting( 'typography.fluid', name );
const [ fontSizes ] = useSetting( 'typography.fontSizes', name );

// Convert static font size values to fluid font sizes if fluidTypography is activated.
const fontSizesWithFluidValues = fontSizes.map( ( font ) => {
if ( !! fluidTypography ) {
font.size = getTypographyFontSizeValue( font, {
fluid: fluidTypography,
} );
}
return font;
} );

const disableCustomFontSizes = ! useSetting(
'typography.customFontSize',
name
Expand Down Expand Up @@ -240,7 +253,7 @@ export default function TypographyPanel( { name, element, headingLevel } ) {
<FontSizePicker
value={ fontSize }
onChange={ setFontSize }
fontSizes={ fontSizes }
fontSizes={ fontSizesWithFluidValues }
disableCustomFontSizes={ disableCustomFontSizes }
withReset={ false }
size="__unstable-large"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,27 @@
*/
import { getComputedFluidTypographyValue } from '@wordpress/block-editor';

/**
* @typedef {Object} FluidPreset
* @property {string|undefined} max A maximum font size value.
* @property {string|undefined} min A minimum font size value.
*/

/**
* @typedef {Object} Preset
* @property {string} size A default font size.
* @property {string} name A font size name, displayed in the UI.
* @property {string} slug A font size slug
* @property {boolean|FluidPreset|undefined} fluid A font size slug
*/

/**
* Returns a font-size value based on a given font-size preset.
* Takes into account fluid typography parameters and attempts to return a css formula depending on available, valid values.
*
* @param {Object} preset
* @param {string} preset.size A default font size.
* @param {string} preset.name A font size name, displayed in the UI.
* @param {string} preset.slug A font size slug.
* @param {Object} preset.fluid
* @param {string|undefined} preset.fluid.max A maximum font size value.
* @param {string|undefined} preset.fluid.min A minimum font size value.
* @param {Object} typographySettings
* @param {boolean} typographySettings.fluid Whether fluid typography is enabled.
* @param {Preset} preset
* @param {Object} typographySettings
* @param {boolean} typographySettings.fluid Whether fluid typography is enabled.
*
* @return {string} An font-size value
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
* Internal dependencies
*/
import { PRESET_METADATA, ROOT_BLOCK_SELECTOR, scopeSelector } from './utils';
import { getTypographyFontSizeValue } from './typography-utils';
import { GlobalStylesContext } from './context';
import { useSetting } from './hooks';

Expand Down Expand Up @@ -276,6 +277,21 @@ export function getStylesDeclarations(
}
}

// Calculate fluid typography rules where available.
if ( cssProperty === 'font-size' ) {
/*
* getTypographyFontSizeValue() will check
* if fluid typography has been activated and also
* whether the incoming value can be converted to a fluid value.
* Values that already have a "clamp()" function will not pass the test,
* and therefore the original $value will be returned.
*/
ruleValue = getTypographyFontSizeValue(
{ size: ruleValue },
tree?.settings?.typography
);
}

output.push( `${ cssProperty }: ${ ruleValue }` );
} );

Expand Down