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

WP 6.1: backport fluid typography #44868

Merged
merged 7 commits into from
Oct 11, 2022
79 changes: 72 additions & 7 deletions lib/block-supports/typography.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
if ( $has_font_size_support && ! $should_skip_font_size ) {
$preset_font_size = array_key_exists( 'fontSize', $block_attributes ) ? "var:preset|font-size|{$block_attributes['fontSize']}" : null;
$custom_font_size = isset( $block_attributes['style']['typography']['fontSize'] ) ? $block_attributes['style']['typography']['fontSize'] : null;
$typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : $custom_font_size;
$typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : gutenberg_get_typography_font_size_value(
array(
'size' => $custom_font_size,
)
);
}

if ( $has_font_family_support && ! $should_skip_font_family ) {
Expand Down Expand Up @@ -228,13 +232,42 @@ function gutenberg_typography_get_css_variable_inline_style( $attributes, $featu
return sprintf( '%s:var(--wp--preset--%s--%s);', $css_property, $css_property, $slug );
}

/**
* Renders typography styles/content to the block wrapper.
*
* @param string $block_content Rendered block content.
* @param array $block Block object.
* @return string Filtered block content.
*/
function gutenberg_render_typography_support( $block_content, $block ) {
if ( ! isset( $block['attrs']['style']['typography']['fontSize'] ) ) {
return $block_content;
}

$custom_font_size = $block['attrs']['style']['typography']['fontSize'];
$fluid_font_size = gutenberg_get_typography_font_size_value( array( 'size' => $custom_font_size ) );

/*
* Checks that $fluid_font_size does not match $custom_font_size,
* which means it's been mutated by the fluid font size functions.
*/
if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) {
// Replaces the first instance of `font-size:$custom_font_size` with `font-size:$fluid_font_size`.
return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 );
}

return $block_content;

}

/**
* Internal method that checks a string for a unit and value and returns an array consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ].
* A raw font size of `value + unit` is expected. If the value is a number, it will convert to `value + 'px'`.
*
* @access private
*
* @param string $raw_value Raw size value from theme.json.
* @param array $options {
* @param string|int|float $raw_value Raw size value from theme.json.
* @param array $options {
* Optional. An associative array of options. Default is empty array.
*
* @type string $coerce_to Coerce the value to rem or px. Default `'rem'`.
Expand All @@ -244,10 +277,25 @@ function gutenberg_typography_get_css_variable_inline_style( $attributes, $featu
* @return array An array consisting of `'value'` and `'unit'` properties.
*/
function gutenberg_get_typography_value_and_unit( $raw_value, $options = array() ) {
if ( ! is_string( $raw_value ) && ! is_int( $raw_value ) && ! is_float( $raw_value ) ) {
_doing_it_wrong(
__FUNCTION__,
__( 'Raw size value must be a string, integer or a float.', 'gutenberg' ),
'6.1.0'
);
return null;
}

// Converts numeric values to pixel values by default.
if ( empty( $raw_value ) ) {
return null;
}

// Converts numbers to pixel values by default.
if ( is_numeric( $raw_value ) ) {
$raw_value = $raw_value . 'px';
}

$defaults = array(
'coerce_to' => '',
'root_size_value' => 16,
Expand Down Expand Up @@ -368,15 +416,27 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) {
* @param array $preset {
* Required. fontSizes preset value as seen in theme.json.
*
* @type string $name Name of the font size preset.
* @type string $slug Kebab-case unique identifier for the font size preset.
* @type string $size CSS font-size value, including units where applicable.
* @type string $name Name of the font size preset.
* @type string $slug Kebab-case unique identifier for the font size preset.
* @type string|int|float $size CSS font-size value, including units where applicable.
* }
* @param bool $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing. Default is `false`.
*
* @return string Font-size value.
* @return string|null Font-size value or `null` if a size is not passed in $preset.
*/
function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_typography = false ) {
if ( ! isset( $preset['size'] ) ) {
return null;
}

/*
* Catches empty values and 0/'0'.
* Fluid calculations cannot be performed on 0.
*/
if ( empty( $preset['size'] ) ) {
return $preset['size'];
}

// Check if fluid font sizes are activated.
$typography_settings = gutenberg_get_global_settings( array( 'typography' ) );
$should_use_fluid_typography = isset( $typography_settings['fluid'] ) && true === $typography_settings['fluid'] ? true : $should_use_fluid_typography;
Expand Down Expand Up @@ -446,3 +506,8 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
'apply' => 'gutenberg_apply_typography_support',
)
);

if ( function_exists( 'wp_render_typography_support' ) ) {
remove_filter( 'render_block', 'wp_render_typography_support' );
}
add_filter( 'render_block', 'gutenberg_render_typography_support', 10, 2 );
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 @@ -967,6 +967,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
9 changes: 9 additions & 0 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## Unreleased

### Bug Fix

- `FontSizePicker`: Update fluid utils so that only string, floats and integers are treated as valid font sizes for the purposes of fluid typography ([#44847](https://github.com/WordPress/gutenberg/pull/44847))
- `getTypographyClassesAndStyles()`: Ensure that font sizes are transformed into fluid values if fluid typography is activated ([#44852](https://github.com/WordPress/gutenberg/pull/44852))

## 10.2.0 (2022-10-05)

## 10.1.0 (2022-09-21)

## 10.0.0 (2022-09-13)

### Breaking change
Expand Down
40 changes: 40 additions & 0 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,45 @@ _Returns_

- `?Object`: Color object included in the colors array whose color property equals colorValue. Returns undefined if no color object matches this requirement.

### getComputedFluidTypographyValue

Computes a fluid font-size value that uses clamp(). A minimum and maxinmum
font size OR a single font size can be specified.

If a single font size is specified, it is scaled up and down by
minimumFontSizeFactor and maximumFontSizeFactor to arrive at the minimum and
maximum sizes.

_Usage_

```js
// Calculate fluid font-size value from a minimum and maximum value.
const fontSize = getComputedFluidTypographyValue( {
minimumFontSize: '20px',
maximumFontSize: '45px',
} );
// Calculate fluid font-size value from a single font size.
const fontSize = getComputedFluidTypographyValue( {
fontSize: '30px',
} );
```

_Parameters_

- _args_ `Object`:
- _args.minimumViewPortWidth_ `?string`: Minimum viewport size from which type will have fluidity. Optional if fontSize is specified.
- _args.maximumViewPortWidth_ `?string`: Maximum size up to which type will have fluidity. Optional if fontSize is specified.
- _args.fontSize_ `[string|number]`: Size to derive maximumFontSize and minimumFontSize from, if necessary. Optional if minimumFontSize and maximumFontSize are specified.
- _args.maximumFontSize_ `?string`: Maximum font size for any clamp() calculation. Optional.
- _args.minimumFontSize_ `?string`: Minimum font size for any clamp() calculation. Optional.
- _args.scaleFactor_ `?number`: A scale factor to determine how fast a font scales within boundaries. Optional.
- _args.minimumFontSizeFactor_ `?number`: How much to scale defaultFontSize by to derive minimumFontSize. Optional.
- _args.maximumFontSizeFactor_ `?number`: How much to scale defaultFontSize by to derive maximumFontSize. Optional.

_Returns_

- `string|null`: A font-size value using clamp().

### getFontSize

Returns the font size object based on an array of named font sizes and the namedFontSize and customFontSize values.
Expand Down Expand Up @@ -482,6 +521,7 @@ attributes.
_Parameters_

- _attributes_ `Object`: Block attributes.
- _isFluidFontSizeActive_ `boolean`: Whether the function should try to convert font sizes to fluid values.

_Returns_

Expand Down