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

Add defaultFontSizes option to theme.json #56661

Merged
merged 9 commits into from
Jan 11, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ Settings related to typography.

| Property | Type | Default | Props |
| --- | --- | --- |--- |
| defaultFontSizes | boolean | true | |
| customFontSize | boolean | true | |
| fontStyle | boolean | true | |
| fontWeight | boolean | true | |
Expand Down
29 changes: 15 additions & 14 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,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',
Expand Down Expand Up @@ -411,19 +411,20 @@ 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,
'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,
'textColumns' => null,
'textDecoration' => null,
'textTransform' => null,
'writingMode' => null,
),
);

Expand Down
1 change: 1 addition & 0 deletions lib/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
},
"typography": {
"customFontSize": true,
"defaultFontSizes": true,
"dropCap": true,
"fontSizes": [
{
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/components/global-styles/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const VALID_SETTINGS = [
'spacing.units',
'typography.fluid',
'typography.customFontSize',
'typography.defaultFontSizes',
'typography.dropCap',
'typography.fontFamilies',
'typography.fontSizes',
Expand Down Expand Up @@ -238,6 +239,7 @@ export function useSettingsForBlockElement(
...updatedSettings.typography,
fontSizes: {},
customFontSize: false,
defaultFontSizes: false,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import TextTransformControl from '../text-transform-control';
import TextDecorationControl from '../text-decoration-control';
import WritingModeControl from '../writing-mode-control';
import { getValueFromVariable, TOOLSPANEL_DROPDOWNMENU_PROPS } from './utils';
import { setImmutably } from '../../utils/object';
import { setImmutably, uniqByProperty } from '../../utils/object';

const MIN_TEXT_COLUMNS = 1;
const MAX_TEXT_COLUMNS = 6;
Expand Down Expand Up @@ -53,7 +53,10 @@ export function useHasTypographyPanel( settings ) {

function useHasFontSizeControl( settings ) {
return (
hasMergedOrigins( 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
);
}
Expand Down Expand Up @@ -100,16 +103,45 @@ function useHasTextColumnsControl( settings ) {
return settings?.typography?.textColumns;
}

function getUniqueFontSizesBySlug( settings ) {
const fontSizes = settings?.typography?.fontSizes;
const mergedFontSizes = fontSizes ? mergeOrigins( fontSizes ) : [];
const uniqueSizes = [];
for ( const currentSize of mergedFontSizes ) {
if ( ! uniqueSizes.some( ( { slug } ) => slug === currentSize.slug ) ) {
uniqueSizes.push( currentSize );
}
}
return uniqueSizes;
/**
* TODO: The reversing and filtering of default font sizes is a hack so the
* dropdown UI matches what is generated in the global styles CSS stylesheet.
*
* This is a temporary solution until #57733 is resolved. At which point,
* the mergedFontSizes would just need to be the concatenated array of all
* presets or a custom dropdown with sections for each.
*
* @see {@link https://github.com/WordPress/gutenberg/issues/57733}
*
* @param {Object} settings The global styles settings.
*
* @return {Array} The merged font sizes.
*/
function getMergedFontSizes( settings ) {
// The font size presets are merged in reverse order so that the duplicates
// that may defined later in the array have higher priority to match the CSS.
const mergedFontSizesAll = uniqByProperty(
[
settings?.typography?.fontSizes?.custom,
settings?.typography?.fontSizes?.theme,
settings?.typography?.fontSizes?.default,
].flatMap( ( presets ) => presets?.toReversed() ?? [] ),
'slug'
).reverse();

// Default presets exist in the global styles CSS no matter the setting, so
// filtering them out in the UI has to be done after merging.
const mergedFontSizes =
settings?.typography?.defaultFontSizes === false
? mergedFontSizesAll.filter(
( { slug } ) =>
! [ 'small', 'medium', 'large', 'x-large' ].includes(
slug
)
)
: mergedFontSizesAll;

return mergedFontSizes;
}

function TypographyToolsPanel( {
Expand Down Expand Up @@ -185,7 +217,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 ) => {
Expand Down
20 changes: 16 additions & 4 deletions packages/block-editor/src/hooks/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ export function useBlockSettings( name, parentLayout ) {
backgroundImage,
backgroundSize,
fontFamilies,
fontSizes,
userFontSizes,
themeFontSizes,
defaultFontSizes,
defaultFontSizesEnabled,
customFontSize,
fontStyle,
fontWeight,
Expand Down Expand Up @@ -222,7 +225,10 @@ export function useBlockSettings( name, parentLayout ) {
'background.backgroundImage',
'background.backgroundSize',
'typography.fontFamilies',
'typography.fontSizes',
'typography.fontSizes.custom',
'typography.fontSizes.theme',
'typography.fontSizes.default',
'typography.defaultFontSizes',
'typography.customFontSize',
'typography.fontStyle',
'typography.fontWeight',
Expand Down Expand Up @@ -304,9 +310,12 @@ export function useBlockSettings( name, parentLayout ) {
custom: fontFamilies,
},
fontSizes: {
custom: fontSizes,
custom: userFontSizes,
theme: themeFontSizes,
default: defaultFontSizes,
},
customFontSize,
defaultFontSizes: defaultFontSizesEnabled,
fontStyle,
fontWeight,
lineHeight,
Expand Down Expand Up @@ -341,7 +350,10 @@ export function useBlockSettings( name, parentLayout ) {
backgroundImage,
backgroundSize,
fontFamilies,
fontSizes,
userFontSizes,
themeFontSizes,
defaultFontSizes,
defaultFontSizesEnabled,
customFontSize,
fontStyle,
fontWeight,
Expand Down
16 changes: 16 additions & 0 deletions packages/block-editor/src/utils/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
} );
}
5 changes: 5 additions & 0 deletions schemas/json/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,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",
Expand Down
Loading