Skip to content

Commit

Permalink
Add defaultFontSizes option to theme.json (#56661)
Browse files Browse the repository at this point in the history
* Add defaultFontSizes option for theme.json

* Fix defaultFontSizes causing errors when missing

* Simplify useMergedSettings

* Simplify more

* Remove the memo because it's probably fine

* Try ignoring how overrides are handled in the dropdown

* Minor performance improvement using reverse instead of toReversed

* Link to a new issue with a more complete description

* Refactor hack into its own funtion
  • Loading branch information
ajlende committed Feb 1, 2024
1 parent da92f2e commit ffb6ef1
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,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 @@ -151,7 +151,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 @@ -409,19 +409,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 @@ -67,6 +67,7 @@ const VALID_SETTINGS = [
'spacing.units',
'typography.fluid',
'typography.customFontSize',
'typography.defaultFontSizes',
'typography.dropCap',
'typography.fontFamilies',
'typography.fontSizes',
Expand Down Expand Up @@ -239,6 +240,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 @@ -224,7 +227,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 @@ -308,9 +314,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 @@ -347,7 +356,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 @@ -489,6 +489,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

0 comments on commit ffb6ef1

Please sign in to comment.