From 2012a36da2a7752dceeda3dcf0af8e58985e8072 Mon Sep 17 00:00:00 2001 From: Alex Lende Date: Thu, 25 Apr 2024 12:57:52 -0500 Subject: [PATCH] Add defaultFontSizes theme.json (v2) (#58409) Co-authored-by: ajlende Co-authored-by: draganescu Co-authored-by: scruffian Co-authored-by: gaambo Co-authored-by: youknowriad Co-authored-by: oandregal --- docs/manifest.json | 2 +- .../theme-json-reference/theme-json-living.md | 12 +- .../theme-json-migrations.md | 24 ++ .../theme-json-reference/theme-json-v2.md | 336 ++++++++++++++++++ lib/class-wp-theme-json-data-gutenberg.php | 2 +- lib/class-wp-theme-json-gutenberg.php | 68 ++-- ...class-wp-theme-json-resolver-gutenberg.php | 13 +- lib/class-wp-theme-json-schema-gutenberg.php | 61 +++- lib/theme.json | 3 +- .../src/components/global-styles/hooks.js | 2 + .../global-styles/typography-panel.js | 38 +- packages/block-editor/src/hooks/utils.js | 4 + packages/block-editor/src/utils/object.js | 16 + ...lobal-styles-controller-gutenberg-test.php | 2 +- phpunit/class-wp-theme-json-schema-test.php | 82 ++++- phpunit/class-wp-theme-json-test.php | 82 ++--- .../theme.json | 2 +- .../theme.json | 2 +- .../theme.json | 2 +- .../block-theme-child/styles/variation-a.json | 2 +- .../block-theme-child/styles/variation-b.json | 2 +- .../themedir1/block-theme-child/theme.json | 2 +- .../block-theme/styles/variation-a.json | 2 +- .../block-theme/styles/variation-b.json | 2 +- .../block-theme/styles/variation.json | 2 +- phpunit/data/themedir1/block-theme/theme.json | 2 +- .../styles/variation-duplicate-fonts.json | 2 +- .../styles/variation-new-font-family.json | 2 +- .../styles/variation-new-font-variations.json | 2 +- .../styles/variation-no-fonts.json | 2 +- .../themedir1/fonts-block-theme/theme.json | 2 +- schemas/json/theme.json | 7 +- test/emptytheme/styles/variation.json | 2 +- test/emptytheme/theme.json | 2 +- .../style-variations/styles/pink.json | 2 +- .../style-variations/styles/yellow.json | 2 +- .../style-variations/theme.json | 2 +- 37 files changed, 656 insertions(+), 138 deletions(-) create mode 100644 docs/reference-guides/theme-json-reference/theme-json-v2.md diff --git a/docs/manifest.json b/docs/manifest.json index cf30aff19c503..df12afa59cbc5 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -564,7 +564,7 @@ "parent": "reference-guides" }, { - "title": "Theme.json Version 2", + "title": "Theme.json Version 3", "slug": "theme-json-living", "markdown_source": "../docs/reference-guides/theme-json-reference/theme-json-living.md", "parent": "theme-json-reference" diff --git a/docs/reference-guides/theme-json-reference/theme-json-living.md b/docs/reference-guides/theme-json-reference/theme-json-living.md index 9120af4f7456c..bea655e61af82 100644 --- a/docs/reference-guides/theme-json-reference/theme-json-living.md +++ b/docs/reference-guides/theme-json-reference/theme-json-living.md @@ -1,10 +1,11 @@ -# Theme.json Version 2 +# Theme.json Version 3 -> This is the living specification for **version 2** of `theme.json`. This version works with WordPress 5.9 or later, and the latest Gutenberg plugin. +> This is the living specification for **version 3** of `theme.json`. This version works with WordPress 5.9 or later, and the latest Gutenberg plugin. > > There are some related documents that you may be interested in: -> - the [theme.json v1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) specification, and -> - the [reference to migrate from theme.json v1 to v2](/docs/reference-guides/theme-json-reference/theme-json-migrations.md). +> - the [theme.json v1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) specification, +> - the [theme.json v2](/docs/reference-guides/theme-json-reference/theme-json-v2.md) specification, and +> - the [reference to migrate from older theme.json versions](/docs/reference-guides/theme-json-reference/theme-json-migrations.md). This reference guide lists the settings and style properties defined in the `theme.json` schema. See the [theme.json how to guide](/docs/how-to-guides/themes/global-settings-and-styles.md) for examples and guidance on how to use the `theme.json` file in your theme. @@ -17,7 +18,7 @@ Code editors can pick up the schema and can provide helpful hints and suggestion ``` { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, ... } ``` @@ -179,6 +180,7 @@ Settings related to typography. | Property | Type | Default | Props | | --- | --- | --- |--- | +| defaultFontSizes | boolean | true | | | customFontSize | boolean | true | | | fontStyle | boolean | true | | | fontWeight | boolean | true | | diff --git a/docs/reference-guides/theme-json-reference/theme-json-migrations.md b/docs/reference-guides/theme-json-reference/theme-json-migrations.md index b043ca1fba52a..07acf41bf2eb7 100644 --- a/docs/reference-guides/theme-json-reference/theme-json-migrations.md +++ b/docs/reference-guides/theme-json-reference/theme-json-migrations.md @@ -63,3 +63,27 @@ Additions to styles: ### Changes to property values The default font sizes provided by core (`settings.typography.fontSizes`) have been updated. The Normal and Huge sizes (with `normal` and `huge` slugs) have been removed from the list, and Extra Large (`x-large` slug) has been added. When the UI controls show the default values provided by core, Normal and Huge will no longer be present. However, their CSS classes and CSS Custom Properties are still enqueued to make sure existing content that uses them still works as expected. + +## Migrating from v2 to v3 + +Upgrading to v3 adjusts preset defaults to be more consistent with one another. + +### How to migrate from v1 to v2: + +1. Update `version` to `3`. +2. Configure the changed defaults. + +### Changed defaults + +#### `settings.typography.defaultFontSizes` + +In theme.json v2, the default font sizes were only shown when theme sizes were not defined. A theme providing font sizes with the same slugs as the defaults would always override them. + +The new `defaultFontSizes` option gives control over showing default font sizes and preventing those defaults from being overridden. + +- When set to `true` it will show the default font sizes and prevent them from being overridden by the theme. +- When set to `false` it will hide the default font sizes and allow the theme to use the default slugs. + +It is `true` by default when switching to v3. This is to be consistent with how other `default*` options work such as `settings.color.defaultPalette`. + +To keep behavior similar to v2, set this value to `false`. diff --git a/docs/reference-guides/theme-json-reference/theme-json-v2.md b/docs/reference-guides/theme-json-reference/theme-json-v2.md new file mode 100644 index 0000000000000..56cdff1c3bb86 --- /dev/null +++ b/docs/reference-guides/theme-json-reference/theme-json-v2.md @@ -0,0 +1,336 @@ +# Theme.json Version 2 + +> This is the living specification for **version 2** of `theme.json`. This version works with WordPress 5.9 or later, and the latest Gutenberg plugin. +> +> There are some related documents that you may be interested in: +> - the [theme.json v1](/docs/reference-guides/theme-json-reference/theme-json-v1.md) specification, and +> - the [reference to migrate from theme.json v1 to v2](/docs/reference-guides/theme-json-reference/theme-json-migrations.md). + +This reference guide lists the settings and style properties defined in the `theme.json` schema. See the [theme.json how to guide](/docs/how-to-guides/themes/global-settings-and-styles.md) for examples and guidance on how to use the `theme.json` file in your theme. + +## Schema + +Remembering the `theme.json` settings and properties while you develop can be difficult, so a [JSON schema](https://schemas.wp.org/trunk/theme.json) was created to help. + +Code editors can pick up the schema and can provide helpful hints and suggestions such as tooltips, autocomplete, or schema validation in the editor. To use the schema in Visual Studio Code, add `$schema`: "https://schemas.wp.org/trunk/theme.json" to the beginning of your theme.json file together with a `version` corresponding to the version you wish to use, e.g.: + +``` +{ + "$schema": "https://schemas.wp.org/trunk/theme.json", + "version": 2, + ... +} +``` + +## Settings + +### appearanceTools + +Setting that enables the following UI tools: + +- background: backgroundImage, backgroundSize +- border: color, radius, style, width +- color: link, heading, button, caption +- dimensions: aspectRatio, minHeight +- position: sticky +- spacing: blockGap, margin, padding +- typography: lineHeight + +--- + +### useRootPaddingAwareAlignments + +_**Note:** Since WordPress 6.1._ + +Enables root padding (the values from `styles.spacing.padding`) to be applied to the contents of full-width blocks instead of the root block. + +Please note that when using this setting, `styles.spacing.padding` should always be set as an object with `top`, `right`, `bottom`, `left` values declared separately. + +--- + +### border + +Settings related to borders. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| color | boolean | false | | +| radius | boolean | false | | +| style | boolean | false | | +| width | boolean | false | | + +--- + +### shadow + +Settings related to shadows. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| defaultPresets | boolean | true | | +| presets | array | | name, shadow, slug | + +--- + +### color + +Settings related to colors. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| background | boolean | true | | +| custom | boolean | true | | +| customDuotone | boolean | true | | +| customGradient | boolean | true | | +| defaultDuotone | boolean | true | | +| defaultGradients | boolean | true | | +| defaultPalette | boolean | true | | +| duotone | array | | colors, name, slug | +| gradients | array | | gradient, name, slug | +| link | boolean | false | | +| palette | array | | color, name, slug | +| text | boolean | true | | +| heading | boolean | true | | +| button | boolean | true | | +| caption | boolean | true | | + +--- + +### background + +Settings related to background. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| backgroundImage | boolean | false | | +| backgroundSize | boolean | false | | + +--- + +### dimensions + +Settings related to dimensions. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| aspectRatio | boolean | false | | +| minHeight | boolean | false | | + +--- + +### layout + +Settings related to layout. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| contentSize | string | | | +| wideSize | string | | | +| allowEditing | boolean | true | | +| allowCustomContentAndWideSize | boolean | true | | + +--- + +### lightbox + +Settings related to the lightbox. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| enabled | boolean | | | +| allowEditing | boolean | | | + +--- + +### position + +Settings related to position. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| sticky | boolean | false | | + +--- + +### spacing + +Settings related to spacing. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| blockGap | boolean, null | null | | +| margin | boolean | false | | +| padding | boolean | false | | +| units | array | px,em,rem,vh,vw,% | | +| customSpacingSize | boolean | true | | +| spacingSizes | array | | name, size, slug | +| spacingScale | object | | | + +--- + +### typography + +Settings related to typography. + +| Property | Type | Default | Props | +| --- | --- | --- |--- | +| customFontSize | boolean | true | | +| fontStyle | boolean | true | | +| fontWeight | boolean | true | | +| fluid | object, boolean | false | _{maxViewportWidth, minFontSize, minViewportWidth}_ | +| letterSpacing | boolean | true | | +| lineHeight | boolean | false | | +| textAlign | boolean | true | | +| textColumns | boolean | false | | +| textDecoration | boolean | true | | +| writingMode | boolean | false | | +| textTransform | boolean | true | | +| dropCap | boolean | true | | +| fontSizes | array | | fluid, name, size, slug | +| fontFamilies | array | | fontFace, fontFamily, name, slug | + +--- + +### custom + +Generate custom CSS custom properties of the form `--wp--custom--{key}--{nested-key}: {value};`. `camelCased` keys are transformed to `kebab-case` as to follow the CSS property naming schema. Keys at different depth levels are separated by `--`, so keys should not include `--` in the name. + +--- + +## Styles + +### border + +Border styles. + +| Property | Type | Props | +| --- | --- |--- | +| color | string, object | | +| radius | string, object | | +| style | string, object | | +| width | string, object | | +| top | object | color, style, width | +| right | object | color, style, width | +| bottom | object | color, style, width | +| left | object | color, style, width | + +--- + +### color + +Color styles. + +| Property | Type | Props | +| --- | --- |--- | +| background | string, object | | +| gradient | string, object | | +| text | string, object | | + +--- + +### dimensions + +Dimensions styles + +| Property | Type | Props | +| --- | --- |--- | +| aspectRatio | string, object | | +| minHeight | string, object | | + +--- + +### spacing + +Spacing styles. + +| Property | Type | Props | +| --- | --- |--- | +| blockGap | string, object | | +| margin | object | bottom, left, right, top | +| padding | object | bottom, left, right, top | + +--- + +### typography + +Typography styles. + +| Property | Type | Props | +| --- | --- |--- | +| fontFamily | string, object | | +| fontSize | string, object | | +| fontStyle | string, object | | +| fontWeight | string, object | | +| letterSpacing | string, object | | +| lineHeight | string, object | | +| textAlign | string | | +| textColumns | string | | +| textDecoration | string, object | | +| writingMode | string, object | | +| textTransform | string, object | | + +--- + +### filter + +CSS and SVG filter styles. + +| Property | Type | Props | +| --- | --- |--- | +| duotone | string, object | | + +--- + +### shadow + +Box shadow styles. + +--- + +### outline + +Outline styles. + +| Property | Type | Props | +| --- | --- |--- | +| color | string, object | | +| offset | string, object | | +| style | string, object | | +| width | string, object | | + +--- + +### css + +Sets custom CSS to apply styling not covered by other theme.json properties. + +--- + +## customTemplates + +Additional metadata for custom templates defined in the templates folder. + +Type: `object`. + +| Property | Description | Type | +| --- | --- | --- | +| name | Filename, without extension, of the template in the templates folder. | string | +| title | Title of the template, translatable. | string | +| postTypes | List of post types that can use this custom template. | array | + +## templateParts + +Additional metadata for template parts defined in the parts folder. + +Type: `object`. + +| Property | Description | Type | +| --- | --- | --- | +| name | Filename, without extension, of the template in the parts folder. | string | +| title | Title of the template, translatable. | string | +| area | The area the template part is used for. Block variations for `header` and `footer` values exist and will be used when the area is set to one of those. | string | + +## Patterns + +An array of pattern slugs to be registered from the Pattern Directory. +Type: `array`. diff --git a/lib/class-wp-theme-json-data-gutenberg.php b/lib/class-wp-theme-json-data-gutenberg.php index 6877a209b687f..c564016b1a711 100644 --- a/lib/class-wp-theme-json-data-gutenberg.php +++ b/lib/class-wp-theme-json-data-gutenberg.php @@ -38,7 +38,7 @@ class WP_Theme_JSON_Data_Gutenberg { * @param array $data Array following the theme.json specification. * @param string $origin The origin of the data: default, theme, user. */ - public function __construct( $data = array(), $origin = 'theme' ) { + public function __construct( $data = array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ), $origin = 'theme' ) { $this->origin = $origin; $this->theme_json = new WP_Theme_JSON_Gutenberg( $data, $this->origin ); } diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 1d3f8feb90e23..d685c7bdc846d 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -159,7 +159,7 @@ class WP_Theme_JSON_Gutenberg { ), array( 'path' => array( 'typography', 'fontSizes' ), - 'prevent_override' => false, + 'prevent_override' => array( 'typography', 'defaultFontSizes' ), 'use_default_names' => true, 'value_func' => 'gutenberg_get_typography_font_size_value', 'css_vars' => '--wp--preset--font-size--$slug', @@ -428,20 +428,21 @@ class WP_Theme_JSON_Gutenberg { 'defaultPresets' => null, ), 'typography' => array( - 'fluid' => null, - 'customFontSize' => null, - 'dropCap' => null, - 'fontFamilies' => null, - 'fontSizes' => null, - 'fontStyle' => null, - 'fontWeight' => null, - 'letterSpacing' => null, - 'lineHeight' => null, - 'textAlign' => null, - 'textColumns' => null, - 'textDecoration' => null, - 'textTransform' => null, - 'writingMode' => null, + 'fluid' => null, + 'customFontSize' => null, + 'defaultFontSizes' => null, + 'dropCap' => null, + 'fontFamilies' => null, + 'fontSizes' => null, + 'fontStyle' => null, + 'fontWeight' => null, + 'letterSpacing' => null, + 'lineHeight' => null, + 'textAlign' => null, + 'textColumns' => null, + 'textDecoration' => null, + 'textTransform' => null, + 'writingMode' => null, ), ); @@ -705,9 +706,10 @@ public static function get_element_class_name( $element ) { * * @since 5.8.0 * @since 5.9.0 Changed value from 1 to 2. + * @since 6.5.0 Changed value from 2 to 3. * @var int */ - const LATEST_SCHEMA = 2; + const LATEST_SCHEMA = 3; /** * Constructor. @@ -718,7 +720,7 @@ public static function get_element_class_name( $element ) { * @param string $origin Optional. What source of data this object represents. * One of 'default', 'theme', or 'custom'. Default 'theme'. */ - public function __construct( $theme_json = array(), $origin = 'theme' ) { + public function __construct( $theme_json = array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ), $origin = 'theme' ) { if ( ! in_array( $origin, static::VALID_ORIGINS, true ) ) { $origin = 'theme'; } @@ -2890,12 +2892,15 @@ public function merge( $incoming ) { } // Replace the presets. - foreach ( static::PRESETS_METADATA as $preset ) { - $override_preset = ! static::get_metadata_boolean( $this->theme_json['settings'], $preset['prevent_override'], true ); + foreach ( static::PRESETS_METADATA as $preset_metadata ) { + $prevent_override = $preset_metadata['prevent_override']; + if ( is_array( $prevent_override ) ) { + $prevent_override = _wp_array_get( $this->theme_json['settings'], $preset_metadata['prevent_override'] ); + } foreach ( static::VALID_ORIGINS as $origin ) { $base_path = $node['path']; - foreach ( $preset['path'] as $leaf ) { + foreach ( $preset_metadata['path'] as $leaf ) { $base_path[] = $leaf; } @@ -2907,7 +2912,8 @@ public function merge( $incoming ) { continue; } - if ( 'theme' === $origin && $preset['use_default_names'] ) { + // Set names for theme presets based on the slug if they are not set and can use default names. + if ( 'theme' === $origin && $preset_metadata['use_default_names'] ) { foreach ( $content as $key => $item ) { if ( ! isset( $item['name'] ) ) { $name = static::get_name_from_defaults( $item['slug'], $base_path ); @@ -2918,19 +2924,17 @@ public function merge( $incoming ) { } } - if ( - ( 'theme' !== $origin ) || - ( 'theme' === $origin && $override_preset ) - ) { - _wp_array_set( $this->theme_json, $path, $content ); - } else { - $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] ); - $slugs = array_merge_recursive( $slugs_global, $slugs_node ); + // Filter out default slugs from theme presets when defaults should not be overridden. + if ( 'theme' === $origin && $prevent_override ) { + $slugs_node = static::get_default_slugs( $this->theme_json, $node['path'] ); + $preset_global = _wp_array_get( $slugs_global, $preset_metadata['path'], array() ); + $preset_node = _wp_array_get( $slugs_node, $preset_metadata['path'], array() ); + $preset_slugs = array_merge_recursive( $preset_global, $preset_node ); - $slugs_for_preset = _wp_array_get( $slugs, $preset['path'], array() ); - $content = static::filter_slugs( $content, $slugs_for_preset ); - _wp_array_set( $this->theme_json, $path, $content ); + $content = static::filter_slugs( $content, $preset_slugs ); } + + _wp_array_set( $this->theme_json, $path, $content ); } } } diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 472e671ee8a26..dcc0bf8b099c3 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -244,7 +244,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() $theme_json_data = static::read_json_file( $theme_json_file ); $theme_json_data = static::translate( $theme_json_data, $wp_theme->get( 'TextDomain' ) ); } else { - $theme_json_data = array(); + $theme_json_data = array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ); } /** @@ -375,7 +375,7 @@ public static function get_block_data() { return static::$blocks; } - $config = array( 'version' => 2 ); + $config = array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ); foreach ( $blocks as $block_name => $block_type ) { if ( isset( $block_type->supports['__experimentalStyle'] ) ) { $config['styles']['blocks'][ $block_name ] = static::remove_json_comments( $block_type->supports['__experimentalStyle'] ); @@ -544,14 +544,17 @@ public static function get_user_data() { isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) && $decoded_data['isGlobalStylesUserThemeJSON'] ) { - unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); $config = $decoded_data; } } /** This filter is documented in wp-includes/class-wp-theme-json-resolver.php */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); - $config = $theme_json->get_data(); + $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); + $config = $theme_json->get_data(); + + // Needs to be set for schema migrations of user data. + $config['isGlobalStylesUserThemeJSON'] = true; + static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); return static::$user; diff --git a/lib/class-wp-theme-json-schema-gutenberg.php b/lib/class-wp-theme-json-schema-gutenberg.php index 8373e133c5aec..553354c438ed4 100644 --- a/lib/class-wp-theme-json-schema-gutenberg.php +++ b/lib/class-wp-theme-json-schema-gutenberg.php @@ -38,6 +38,7 @@ class WP_Theme_JSON_Schema_Gutenberg { * Function that migrates a given theme.json structure to the last version. * * @since 5.9.0 + * @since 6.5.0 Migrate up to v3. * * @param array $theme_json The structure to migrate. * @@ -50,8 +51,14 @@ public static function migrate( $theme_json ) { ); } - if ( 1 === $theme_json['version'] ) { - $theme_json = self::migrate_v1_to_v2( $theme_json ); + // Migrate each version in order starting with the current version. + switch ( $theme_json['version'] ) { + case 1: + $theme_json = self::migrate_v1_to_v2( $theme_json ); + // no break + case 2: + $theme_json = self::migrate_v2_to_v3( $theme_json ); + // no break } return $theme_json; @@ -87,6 +94,56 @@ private static function migrate_v1_to_v2( $old ) { return $new; } + /** + * Migrates from v2 to v3. + * + * - Sets settings.typography.defaultFontSizes to false. + * + * @since 6.5.0 + * + * @param array $old Data to migrate. + * + * @return array Data with defaultFontSizes set to false. + */ + private static function migrate_v2_to_v3( $old ) { + // Copy everything. + $new = $old; + + // Set the new version. + $new['version'] = 3; + + /* + * Remaining changes do not need to be applied to the custom origin, + * as they should take on the value of the theme origin. + */ + if ( + isset( $new['isGlobalStylesUserThemeJSON'] ) && + true === $new['isGlobalStylesUserThemeJSON'] + ) { + return $new; + } + + /* + * Even though defaultFontSizes is a new setting, we need to migrate + * it as it controls the PRESETS_METADATA prevent_override which was + * previously hardcoded to false. This only needs to happen when the + * theme provided font sizes as they could match the default ones and + * affect the generated CSS. And in v2 we provided default font sizes + * when the theme did not provide any. + */ + if ( isset( $new['settings']['typography']['fontSizes'] ) ) { + if ( ! isset( $new['settings'] ) ) { + $new['settings'] = array(); + } + if ( ! isset( $new['settings']['typography'] ) ) { + $new['settings']['typography'] = array(); + } + $new['settings']['typography']['defaultFontSizes'] = false; + } + + return $new; + } + /** * Processes the settings subtree. * diff --git a/lib/theme.json b/lib/theme.json index ece76b5f63cb2..574226f474152 100644 --- a/lib/theme.json +++ b/lib/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "appearanceTools": false, "useRootPaddingAwareAlignments": false, @@ -236,6 +236,7 @@ }, "typography": { "customFontSize": true, + "defaultFontSizes": true, "dropCap": true, "fontSizes": [ { diff --git a/packages/block-editor/src/components/global-styles/hooks.js b/packages/block-editor/src/components/global-styles/hooks.js index bdda9563edae0..e0de34cf2280e 100644 --- a/packages/block-editor/src/components/global-styles/hooks.js +++ b/packages/block-editor/src/components/global-styles/hooks.js @@ -68,6 +68,7 @@ const VALID_SETTINGS = [ 'spacing.units', 'typography.fluid', 'typography.customFontSize', + 'typography.defaultFontSizes', 'typography.dropCap', 'typography.fontFamilies', 'typography.fontSizes', @@ -240,6 +241,7 @@ export function useSettingsForBlockElement( ...updatedSettings.typography, fontSizes: {}, customFontSize: false, + defaultFontSizes: false, }; } 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 e82804c9cc9d4..76836c775bb80 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -13,11 +13,7 @@ import { useCallback } from '@wordpress/element'; /** * Internal dependencies */ -import { - mergeOrigins, - overrideOrigins, - hasOriginValue, -} from '../../store/get-block-settings'; +import { mergeOrigins, hasOriginValue } from '../../store/get-block-settings'; import FontFamilyControl from '../font-family'; import FontAppearanceControl from '../font-appearance-control'; import LineHeightControl from '../line-height-control'; @@ -57,7 +53,10 @@ export function useHasTypographyPanel( settings ) { function useHasFontSizeControl( settings ) { return ( - hasOriginValue( settings?.typography?.fontSizes ) || + ( settings?.typography?.defaultFontSizes !== false && + settings?.typography?.fontSizes?.default?.length ) || + settings?.typography?.fontSizes?.theme?.length || + settings?.typography?.fontSizes?.custom?.length || settings?.typography?.customFontSize ); } @@ -104,16 +103,21 @@ function useHasTextColumnsControl( settings ) { return settings?.typography?.textColumns; } -function getUniqueFontSizesBySlug( settings ) { - const fontSizes = settings?.typography?.fontSizes ?? {}; - const overriddenFontSizes = overrideOrigins( fontSizes ) ?? []; - const uniqueSizes = []; - for ( const currentSize of overriddenFontSizes ) { - if ( ! uniqueSizes.some( ( { slug } ) => slug === currentSize.slug ) ) { - uniqueSizes.push( currentSize ); - } - } - return uniqueSizes; +/** + * Concatenate all the font sizes into a single list for the font size picker. + * + * @param {Object} settings The global styles settings. + * + * @return {Array} The merged font sizes. + */ +function getMergedFontSizes( settings ) { + const fontSizes = settings?.typography?.fontSizes; + const defaultFontSizesEnabled = !! settings?.typography?.defaultFontSizes; + return [ + ...( fontSizes?.custom ?? [] ), + ...( fontSizes?.theme ?? [] ), + ...( defaultFontSizesEnabled ? fontSizes?.default ?? [] : [] ), + ]; } function TypographyToolsPanel( { @@ -189,7 +193,7 @@ export default function TypographyPanel( { // Font Size const hasFontSizeEnabled = useHasFontSizeControl( settings ); const disableCustomFontSizes = ! settings?.typography?.customFontSize; - const mergedFontSizes = getUniqueFontSizesBySlug( settings ); + const mergedFontSizes = getMergedFontSizes( settings ); const fontSize = decodeValue( inheritedValue?.typography?.fontSize ); const setFontSize = ( newValue, metadata ) => { diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 2148b2bb8e5ce..d2bbcd26a6eff 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -213,6 +213,7 @@ export function useBlockSettings( name, parentLayout ) { customFontFamilies, defaultFontFamilies, themeFontFamilies, + defaultFontSizesEnabled, customFontSizes, defaultFontSizes, themeFontSizes, @@ -265,6 +266,7 @@ export function useBlockSettings( name, parentLayout ) { 'typography.fontFamilies.custom', 'typography.fontFamilies.default', 'typography.fontFamilies.theme', + 'typography.defaultFontSizes', 'typography.fontSizes.custom', 'typography.fontSizes.default', 'typography.fontSizes.theme', @@ -359,6 +361,7 @@ export function useBlockSettings( name, parentLayout ) { theme: themeFontSizes, }, customFontSize, + defaultFontSizes: defaultFontSizesEnabled, fontStyle, fontWeight, lineHeight, @@ -398,6 +401,7 @@ export function useBlockSettings( name, parentLayout ) { customFontFamilies, defaultFontFamilies, themeFontFamilies, + defaultFontSizesEnabled, customFontSizes, defaultFontSizes, themeFontSizes, diff --git a/packages/block-editor/src/utils/object.js b/packages/block-editor/src/utils/object.js index 8f6c82a9c3991..c78fe0e656dfe 100644 --- a/packages/block-editor/src/utils/object.js +++ b/packages/block-editor/src/utils/object.js @@ -49,3 +49,19 @@ export const getValueFromObjectPath = ( object, path, defaultValue ) => { } ); return value ?? defaultValue; }; + +/** + * Helper util to filter out objects with duplicate values for a given property. + * + * @param {Object[]} array Array of objects to filter. + * @param {string} property Property to filter unique values by. + * + * @return {Object[]} Array of objects with unique values for the specified property. + */ +export function uniqByProperty( array, property ) { + const seen = new Set(); + return array.filter( ( item ) => { + const value = item[ property ]; + return seen.has( value ) ? false : seen.add( value ); + } ); +} diff --git a/phpunit/class-wp-rest-global-styles-controller-gutenberg-test.php b/phpunit/class-wp-rest-global-styles-controller-gutenberg-test.php index 568dbc276dd59..563037f41db9d 100644 --- a/phpunit/class-wp-rest-global-styles-controller-gutenberg-test.php +++ b/phpunit/class-wp-rest-global-styles-controller-gutenberg-test.php @@ -122,7 +122,7 @@ public function test_get_theme_items() { $data = $response->get_data(); $expected = array( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( diff --git a/phpunit/class-wp-theme-json-schema-test.php b/phpunit/class-wp-theme-json-schema-test.php index 9c1103197d72e..4259b8b5de6d4 100644 --- a/phpunit/class-wp-theme-json-schema-test.php +++ b/phpunit/class-wp-theme-json-schema-test.php @@ -35,6 +35,18 @@ public function test_migrate_v1_to_latest() { 'width' => false, ), 'typography' => array( + 'fontSizes' => array( + array( + 'name' => 'Small', + 'slug' => 'small', + 'size' => 12, + ), + array( + 'name' => 'Normal', + 'slug' => 'normal', + 'size' => 16, + ), + ), 'fontStyle' => false, 'fontWeight' => false, 'letterSpacing' => false, @@ -120,11 +132,24 @@ public function test_migrate_v1_to_latest() { 'width' => false, ), 'typography' => array( - 'fontStyle' => false, - 'fontWeight' => false, - 'letterSpacing' => false, - 'textDecoration' => false, - 'textTransform' => false, + 'defaultFontSizes' => false, + 'fontSizes' => array( + array( + 'name' => 'Small', + 'slug' => 'small', + 'size' => 12, + ), + array( + 'name' => 'Normal', + 'slug' => 'normal', + 'size' => 16, + ), + ), + 'fontStyle' => false, + 'fontWeight' => false, + 'letterSpacing' => false, + 'textDecoration' => false, + 'textTransform' => false, ), 'blocks' => array( 'core/group' => array( @@ -179,4 +204,51 @@ public function test_migrate_v1_to_latest() { $this->assertEqualSetsWithIndex( $expected, $actual ); } + + public function test_migrate_v2_to_latest() { + $theme_json_v2 = array( + 'version' => 2, + 'settings' => array( + 'typography' => array( + 'fontSizes' => array( + array( + 'name' => 'Small', + 'slug' => 'small', + 'size' => 12, + ), + array( + 'name' => 'Normal', + 'slug' => 'normal', + 'size' => 16, + ), + ), + ), + ), + ); + + $actual = WP_Theme_JSON_Schema_Gutenberg::migrate( $theme_json_v2 ); + + $expected = array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'settings' => array( + 'typography' => array( + 'defaultFontSizes' => false, + 'fontSizes' => array( + array( + 'name' => 'Small', + 'slug' => 'small', + 'size' => 12, + ), + array( + 'name' => 'Normal', + 'slug' => 'normal', + 'size' => 16, + ), + ), + ), + ), + ); + + $this->assertEqualSetsWithIndex( $expected, $actual ); + } } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 1ab2639b5d539..65b9f745e4583 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -3195,7 +3195,7 @@ public function test_get_editor_settings_custom_units_can_be_filtered() { public function test_export_data() { $theme = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3216,7 +3216,7 @@ public function test_export_data() { ); $user = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3240,7 +3240,7 @@ public function test_export_data() { $theme->merge( $user ); $actual = $theme->get_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3270,7 +3270,7 @@ public function test_export_data() { public function test_export_data_deals_with_empty_user_data() { $theme = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3292,7 +3292,7 @@ public function test_export_data_deals_with_empty_user_data() { $actual = $theme->get_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3317,7 +3317,7 @@ public function test_export_data_deals_with_empty_user_data() { public function test_export_data_deals_with_empty_theme_data() { $user = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3340,7 +3340,7 @@ public function test_export_data_deals_with_empty_theme_data() { $actual = $user->get_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'color' => array( 'palette' => array( @@ -3363,31 +3363,19 @@ public function test_export_data_deals_with_empty_theme_data() { } public function test_export_data_deals_with_empty_data() { - $theme_v2 = new WP_Theme_JSON_Gutenberg( - array( - 'version' => 2, - ), - 'theme' - ); - $actual_v2 = $theme_v2->get_data(); - $expected_v2 = array( 'version' => 2 ); - $this->assertEqualSetsWithIndex( $expected_v2, $actual_v2 ); - - $theme_v1 = new WP_Theme_JSON_Gutenberg( - array( - 'version' => 1, - ), + $theme = new WP_Theme_JSON_Gutenberg( + array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ), 'theme' ); - $actual_v1 = $theme_v1->get_data(); - $expected_v1 = array( 'version' => 2 ); - $this->assertEqualSetsWithIndex( $expected_v1, $actual_v1 ); + $actual = $theme->get_data(); + $expected = array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ); + $this->assertEqualSetsWithIndex( $expected, $actual ); } public function test_export_data_sets_appearance_tools() { $theme = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'appearanceTools' => true, 'blocks' => array( @@ -3401,7 +3389,7 @@ public function test_export_data_sets_appearance_tools() { $actual = $theme->get_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'appearanceTools' => true, 'blocks' => array( @@ -3418,7 +3406,7 @@ public function test_export_data_sets_appearance_tools() { public function test_export_data_sets_use_root_padding_aware_alignments() { $theme = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'useRootPaddingAwareAlignments' => true, 'blocks' => array( @@ -3432,7 +3420,7 @@ public function test_export_data_sets_use_root_padding_aware_alignments() { $actual = $theme->get_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'useRootPaddingAwareAlignments' => true, 'blocks' => array( @@ -3513,7 +3501,7 @@ public function test_get_element_class_name_invalid() { public function test_get_property_value_valid() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'color' => array( 'background' => '#ffffff', @@ -3591,7 +3579,7 @@ public function data_get_property_value_should_return_string_for_invalid_paths_o public function test_get_property_value_loop() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'color' => array( 'background' => '#ffffff', @@ -3624,7 +3612,7 @@ public function test_get_property_value_loop() { public function test_get_property_value_recursion() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'color' => array( 'background' => '#ffffff', @@ -3656,7 +3644,7 @@ public function test_get_property_value_recursion() { public function test_get_property_value_self() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'color' => array( 'background' => '#ffffff', @@ -3674,7 +3662,7 @@ public function test_get_property_value_self() { public function test_get_styles_for_block_with_padding_aware_alignments() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'spacing' => array( 'padding' => array( @@ -3705,7 +3693,7 @@ public function test_get_styles_for_block_with_padding_aware_alignments() { public function test_get_styles_for_block_without_padding_aware_alignments() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'spacing' => array( 'padding' => array( @@ -3733,7 +3721,7 @@ public function test_get_styles_for_block_without_padding_aware_alignments() { public function test_get_styles_for_block_with_content_width() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'layout' => array( 'contentSize' => '800px', @@ -3757,7 +3745,7 @@ public function test_get_styles_for_block_with_content_width() { public function test_get_styles_with_appearance_tools() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'appearanceTools' => true, ), @@ -3777,7 +3765,7 @@ public function test_get_styles_with_appearance_tools() { public function test_sanitization() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'spacing' => array( 'blockGap' => 'valid value', @@ -3796,7 +3784,7 @@ public function test_sanitization() { $actual = $theme_json->get_raw_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'spacing' => array( 'blockGap' => 'valid value', @@ -3817,7 +3805,7 @@ public function test_sanitization() { public function test_sanitize_for_unregistered_style_variations() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'blocks' => array( 'core/quote' => array( @@ -3841,7 +3829,7 @@ public function test_sanitize_for_unregistered_style_variations() { $sanitized_theme_json = $theme_json->get_raw_data(); $expected = array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'blocks' => array( 'core/quote' => array( @@ -3868,7 +3856,7 @@ public function test_sanitize_for_unregistered_style_variations() { public function test_sanitize_for_block_with_style_variations( $theme_json_variations, $expected_sanitized ) { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'blocks' => array( 'core/quote' => $theme_json_variations, @@ -3950,7 +3938,7 @@ public function data_sanitize_for_block_with_style_variations() { public function test_sanitize_indexed_arrays() { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => '2', + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'badKey2' => 'I am Evil!', 'settings' => array( 'badKey3' => 'I am Evil!', @@ -4018,7 +4006,7 @@ public function test_sanitize_indexed_arrays() { ); $expected_sanitized = array( - 'version' => '2', + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'typography' => array( 'fontFamilies' => array( @@ -4085,7 +4073,7 @@ public function test_sanitize_indexed_arrays() { public function test_sanitize_with_invalid_style_variation( $theme_json_variations ) { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'blocks' => array( 'core/quote' => $theme_json_variations, @@ -4130,7 +4118,7 @@ public function data_sanitize_with_invalid_style_variation() { public function test_get_styles_for_block_with_style_variations( $theme_json_variations, $metadata_variations, $expected ) { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'styles' => array( 'blocks' => array( 'core/quote' => $theme_json_variations, @@ -4282,7 +4270,7 @@ public function test_block_style_variations_with_invalid_properties() { public function test_set_spacing_sizes( $spacing_scale, $expected_output ) { $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'spacing' => array( 'spacingScale' => $spacing_scale, @@ -4572,7 +4560,7 @@ public function test_set_spacing_sizes_when_invalid( $spacing_scale, $expected_o $theme_json = new WP_Theme_JSON_Gutenberg( array( - 'version' => 2, + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, 'settings' => array( 'spacing' => array( 'spacingScale' => $spacing_scale, diff --git a/phpunit/data/themedir1/block-theme-child-with-fluid-layout/theme.json b/phpunit/data/themedir1/block-theme-child-with-fluid-layout/theme.json index 710ec336df70b..813024ba8abeb 100644 --- a/phpunit/data/themedir1/block-theme-child-with-fluid-layout/theme.json +++ b/phpunit/data/themedir1/block-theme-child-with-fluid-layout/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "appearanceTools": true, "layout": { diff --git a/phpunit/data/themedir1/block-theme-child-with-fluid-typography-config/theme.json b/phpunit/data/themedir1/block-theme-child-with-fluid-typography-config/theme.json index dcd3745f1630c..3aa0560aaf062 100644 --- a/phpunit/data/themedir1/block-theme-child-with-fluid-typography-config/theme.json +++ b/phpunit/data/themedir1/block-theme-child-with-fluid-typography-config/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "appearanceTools": true, "layout": { diff --git a/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json b/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json index 7b34524270295..b2624775a5003 100644 --- a/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json +++ b/phpunit/data/themedir1/block-theme-child-with-fluid-typography/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "appearanceTools": true, "typography": { diff --git a/phpunit/data/themedir1/block-theme-child/styles/variation-a.json b/phpunit/data/themedir1/block-theme-child/styles/variation-a.json index a9d5ade894692..53c3ef60619b5 100644 --- a/phpunit/data/themedir1/block-theme-child/styles/variation-a.json +++ b/phpunit/data/themedir1/block-theme-child/styles/variation-a.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "settings": { "blocks": { "core/paragraph": { diff --git a/phpunit/data/themedir1/block-theme-child/styles/variation-b.json b/phpunit/data/themedir1/block-theme-child/styles/variation-b.json index 0a8a4fcab99f6..4e949f24c7f40 100644 --- a/phpunit/data/themedir1/block-theme-child/styles/variation-b.json +++ b/phpunit/data/themedir1/block-theme-child/styles/variation-b.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "settings": { "blocks": { "core/post-title": { diff --git a/phpunit/data/themedir1/block-theme-child/theme.json b/phpunit/data/themedir1/block-theme-child/theme.json index 1157fa9128030..185437e9b81c4 100644 --- a/phpunit/data/themedir1/block-theme-child/theme.json +++ b/phpunit/data/themedir1/block-theme-child/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "color": { "palette": [ diff --git a/phpunit/data/themedir1/block-theme/styles/variation-a.json b/phpunit/data/themedir1/block-theme/styles/variation-a.json index 42c20fc63b592..eb08d0090c177 100644 --- a/phpunit/data/themedir1/block-theme/styles/variation-a.json +++ b/phpunit/data/themedir1/block-theme/styles/variation-a.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "settings": { "blocks": { "core/paragraph": { diff --git a/phpunit/data/themedir1/block-theme/styles/variation-b.json b/phpunit/data/themedir1/block-theme/styles/variation-b.json index 340198ffe0b65..efdbe8aa86650 100644 --- a/phpunit/data/themedir1/block-theme/styles/variation-b.json +++ b/phpunit/data/themedir1/block-theme/styles/variation-b.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "settings": { "blocks": { "core/post-title": { diff --git a/phpunit/data/themedir1/block-theme/styles/variation.json b/phpunit/data/themedir1/block-theme/styles/variation.json index d0f316cb454dd..debb3666a767b 100644 --- a/phpunit/data/themedir1/block-theme/styles/variation.json +++ b/phpunit/data/themedir1/block-theme/styles/variation.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "title": "Block theme variation", "settings": { "color": { diff --git a/phpunit/data/themedir1/block-theme/theme.json b/phpunit/data/themedir1/block-theme/theme.json index fb24069fb6429..2c29884bf4dcb 100644 --- a/phpunit/data/themedir1/block-theme/theme.json +++ b/phpunit/data/themedir1/block-theme/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "title": "Block theme", "settings": { "color": { diff --git a/phpunit/data/themedir1/fonts-block-theme/styles/variation-duplicate-fonts.json b/phpunit/data/themedir1/fonts-block-theme/styles/variation-duplicate-fonts.json index 040689043379d..c24a4a85a4f67 100644 --- a/phpunit/data/themedir1/fonts-block-theme/styles/variation-duplicate-fonts.json +++ b/phpunit/data/themedir1/fonts-block-theme/styles/variation-duplicate-fonts.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "title": "Variation: duplicate fonts", "settings": { "typography": { diff --git a/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-family.json b/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-family.json index 0af954cbecaa8..dfc83f3726d79 100644 --- a/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-family.json +++ b/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-family.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "title": "Variation: new font family", "settings": { "typography": { diff --git a/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-variations.json b/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-variations.json index 81268817ade70..95cb7b88d0fb7 100644 --- a/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-variations.json +++ b/phpunit/data/themedir1/fonts-block-theme/styles/variation-new-font-variations.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "title": "Variation: new font variations", "settings": { "typography": { diff --git a/phpunit/data/themedir1/fonts-block-theme/styles/variation-no-fonts.json b/phpunit/data/themedir1/fonts-block-theme/styles/variation-no-fonts.json index 9c98c6893fa06..fcdd368ec691b 100644 --- a/phpunit/data/themedir1/fonts-block-theme/styles/variation-no-fonts.json +++ b/phpunit/data/themedir1/fonts-block-theme/styles/variation-no-fonts.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "title": "Variation - no fonts", "styles": { "typography": { diff --git a/phpunit/data/themedir1/fonts-block-theme/theme.json b/phpunit/data/themedir1/fonts-block-theme/theme.json index a5d40da2b5bb2..a7946a3f11023 100644 --- a/phpunit/data/themedir1/fonts-block-theme/theme.json +++ b/phpunit/data/themedir1/fonts-block-theme/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "appearanceTools": true, "color": { diff --git a/schemas/json/theme.json b/schemas/json/theme.json index 7cb34945b5681..ccd2ee7f2ce53 100644 --- a/schemas/json/theme.json +++ b/schemas/json/theme.json @@ -499,6 +499,11 @@ "description": "Settings related to typography.", "type": "object", "properties": { + "defaultFontSizes": { + "description": "Allow users to choose font sizes from the default font size presets.", + "type": "boolean", + "default": true + }, "customFontSize": { "description": "Allow users to set custom font sizes.", "type": "boolean", @@ -2244,7 +2249,7 @@ "version": { "description": "Version of theme.json to use.", "type": "integer", - "enum": [ 2 ] + "enum": [ 3 ] }, "title": { "type": "string", diff --git a/test/emptytheme/styles/variation.json b/test/emptytheme/styles/variation.json index 0ab221d087035..06f672f6fd25d 100644 --- a/test/emptytheme/styles/variation.json +++ b/test/emptytheme/styles/variation.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "settings": { "color": { "palette": [ diff --git a/test/emptytheme/theme.json b/test/emptytheme/theme.json index d95ed844e6b1c..62ce296e971c3 100644 --- a/test/emptytheme/theme.json +++ b/test/emptytheme/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "settings": { "appearanceTools": true, "layout": { diff --git a/test/gutenberg-test-themes/style-variations/styles/pink.json b/test/gutenberg-test-themes/style-variations/styles/pink.json index bdbf2829eb552..c9e4ac85c1c79 100644 --- a/test/gutenberg-test-themes/style-variations/styles/pink.json +++ b/test/gutenberg-test-themes/style-variations/styles/pink.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "settings": { "color": { "palette": [ diff --git a/test/gutenberg-test-themes/style-variations/styles/yellow.json b/test/gutenberg-test-themes/style-variations/styles/yellow.json index 9bf00e21b4220..df82e52408da3 100644 --- a/test/gutenberg-test-themes/style-variations/styles/yellow.json +++ b/test/gutenberg-test-themes/style-variations/styles/yellow.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "styles": { "color": { "background": "#ffef0b", diff --git a/test/gutenberg-test-themes/style-variations/theme.json b/test/gutenberg-test-themes/style-variations/theme.json index f0fc1ae54042a..dee779a4ca0df 100644 --- a/test/gutenberg-test-themes/style-variations/theme.json +++ b/test/gutenberg-test-themes/style-variations/theme.json @@ -1,6 +1,6 @@ { "$schema": "https://schemas.wp.org/trunk/theme.json", - "version": 2, + "version": 3, "styles": { "color": { "background": "red"