From 4cda9060789f1837d60b77e9f9142f20f4bef781 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Tue, 22 Nov 2022 16:25:42 +1100 Subject: [PATCH 1/9] Initial commit. And the worst commit. --- packages/block-editor/package.json | 1 + .../components/block-global-styles/context.js | 17 ++ .../block-global-styles/provider.js | 158 ++++++++++++++++++ packages/block-editor/src/components/index.js | 2 + .../block-editor/src/hooks/line-height.js | 25 ++- packages/block-editor/src/hooks/style.js | 5 +- packages/block-editor/src/hooks/typography.js | 1 + 7 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 packages/block-editor/src/components/block-global-styles/context.js create mode 100644 packages/block-editor/src/components/block-global-styles/provider.js diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index dce5352d5812a6..5e746736397aad 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -39,6 +39,7 @@ "@wordpress/blocks": "file:../blocks", "@wordpress/components": "file:../components", "@wordpress/compose": "file:../compose", + "@wordpress/core-data": "file:../core-data", "@wordpress/data": "file:../data", "@wordpress/date": "file:../date", "@wordpress/deprecated": "file:../deprecated", diff --git a/packages/block-editor/src/components/block-global-styles/context.js b/packages/block-editor/src/components/block-global-styles/context.js new file mode 100644 index 00000000000000..0e2478cb7f3b3e --- /dev/null +++ b/packages/block-editor/src/components/block-global-styles/context.js @@ -0,0 +1,17 @@ +/** + * WordPress dependencies + */ +import { createContext } from '@wordpress/element'; + +export const DEFAULT_BLOCK_GLOBAL_STYLES_CONTEXT = { + base: {}, + user: {}, + merged: {}, + setBlockGlobalStyles: () => {}, +}; + +const BlockGlobalStylesContext = createContext( + DEFAULT_BLOCK_GLOBAL_STYLES_CONTEXT +); + +export default BlockGlobalStylesContext; diff --git a/packages/block-editor/src/components/block-global-styles/provider.js b/packages/block-editor/src/components/block-global-styles/provider.js new file mode 100644 index 00000000000000..95d63a92fca226 --- /dev/null +++ b/packages/block-editor/src/components/block-global-styles/provider.js @@ -0,0 +1,158 @@ +/** + * External dependencies + */ +import { mergeWith, isEmpty, mapValues } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useMemo, useCallback } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +/** + * Internal dependencies + */ +import BlockGlobalStylesContext from './context'; +import { store as blockEditorStore } from '../../store'; + +function mergeTreesCustomizer( _, srcValue ) { + // We only pass as arrays the presets, + // in which case we want the new array of values + // to override the old array (no merging). + if ( Array.isArray( srcValue ) ) { + return srcValue; + } +} + +export function mergeBaseAndUserConfigs( base, user ) { + return mergeWith( {}, base, user, mergeTreesCustomizer ); +} + +function cleanEmptyObject( object ) { + if ( + object === null || + typeof object !== 'object' || + Array.isArray( object ) + ) { + return object; + } + const cleanedNestedObjects = Object.fromEntries( + Object.entries( mapValues( object, cleanEmptyObject ) ).filter( + ( [ , value ] ) => Boolean( value ) + ) + ); + return isEmpty( cleanedNestedObjects ) ? undefined : cleanedNestedObjects; +} + +function useBaseBlockGlobalStyles( blockName ) { + const baseConfig = useSelect( ( select ) => { + return select( + coreStore + ).__experimentalGetCurrentThemeBaseGlobalStyles(); + }, [] ); + + return [ !! baseConfig, baseConfig?.styles?.blocks?.[ blockName ] || {} ]; +} + +function useUserBlockGlobalStyles() { + const { globalStylesId, blockName, styles } = useSelect( ( select ) => { + const _globalStylesId = + select( coreStore ).__experimentalGetCurrentGlobalStylesId(); + const record = _globalStylesId + ? select( coreStore ).getEditedEntityRecord( + 'root', + 'globalStyles', + _globalStylesId + ) + : undefined; + const { getBlockName, getSelectedBlockClientId } = + select( blockEditorStore ); + const selectedBlockClientId = getSelectedBlockClientId(); + const selectedBlockName = + selectedBlockClientId && getBlockName( selectedBlockClientId ); + return { + globalStylesId: _globalStylesId, + blockName: selectedBlockName, + styles: record?.styles, + }; + }, [] ); + + const { getEditedEntityRecord } = useSelect( coreStore ); + const { editEntityRecord } = useDispatch( coreStore ); + const isReady = !! styles || !! blockName; + + const setBlockGlobalStyles = useCallback( + ( callback ) => { + const record = getEditedEntityRecord( + 'root', + 'globalStyles', + globalStylesId + ); + const currentBlockStyles = record?.styles?.[ blockName ] ?? {}; + const updatedBlockStyles = + cleanEmptyObject( callback( currentBlockStyles ) ) || {}; + editEntityRecord( 'root', 'globalStyles', globalStylesId, { + styles: { + ...record?.styles, + blocks: { + ...record?.styles?.blocks, + [ blockName ]: updatedBlockStyles, + }, + }, + } ); + }, + [ globalStylesId ] + ); + + return [ + isReady, + blockName, + styles?.blocks?.[ blockName ] || {}, + setBlockGlobalStyles, + ]; +} + +function useBlockGlobalStylesContext() { + const [ + areUserBlockGlobalStylesReady, + blockName, + userBlockStyles, + setUserBlockStyles, + ] = useUserBlockGlobalStyles(); + + const [ areBaseBlockGlobalStylesReady, baseBlockStyles ] = + useBaseBlockGlobalStyles( blockName ); + + const mergedBlockStyles = useMemo( () => { + if ( ! baseBlockStyles || ! userBlockStyles ) { + return {}; + } + return mergeBaseAndUserConfigs( baseBlockStyles, userBlockStyles ); + }, [ userBlockStyles, baseBlockStyles ] ); + + const context = useMemo( () => { + return { + isReady: + areUserBlockGlobalStylesReady && areBaseBlockGlobalStylesReady, + user: userBlockStyles, + base: baseBlockStyles, + merged: mergedBlockStyles, + setUserBlockStyles, + }; + }, [ mergedBlockStyles, baseBlockStyles, userBlockStyles ] ); + return context; +} + +export default function BlockGlobalStylesProvider( { children } ) { + const context = useBlockGlobalStylesContext(); + if ( ! context.isReady ) { + return null; + } + + return ( + + { children } + + ); +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 03ce8f3880ad32..0a0ad70140976c 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -164,3 +164,5 @@ export { default as __experimentalInspectorPopoverHeader } from './inspector-pop export { default as BlockEditorProvider } from './provider'; export { default as useSetting } from './use-setting'; +export { default as BlockGlobalStylesProvider } from './block-global-styles/provider'; +export { default as BlockGlobalStylesContext } from './block-global-styles/context'; diff --git a/packages/block-editor/src/hooks/line-height.js b/packages/block-editor/src/hooks/line-height.js index c8397d850a1e55..8623e9f9bc0758 100644 --- a/packages/block-editor/src/hooks/line-height.js +++ b/packages/block-editor/src/hooks/line-height.js @@ -2,13 +2,14 @@ * WordPress dependencies */ import { hasBlockSupport } from '@wordpress/blocks'; - +import { useContext } from '@wordpress/element'; /** * Internal dependencies */ import LineHeightControl from '../components/line-height-control'; import { cleanEmptyObject } from './utils'; import useSetting from '../components/use-setting'; +import BlockGlobalStylesContext from '../components/block-global-styles/context'; export const LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; @@ -24,7 +25,15 @@ export function LineHeightEdit( props ) { attributes: { style }, setAttributes, } = props; - + const { + base: baseBlockStyles, + user: userBlockStyles, + merged: mergedBlockStyles, + setUserBlockStyles, + } = useContext( BlockGlobalStylesContext ); +console.log( 'mergedBlockStyles', mergedBlockStyles ); +console.log( 'userBlockStyles', userBlockStyles ); +console.log( 'baseBlockStyles', baseBlockStyles ); const onChange = ( newLineHeightValue ) => { const newStyle = { ...style, @@ -33,7 +42,17 @@ export function LineHeightEdit( props ) { lineHeight: newLineHeightValue, }, }; - + setUserBlockStyles( ( currentStyles ) => { + console.log( 'newStyle', newStyle ); + console.log( 'currentStyles', currentStyles ); + return { + ...currentStyles, + typography: { + ...currentStyles?.typography, + lineHeight: newLineHeightValue, + }, + }; + } ); setAttributes( { style: cleanEmptyObject( newStyle ) } ); }; return ( diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index b6fe7b8188c2be..5822a092b7b9c6 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -34,6 +34,7 @@ import { } from './dimensions'; import useDisplayBlockControls from '../components/use-display-block-controls'; import { shouldSkipSerialization } from './utils'; +import BlockGlobalStylesProvider from '../components/block-global-styles/provider'; const styleSupportKeys = [ ...TYPOGRAPHY_SUPPORT_KEYS, @@ -351,12 +352,12 @@ export const withBlockControls = createHigherOrderComponent( return ( <> { shouldDisplayControls && ( - <> + - + ) } diff --git a/packages/block-editor/src/hooks/typography.js b/packages/block-editor/src/hooks/typography.js index bbdadaed3ba52b..32ea7e123b818d 100644 --- a/packages/block-editor/src/hooks/typography.js +++ b/packages/block-editor/src/hooks/typography.js @@ -5,6 +5,7 @@ import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks'; import { __experimentalToolsPanelItem as ToolsPanelItem } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; + /** * Internal dependencies */ From 4373d968000887b0b3c77aaac3603526fb692c20 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 23 Nov 2022 14:36:56 +1100 Subject: [PATCH 2/9] Added other styles --- packages/block-editor/src/hooks/border.js | 8 +- packages/block-editor/src/hooks/color.js | 7 +- .../block-editor/src/hooks/font-family.js | 5 ++ packages/block-editor/src/hooks/font-size.js | 6 ++ .../block-editor/src/hooks/letter-spacing.js | 2 + .../block-editor/src/hooks/line-height.js | 26 +----- packages/block-editor/src/hooks/margin.js | 3 + packages/block-editor/src/hooks/padding.js | 6 ++ packages/block-editor/src/hooks/style.js | 83 +++++++++++++++++-- 9 files changed, 116 insertions(+), 30 deletions(-) diff --git a/packages/block-editor/src/hooks/border.js b/packages/block-editor/src/hooks/border.js index 11ee3e95f4d663..c1e5ec71eb8f8d 100644 --- a/packages/block-editor/src/hooks/border.js +++ b/packages/block-editor/src/hooks/border.js @@ -157,7 +157,7 @@ function getColorSlugFromVariable( value ) { } export function BorderPanel( props ) { - const { attributes, clientId, setAttributes } = props; + const { attributes, clientId, setAttributes, setBlockGlobalStyles } = props; const { style } = attributes; const { colors } = useMultipleOriginColorsAndGradients(); @@ -250,6 +250,12 @@ export function BorderPanel( props ) { style: newStyle, borderColor: newBorderColor, } ); + + // @TODO check if this will overwrite existing, saved global styles. + setBlockGlobalStyles( 'border', { + radius: style?.border?.radius, + ...newBorderStyles, + } ); }; const hydratedBorder = getBorderObject( attributes, colors ); diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index 593eea881e3107..4b711272cd643e 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -290,7 +290,7 @@ const getLinkColorFromAttributeValue = ( colors, value ) => { * @return {WPElement} Color edit element. */ export function ColorEdit( props ) { - const { name: blockName, attributes } = props; + const { name: blockName, attributes, setBlockGlobalStyles } = props; // Some color settings have a special handling for deprecated flags in `useSetting`, // so we can't unwrap them by doing const { ... } = useSetting('color') // until https://github.com/WordPress/gutenberg/issues/37094 is fixed. @@ -393,6 +393,11 @@ export function ColorEdit( props ) { ...localAttributes.current, ...newAttributes, }; + + setBlockGlobalStyles( + `color.${ name }`, + colorObject?.slug ? `var:preset|color|${ colorObject.slug }` : value + ); }; const onChangeGradient = ( value ) => { diff --git a/packages/block-editor/src/hooks/font-family.js b/packages/block-editor/src/hooks/font-family.js index fe8693f64421bf..bb100c4d22a6bb 100644 --- a/packages/block-editor/src/hooks/font-family.js +++ b/packages/block-editor/src/hooks/font-family.js @@ -108,6 +108,7 @@ function addEditProps( settings ) { export function FontFamilyEdit( { setAttributes, attributes: { fontFamily }, + setBlockGlobalStyles, } ) { const fontFamilies = useSetting( 'typography.fontFamilies' ); @@ -124,6 +125,10 @@ export function FontFamilyEdit( { setAttributes( { fontFamily: predefinedFontFamily?.slug, } ); + setBlockGlobalStyles( + 'typography.fontFamily', + `var:preset|font-family|${ predefinedFontFamily?.slug }` + ); } return ( diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js index 6cb950afc45641..f5277efddd4cdf 100644 --- a/packages/block-editor/src/hooks/font-size.js +++ b/packages/block-editor/src/hooks/font-size.js @@ -118,6 +118,7 @@ export function FontSizeEdit( props ) { const { attributes: { fontSize, style }, setAttributes, + setBlockGlobalStyles, } = props; const fontSizes = useSetting( 'typography.fontSizes' ); @@ -134,6 +135,11 @@ export function FontSizeEdit( props ) { } ), fontSize: fontSizeSlug, } ); + + setBlockGlobalStyles( + FONT_SIZE_SUPPORT_KEY, + fontSizeSlug ? `var:preset|font-size|${ fontSizeSlug }` : value + ); }; const fontSizeObject = getFontSize( diff --git a/packages/block-editor/src/hooks/letter-spacing.js b/packages/block-editor/src/hooks/letter-spacing.js index 9e214fd07d792c..ac1156fc188196 100644 --- a/packages/block-editor/src/hooks/letter-spacing.js +++ b/packages/block-editor/src/hooks/letter-spacing.js @@ -27,6 +27,7 @@ export function LetterSpacingEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; function onChange( newSpacing ) { @@ -39,6 +40,7 @@ export function LetterSpacingEdit( props ) { }, } ), } ); + setBlockGlobalStyles( 'typography.letterSpacing', newSpacing ); } return ( diff --git a/packages/block-editor/src/hooks/line-height.js b/packages/block-editor/src/hooks/line-height.js index 8623e9f9bc0758..04c0e99d31a531 100644 --- a/packages/block-editor/src/hooks/line-height.js +++ b/packages/block-editor/src/hooks/line-height.js @@ -2,14 +2,13 @@ * WordPress dependencies */ import { hasBlockSupport } from '@wordpress/blocks'; -import { useContext } from '@wordpress/element'; + /** * Internal dependencies */ import LineHeightControl from '../components/line-height-control'; import { cleanEmptyObject } from './utils'; import useSetting from '../components/use-setting'; -import BlockGlobalStylesContext from '../components/block-global-styles/context'; export const LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; @@ -24,16 +23,9 @@ export function LineHeightEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; - const { - base: baseBlockStyles, - user: userBlockStyles, - merged: mergedBlockStyles, - setUserBlockStyles, - } = useContext( BlockGlobalStylesContext ); -console.log( 'mergedBlockStyles', mergedBlockStyles ); -console.log( 'userBlockStyles', userBlockStyles ); -console.log( 'baseBlockStyles', baseBlockStyles ); + const onChange = ( newLineHeightValue ) => { const newStyle = { ...style, @@ -42,17 +34,7 @@ console.log( 'baseBlockStyles', baseBlockStyles ); lineHeight: newLineHeightValue, }, }; - setUserBlockStyles( ( currentStyles ) => { - console.log( 'newStyle', newStyle ); - console.log( 'currentStyles', currentStyles ); - return { - ...currentStyles, - typography: { - ...currentStyles?.typography, - lineHeight: newLineHeightValue, - }, - }; - } ); + setBlockGlobalStyles( LINE_HEIGHT_SUPPORT_KEY, newLineHeightValue ); setAttributes( { style: cleanEmptyObject( newStyle ) } ); }; return ( diff --git a/packages/block-editor/src/hooks/margin.js b/packages/block-editor/src/hooks/margin.js index 8491ab41dfe636..d96808f6f549ba 100644 --- a/packages/block-editor/src/hooks/margin.js +++ b/packages/block-editor/src/hooks/margin.js @@ -103,6 +103,7 @@ export function MarginEdit( props ) { setAttributes, onMouseOver, onMouseOut, + setBlockGlobalStyles, } = props; const spacingSizes = useSetting( 'spacing.spacingSizes' ); @@ -136,6 +137,8 @@ export function MarginEdit( props ) { setAttributes( { style: cleanEmptyObject( newStyle ), } ); + + setBlockGlobalStyles( 'spacing.margin ', cleanEmptyObject( newStyle ) ); }; return Platform.select( { diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index 0c039e637619f8..44ecaa497e6026 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -102,6 +102,7 @@ export function PaddingEdit( props ) { setAttributes, onMouseOver, onMouseOut, + setBlockGlobalStyles, } = props; const spacingSizes = useSetting( 'spacing.spacingSizes' ); @@ -135,6 +136,11 @@ export function PaddingEdit( props ) { setAttributes( { style: cleanEmptyObject( newStyle ), } ); + + setBlockGlobalStyles( + 'spacing.padding ', + cleanEmptyObject( newStyle ) + ); }; return Platform.select( { diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index 5822a092b7b9c6..308a1bc13213fb 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -2,11 +2,17 @@ * External dependencies */ import classnames from 'classnames'; +import { set } from 'lodash'; /** * WordPress dependencies */ -import { useContext, useMemo, createPortal } from '@wordpress/element'; +import { + useContext, + useMemo, + createPortal, + useState, +} from '@wordpress/element'; import { addFilter } from '@wordpress/hooks'; import { getBlockSupport, @@ -15,6 +21,7 @@ import { } from '@wordpress/blocks'; import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose'; import { getCSSRules, compileCSS } from '@wordpress/style-engine'; +import { Button } from '@wordpress/components'; /** * Internal dependencies @@ -35,6 +42,8 @@ import { import useDisplayBlockControls from '../components/use-display-block-controls'; import { shouldSkipSerialization } from './utils'; import BlockGlobalStylesProvider from '../components/block-global-styles/provider'; +import BlockGlobalStylesContext from '../components/block-global-styles/context'; +import { InspectorControls } from '../components'; const styleSupportKeys = [ ...TYPOGRAPHY_SUPPORT_KEYS, @@ -337,6 +346,71 @@ export function addEditProps( settings ) { return settings; } +function StylePanels( props ) { + /* + * Why pass down a callback to every possible block supports style? + * Good question. Well, it's because we might need to make thing granular later, e.g., + * push typography[ feature ] only, and not all styles for one. + * Also some styles use presets, which we can't keep track of individually. It's up to the style itself to deal with it. + * @TODO: + * - Think about how we should update global styles live in the post editor (prerequisite). Because of this, I think we should start in the side editor. + * - Deal with presets, e.g., pass `var:preset|...` as the value where appropriate. + * - Deal with "sides", so we need to parse border-top-radius... ??? + * - Validate the constraints, e.g., we should only push styles that are possible to edit in theme.json/global styles. + * - Decide how to deal with individual changes, e.g., preserving any global styles when we're only changing border color (and not radius). + */ + const { merged: mergedBlockStyles, setUserBlockStyles } = useContext( + BlockGlobalStylesContext + ); + const [ shouldPushToGlobalStyles, setShouldPushToGlobalStyles ] = + useState( false ); + const newProps = { + ...props, + setBlockGlobalStyles: ( path, newValue ) => { + console.log( 'path, newValue', path, newValue ); + if ( ! shouldPushToGlobalStyles ) { + return; + } + setUserBlockStyles( ( currentStyles ) => { + // Deep clone `mergedBlockStyles` to avoid mutating it later. + // Why use mergedBlockStyles? + const newCurrentStyles = JSON.parse( + JSON.stringify( mergedBlockStyles ) + ); + console.log( 'currentStyles', currentStyles ); + set( newCurrentStyles, path, newValue ); + return newCurrentStyles; + } ); + }, + }; + + return ( + <> + + + + + + + + + ); +} + /** * Override the default edit UI to include new inspector controls for * all the custom styles configs. @@ -353,10 +427,7 @@ export const withBlockControls = createHigherOrderComponent( <> { shouldDisplayControls && ( - - - - + ) } @@ -409,7 +480,7 @@ const withElementsStyles = createHigherOrderComponent( // The .editor-styles-wrapper selector is required on elements styles. As it is // added to all other editor styles, not providing it causes reset and global // styles to override element styles because of higher specificity. - selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS[ elementName ] }`, + selector: `editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS[ elementName ] }`, } ); if ( !! cssRule ) { elementCssRules.push( cssRule ); From 87acafc021c2437678f55bdf9a4961549ece2725 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 23 Nov 2022 14:37:49 +1100 Subject: [PATCH 3/9] Updated comments --- packages/block-editor/src/hooks/style.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index 308a1bc13213fb..d1c76ebd41c901 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -353,7 +353,8 @@ function StylePanels( props ) { * push typography[ feature ] only, and not all styles for one. * Also some styles use presets, which we can't keep track of individually. It's up to the style itself to deal with it. * @TODO: - * - Think about how we should update global styles live in the post editor (prerequisite). Because of this, I think we should start in the side editor. + * - Think about how we should update global styles live in the post editor (prerequisite). + * Because of this, I think we should start in the side editor and use an exported `GlobalStylesContext` here. * - Deal with presets, e.g., pass `var:preset|...` as the value where appropriate. * - Deal with "sides", so we need to parse border-top-radius... ??? * - Validate the constraints, e.g., we should only push styles that are possible to edit in theme.json/global styles. From 65df5df74a7101904a0b7a4c9d751dbeb3715994 Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 23 Nov 2022 15:12:16 +1100 Subject: [PATCH 4/9] Space! --- packages/block-editor/src/hooks/margin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/margin.js b/packages/block-editor/src/hooks/margin.js index d96808f6f549ba..582ca44f7995f8 100644 --- a/packages/block-editor/src/hooks/margin.js +++ b/packages/block-editor/src/hooks/margin.js @@ -138,7 +138,7 @@ export function MarginEdit( props ) { style: cleanEmptyObject( newStyle ), } ); - setBlockGlobalStyles( 'spacing.margin ', cleanEmptyObject( newStyle ) ); + setBlockGlobalStyles( 'spacing.margin', cleanEmptyObject( newStyle ) ); }; return Platform.select( { From 9fa9e1230516f8eacee5e99ed455baedff0f44ec Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 23 Nov 2022 15:12:40 +1100 Subject: [PATCH 5/9] Space! --- packages/block-editor/src/hooks/padding.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index 44ecaa497e6026..850566f91dc1f2 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -138,7 +138,7 @@ export function PaddingEdit( props ) { } ); setBlockGlobalStyles( - 'spacing.padding ', + 'spacing.padding', cleanEmptyObject( newStyle ) ); }; From 4f0db53deb22e88d22e9c00f33e4186622057062 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Thu, 24 Nov 2022 13:02:13 +1100 Subject: [PATCH 6/9] This commit adds a new filter for block supports controls for global styles so we can hook into the global styles context. --- packages/block-editor/src/components/index.js | 2 +- packages/block-editor/src/hooks/gap.js | 6 ++ packages/block-editor/src/hooks/index.js | 4 + packages/block-editor/src/hooks/padding.js | 5 +- packages/block-editor/src/hooks/style.js | 8 +- packages/block-editor/src/hooks/typography.js | 2 +- packages/block-editor/src/index.js | 4 + .../global-styles/use-global-styles-output.js | 6 +- .../src/hooks/block-supports-styles.js | 102 ++++++++++++++++++ packages/edit-site/src/hooks/index.js | 1 + packages/edit-site/src/index.js | 6 +- packages/style-engine/src/index.ts | 5 +- packages/style-engine/src/styles/index.ts | 5 +- 13 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 packages/edit-site/src/hooks/block-supports-styles.js diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 0a0ad70140976c..1133a19660bb39 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -157,7 +157,7 @@ export { export { default as __experimentalBlockPatternsList } from './block-patterns-list'; export { default as __experimentalPublishDateTimePicker } from './publish-date-time-picker'; export { default as __experimentalInspectorPopoverHeader } from './inspector-popover-header'; - +export { default as useDisplayBlockControls } from './use-display-block-controls'; /* * State Related Components */ diff --git a/packages/block-editor/src/hooks/gap.js b/packages/block-editor/src/hooks/gap.js index 018872eb840329..aee205ee09c154 100644 --- a/packages/block-editor/src/hooks/gap.js +++ b/packages/block-editor/src/hooks/gap.js @@ -129,6 +129,7 @@ export function GapEdit( props ) { attributes: { style }, name: blockName, setAttributes, + setBlockGlobalStyles, } = props; const spacingSizes = useSetting( 'spacing.spacingSizes' ); @@ -175,6 +176,11 @@ export function GapEdit( props ) { style: cleanEmptyObject( newStyle ), } ); + setBlockGlobalStyles( + 'spacing.blockGap', + cleanEmptyObject( newStyle ) + ); + // In Safari, changing the `gap` CSS value on its own will not trigger the layout // to be recalculated / re-rendered. To force the updated gap to re-render, here // we replace the block's node with itself. diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index f6fa73a053ac58..9281ae13f62294 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -27,3 +27,7 @@ export { getSpacingClassesAndStyles } from './use-spacing-props'; export { getTypographyClassesAndStyles } from './use-typography-props'; export { getGapCSSValue } from './gap'; export { useCachedTruthy } from './use-cached-truthy'; +export { BORDER_SUPPORT_KEY, BorderPanel } from './border'; +export { COLOR_SUPPORT_KEY, ColorEdit } from './color'; +export { TypographyPanel, TYPOGRAPHY_SUPPORT_KEY } from './typography'; +export { SPACING_SUPPORT_KEY, DimensionsPanel } from './dimensions'; diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index 850566f91dc1f2..d9471b792a3d67 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -137,10 +137,7 @@ export function PaddingEdit( props ) { style: cleanEmptyObject( newStyle ), } ); - setBlockGlobalStyles( - 'spacing.padding', - cleanEmptyObject( newStyle ) - ); + setBlockGlobalStyles( 'spacing.padding', cleanEmptyObject( newStyle ) ); }; return Platform.select( { diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index d1c76ebd41c901..5df494840e15f2 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -425,14 +425,12 @@ export const withBlockControls = createHigherOrderComponent( const shouldDisplayControls = useDisplayBlockControls(); return ( - <> + { shouldDisplayControls && ( - - - + ) } - + ); }, 'withToolbarControls' diff --git a/packages/block-editor/src/hooks/typography.js b/packages/block-editor/src/hooks/typography.js index 32ea7e123b818d..2f69011d83e3bd 100644 --- a/packages/block-editor/src/hooks/typography.js +++ b/packages/block-editor/src/hooks/typography.js @@ -1,4 +1,4 @@ -/** + /** * WordPress dependencies */ import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks'; diff --git a/packages/block-editor/src/index.js b/packages/block-editor/src/index.js index 1c81c910b21e12..6a0ec31484ec30 100644 --- a/packages/block-editor/src/index.js +++ b/packages/block-editor/src/index.js @@ -14,6 +14,10 @@ export { useCachedTruthy, useLayoutClasses as __experimentaluseLayoutClasses, useLayoutStyles as __experimentaluseLayoutStyles, + ColorEdit, + TypographyPanel, + BorderPanel, + DimensionsPanel, } from './hooks'; export * from './components'; export * from './elements'; diff --git a/packages/edit-site/src/components/global-styles/use-global-styles-output.js b/packages/edit-site/src/components/global-styles/use-global-styles-output.js index b32201fe2d2c22..d7afa0aa33fc9e 100644 --- a/packages/edit-site/src/components/global-styles/use-global-styles-output.js +++ b/packages/edit-site/src/components/global-styles/use-global-styles-output.js @@ -18,6 +18,7 @@ import { __unstablePresetDuotoneFilter as PresetDuotoneFilter, __experimentalGetGapCSSValue as getGapCSSValue, store as blockEditorStore, + BlockGlobalStylesContext, } from '@wordpress/block-editor'; /** @@ -883,7 +884,10 @@ function updateConfigWithSeparator( config ) { export function useGlobalStylesOutput() { let { merged: mergedConfig } = useContext( GlobalStylesContext ); - + const { merged: mergedBlockStyles } = useContext( + BlockGlobalStylesContext + ); + console.log( 'mergedBlockStyles', mergedBlockStyles ); const [ blockGap ] = useSetting( 'spacing.blockGap' ); const hasBlockGapSupport = blockGap !== null; const hasFallbackGapSupport = ! hasBlockGapSupport; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback styles support. diff --git a/packages/edit-site/src/hooks/block-supports-styles.js b/packages/edit-site/src/hooks/block-supports-styles.js new file mode 100644 index 00000000000000..80a7e1859c38b4 --- /dev/null +++ b/packages/edit-site/src/hooks/block-supports-styles.js @@ -0,0 +1,102 @@ +/** + * External dependencies + */ +import { set } from 'lodash'; + +/** + * WordPress dependencies + */ +import { addFilter } from '@wordpress/hooks'; +import { createHigherOrderComponent } from '@wordpress/compose'; +import { useContext, useState } from '@wordpress/element'; +import { + ColorEdit, + TypographyPanel, + BorderPanel, + DimensionsPanel, + useDisplayBlockControls, + InspectorControls, +} from '@wordpress/block-editor'; +import { Button, PanelBody } from '@wordpress/components'; +import { getCSSVarFromStyleValue } from '@wordpress/style-engine'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { GlobalStylesContext } from '../components/global-styles/context'; + +export const withEditBlockControls = createHigherOrderComponent( + ( BlockEdit ) => ( props ) => { + const { name } = props; + const [ shouldPushToGlobalStyles, setShouldPushToGlobalStyles ] = + useState( false ); + const { setUserConfig } = useContext( GlobalStylesContext ); + + const shouldDisplayControls = useDisplayBlockControls(); + const blockSupportControlProps = { + ...props, + setBlockGlobalStyles: ( path, newValue ) => { + if ( ! shouldPushToGlobalStyles ) { + return; + } + const fullPath = `styles.blocks.${ name }.${ path }`; + setUserConfig( ( currentConfig ) => { + // Deep clone `currentConfig` to avoid mutating it later. + const newUserConfig = JSON.parse( + JSON.stringify( currentConfig ) + ); + set( newUserConfig, fullPath, getCSSVarFromStyleValue( newValue ) ); + return newUserConfig; + } ); + }, + }; + + return ( + <> + { shouldDisplayControls && ( + <> + + + + + + + +

+ { __( + "When activated, all changes to this block's styles will be applied to all blocks of this type. Note that only typography, dimensions, color and border styles will be copied." + ) } +

+
+
+ + ) } + + + ); + }, + 'withEditBlockControls' +); + +addFilter( + 'editor.BlockEdit', + 'core/edit-site/block-supports-styles', + withEditBlockControls +); diff --git a/packages/edit-site/src/hooks/index.js b/packages/edit-site/src/hooks/index.js index 1f7196dd2256c8..69f509688fc666 100644 --- a/packages/edit-site/src/hooks/index.js +++ b/packages/edit-site/src/hooks/index.js @@ -3,3 +3,4 @@ */ import './components'; import './template-part-edit'; +import './block-supports-styles'; diff --git a/packages/edit-site/src/index.js b/packages/edit-site/src/index.js index 4b619f7aac9a97..53c7835b099fd2 100644 --- a/packages/edit-site/src/index.js +++ b/packages/edit-site/src/index.js @@ -15,7 +15,7 @@ import { import { store as editorStore } from '@wordpress/editor'; import { store as interfaceStore } from '@wordpress/interface'; import { store as preferencesStore } from '@wordpress/preferences'; -import { addFilter } from '@wordpress/hooks'; +import { addFilter, removeFilter } from '@wordpress/hooks'; /** * Internal dependencies @@ -118,6 +118,10 @@ export function initializeEditor( id, settings ) { reinitializeEditor( target, settings ); } +// Removes the block supports edit controls added in packages/block-editor/src/hooks/style.js, +// so that we can register another in packages/edit-site/src/hooks/block-supports-styles.js. +removeFilter( 'editor.BlockEdit', 'core/style/with-block-controls' ); + export { default as PluginSidebar } from './components/sidebar-edit-mode/plugin-sidebar'; export { default as PluginSidebarMoreMenuItem } from './components/header-edit-mode/plugin-sidebar-more-menu-item'; export { default as PluginMoreMenuItem } from './components/header-edit-mode/plugin-more-menu-item'; diff --git a/packages/style-engine/src/index.ts b/packages/style-engine/src/index.ts index 64e4e4a6edeb91..c19e3eedfd99a3 100644 --- a/packages/style-engine/src/index.ts +++ b/packages/style-engine/src/index.ts @@ -12,7 +12,7 @@ import type { GeneratedCSSRule, StyleDefinition, } from './types'; -import { styleDefinitions } from './styles'; +import { styleDefinitions, getCSSVarFromStyleValue } from './styles'; /** * Generates a stylesheet for a given style object and selector. @@ -78,3 +78,6 @@ export function getCSSRules( return rules; } + +/* Styles utility functions */ +export { getCSSVarFromStyleValue }; diff --git a/packages/style-engine/src/styles/index.ts b/packages/style-engine/src/styles/index.ts index 5dc1b8743e2ab4..bb42c4bcfb5ebc 100644 --- a/packages/style-engine/src/styles/index.ts +++ b/packages/style-engine/src/styles/index.ts @@ -8,8 +8,9 @@ import shadow from './shadow'; import outline from './outline'; import spacing from './spacing'; import typography from './typography'; +import { getCSSVarFromStyleValue } from './utils'; -export const styleDefinitions = [ +const styleDefinitions = [ ...border, ...color, ...dimensions, @@ -18,3 +19,5 @@ export const styleDefinitions = [ ...typography, ...shadow, ]; + +export { getCSSVarFromStyleValue, styleDefinitions }; From cd9a54953a77b20435290e7076368c2ac2247053 Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 7 Dec 2022 14:34:31 +1100 Subject: [PATCH 7/9] Removing changes that would affect post-editor, and isolating to site editor Removing blockglobalstyle context and provider since we'll use global style provider. Starting to reset user config when resetting block-level styles. Deliberately not rebuilding docs here :) --- packages/block-editor/package.json | 1 - .../components/block-global-styles/context.js | 17 -- .../block-global-styles/provider.js | 158 ------------------ packages/block-editor/src/components/index.js | 2 - .../block-editor/src/hooks/border-radius.js | 16 +- packages/block-editor/src/hooks/border.js | 45 +++-- packages/block-editor/src/hooks/color.js | 84 +++++++--- .../block-editor/src/hooks/font-family.js | 8 +- packages/block-editor/src/hooks/font-size.js | 14 +- .../block-editor/src/hooks/letter-spacing.js | 14 +- packages/block-editor/src/hooks/style.js | 75 +-------- .../global-styles/use-global-styles-output.js | 6 +- 12 files changed, 134 insertions(+), 306 deletions(-) delete mode 100644 packages/block-editor/src/components/block-global-styles/context.js delete mode 100644 packages/block-editor/src/components/block-global-styles/provider.js diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 5e746736397aad..dce5352d5812a6 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -39,7 +39,6 @@ "@wordpress/blocks": "file:../blocks", "@wordpress/components": "file:../components", "@wordpress/compose": "file:../compose", - "@wordpress/core-data": "file:../core-data", "@wordpress/data": "file:../data", "@wordpress/date": "file:../date", "@wordpress/deprecated": "file:../deprecated", diff --git a/packages/block-editor/src/components/block-global-styles/context.js b/packages/block-editor/src/components/block-global-styles/context.js deleted file mode 100644 index 0e2478cb7f3b3e..00000000000000 --- a/packages/block-editor/src/components/block-global-styles/context.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * WordPress dependencies - */ -import { createContext } from '@wordpress/element'; - -export const DEFAULT_BLOCK_GLOBAL_STYLES_CONTEXT = { - base: {}, - user: {}, - merged: {}, - setBlockGlobalStyles: () => {}, -}; - -const BlockGlobalStylesContext = createContext( - DEFAULT_BLOCK_GLOBAL_STYLES_CONTEXT -); - -export default BlockGlobalStylesContext; diff --git a/packages/block-editor/src/components/block-global-styles/provider.js b/packages/block-editor/src/components/block-global-styles/provider.js deleted file mode 100644 index 95d63a92fca226..00000000000000 --- a/packages/block-editor/src/components/block-global-styles/provider.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * External dependencies - */ -import { mergeWith, isEmpty, mapValues } from 'lodash'; - -/** - * WordPress dependencies - */ -import { useMemo, useCallback } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; - -/** - * Internal dependencies - */ -import BlockGlobalStylesContext from './context'; -import { store as blockEditorStore } from '../../store'; - -function mergeTreesCustomizer( _, srcValue ) { - // We only pass as arrays the presets, - // in which case we want the new array of values - // to override the old array (no merging). - if ( Array.isArray( srcValue ) ) { - return srcValue; - } -} - -export function mergeBaseAndUserConfigs( base, user ) { - return mergeWith( {}, base, user, mergeTreesCustomizer ); -} - -function cleanEmptyObject( object ) { - if ( - object === null || - typeof object !== 'object' || - Array.isArray( object ) - ) { - return object; - } - const cleanedNestedObjects = Object.fromEntries( - Object.entries( mapValues( object, cleanEmptyObject ) ).filter( - ( [ , value ] ) => Boolean( value ) - ) - ); - return isEmpty( cleanedNestedObjects ) ? undefined : cleanedNestedObjects; -} - -function useBaseBlockGlobalStyles( blockName ) { - const baseConfig = useSelect( ( select ) => { - return select( - coreStore - ).__experimentalGetCurrentThemeBaseGlobalStyles(); - }, [] ); - - return [ !! baseConfig, baseConfig?.styles?.blocks?.[ blockName ] || {} ]; -} - -function useUserBlockGlobalStyles() { - const { globalStylesId, blockName, styles } = useSelect( ( select ) => { - const _globalStylesId = - select( coreStore ).__experimentalGetCurrentGlobalStylesId(); - const record = _globalStylesId - ? select( coreStore ).getEditedEntityRecord( - 'root', - 'globalStyles', - _globalStylesId - ) - : undefined; - const { getBlockName, getSelectedBlockClientId } = - select( blockEditorStore ); - const selectedBlockClientId = getSelectedBlockClientId(); - const selectedBlockName = - selectedBlockClientId && getBlockName( selectedBlockClientId ); - return { - globalStylesId: _globalStylesId, - blockName: selectedBlockName, - styles: record?.styles, - }; - }, [] ); - - const { getEditedEntityRecord } = useSelect( coreStore ); - const { editEntityRecord } = useDispatch( coreStore ); - const isReady = !! styles || !! blockName; - - const setBlockGlobalStyles = useCallback( - ( callback ) => { - const record = getEditedEntityRecord( - 'root', - 'globalStyles', - globalStylesId - ); - const currentBlockStyles = record?.styles?.[ blockName ] ?? {}; - const updatedBlockStyles = - cleanEmptyObject( callback( currentBlockStyles ) ) || {}; - editEntityRecord( 'root', 'globalStyles', globalStylesId, { - styles: { - ...record?.styles, - blocks: { - ...record?.styles?.blocks, - [ blockName ]: updatedBlockStyles, - }, - }, - } ); - }, - [ globalStylesId ] - ); - - return [ - isReady, - blockName, - styles?.blocks?.[ blockName ] || {}, - setBlockGlobalStyles, - ]; -} - -function useBlockGlobalStylesContext() { - const [ - areUserBlockGlobalStylesReady, - blockName, - userBlockStyles, - setUserBlockStyles, - ] = useUserBlockGlobalStyles(); - - const [ areBaseBlockGlobalStylesReady, baseBlockStyles ] = - useBaseBlockGlobalStyles( blockName ); - - const mergedBlockStyles = useMemo( () => { - if ( ! baseBlockStyles || ! userBlockStyles ) { - return {}; - } - return mergeBaseAndUserConfigs( baseBlockStyles, userBlockStyles ); - }, [ userBlockStyles, baseBlockStyles ] ); - - const context = useMemo( () => { - return { - isReady: - areUserBlockGlobalStylesReady && areBaseBlockGlobalStylesReady, - user: userBlockStyles, - base: baseBlockStyles, - merged: mergedBlockStyles, - setUserBlockStyles, - }; - }, [ mergedBlockStyles, baseBlockStyles, userBlockStyles ] ); - return context; -} - -export default function BlockGlobalStylesProvider( { children } ) { - const context = useBlockGlobalStylesContext(); - if ( ! context.isReady ) { - return null; - } - - return ( - - { children } - - ); -} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 1133a19660bb39..5c0bf429889908 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -164,5 +164,3 @@ export { default as useDisplayBlockControls } from './use-display-block-controls export { default as BlockEditorProvider } from './provider'; export { default as useSetting } from './use-setting'; -export { default as BlockGlobalStylesProvider } from './block-global-styles/provider'; -export { default as BlockGlobalStylesContext } from './block-global-styles/context'; diff --git a/packages/block-editor/src/hooks/border-radius.js b/packages/block-editor/src/hooks/border-radius.js index 6b247e141b6818..a21f7643ef5ac0 100644 --- a/packages/block-editor/src/hooks/border-radius.js +++ b/packages/block-editor/src/hooks/border-radius.js @@ -16,6 +16,7 @@ export function BorderRadiusEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; const onChange = ( newRadius ) => { @@ -28,6 +29,7 @@ export function BorderRadiusEdit( props ) { } ); setAttributes( { style: newStyle } ); + setBlockGlobalStyles( 'border.radius', newRadius ); }; return ( @@ -60,11 +62,17 @@ export function hasBorderRadiusValue( props ) { * disabling the border radius support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetBorderRadius( { attributes = {}, setAttributes } ) { +export function resetBorderRadius( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { style: removeBorderAttribute( style, 'radius' ) } ); + setBlockGlobalStyles( 'border.radius', undefined ); } diff --git a/packages/block-editor/src/hooks/border.js b/packages/block-editor/src/hooks/border.js index c1e5ec71eb8f8d..9d99593b755338 100644 --- a/packages/block-editor/src/hooks/border.js +++ b/packages/block-editor/src/hooks/border.js @@ -43,29 +43,41 @@ const hasBorderValue = ( props ) => { // The border color, style, and width are omitted so they get undefined. The // border radius is separate and must retain its selection. -const resetBorder = ( { attributes = {}, setAttributes } ) => { +const resetBorder = ( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) => { const { style } = attributes; + const border = cleanEmptyObject( { + radius: style?.border?.radius, + } ); setAttributes( { borderColor: undefined, style: { ...style, - border: cleanEmptyObject( { - radius: style?.border?.radius, - } ), + border, }, } ); + + setBlockGlobalStyles( 'border', border ); }; -const resetBorderFilter = ( newAttributes ) => ( { - ...newAttributes, - borderColor: undefined, - style: { - ...newAttributes.style, - border: { - radius: newAttributes.style?.border?.radius, +const resetBorderFilter = ( newAttributes, { setBlockGlobalStyles } ) => { + setBlockGlobalStyles( 'border', { + radius: newAttributes.style?.border?.radius, + } ); + return { + ...newAttributes, + borderColor: undefined, + style: { + ...newAttributes.style, + border: { + radius: newAttributes.style?.border?.radius, + }, }, - }, -} ); + }; +}; const getColorByProperty = ( colors, property, value ) => { let matchedColor; @@ -255,6 +267,9 @@ export function BorderPanel( props ) { setBlockGlobalStyles( 'border', { radius: style?.border?.radius, ...newBorderStyles, + color: newBorderColor + ? `var:preset|color|${ newBorderColor }` + : newBorderStyles.color, } ); }; @@ -268,7 +283,9 @@ export function BorderPanel( props ) { label={ __( 'Border' ) } onDeselect={ () => resetBorder( props ) } isShownByDefault={ showBorderByDefault } - resetAllFilter={ resetBorderFilter } + resetAllFilter={ ( newAttributes ) => + resetBorderFilter( newAttributes, props ) + } panelId={ clientId } > /** * Clears text color related properties from supplied attributes. * - * @param {Object} attributes Block attributes. + * @param {Object} attributes Block attributes. + * @param {Object} root0 + * @param {Function} root0.setBlockGlobalStyles A function to set global style for a block. * @return {Object} Update block attributes with text color properties omitted. */ -const resetAllTextFilter = ( attributes ) => ( { - textColor: undefined, - style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ), -} ); +const resetAllTextFilter = ( attributes, { setBlockGlobalStyles } ) => { + setBlockGlobalStyles( 'color.text', undefined ); + return { + textColor: undefined, + style: clearColorFromStyles( [ 'color', 'text' ], attributes.style ), + }; +}; /** * Clears link color related properties from supplied attributes. * - * @param {Object} attributes Block attributes. + * @param {Object} attributes Block attributes. + * @param {Object} root0 + * @param {Function} root0.setBlockGlobalStyles A function to set global style for a block. * @return {Object} Update block attributes with link color properties omitted. */ -const resetAllLinkFilter = ( attributes ) => ( { - style: clearColorFromStyles( - [ 'elements', 'link', 'color', 'text' ], - attributes.style - ), -} ); +const resetAllLinkFilter = ( attributes, { setBlockGlobalStyles } ) => { + setBlockGlobalStyles( 'elements.link.color.text', undefined ); + return { + style: clearColorFromStyles( + [ 'elements', 'link', 'color', 'text' ], + attributes.style + ), + }; +}; /** * Clears all background color related properties including gradients from * supplied block attributes. * - * @param {Object} attributes Block attributes. + * @param {Object} attributes Block attributes. + * @param {Object} root0 + * @param {Function} root0.setBlockGlobalStyles A function to set global style for a block * @return {Object} Block attributes with background and gradient omitted. */ -const clearBackgroundAndGradient = ( attributes ) => ( { - backgroundColor: undefined, - gradient: undefined, - style: { - ...attributes.style, - color: { - ...attributes.style?.color, - background: undefined, - gradient: undefined, +const clearBackgroundAndGradient = ( attributes, { setBlockGlobalStyles } ) => { + setBlockGlobalStyles( 'color.background', undefined ); + setBlockGlobalStyles( 'color.gradient', undefined ); + return { + backgroundColor: undefined, + gradient: undefined, + style: { + ...attributes.style, + color: { + ...attributes.style?.color, + background: undefined, + gradient: undefined, + }, }, - }, -} ); + }; +}; /** * Filters registered block settings, extending attributes to include @@ -429,6 +445,10 @@ export function ColorEdit( props ) { }; } props.setAttributes( newAttributes ); + setBlockGlobalStyles( + 'color.gradient', + slug ? `var:preset|gradient|${ slug }` : value + ); localAttributes.current = { ...localAttributes.current, ...newAttributes, @@ -449,6 +469,7 @@ export function ColorEdit( props ) { ) ); props.setAttributes( { style: newStyle } ); + setBlockGlobalStyles( 'elements.link.color.text', newLinkColorValue ); localAttributes.current = { ...localAttributes.current, ...{ style: newStyle }, @@ -492,7 +513,9 @@ export function ColorEdit( props ) { style?.color?.text ).color, isShownByDefault: defaultColorControls?.text, - resetAllFilter: resetAllTextFilter, + resetAllFilter: ( newAttributes ) => { + resetAllTextFilter( newAttributes, props ); + }, }, ] : [] ), @@ -514,7 +537,12 @@ export function ColorEdit( props ) { : undefined, isShownByDefault: defaultColorControls?.background, - resetAllFilter: clearBackgroundAndGradient, + resetAllFilter: ( newAttributes ) => { + clearBackgroundAndGradient( + newAttributes, + props + ); + }, }, ] : [] ), @@ -530,7 +558,9 @@ export function ColorEdit( props ) { clearable: !! style?.elements?.link?.color?.text, isShownByDefault: defaultColorControls?.link, - resetAllFilter: resetAllLinkFilter, + resetAllFilter: ( newAttributes ) => { + resetAllLinkFilter( newAttributes, props ); + }, }, ] : [] ), diff --git a/packages/block-editor/src/hooks/font-family.js b/packages/block-editor/src/hooks/font-family.js index bb100c4d22a6bb..3b41a8448908d1 100644 --- a/packages/block-editor/src/hooks/font-family.js +++ b/packages/block-editor/src/hooks/font-family.js @@ -173,11 +173,13 @@ export function hasFontFamilyValue( props ) { * disabling the font family support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetFontFamily( { setAttributes } ) { +export function resetFontFamily( { setAttributes, setBlockGlobalStyles } ) { setAttributes( { fontFamily: undefined } ); + setBlockGlobalStyles( 'typography.fontFamily', undefined ); } addFilter( diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js index f5277efddd4cdf..523498276622a0 100644 --- a/packages/block-editor/src/hooks/font-size.js +++ b/packages/block-editor/src/hooks/font-size.js @@ -179,11 +179,16 @@ export function hasFontSizeValue( props ) { * disabling the font size support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetFontSize( { attributes = {}, setAttributes } ) { +export function resetFontSize( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -196,6 +201,7 @@ export function resetFontSize( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'typography.fontSize', undefined ); } /** diff --git a/packages/block-editor/src/hooks/letter-spacing.js b/packages/block-editor/src/hooks/letter-spacing.js index ac1156fc188196..82f9e3d2af2f93 100644 --- a/packages/block-editor/src/hooks/letter-spacing.js +++ b/packages/block-editor/src/hooks/letter-spacing.js @@ -84,11 +84,16 @@ export function hasLetterSpacingValue( props ) { * disabling the letter spacing support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetLetterSpacing( { attributes = {}, setAttributes } ) { +export function resetLetterSpacing( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -100,4 +105,5 @@ export function resetLetterSpacing( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'typography.letterSpacing', undefined ); } diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index 5df494840e15f2..dcaaf1d741ae36 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -2,17 +2,11 @@ * External dependencies */ import classnames from 'classnames'; -import { set } from 'lodash'; /** * WordPress dependencies */ -import { - useContext, - useMemo, - createPortal, - useState, -} from '@wordpress/element'; +import { useContext, useMemo, createPortal } from '@wordpress/element'; import { addFilter } from '@wordpress/hooks'; import { getBlockSupport, @@ -21,7 +15,6 @@ import { } from '@wordpress/blocks'; import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose'; import { getCSSRules, compileCSS } from '@wordpress/style-engine'; -import { Button } from '@wordpress/components'; /** * Internal dependencies @@ -41,9 +34,6 @@ import { } from './dimensions'; import useDisplayBlockControls from '../components/use-display-block-controls'; import { shouldSkipSerialization } from './utils'; -import BlockGlobalStylesProvider from '../components/block-global-styles/provider'; -import BlockGlobalStylesContext from '../components/block-global-styles/context'; -import { InspectorControls } from '../components'; const styleSupportKeys = [ ...TYPOGRAPHY_SUPPORT_KEYS, @@ -347,67 +337,16 @@ export function addEditProps( settings ) { } function StylePanels( props ) { - /* - * Why pass down a callback to every possible block supports style? - * Good question. Well, it's because we might need to make thing granular later, e.g., - * push typography[ feature ] only, and not all styles for one. - * Also some styles use presets, which we can't keep track of individually. It's up to the style itself to deal with it. - * @TODO: - * - Think about how we should update global styles live in the post editor (prerequisite). - * Because of this, I think we should start in the side editor and use an exported `GlobalStylesContext` here. - * - Deal with presets, e.g., pass `var:preset|...` as the value where appropriate. - * - Deal with "sides", so we need to parse border-top-radius... ??? - * - Validate the constraints, e.g., we should only push styles that are possible to edit in theme.json/global styles. - * - Decide how to deal with individual changes, e.g., preserving any global styles when we're only changing border color (and not radius). - */ - const { merged: mergedBlockStyles, setUserBlockStyles } = useContext( - BlockGlobalStylesContext - ); - const [ shouldPushToGlobalStyles, setShouldPushToGlobalStyles ] = - useState( false ); const newProps = { ...props, - setBlockGlobalStyles: ( path, newValue ) => { - console.log( 'path, newValue', path, newValue ); - if ( ! shouldPushToGlobalStyles ) { - return; - } - setUserBlockStyles( ( currentStyles ) => { - // Deep clone `mergedBlockStyles` to avoid mutating it later. - // Why use mergedBlockStyles? - const newCurrentStyles = JSON.parse( - JSON.stringify( mergedBlockStyles ) - ); - console.log( 'currentStyles', currentStyles ); - set( newCurrentStyles, path, newValue ); - return newCurrentStyles; - } ); - }, + setBlockGlobalStyles: () => {}, }; - return ( <> - - - ); } @@ -425,12 +364,14 @@ export const withBlockControls = createHigherOrderComponent( const shouldDisplayControls = useDisplayBlockControls(); return ( - + <> { shouldDisplayControls && ( - + <> + + ) } - + ); }, 'withToolbarControls' @@ -479,7 +420,7 @@ const withElementsStyles = createHigherOrderComponent( // The .editor-styles-wrapper selector is required on elements styles. As it is // added to all other editor styles, not providing it causes reset and global // styles to override element styles because of higher specificity. - selector: `editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS[ elementName ] }`, + selector: `.editor-styles-wrapper .${ blockElementsContainerIdentifier } ${ ELEMENTS[ elementName ] }`, } ); if ( !! cssRule ) { elementCssRules.push( cssRule ); diff --git a/packages/edit-site/src/components/global-styles/use-global-styles-output.js b/packages/edit-site/src/components/global-styles/use-global-styles-output.js index d7afa0aa33fc9e..b32201fe2d2c22 100644 --- a/packages/edit-site/src/components/global-styles/use-global-styles-output.js +++ b/packages/edit-site/src/components/global-styles/use-global-styles-output.js @@ -18,7 +18,6 @@ import { __unstablePresetDuotoneFilter as PresetDuotoneFilter, __experimentalGetGapCSSValue as getGapCSSValue, store as blockEditorStore, - BlockGlobalStylesContext, } from '@wordpress/block-editor'; /** @@ -884,10 +883,7 @@ function updateConfigWithSeparator( config ) { export function useGlobalStylesOutput() { let { merged: mergedConfig } = useContext( GlobalStylesContext ); - const { merged: mergedBlockStyles } = useContext( - BlockGlobalStylesContext - ); - console.log( 'mergedBlockStyles', mergedBlockStyles ); + const [ blockGap ] = useSetting( 'spacing.blockGap' ); const hasBlockGapSupport = blockGap !== null; const hasFallbackGapSupport = ! hasBlockGapSupport; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback styles support. From e0950bc4f9f79d27e3b901ef1301fcbe2ec86dfc Mon Sep 17 00:00:00 2001 From: ramonjd Date: Wed, 7 Dec 2022 15:24:16 +1100 Subject: [PATCH 8/9] Adding support for remaining block support styles. --- packages/block-editor/src/hooks/gap.js | 14 ++++++++++---- packages/block-editor/src/hooks/margin.js | 14 ++++++++++---- packages/block-editor/src/hooks/min-height.js | 12 ++++++++++-- packages/block-editor/src/hooks/padding.js | 14 ++++++++++---- .../block-editor/src/hooks/text-decoration.js | 16 ++++++++++++---- .../block-editor/src/hooks/text-transform.js | 16 ++++++++++++---- 6 files changed, 64 insertions(+), 22 deletions(-) diff --git a/packages/block-editor/src/hooks/gap.js b/packages/block-editor/src/hooks/gap.js index aee205ee09c154..170becf1e40fde 100644 --- a/packages/block-editor/src/hooks/gap.js +++ b/packages/block-editor/src/hooks/gap.js @@ -87,11 +87,16 @@ export function getGapCSSValue( blockGapValue, defaultValue = '0' ) { * Resets the gap block support attribute. This can be used when disabling * the gap support controls for a block via a progressive discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetGap( { attributes = {}, setAttributes } ) { +export function resetGap( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -103,6 +108,7 @@ export function resetGap( { attributes = {}, setAttributes } ) { }, }, } ); + setBlockGlobalStyles( 'spacing.blockGap', undefined ); } /** diff --git a/packages/block-editor/src/hooks/margin.js b/packages/block-editor/src/hooks/margin.js index 582ca44f7995f8..362a16dab0c1aa 100644 --- a/packages/block-editor/src/hooks/margin.js +++ b/packages/block-editor/src/hooks/margin.js @@ -57,11 +57,16 @@ export function hasMarginValue( props ) { * Resets the margin block support attributes. This can be used when disabling * the margin support controls for a block via a `ToolsPanel`. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetMargin( { attributes = {}, setAttributes } ) { +export function resetMargin( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -73,6 +78,7 @@ export function resetMargin( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'spacing.margin', undefined ); } /** diff --git a/packages/block-editor/src/hooks/min-height.js b/packages/block-editor/src/hooks/min-height.js index e123f0cee98b22..86fefc6892dd9f 100644 --- a/packages/block-editor/src/hooks/min-height.js +++ b/packages/block-editor/src/hooks/min-height.js @@ -39,9 +39,14 @@ export function hasMinHeightValue( props ) { * * @param {Object} props Block props. * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetMinHeight( { attributes = {}, setAttributes } ) { +export function resetMinHeight( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -53,6 +58,7 @@ export function resetMinHeight( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'dimensions.minHeight', undefined ); } /** @@ -76,6 +82,7 @@ export function MinHeightEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; if ( useIsMinHeightDisabled( props ) ) { @@ -92,6 +99,7 @@ export function MinHeightEdit( props ) { }; setAttributes( { style: cleanEmptyObject( newStyle ) } ); + setBlockGlobalStyles( 'dimensions.minHeight', next ); }; return ( diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index d9471b792a3d67..0f798c44348948 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -56,11 +56,16 @@ export function hasPaddingValue( props ) { * Resets the padding block support attributes. This can be used when disabling * the padding support controls for a block via a `ToolsPanel`. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetPadding( { attributes = {}, setAttributes } ) { +export function resetPadding( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -72,6 +77,7 @@ export function resetPadding( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'spacing.padding', undefined ); } /** diff --git a/packages/block-editor/src/hooks/text-decoration.js b/packages/block-editor/src/hooks/text-decoration.js index 17ba9ee73f698f..82071d9d98c47c 100644 --- a/packages/block-editor/src/hooks/text-decoration.js +++ b/packages/block-editor/src/hooks/text-decoration.js @@ -28,6 +28,7 @@ export function TextDecorationEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; function onChange( newDecoration ) { @@ -40,6 +41,7 @@ export function TextDecorationEdit( props ) { }, } ), } ); + setBlockGlobalStyles( 'typography.textDecoration', newDecoration ); } return ( @@ -83,11 +85,16 @@ export function hasTextDecorationValue( props ) { * disabling the text decoration support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetTextDecoration( { attributes = {}, setAttributes } ) { +export function resetTextDecoration( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -99,4 +106,5 @@ export function resetTextDecoration( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'typography.textDecoration', undefined ); } diff --git a/packages/block-editor/src/hooks/text-transform.js b/packages/block-editor/src/hooks/text-transform.js index 588327633ecb8a..682d2d2cfdcd88 100644 --- a/packages/block-editor/src/hooks/text-transform.js +++ b/packages/block-editor/src/hooks/text-transform.js @@ -28,6 +28,7 @@ export function TextTransformEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; function onChange( newTransform ) { @@ -40,6 +41,7 @@ export function TextTransformEdit( props ) { }, } ), } ); + setBlockGlobalStyles( 'typography.textTransform', newTransform ); } return ( @@ -82,11 +84,16 @@ export function hasTextTransformValue( props ) { * disabling the text transform support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetTextTransform( { attributes = {}, setAttributes } ) { +export function resetTextTransform( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -98,4 +105,5 @@ export function resetTextTransform( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'typography.textTransform', undefined ); } From 7877bc09226e74639042a77b159f98ea1c66587a Mon Sep 17 00:00:00 2001 From: ramonjd Date: Thu, 8 Dec 2022 13:25:07 +1100 Subject: [PATCH 9/9] Use toggle button Apply global styles reset in resetAllFilters Appearance and line height reset methods --- packages/block-editor/README.md | 36 ++++++++ .../block-editor/src/hooks/font-appearance.js | 18 +++- .../block-editor/src/hooks/line-height.js | 14 ++- packages/block-editor/src/hooks/style.js | 1 + packages/block-editor/src/hooks/typography.js | 86 +++++++++++-------- .../src/hooks/block-supports-styles.js | 52 +++++------ packages/style-engine/README.md | 12 +++ 7 files changed, 148 insertions(+), 71 deletions(-) diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 5760f1584c5db8..eb908091d28b18 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -282,6 +282,10 @@ _Related_ - +### BorderPanel + +Undocumented declaration. + ### ButtonBlockAppender _Related_ @@ -294,6 +298,18 @@ _Related_ Use `ButtonBlockAppender` instead. +### ColorEdit + +Inspector control panel containing the color related configuration + +_Parameters_ + +- _props_ `Object`: + +_Returns_ + +- `WPElement`: Color edit element. + ### ColorPalette Undocumented declaration. @@ -348,6 +364,18 @@ _Returns_ Undocumented declaration. +### DimensionsPanel + +Inspector controls for dimensions support. + +_Parameters_ + +- _props_ `Object`: Block props. + +_Returns_ + +- `WPElement`: Inspector controls for dimensions and spacing support features. + ### FontSizePicker _Related_ @@ -706,6 +734,10 @@ Ensures that the text selection keeps the same vertical distance from the viewport during keyboard events within this component. The vertical distance can vary. It is the last clicked or scrolled to position. +### TypographyPanel + +Undocumented declaration. + ### URLInput _Related_ @@ -787,6 +819,10 @@ _Returns_ - `any`: value +### useDisplayBlockControls + +Undocumented declaration. + ### useInnerBlocksProps This hook is used to lightly mark an element as an inner blocks wrapper diff --git a/packages/block-editor/src/hooks/font-appearance.js b/packages/block-editor/src/hooks/font-appearance.js index af25daed0d30b5..0253e4e5263040 100644 --- a/packages/block-editor/src/hooks/font-appearance.js +++ b/packages/block-editor/src/hooks/font-appearance.js @@ -31,6 +31,7 @@ export function FontAppearanceEdit( props ) { const { attributes: { style }, setAttributes, + setBlockGlobalStyles, } = props; const hasFontStyles = ! useIsFontStyleDisabled( props ); @@ -47,6 +48,8 @@ export function FontAppearanceEdit( props ) { }, } ), } ); + setBlockGlobalStyles( 'typography.fontStyle', newStyles.fontStyle ); + setBlockGlobalStyles( 'typography.fontWeight', newStyles.fontWeight ); }; const fontStyle = style?.typography?.fontStyle; @@ -126,11 +129,16 @@ export function hasFontAppearanceValue( props ) { * when disabling the font appearance support controls for a block via a * progressive discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetFontAppearance( { attributes = {}, setAttributes } ) { +export function resetFontAppearance( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -143,4 +151,6 @@ export function resetFontAppearance( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( 'typography.fontStyle', undefined ); + setBlockGlobalStyles( 'typography.fontWeight', undefined ); } diff --git a/packages/block-editor/src/hooks/line-height.js b/packages/block-editor/src/hooks/line-height.js index 04c0e99d31a531..86df45b2e793e7 100644 --- a/packages/block-editor/src/hooks/line-height.js +++ b/packages/block-editor/src/hooks/line-height.js @@ -77,11 +77,16 @@ export function hasLineHeightValue( props ) { * disabling the line height support controls for a block via a progressive * discovery panel. * - * @param {Object} props Block props. - * @param {Object} props.attributes Block's attributes. - * @param {Object} props.setAttributes Function to set block's attributes. + * @param {Object} props Block props. + * @param {Object} props.attributes Block's attributes. + * @param {Function} props.setAttributes Function to set block's attributes. + * @param {Function} props.setBlockGlobalStyles Function to set block's global styles. */ -export function resetLineHeight( { attributes = {}, setAttributes } ) { +export function resetLineHeight( { + attributes = {}, + setAttributes, + setBlockGlobalStyles, +} ) { const { style } = attributes; setAttributes( { @@ -93,4 +98,5 @@ export function resetLineHeight( { attributes = {}, setAttributes } ) { }, } ), } ); + setBlockGlobalStyles( LINE_HEIGHT_SUPPORT_KEY, undefined ); } diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index dcaaf1d741ae36..4e93dd06582362 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -339,6 +339,7 @@ export function addEditProps( settings ) { function StylePanels( props ) { const newProps = { ...props, + // Assign a noop value for method that only appears in site editor. setBlockGlobalStyles: () => {}, }; return ( diff --git a/packages/block-editor/src/hooks/typography.js b/packages/block-editor/src/hooks/typography.js index 2f69011d83e3bd..3e479f82d7a5eb 100644 --- a/packages/block-editor/src/hooks/typography.js +++ b/packages/block-editor/src/hooks/typography.js @@ -1,11 +1,10 @@ - /** +/** * WordPress dependencies */ import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks'; import { __experimentalToolsPanelItem as ToolsPanelItem } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; - /** * Internal dependencies */ @@ -100,16 +99,26 @@ export function TypographyPanel( props ) { '__experimentalDefaultControls', ] ); - const createResetAllFilter = ( attribute ) => ( newAttributes ) => ( { - ...newAttributes, - style: { - ...newAttributes.style, - typography: { - ...newAttributes.style?.typography, - [ attribute ]: undefined, - }, - }, - } ); + const createResetAllFilter = + ( styleProperty, customAttribute ) => ( newAttributes ) => { + props?.setBlockGlobalStyles( + `typography.${ styleProperty }`, + undefined + ); + return { + ...newAttributes, + ...( !! customAttribute && { [ customAttribute ]: undefined } ), + style: { + ...newAttributes.style, + typography: { + ...newAttributes.style?.typography, + ...( !! styleProperty && { + [ styleProperty ]: undefined, + } ), + }, + }, + }; + }; return ( @@ -119,10 +128,10 @@ export function TypographyPanel( props ) { label={ __( 'Font family' ) } onDeselect={ () => resetFontFamily( props ) } isShownByDefault={ defaultControls?.fontFamily } - resetAllFilter={ ( newAttributes ) => ( { - ...newAttributes, - fontFamily: undefined, - } ) } + resetAllFilter={ createResetAllFilter( + 'fontFamily', + 'fontFamily' + ) } panelId={ clientId } > @@ -135,17 +144,10 @@ export function TypographyPanel( props ) { label={ __( 'Font size' ) } onDeselect={ () => resetFontSize( props ) } isShownByDefault={ defaultControls?.fontSize } - resetAllFilter={ ( newAttributes ) => ( { - ...newAttributes, - fontSize: undefined, - style: { - ...newAttributes.style, - typography: { - ...newAttributes.style?.typography, - fontSize: undefined, - }, - }, - } ) } + resetAllFilter={ createResetAllFilter( + 'fontSize', + 'fontSize' + ) } panelId={ clientId } > @@ -161,17 +163,27 @@ export function TypographyPanel( props ) { ) } onDeselect={ () => resetFontAppearance( props ) } isShownByDefault={ defaultControls?.fontAppearance } - resetAllFilter={ ( newAttributes ) => ( { - ...newAttributes, - style: { - ...newAttributes.style, - typography: { - ...newAttributes.style?.typography, - fontStyle: undefined, - fontWeight: undefined, + resetAllFilter={ ( newAttributes ) => { + props.setBlockGlobalStyles( + 'typography.fontStyle', + undefined + ); + props.setBlockGlobalStyles( + 'typography.fontWeight', + undefined + ); + return { + ...newAttributes, + style: { + ...newAttributes.style, + typography: { + ...newAttributes.style?.typography, + fontStyle: undefined, + fontWeight: undefined, + }, }, - }, - } ) } + }; + } } panelId={ clientId } > diff --git a/packages/edit-site/src/hooks/block-supports-styles.js b/packages/edit-site/src/hooks/block-supports-styles.js index 80a7e1859c38b4..40e7b6a80087a9 100644 --- a/packages/edit-site/src/hooks/block-supports-styles.js +++ b/packages/edit-site/src/hooks/block-supports-styles.js @@ -17,7 +17,7 @@ import { useDisplayBlockControls, InspectorControls, } from '@wordpress/block-editor'; -import { Button, PanelBody } from '@wordpress/components'; +import { ToggleControl } from '@wordpress/components'; import { getCSSVarFromStyleValue } from '@wordpress/style-engine'; import { __ } from '@wordpress/i18n'; @@ -46,7 +46,11 @@ export const withEditBlockControls = createHigherOrderComponent( const newUserConfig = JSON.parse( JSON.stringify( currentConfig ) ); - set( newUserConfig, fullPath, getCSSVarFromStyleValue( newValue ) ); + set( + newUserConfig, + fullPath, + getCSSVarFromStyleValue( newValue ) + ); return newUserConfig; } ); }, @@ -61,30 +65,26 @@ export const withEditBlockControls = createHigherOrderComponent( - - -

- { __( - "When activated, all changes to this block's styles will be applied to all blocks of this type. Note that only typography, dimensions, color and border styles will be copied." - ) } -

-
+ { + setShouldPushToGlobalStyles( + ( state ) => ! state + ); + } } + label={ + shouldPushToGlobalStyles + ? __( 'Apply styles to all blocks' ) + : __( + 'Do not apply styles to all blocks' + ) + } + type="checkbox" + size="small" + help={ __( + "When activated, all changes to this block's styles will be applied to all blocks of this type. Note that only typography, dimensions, color and border styles will be copied." + ) } + />
) } diff --git a/packages/style-engine/README.md b/packages/style-engine/README.md index 999fab2aa835e9..a4ac2391706c64 100644 --- a/packages/style-engine/README.md +++ b/packages/style-engine/README.md @@ -237,6 +237,18 @@ _Changelog_ `6.1.0` Introduced in WordPress core. +### getCSSVarFromStyleValue + +Returns a CSS var value from incoming style value following the pattern `var:description|context|slug`. + +_Parameters_ + +- _styleValue_ `string`: A raw style value. + +_Returns_ + +- `string`: string A CSS var value. + ## Glossary