diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php index ffa515cd8bae4..0d61ad32f02a2 100644 --- a/lib/block-supports/typography.php +++ b/lib/block-supports/typography.php @@ -206,6 +206,53 @@ function gutenberg_typography_get_css_variable_inline_style( $attributes, $featu return sprintf( '%s:var(--wp--preset--%s--%s);', $css_property, $css_property, $slug ); } +function gutenberg_get_typography_font_size_value( $preset ) { + // This is where we'll keep options I guess. + // Comment out to show how things work. + $typography_settings = gutenberg_get_global_settings( array( 'typography' ) ); + +// if ( ! isset( $typography_settings['fluid'] ) ) { +// return $preset['size']; +// } + + // Should be defined by theme.json, maybe take from layout? + $minimum_viewport_width = 640 / 16; // rem for now. 1200(px) / 16 to get rem. + $maximum_viewport_width = 1600 / 16; // Ditto. + + /* + Up next; + - Challenge: looping through fontSizes and calculating clamp functions for every size relies preferably on rem/px or unitless values. + - Apply this to custom font-size values. + */ + + // Matches rem or unitless values only. + $pattern = '/^(\d*\.?\d+)(rem|px)?$/'; + preg_match_all( $pattern, $preset['size'], $matches ); + + if ( isset( $matches[1][0] ) ) { + $base_value = intval( $matches[1][0] ); + + if ( isset( $matches[2][0] ) && 'px' === $matches[2][0] ) { + // Calculate rem to px. + + $base_value = $base_value / 16; + } + + $minimum_font_size = $base_value * 1; // A min value should ideally be coming from theme.json. + $maximum_font_size = $base_value * 1.5; // Ditto on the max. + $factor = ( 1 / ( $maximum_viewport_width - $minimum_viewport_width ) ) * ( $maximum_font_size - $minimum_font_size ); + $calc_rem = $minimum_font_size - ( $minimum_viewport_width * $factor ); + $calc_vw = 100 * $factor; + $min = min( $minimum_font_size, $maximum_font_size ); + $max = max( $minimum_font_size, $maximum_font_size ); + + return "clamp({$min}rem, {$calc_rem}rem + {$calc_vw}vw, {$max}rem)"; + + } else { + return $preset['size']; + } +} + // Register the block support. WP_Block_Supports::get_instance()->register( 'typography', diff --git a/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php b/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php index 567dfb0cf4027..9d466a239ebb0 100644 --- a/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php +++ b/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php @@ -16,6 +16,114 @@ */ class WP_Theme_JSON_Gutenberg extends WP_Theme_JSON_5_9 { + /** + * Presets are a set of values that serve + * to bootstrap some styles: colors, font sizes, etc. + * + * They are a unkeyed array of values such as: + * + * ```php + * array( + * array( + * 'slug' => 'unique-name-within-the-set', + * 'name' => 'Name for the UI', + * => 'value' + * ), + * ) + * ``` + * + * This contains the necessary metadata to process them: + * + * - path => Where to find the preset within the settings section. + * - prevent_override => Whether a theme preset with the same slug as a default preset + * should not override it or the path to a setting for the same + * When defaults. + * The relationship between whether to override the defaults + * and whether the defaults are enabled is inverse: + * - If defaults are enabled => theme presets should not be overriden + * - If defaults are disabled => theme presets should be overriden + * For example, a theme sets defaultPalette to false, + * making the default palette hidden from the user. + * In that case, we want all the theme presets to be present, + * so they should override the defaults by setting this false. + * - value_key => the key that represents the value + * - value_func => optionally, instead of value_key, a function to generate + * the value that takes a preset as an argument + * (either value_key or value_func should be present) + * - css_vars => template string to use in generating the CSS Custom Property. + * Example output: "--wp--preset--duotone--blue: " will generate as many CSS Custom Properties as presets defined + * substituting the $slug for the slug's value for each preset value. + * - classes => array containing a structure with the classes to + * generate for the presets, where for each array item + * the key is the class name and the value the property name. + * The "$slug" substring will be replaced by the slug of each preset. + * For example: + * 'classes' => array( + * '.has-$slug-color' => 'color', + * '.has-$slug-background-color' => 'background-color', + * '.has-$slug-border-color' => 'border-color', + * ) + * - properties => array of CSS properties to be used by kses to + * validate the content of each preset + * by means of the remove_insecure_properties method. + */ + const PRESETS_METADATA = array( + array( + 'path' => array( 'color', 'palette' ), + 'prevent_override' => array( 'color', 'defaultPalette' ), + 'use_default_presets' => array( 'color', 'defaultPalette' ), + 'use_default_names' => false, + 'value_key' => 'color', + 'css_vars' => '--wp--preset--color--$slug', + 'classes' => array( + '.has-$slug-color' => 'color', + '.has-$slug-background-color' => 'background-color', + '.has-$slug-border-color' => 'border-color', + ), + 'properties' => array( 'color', 'background-color', 'border-color' ), + ), + array( + 'path' => array( 'color', 'gradients' ), + 'prevent_override' => array( 'color', 'defaultGradients' ), + 'use_default_presets' => array( 'color', 'defaultGradients' ), + 'use_default_names' => false, + 'value_key' => 'gradient', + 'css_vars' => '--wp--preset--gradient--$slug', + 'classes' => array( '.has-$slug-gradient-background' => 'background' ), + 'properties' => array( 'background' ), + ), + array( + 'path' => array( 'color', 'duotone' ), + 'prevent_override' => array( 'color', 'defaultDuotone' ), + 'use_default_presets' => array( 'color', 'defaultDuotone' ), + 'use_default_names' => false, + 'value_func' => 'gutenberg_get_duotone_filter_property', + 'css_vars' => '--wp--preset--duotone--$slug', + 'classes' => array(), + 'properties' => array( 'filter' ), + ), + array( + 'path' => array( 'typography', 'fontSizes' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => true, + 'value_func' => 'gutenberg_get_typography_font_size_value', + 'css_vars' => '--wp--preset--font-size--$slug', + 'classes' => array( '.has-$slug-font-size' => 'font-size' ), + 'properties' => array( 'font-size' ), + ), + array( + 'path' => array( 'typography', 'fontFamilies' ), + 'prevent_override' => false, + 'use_default_presets' => true, + 'use_default_names' => false, + 'value_key' => 'fontFamily', + 'css_vars' => '--wp--preset--font-family--$slug', + 'classes' => array( '.has-$slug-font-family' => 'font-family' ), + 'properties' => array( 'font-family' ), + ), + ); + /** * The top-level keys a theme.json can have. *