From 64c69123ea57a3c342475c8a72d274d4cf9764a3 Mon Sep 17 00:00:00 2001 From: David Calhoun <438664+dcalhoun@users.noreply.github.com> Date: Thu, 19 Jan 2023 15:01:36 -0700 Subject: [PATCH 01/13] Mobile Release v1.87.2 (#47257) * Release script: Update react-native-editor version to 1.87.0 * Release script: Update with changes from 'npm run core preios' * Mobile - Update changelog * Release script: Update react-native-editor version to 1.87.1 * Release script: Update with changes from 'npm run core preios' * [RNMobile] Remove unnecessary negative margin around empty gallery block (#47086) This PR removes some unwanted negative margin space from empty gallery blocks on native. * [Mobile] - RichText - Parse CSS values and avoid setting undefined ones (#47080) * parseCssUnitToPx - Fix issue with decimals in math expressions * Mobile - RichText - Parse CSS values from line height values and avoid undefined or NaN values being sent to the native TextInput * Mobile - Update Changelog * Release script: Update react-native-editor version to 1.87.2 * Release script: Update with changes from 'npm run core preios' * Add boolean contentStyle and clientId check to Column Edit InnerBlocks * Mobile - Column block - Move parentWidth to a const variable * docs: Update changelog * [Mobile] - Line-height and font-size regression fixes (#47284) * Revert "[Mobile] - RichText - Parse CSS values and avoid setting undefined ones (#47080)" This reverts commit 2d44f063833189b81e2208a7036e2a094a1f1f54. * parseCssUnitToPx - Fix issue with decimals in math expressions * Mobile - Avoid passing NaN line height values to Aztec. It also disables passing font size and line height values on Android for pre elements. * Mobile - Preformatted - Update snapshot to remove the fontSize value as it will be set by Aztec for Android * Update react-native-editor changelog Co-authored-by: Gerardo Co-authored-by: Siobhan Bamber Co-authored-by: Derek Blank Co-authored-by: Carlos Garcia --- packages/block-library/src/column/edit.native.js | 7 ++++++- packages/react-native-aztec/package.json | 2 +- packages/react-native-bridge/package.json | 2 +- packages/react-native-editor/CHANGELOG.md | 4 ++++ packages/react-native-editor/ios/Gemfile.lock | 4 +--- packages/react-native-editor/ios/Podfile.lock | 8 ++++---- packages/react-native-editor/package.json | 2 +- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/block-library/src/column/edit.native.js b/packages/block-library/src/column/edit.native.js index b3fcb3f84d2cd..e5ad6c7827d23 100644 --- a/packages/block-library/src/column/edit.native.js +++ b/packages/block-library/src/column/edit.native.js @@ -152,6 +152,11 @@ function ColumnEdit( { ); } + const parentWidth = + contentStyle && + contentStyle[ clientId ] && + contentStyle[ clientId ].width; + return ( <> { isSelected && ( @@ -211,7 +216,7 @@ function ColumnEdit( { > diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json index 35830b49a316b..8254581bb4652 100644 --- a/packages/react-native-aztec/package.json +++ b/packages/react-native-aztec/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-aztec", - "version": "1.87.1", + "version": "1.87.2", "description": "Aztec view for react-native.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-bridge/package.json b/packages/react-native-bridge/package.json index d3cb662438b43..07df9faa5ab77 100644 --- a/packages/react-native-bridge/package.json +++ b/packages/react-native-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-bridge", - "version": "1.87.1", + "version": "1.87.2", "description": "Native bridge library used to integrate the block editor into a native App.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 05075dd17058c..80ef6c4dd39bb 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,6 +11,10 @@ For each user feature we should also add a importance categorization label to i ## Unreleased +## 1.87.2 +- [*] Add boolean contentStyle and clientId check to Column Edit InnerBlocks [#47234] +- [*] Line-height and font-size regression fixes [#47284] + ## 1.87.1 - [**] Gallery block: Address styling regression, in which negative margin was added [#47086] - [*] RichText - Parse CSS values and avoid setting undefined ones [#47080] diff --git a/packages/react-native-editor/ios/Gemfile.lock b/packages/react-native-editor/ios/Gemfile.lock index 842ff6acd396f..f03dae6867378 100644 --- a/packages/react-native-editor/ios/Gemfile.lock +++ b/packages/react-native-editor/ios/Gemfile.lock @@ -89,12 +89,10 @@ GEM PLATFORMS arm64-darwin-21 + arm64-darwin-22 DEPENDENCIES cocoapods (~> 1.11, >= 1.11.2) -RUBY VERSION - ruby 2.7.5p203 - BUNDLED WITH 2.3.18 diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index e2cae7676b159..ffc274d5dfee1 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -13,7 +13,7 @@ PODS: - ReactCommon/turbomodule/core (= 0.69.4) - fmt (6.2.1) - glog (0.3.5) - - Gutenberg (1.87.1): + - Gutenberg (1.87.2): - React-Core (= 0.69.4) - React-CoreModules (= 0.69.4) - React-RCTImage (= 0.69.4) @@ -362,7 +362,7 @@ PODS: - React-Core - RNSVG (9.13.6): - React-Core - - RNTAztecView (1.87.1): + - RNTAztecView (1.87.2): - React-Core - WordPress-Aztec-iOS (~> 1.19.8) - SDWebImage (5.11.1): @@ -545,7 +545,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: 2ff441cbe6e58c1778d8a5cf3311831a6a8c0809 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a - Gutenberg: b219cca657de7ff779bd54599f2a6a8e6913a451 + Gutenberg: 757eefbcd013a07e4816776bb65af1b1dc6098dc libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a RCTRequired: bd9d2ab0fda10171fcbcf9ba61a7df4dc15a28f4 @@ -588,7 +588,7 @@ SPEC CHECKSUMS: RNReanimated: 8b189a09da0345d84b33b8cde57a57f8ed847352 RNScreens: 953633729a42e23ad0c93574d676b361e3335e8b RNSVG: 36a7359c428dcb7c6bce1cc546fbfebe069809b0 - RNTAztecView: 9eae3a2810d6ad86d210d78c8069e5a5cf94761d + RNTAztecView: 37b773533f15466aac927b4c0f787edd933c2f87 SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d WordPress-Aztec-iOS: 7d11d598f14c82c727c08b56bd35fbeb7dafb504 diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index 985104b707be9..5a85e8d4f0a9c 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-editor", - "version": "1.87.1", + "version": "1.87.2", "description": "Mobile WordPress gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later", From 77c6c5dd2b758ed0fec0e2a69e04bf5fd9f6674c Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 20 Jan 2023 14:56:12 +1100 Subject: [PATCH 02/13] Move Global Styles APIs to @wordpress/block-editor (#47098) * Move things around * lock() the Global Styles APIs * Update package-lock.json * Move tests to block-editor --- package-lock.json | 2 + packages/block-editor/README.md | 4 + packages/block-editor/package.json | 1 + .../src/components/global-styles/README.md | 78 ++++ .../src/components/global-styles/context.js | 0 .../src/components/global-styles/hooks.js | 157 ++++++++ .../src/components/global-styles/index.js | 7 + .../global-styles/test/typography-utils.js | 0 .../test/use-global-styles-output.js | 0 .../components/global-styles/test/utils.js | 0 .../global-styles/typography-utils.js | 4 +- .../global-styles/use-global-styles-output.js | 12 +- .../src/components/global-styles/utils.js | 366 +++++++++++++++++ packages/block-editor/src/experiments.js | 23 ++ packages/block-editor/src/index.js | 1 + packages/edit-site/package.json | 1 + .../global-styles-renderer/index.js | 7 +- .../src/components/global-styles/README.md | 76 +--- .../components/global-styles/border-panel.js | 32 +- .../global-styles/color-palette-panel.js | 17 +- .../components/global-styles/custom-css.js | 9 +- .../global-styles/dimensions-panel.js | 42 +- .../global-styles/global-styles-provider.js | 5 +- .../global-styles/gradients-palette-panel.js | 28 +- .../src/components/global-styles/hooks.js | 181 ++------- .../src/components/global-styles/index.js | 2 - .../src/components/global-styles/palette.js | 14 +- .../src/components/global-styles/preview.js | 32 +- .../global-styles/screen-background-color.js | 31 +- .../global-styles/screen-button-color.js | 32 +- .../components/global-styles/screen-colors.js | 24 +- .../global-styles/screen-heading-color.js | 37 +- .../global-styles/screen-link-color.js | 34 +- .../global-styles/screen-style-variations.js | 9 +- .../global-styles/screen-text-color.js | 28 +- .../global-styles/screen-typography.js | 31 +- .../global-styles/typography-panel.js | 54 +-- .../global-styles/typography-preview.js | 37 +- .../src/components/global-styles/utils.js | 367 ------------------ .../global-styles-sidebar.js | 6 +- .../src/components/style-book/index.js | 13 +- packages/edit-site/src/experiments.js | 10 + .../push-changes-to-global-styles/index.js | 68 +++- packages/experiments/src/implementation.js | 1 + 44 files changed, 1068 insertions(+), 815 deletions(-) create mode 100644 packages/block-editor/src/components/global-styles/README.md rename packages/{edit-site => block-editor}/src/components/global-styles/context.js (100%) create mode 100644 packages/block-editor/src/components/global-styles/hooks.js create mode 100644 packages/block-editor/src/components/global-styles/index.js rename packages/{edit-site => block-editor}/src/components/global-styles/test/typography-utils.js (100%) rename packages/{edit-site => block-editor}/src/components/global-styles/test/use-global-styles-output.js (100%) rename packages/{edit-site => block-editor}/src/components/global-styles/test/utils.js (100%) rename packages/{edit-site => block-editor}/src/components/global-styles/typography-utils.js (96%) rename packages/{edit-site => block-editor}/src/components/global-styles/use-global-styles-output.js (99%) create mode 100644 packages/block-editor/src/components/global-styles/utils.js create mode 100644 packages/block-editor/src/experiments.js create mode 100644 packages/edit-site/src/experiments.js diff --git a/package-lock.json b/package-lock.json index e5095432624b7..c196eed47005e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17416,6 +17416,7 @@ "@wordpress/dom": "file:packages/dom", "@wordpress/element": "file:packages/element", "@wordpress/escape-html": "file:packages/escape-html", + "@wordpress/experiments": "file:packages/experiments", "@wordpress/hooks": "file:packages/hooks", "@wordpress/html-entities": "file:packages/html-entities", "@wordpress/i18n": "file:packages/i18n", @@ -17886,6 +17887,7 @@ "@wordpress/deprecated": "file:packages/deprecated", "@wordpress/editor": "file:packages/editor", "@wordpress/element": "file:packages/element", + "@wordpress/experiments": "file:packages/experiments", "@wordpress/hooks": "file:packages/hooks", "@wordpress/html-entities": "file:packages/html-entities", "@wordpress/i18n": "file:packages/i18n", diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 5a861eaa1acad..7ccac465a336a 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -348,6 +348,10 @@ _Returns_ Undocumented declaration. +### experiments + +Experimental @wordpress/block-editor APIs. + ### FontSizePicker _Related_ diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index d33c015ad77dd..00e570a3fefc4 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -45,6 +45,7 @@ "@wordpress/dom": "file:../dom", "@wordpress/element": "file:../element", "@wordpress/escape-html": "file:../escape-html", + "@wordpress/experiments": "file:../experiments", "@wordpress/hooks": "file:../hooks", "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", diff --git a/packages/block-editor/src/components/global-styles/README.md b/packages/block-editor/src/components/global-styles/README.md new file mode 100644 index 0000000000000..dc4d52eaff4d0 --- /dev/null +++ b/packages/block-editor/src/components/global-styles/README.md @@ -0,0 +1,78 @@ +# Global Styles + +This folder contains all the necessary APIs to manipulate the global styles data. It can be potentially extracted to its own package. + +# Available public APIs + +## useGlobalStylesReset + +A React hook used to retrieve whether the Global Styles have been edited and a callback to reset to the default theme values. + +```js +import { useGlobalStylesReset } from '@wordpress/block-editor'; + +function MyComponent() { + const [ canReset, reset ] = useGlobalStylesReset(); + + return canReset + ? + : null; +} +``` + +## useGlobalStylesOutput + +A React hook used to retrieve the styles array and settings to provide for block editor instances based on the current global styles. + +```js +import { useGlobalStylesOutput, BlockEditorProvider, BlockList } from '@wordpress/block-editor'; + +function MyComponent() { + const [ styles, settings ] = useGlobalStylesOutput(); + + return + + +} +``` + +## useGlobalStyle + +A react hook used to retrieve the style applied to a given context. + +```js +import { useGlobalStyle } from '@wordpress/block-editor'; + +function MyComponent() { + // Text color for the site root. + const [ color, setColor ] = useGlobalStyle( 'color.text' ); + + // The user modified color for the core paragraph block. + const [ pColor, setPColor ] = useGlobalStyle( 'color.text', 'core/paragraph', 'user' ); + + return "Something"; +} +``` + +## useGlobalSetting + +A react hook used to retrieve the setting applied to a given context. + +```js +import { useGlobalSetting } from '@wordpress/block-editor'; + +function MyComponent() { + // The default color palette. + const [ colorPalette, setColorPalette ] = useGlobalSetting( 'color.palette' ); + + // The base (theme + core) color palette for the paragraph block, + // ignoring user provided palette. + // If the palette is not defined for the paragraph block, the root one is returned. + const [ pColor, setPColor ] = useGlobalSetting( 'color.palette', 'core/paragraph', 'base' ); + + return "Something"; +} +``` diff --git a/packages/edit-site/src/components/global-styles/context.js b/packages/block-editor/src/components/global-styles/context.js similarity index 100% rename from packages/edit-site/src/components/global-styles/context.js rename to packages/block-editor/src/components/global-styles/context.js diff --git a/packages/block-editor/src/components/global-styles/hooks.js b/packages/block-editor/src/components/global-styles/hooks.js new file mode 100644 index 0000000000000..776b83b71aa4d --- /dev/null +++ b/packages/block-editor/src/components/global-styles/hooks.js @@ -0,0 +1,157 @@ +/** + * External dependencies + */ +import fastDeepEqual from 'fast-deep-equal/es6'; +import { get, set } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useContext, useCallback } from '@wordpress/element'; +import { __EXPERIMENTAL_PATHS_WITH_MERGE as PATHS_WITH_MERGE } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import { getValueFromVariable, getPresetVariableFromValue } from './utils'; +import { GlobalStylesContext } from './context'; + +const EMPTY_CONFIG = { settings: {}, styles: {} }; + +export const useGlobalStylesReset = () => { + const { user: config, setUserConfig } = useContext( GlobalStylesContext ); + const canReset = !! config && ! fastDeepEqual( config, EMPTY_CONFIG ); + return [ + canReset, + useCallback( + () => setUserConfig( () => EMPTY_CONFIG ), + [ setUserConfig ] + ), + ]; +}; + +export function useGlobalSetting( path, blockName, source = 'all' ) { + const { + merged: mergedConfig, + base: baseConfig, + user: userConfig, + setUserConfig, + } = useContext( GlobalStylesContext ); + + const fullPath = ! blockName + ? `settings.${ path }` + : `settings.blocks.${ blockName }.${ path }`; + + const setSetting = ( newValue ) => { + setUserConfig( ( currentConfig ) => { + // Deep clone `currentConfig` to avoid mutating it later. + const newUserConfig = JSON.parse( JSON.stringify( currentConfig ) ); + const pathToSet = PATHS_WITH_MERGE[ path ] + ? fullPath + '.custom' + : fullPath; + set( newUserConfig, pathToSet, newValue ); + + return newUserConfig; + } ); + }; + + const getSettingValueForContext = ( name ) => { + const currentPath = ! name + ? `settings.${ path }` + : `settings.blocks.${ name }.${ path }`; + + const getSettingValue = ( configToUse ) => { + const result = get( configToUse, currentPath ); + if ( PATHS_WITH_MERGE[ path ] ) { + return result?.custom ?? result?.theme ?? result?.default; + } + return result; + }; + + let result; + switch ( source ) { + case 'all': + result = getSettingValue( mergedConfig ); + break; + case 'user': + result = getSettingValue( userConfig ); + break; + case 'base': + result = getSettingValue( baseConfig ); + break; + default: + throw 'Unsupported source'; + } + + return result; + }; + + // Unlike styles settings get inherited from top level settings. + const resultWithFallback = + getSettingValueForContext( blockName ) ?? getSettingValueForContext(); + + return [ resultWithFallback, setSetting ]; +} + +export function useGlobalStyle( path, blockName, source = 'all' ) { + const { + merged: mergedConfig, + base: baseConfig, + user: userConfig, + setUserConfig, + } = useContext( GlobalStylesContext ); + const finalPath = ! blockName + ? `styles.${ path }` + : `styles.blocks.${ blockName }.${ path }`; + + const setStyle = ( newValue ) => { + setUserConfig( ( currentConfig ) => { + // Deep clone `currentConfig` to avoid mutating it later. + const newUserConfig = JSON.parse( JSON.stringify( currentConfig ) ); + set( + newUserConfig, + finalPath, + getPresetVariableFromValue( + mergedConfig.settings, + blockName, + path, + newValue + ) + ); + return newUserConfig; + } ); + }; + + let result; + switch ( source ) { + case 'all': + result = getValueFromVariable( + mergedConfig, + blockName, + // The stlyes.css path is allowed to be empty, so don't revert to base if undefined. + finalPath === 'styles.css' + ? get( userConfig, finalPath ) + : get( userConfig, finalPath ) ?? + get( baseConfig, finalPath ) + ); + break; + case 'user': + result = getValueFromVariable( + mergedConfig, + blockName, + get( userConfig, finalPath ) + ); + break; + case 'base': + result = getValueFromVariable( + baseConfig, + blockName, + get( baseConfig, finalPath ) + ); + break; + default: + throw 'Unsupported source'; + } + + return [ result, setStyle ]; +} diff --git a/packages/block-editor/src/components/global-styles/index.js b/packages/block-editor/src/components/global-styles/index.js new file mode 100644 index 0000000000000..cd0c8cdf487c5 --- /dev/null +++ b/packages/block-editor/src/components/global-styles/index.js @@ -0,0 +1,7 @@ +export { + useGlobalStylesReset, + useGlobalSetting, + useGlobalStyle, +} from './hooks'; +export { useGlobalStylesOutput } from './use-global-styles-output'; +export { GlobalStylesContext } from './context'; diff --git a/packages/edit-site/src/components/global-styles/test/typography-utils.js b/packages/block-editor/src/components/global-styles/test/typography-utils.js similarity index 100% rename from packages/edit-site/src/components/global-styles/test/typography-utils.js rename to packages/block-editor/src/components/global-styles/test/typography-utils.js diff --git a/packages/edit-site/src/components/global-styles/test/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/test/use-global-styles-output.js similarity index 100% rename from packages/edit-site/src/components/global-styles/test/use-global-styles-output.js rename to packages/block-editor/src/components/global-styles/test/use-global-styles-output.js diff --git a/packages/edit-site/src/components/global-styles/test/utils.js b/packages/block-editor/src/components/global-styles/test/utils.js similarity index 100% rename from packages/edit-site/src/components/global-styles/test/utils.js rename to packages/block-editor/src/components/global-styles/test/utils.js diff --git a/packages/edit-site/src/components/global-styles/typography-utils.js b/packages/block-editor/src/components/global-styles/typography-utils.js similarity index 96% rename from packages/edit-site/src/components/global-styles/typography-utils.js rename to packages/block-editor/src/components/global-styles/typography-utils.js index 5720fdeb6ce91..bfbc2569211c3 100644 --- a/packages/edit-site/src/components/global-styles/typography-utils.js +++ b/packages/block-editor/src/components/global-styles/typography-utils.js @@ -5,9 +5,9 @@ */ /** - * WordPress dependencies + * Internal dependencies */ -import { getComputedFluidTypographyValue } from '@wordpress/block-editor'; +import { getComputedFluidTypographyValue } from '../font-sizes/fluid-utils'; /** * @typedef {Object} FluidPreset diff --git a/packages/edit-site/src/components/global-styles/use-global-styles-output.js b/packages/block-editor/src/components/global-styles/use-global-styles-output.js similarity index 99% rename from packages/edit-site/src/components/global-styles/use-global-styles-output.js rename to packages/block-editor/src/components/global-styles/use-global-styles-output.js index 080148b926559..cc7dc5c6669fd 100644 --- a/packages/edit-site/src/components/global-styles/use-global-styles-output.js +++ b/packages/block-editor/src/components/global-styles/use-global-styles-output.js @@ -15,11 +15,6 @@ import { import { useSelect } from '@wordpress/data'; import { useContext, useMemo } from '@wordpress/element'; import { getCSSRules } from '@wordpress/style-engine'; -import { - __unstablePresetDuotoneFilter as PresetDuotoneFilter, - __experimentalGetGapCSSValue as getGapCSSValue, - store as blockEditorStore, -} from '@wordpress/block-editor'; /** * Internal dependencies @@ -27,7 +22,10 @@ import { import { PRESET_METADATA, ROOT_BLOCK_SELECTOR, scopeSelector } from './utils'; import { getTypographyFontSizeValue } from './typography-utils'; import { GlobalStylesContext } from './context'; -import { useSetting } from './hooks'; +import { useGlobalSetting } from './hooks'; +import { PresetDuotoneFilter } from '../duotone/components'; +import { getGapCSSValue } from '../../hooks/gap'; +import { store as blockEditorStore } from '../../store'; // List of block support features that can have their related styles // generated under their own feature level selector rather than the block's. @@ -999,7 +997,7 @@ function updateConfigWithSeparator( config ) { export function useGlobalStylesOutput() { let { merged: mergedConfig } = useContext( GlobalStylesContext ); - const [ blockGap ] = useSetting( 'spacing.blockGap' ); + const [ blockGap ] = useGlobalSetting( '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. const disableLayoutStyles = useSelect( ( select ) => { diff --git a/packages/block-editor/src/components/global-styles/utils.js b/packages/block-editor/src/components/global-styles/utils.js new file mode 100644 index 0000000000000..e3c3bf47d4a5a --- /dev/null +++ b/packages/block-editor/src/components/global-styles/utils.js @@ -0,0 +1,366 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * Internal dependencies + */ +import { getTypographyFontSizeValue } from './typography-utils'; + +/* Supporting data. */ +export const ROOT_BLOCK_NAME = 'root'; +export const ROOT_BLOCK_SELECTOR = 'body'; +export const ROOT_BLOCK_SUPPORTS = [ + 'background', + 'backgroundColor', + 'color', + 'linkColor', + 'buttonColor', + 'fontFamily', + 'fontSize', + 'fontStyle', + 'fontWeight', + 'lineHeight', + 'textDecoration', + 'textTransform', + 'padding', +]; + +export const PRESET_METADATA = [ + { + path: [ 'color', 'palette' ], + valueKey: 'color', + cssVarInfix: 'color', + classes: [ + { classSuffix: 'color', propertyName: 'color' }, + { + classSuffix: 'background-color', + propertyName: 'background-color', + }, + { + classSuffix: 'border-color', + propertyName: 'border-color', + }, + ], + }, + { + path: [ 'color', 'gradients' ], + valueKey: 'gradient', + cssVarInfix: 'gradient', + classes: [ + { + classSuffix: 'gradient-background', + propertyName: 'background', + }, + ], + }, + { + path: [ 'color', 'duotone' ], + cssVarInfix: 'duotone', + valueFunc: ( { slug } ) => `url( '#wp-duotone-${ slug }' )`, + classes: [], + }, + { + path: [ 'typography', 'fontSizes' ], + valueFunc: ( preset, { typography: typographySettings } ) => + getTypographyFontSizeValue( preset, typographySettings ), + valueKey: 'size', + cssVarInfix: 'font-size', + classes: [ { classSuffix: 'font-size', propertyName: 'font-size' } ], + }, + { + path: [ 'typography', 'fontFamilies' ], + valueKey: 'fontFamily', + cssVarInfix: 'font-family', + classes: [ + { classSuffix: 'font-family', propertyName: 'font-family' }, + ], + }, + { + path: [ 'spacing', 'spacingSizes' ], + valueKey: 'size', + cssVarInfix: 'spacing', + valueFunc: ( { size } ) => size, + classes: [], + }, +]; + +export const STYLE_PATH_TO_CSS_VAR_INFIX = { + 'color.background': 'color', + 'color.text': 'color', + 'elements.link.color.text': 'color', + 'elements.link.:hover.color.text': 'color', + 'elements.link.typography.fontFamily': 'font-family', + 'elements.link.typography.fontSize': 'font-size', + 'elements.button.color.text': 'color', + 'elements.button.color.background': 'color', + 'elements.button.typography.fontFamily': 'font-family', + 'elements.button.typography.fontSize': 'font-size', + 'elements.heading.color': 'color', + 'elements.heading.color.background': 'color', + 'elements.heading.typography.fontFamily': 'font-family', + 'elements.heading.gradient': 'gradient', + 'elements.heading.color.gradient': 'gradient', + 'elements.h1.color': 'color', + 'elements.h1.color.background': 'color', + 'elements.h1.typography.fontFamily': 'font-family', + 'elements.h1.color.gradient': 'gradient', + 'elements.h2.color': 'color', + 'elements.h2.color.background': 'color', + 'elements.h2.typography.fontFamily': 'font-family', + 'elements.h2.color.gradient': 'gradient', + 'elements.h3.color': 'color', + 'elements.h3.color.background': 'color', + 'elements.h3.typography.fontFamily': 'font-family', + 'elements.h3.color.gradient': 'gradient', + 'elements.h4.color': 'color', + 'elements.h4.color.background': 'color', + 'elements.h4.typography.fontFamily': 'font-family', + 'elements.h4.color.gradient': 'gradient', + 'elements.h5.color': 'color', + 'elements.h5.color.background': 'color', + 'elements.h5.typography.fontFamily': 'font-family', + 'elements.h5.color.gradient': 'gradient', + 'elements.h6.color': 'color', + 'elements.h6.color.background': 'color', + 'elements.h6.typography.fontFamily': 'font-family', + 'elements.h6.color.gradient': 'gradient', + 'color.gradient': 'gradient', + 'typography.fontSize': 'font-size', + 'typography.fontFamily': 'font-family', +}; + +// A static list of block attributes that store global style preset slugs. +export const STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = { + 'color.background': 'backgroundColor', + 'color.text': 'textColor', + 'color.gradient': 'gradient', + 'typography.fontSize': 'fontSize', + 'typography.fontFamily': 'fontFamily', +}; + +function findInPresetsBy( + features, + blockName, + presetPath, + presetProperty, + presetValueValue +) { + // Block presets take priority above root level presets. + const orderedPresetsByOrigin = [ + get( features, [ 'blocks', blockName, ...presetPath ] ), + get( features, presetPath ), + ]; + + for ( const presetByOrigin of orderedPresetsByOrigin ) { + if ( presetByOrigin ) { + // Preset origins ordered by priority. + const origins = [ 'custom', 'theme', 'default' ]; + for ( const origin of origins ) { + const presets = presetByOrigin[ origin ]; + if ( presets ) { + const presetObject = presets.find( + ( preset ) => + preset[ presetProperty ] === presetValueValue + ); + if ( presetObject ) { + if ( presetProperty === 'slug' ) { + return presetObject; + } + // If there is a highest priority preset with the same slug but different value the preset we found was overwritten and should be ignored. + const highestPresetObjectWithSameSlug = findInPresetsBy( + features, + blockName, + presetPath, + 'slug', + presetObject.slug + ); + if ( + highestPresetObjectWithSameSlug[ + presetProperty + ] === presetObject[ presetProperty ] + ) { + return presetObject; + } + return undefined; + } + } + } + } + } +} + +export function getPresetVariableFromValue( + features, + blockName, + variableStylePath, + presetPropertyValue +) { + if ( ! presetPropertyValue ) { + return presetPropertyValue; + } + + const cssVarInfix = STYLE_PATH_TO_CSS_VAR_INFIX[ variableStylePath ]; + + const metadata = PRESET_METADATA.find( + ( data ) => data.cssVarInfix === cssVarInfix + ); + + if ( ! metadata ) { + // The property doesn't have preset data + // so the value should be returned as it is. + return presetPropertyValue; + } + const { valueKey, path } = metadata; + + const presetObject = findInPresetsBy( + features, + blockName, + path, + valueKey, + presetPropertyValue + ); + + if ( ! presetObject ) { + // Value wasn't found in the presets, + // so it must be a custom value. + return presetPropertyValue; + } + + return `var:preset|${ cssVarInfix }|${ presetObject.slug }`; +} + +function getValueFromPresetVariable( + features, + blockName, + variable, + [ presetType, slug ] +) { + const metadata = PRESET_METADATA.find( + ( data ) => data.cssVarInfix === presetType + ); + if ( ! metadata ) { + return variable; + } + + const presetObject = findInPresetsBy( + features.settings, + blockName, + metadata.path, + 'slug', + slug + ); + + if ( presetObject ) { + const { valueKey } = metadata; + const result = presetObject[ valueKey ]; + return getValueFromVariable( features, blockName, result ); + } + + return variable; +} + +function getValueFromCustomVariable( features, blockName, variable, path ) { + const result = + get( features.settings, [ 'blocks', blockName, 'custom', ...path ] ) ?? + get( features.settings, [ 'custom', ...path ] ); + if ( ! result ) { + return variable; + } + // A variable may reference another variable so we need recursion until we find the value. + return getValueFromVariable( features, blockName, result ); +} + +/** + * Attempts to fetch the value of a theme.json CSS variable. + * + * @param {Object} features GlobalStylesContext config, e.g., user, base or merged. Represents the theme.json tree. + * @param {string} blockName The name of a block as represented in the styles property. E.g., 'root' for root-level, and 'core/${blockName}' for blocks. + * @param {string|*} variable An incoming style value. A CSS var value is expected, but it could be any value. + * @return {string|*|{ref}} The value of the CSS var, if found. If not found, the passed variable argument. + */ +export function getValueFromVariable( features, blockName, variable ) { + if ( ! variable || typeof variable !== 'string' ) { + if ( variable?.ref && typeof variable?.ref === 'string' ) { + const refPath = variable.ref.split( '.' ); + variable = get( features, refPath ); + // Presence of another ref indicates a reference to another dynamic value. + // Pointing to another dynamic value is not supported. + if ( ! variable || !! variable?.ref ) { + return variable; + } + } else { + return variable; + } + } + const USER_VALUE_PREFIX = 'var:'; + const THEME_VALUE_PREFIX = 'var(--wp--'; + const THEME_VALUE_SUFFIX = ')'; + + let parsedVar; + + if ( variable.startsWith( USER_VALUE_PREFIX ) ) { + parsedVar = variable.slice( USER_VALUE_PREFIX.length ).split( '|' ); + } else if ( + variable.startsWith( THEME_VALUE_PREFIX ) && + variable.endsWith( THEME_VALUE_SUFFIX ) + ) { + parsedVar = variable + .slice( THEME_VALUE_PREFIX.length, -THEME_VALUE_SUFFIX.length ) + .split( '--' ); + } else { + // We don't know how to parse the value: either is raw of uses complex CSS such as `calc(1px * var(--wp--variable) )` + return variable; + } + + const [ type, ...path ] = parsedVar; + if ( type === 'preset' ) { + return getValueFromPresetVariable( + features, + blockName, + variable, + path + ); + } + if ( type === 'custom' ) { + return getValueFromCustomVariable( + features, + blockName, + variable, + path + ); + } + return variable; +} + +/** + * Function that scopes a selector with another one. This works a bit like + * SCSS nesting except the `&` operator isn't supported. + * + * @example + * ```js + * const scope = '.a, .b .c'; + * const selector = '> .x, .y'; + * const merged = scopeSelector( scope, selector ); + * // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y' + * ``` + * + * @param {string} scope Selector to scope to. + * @param {string} selector Original selector. + * + * @return {string} Scoped selector. + */ +export function scopeSelector( scope, selector ) { + const scopes = scope.split( ',' ); + const selectors = selector.split( ',' ); + + const selectorsScoped = []; + scopes.forEach( ( outer ) => { + selectors.forEach( ( inner ) => { + selectorsScoped.push( `${ outer.trim() } ${ inner.trim() }` ); + } ); + } ); + + return selectorsScoped.join( ', ' ); +} diff --git a/packages/block-editor/src/experiments.js b/packages/block-editor/src/experiments.js new file mode 100644 index 0000000000000..b217e14ec273b --- /dev/null +++ b/packages/block-editor/src/experiments.js @@ -0,0 +1,23 @@ +/** + * WordPress dependencies + */ +import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments'; + +/** + * Internal dependencies + */ +import * as globalStyles from './components/global-styles'; + +export const { lock, unlock } = + __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.', + '@wordpress/block-editor' + ); + +/** + * Experimental @wordpress/block-editor APIs. + */ +export const experiments = {}; +lock( experiments, { + ...globalStyles, +} ); diff --git a/packages/block-editor/src/index.js b/packages/block-editor/src/index.js index 1c81c910b21e1..d883aa455bc8f 100644 --- a/packages/block-editor/src/index.js +++ b/packages/block-editor/src/index.js @@ -20,3 +20,4 @@ export * from './elements'; export * from './utils'; export { storeConfig, store } from './store'; export { SETTINGS_DEFAULTS } from './store/defaults'; +export { experiments } from './experiments'; diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index f3a8e8d72edd4..dc1ba91a20f14 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -39,6 +39,7 @@ "@wordpress/deprecated": "file:../deprecated", "@wordpress/editor": "file:../editor", "@wordpress/element": "file:../element", + "@wordpress/experiments": "file:../experiments", "@wordpress/hooks": "file:../hooks", "@wordpress/html-entities": "file:../html-entities", "@wordpress/i18n": "file:../i18n", diff --git a/packages/edit-site/src/components/global-styles-renderer/index.js b/packages/edit-site/src/components/global-styles-renderer/index.js index 6dc3bbd9c4a97..5cc592131c6b8 100644 --- a/packages/edit-site/src/components/global-styles-renderer/index.js +++ b/packages/edit-site/src/components/global-styles-renderer/index.js @@ -3,16 +3,15 @@ */ import { useEffect } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ import { store as editSiteStore } from '../../store'; +import { unlock } from '../../experiments'; -/** - * Internal dependencies - */ -import { useGlobalStylesOutput } from '../global-styles/use-global-styles-output'; +const { useGlobalStylesOutput } = unlock( blockEditorExperiments ); function useGlobalStylesRenderer() { const [ styles, settings, svgFilters ] = useGlobalStylesOutput(); diff --git a/packages/edit-site/src/components/global-styles/README.md b/packages/edit-site/src/components/global-styles/README.md index ac728f3eb8bf5..9077b9e468d38 100644 --- a/packages/edit-site/src/components/global-styles/README.md +++ b/packages/edit-site/src/components/global-styles/README.md @@ -1,6 +1,6 @@ # Global Styles -This folder contains all the necessary APIs to render the global styles UI and to manipulate the global styles data. It can be potentially extracted to its own package. +This folder contains the global styles UI. # Available public APIs @@ -15,77 +15,3 @@ function MyComponent() { return ; } ``` - -## useGlobalStylesReset - -A React hook used to retrieve whether the Global Styles have been edited and a callback to reset to the default theme values. - -```js -import { useGlobalStylesReset } from './global-styles'; - -function MyComponent() { - const [ canReset, reset ] = useGlobalStylesReset(); - - return canReset - ? - : null; -} -``` - -## useGlobalStylesOutput - -A React hook used to retrieve the styles array and settings to provide for block editor instances based on the current global styles. - -```js -import { useGlobalStylesOutput } from './global-styles'; -import { BlockEditorProvider, BlockList } from '@wordpress/block-editor'; - -function MyComponent() { - const [ styles, settings ] = useGlobalStylesOutput(); - - return - - -} -``` - -## useStyle - -A react hook used to retrieve the style applied to a given context. - -```js -import { useStyle } from './global-styles'; - -function MyComponent() { - // Text color for the site root. - const [ color, setColor ] = useStyle( 'color.text' ); - - // The user modified color for the core paragraph block. - const [ pColor, setPColor ] = useStyle( 'color.text', 'core/paragraph', 'user' ); - - return "Something"; -} -``` - -## useSetting - -A react hook used to retrieve the setting applied to a given context. - -```js -import { useSetting } from './global-styles'; - -function MyComponent() { - // The default color palette. - const [ colorPalette, setColorPalette ] = useSetting( 'color.palette' ); - - // The base (theme + core) color palette for the paragraph block, - // ignoring user provided palette. - // If the palette is not defined for the paragraph block, the root one is returned. - const [ pColor, setPColor ] = useSetting( 'color.palette', 'core/paragraph', 'base' ); - - return "Something"; -} -``` diff --git a/packages/edit-site/src/components/global-styles/border-panel.js b/packages/edit-site/src/components/global-styles/border-panel.js index 91d467dfb13fd..cc38d09b4c716 100644 --- a/packages/edit-site/src/components/global-styles/border-panel.js +++ b/packages/edit-site/src/components/global-styles/border-panel.js @@ -1,7 +1,10 @@ /** * WordPress dependencies */ -import { __experimentalBorderRadiusControl as BorderRadiusControl } from '@wordpress/block-editor'; +import { + __experimentalBorderRadiusControl as BorderRadiusControl, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; import { __experimentalBorderBoxControl as BorderBoxControl, __experimentalHasSplitBorders as hasSplitBorders, @@ -15,12 +18,10 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { - getSupportedGlobalStylesPanels, - useColorsPerOrigin, - useSetting, - useStyle, -} from './hooks'; +import { getSupportedGlobalStylesPanels, useColorsPerOrigin } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); export function useHasBorderPanel( name ) { const controls = [ @@ -36,7 +37,7 @@ export function useHasBorderPanel( name ) { function useHasBorderColorControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); return ( - useSetting( 'border.color', name )[ 0 ] && + useGlobalSetting( 'border.color', name )[ 0 ] && supports.includes( 'borderColor' ) ); } @@ -44,7 +45,7 @@ function useHasBorderColorControl( name ) { function useHasBorderRadiusControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); return ( - useSetting( 'border.radius', name )[ 0 ] && + useGlobalSetting( 'border.radius', name )[ 0 ] && supports.includes( 'borderRadius' ) ); } @@ -52,7 +53,7 @@ function useHasBorderRadiusControl( name ) { function useHasBorderStyleControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); return ( - useSetting( 'border.style', name )[ 0 ] && + useGlobalSetting( 'border.style', name )[ 0 ] && supports.includes( 'borderStyle' ) ); } @@ -60,7 +61,7 @@ function useHasBorderStyleControl( name ) { function useHasBorderWidthControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); return ( - useSetting( 'border.width', name )[ 0 ] && + useGlobalSetting( 'border.width', name )[ 0 ] && supports.includes( 'borderWidth' ) ); } @@ -97,12 +98,15 @@ function applyAllFallbackStyles( border ) { export default function BorderPanel( { name, variationPath = '' } ) { // To better reflect if the user has customized a value we need to // ensure the style value being checked is from the `user` origin. - const [ userBorderStyles ] = useStyle( + const [ userBorderStyles ] = useGlobalStyle( `${ variationPath }border`, name, 'user' ); - const [ border, setBorder ] = useStyle( `${ variationPath }border`, name ); + const [ border, setBorder ] = useGlobalStyle( + `${ variationPath }border`, + name + ); const colors = useColorsPerOrigin( name ); const showBorderColor = useHasBorderColorControl( name ); @@ -111,7 +115,7 @@ export default function BorderPanel( { name, variationPath = '' } ) { // Border radius. const showBorderRadius = useHasBorderRadiusControl( name ); - const [ borderRadiusValues, setBorderRadius ] = useStyle( + const [ borderRadiusValues, setBorderRadius ] = useGlobalStyle( `${ variationPath }border.radius`, name ); diff --git a/packages/edit-site/src/components/global-styles/color-palette-panel.js b/packages/edit-site/src/components/global-styles/color-palette-panel.js index fd2c10568de21..f29adec52b5ce 100644 --- a/packages/edit-site/src/components/global-styles/color-palette-panel.js +++ b/packages/edit-site/src/components/global-styles/color-palette-panel.js @@ -6,37 +6,40 @@ import { __experimentalVStack as VStack, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { useSetting } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting } = unlock( blockEditorExperiments ); export default function ColorPalettePanel( { name } ) { - const [ themeColors, setThemeColors ] = useSetting( + const [ themeColors, setThemeColors ] = useGlobalSetting( 'color.palette.theme', name ); - const [ baseThemeColors ] = useSetting( + const [ baseThemeColors ] = useGlobalSetting( 'color.palette.theme', name, 'base' ); - const [ defaultColors, setDefaultColors ] = useSetting( + const [ defaultColors, setDefaultColors ] = useGlobalSetting( 'color.palette.default', name ); - const [ baseDefaultColors ] = useSetting( + const [ baseDefaultColors ] = useGlobalSetting( 'color.palette.default', name, 'base' ); - const [ customColors, setCustomColors ] = useSetting( + const [ customColors, setCustomColors ] = useGlobalSetting( 'color.palette.custom', name ); - const [ defaultPaletteEnabled ] = useSetting( + const [ defaultPaletteEnabled ] = useGlobalSetting( 'color.defaultPalette', name ); diff --git a/packages/edit-site/src/components/global-styles/custom-css.js b/packages/edit-site/src/components/global-styles/custom-css.js index 34ec3101410ba..944ec4afb8bb1 100644 --- a/packages/edit-site/src/components/global-styles/custom-css.js +++ b/packages/edit-site/src/components/global-styles/custom-css.js @@ -8,15 +8,18 @@ import { PanelBody, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { useStyle } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalStyle } = unlock( blockEditorExperiments ); function CustomCSSControl() { - const [ customCSS, setCustomCSS ] = useStyle( 'css' ); - const [ themeCSS ] = useStyle( 'css', null, 'base' ); + const [ customCSS, setCustomCSS ] = useGlobalStyle( 'css' ); + const [ themeCSS ] = useGlobalStyle( 'css', null, 'base' ); const ignoreThemeCustomCSS = '/* IgnoreThemeCustomCSS */'; // If there is custom css from theme.json show it in the edit box diff --git a/packages/edit-site/src/components/global-styles/dimensions-panel.js b/packages/edit-site/src/components/global-styles/dimensions-panel.js index 960ec0936cd42..772eb5f3e47f5 100644 --- a/packages/edit-site/src/components/global-styles/dimensions-panel.js +++ b/packages/edit-site/src/components/global-styles/dimensions-panel.js @@ -20,13 +20,17 @@ import { __experimentalUseCustomSides as useCustomSides, __experimentalHeightControl as HeightControl, __experimentalSpacingSizesControl as SpacingSizesControl, + experiments as blockEditorExperiments, } from '@wordpress/block-editor'; import { Icon, positionCenter, stretchWide } from '@wordpress/icons'; /** * Internal dependencies */ -import { getSupportedGlobalStylesPanels, useSetting, useStyle } from './hooks'; +import { getSupportedGlobalStylesPanels } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); const AXIAL_SIDES = [ 'horizontal', 'vertical' ]; @@ -50,48 +54,48 @@ export function useHasDimensionsPanel( name ) { function useHasContentSize( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ settings ] = useSetting( 'layout.contentSize', name ); + const [ settings ] = useGlobalSetting( 'layout.contentSize', name ); return settings && supports.includes( 'contentSize' ); } function useHasWideSize( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ settings ] = useSetting( 'layout.wideSize', name ); + const [ settings ] = useGlobalSetting( 'layout.wideSize', name ); return settings && supports.includes( 'wideSize' ); } function useHasPadding( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ settings ] = useSetting( 'spacing.padding', name ); + const [ settings ] = useGlobalSetting( 'spacing.padding', name ); return settings && supports.includes( 'padding' ); } function useHasMargin( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ settings ] = useSetting( 'spacing.margin', name ); + const [ settings ] = useGlobalSetting( 'spacing.margin', name ); return settings && supports.includes( 'margin' ); } function useHasGap( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ settings ] = useSetting( 'spacing.blockGap', name ); + const [ settings ] = useGlobalSetting( 'spacing.blockGap', name ); return settings && supports.includes( 'blockGap' ); } function useHasMinHeight( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ settings ] = useSetting( 'dimensions.minHeight', name ); + const [ settings ] = useGlobalSetting( 'dimensions.minHeight', name ); return settings && supports.includes( 'minHeight' ); } function useHasSpacingPresets() { - const [ settings ] = useSetting( 'spacing.spacingSizes' ); + const [ settings ] = useGlobalSetting( 'spacing.spacingSizes' ); return settings && settings.length > 0; } @@ -156,11 +160,11 @@ function splitGapValue( value ) { // Props for managing `layout.contentSize`. function useContentSizeProps( name ) { - const [ contentSizeValue, setContentSizeValue ] = useSetting( + const [ contentSizeValue, setContentSizeValue ] = useGlobalSetting( 'layout.contentSize', name ); - const [ userSetContentSizeValue ] = useSetting( + const [ userSetContentSizeValue ] = useGlobalSetting( 'layout.contentSize', name, 'user' @@ -177,11 +181,11 @@ function useContentSizeProps( name ) { // Props for managing `layout.wideSize`. function useWideSizeProps( name ) { - const [ wideSizeValue, setWideSizeValue ] = useSetting( + const [ wideSizeValue, setWideSizeValue ] = useGlobalSetting( 'layout.wideSize', name ); - const [ userSetWideSizeValue ] = useSetting( + const [ userSetWideSizeValue ] = useGlobalSetting( 'layout.wideSize', name, 'user' @@ -198,7 +202,7 @@ function useWideSizeProps( name ) { // Props for managing `spacing.padding`. function usePaddingProps( name, variationPath = '' ) { - const [ rawPadding, setRawPadding ] = useStyle( + const [ rawPadding, setRawPadding ] = useGlobalStyle( variationPath + 'spacing.padding', name ); @@ -213,7 +217,7 @@ function usePaddingProps( name, variationPath = '' ) { setRawPadding( padding ); }; const resetPaddingValue = () => setPaddingValues( {} ); - const [ userSetPaddingValue ] = useStyle( + const [ userSetPaddingValue ] = useGlobalStyle( variationPath + 'spacing.padding', name, 'user' @@ -233,7 +237,7 @@ function usePaddingProps( name, variationPath = '' ) { // Props for managing `spacing.margin`. function useMarginProps( name, variationPath = '' ) { - const [ rawMargin, setRawMargin ] = useStyle( + const [ rawMargin, setRawMargin ] = useGlobalStyle( variationPath + 'spacing.margin', name ); @@ -263,7 +267,7 @@ function useMarginProps( name, variationPath = '' ) { // Props for managing `spacing.blockGap`. function useBlockGapProps( name, variationPath = '' ) { - const [ gapValue, setGapValue ] = useStyle( + const [ gapValue, setGapValue ] = useGlobalStyle( variationPath + 'spacing.blockGap', name ); @@ -272,7 +276,7 @@ function useBlockGapProps( name, variationPath = '' ) { const isAxialGap = gapSides && gapSides.some( ( side ) => AXIAL_SIDES.includes( side ) ); const resetGapValue = () => setGapValue( undefined ); - const [ userSetGapValue ] = useStyle( + const [ userSetGapValue ] = useGlobalStyle( variationPath + 'spacing.blockGap', name, 'user' @@ -306,7 +310,7 @@ function useBlockGapProps( name, variationPath = '' ) { // Props for managing `dimensions.minHeight`. function useMinHeightProps( name, variationPath = '' ) { - const [ minHeightValue, setMinHeightValue ] = useStyle( + const [ minHeightValue, setMinHeightValue ] = useGlobalStyle( variationPath + 'dimensions.minHeight', name ); @@ -329,7 +333,7 @@ export default function DimensionsPanel( { name, variationPath = '' } ) { const showMinHeightControl = useHasMinHeight( name ); const showSpacingPresetsControl = useHasSpacingPresets(); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units', name )[ 0 ] || [ + availableUnits: useGlobalSetting( 'spacing.units', name )[ 0 ] || [ '%', 'px', 'em', diff --git a/packages/edit-site/src/components/global-styles/global-styles-provider.js b/packages/edit-site/src/components/global-styles/global-styles-provider.js index 68e190443d1f3..5570522383122 100644 --- a/packages/edit-site/src/components/global-styles/global-styles-provider.js +++ b/packages/edit-site/src/components/global-styles/global-styles-provider.js @@ -9,12 +9,15 @@ import { mergeWith, isEmpty, mapValues } from 'lodash'; import { useMemo, useCallback } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { GlobalStylesContext } from './context'; import CanvasSpinner from '../canvas-spinner'; +import { unlock } from '../../experiments'; + +const { GlobalStylesContext } = unlock( blockEditorExperiments ); function mergeTreesCustomizer( _, srcValue ) { // We only pass as arrays the presets, diff --git a/packages/edit-site/src/components/global-styles/gradients-palette-panel.js b/packages/edit-site/src/components/global-styles/gradients-palette-panel.js index 22cad685a3185..6febec95e1197 100644 --- a/packages/edit-site/src/components/global-styles/gradients-palette-panel.js +++ b/packages/edit-site/src/components/global-styles/gradients-palette-panel.js @@ -8,48 +8,54 @@ import { DuotonePicker, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { useSetting } from './hooks'; import Subtitle from './subtitle'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting } = unlock( blockEditorExperiments ); const noop = () => {}; export default function GradientPalettePanel( { name } ) { - const [ themeGradients, setThemeGradients ] = useSetting( + const [ themeGradients, setThemeGradients ] = useGlobalSetting( 'color.gradients.theme', name ); - const [ baseThemeGradients ] = useSetting( + const [ baseThemeGradients ] = useGlobalSetting( 'color.gradients.theme', name, 'base' ); - const [ defaultGradients, setDefaultGradients ] = useSetting( + const [ defaultGradients, setDefaultGradients ] = useGlobalSetting( 'color.gradients.default', name ); - const [ baseDefaultGradients ] = useSetting( + const [ baseDefaultGradients ] = useGlobalSetting( 'color.gradients.default', name, 'base' ); - const [ customGradients, setCustomGradients ] = useSetting( + const [ customGradients, setCustomGradients ] = useGlobalSetting( 'color.gradients.custom', name ); - const [ defaultPaletteEnabled ] = useSetting( + const [ defaultPaletteEnabled ] = useGlobalSetting( 'color.defaultGradients', name ); - const [ customDuotone ] = useSetting( 'color.duotone.custom' ) || []; - const [ defaultDuotone ] = useSetting( 'color.duotone.default' ) || []; - const [ themeDuotone ] = useSetting( 'color.duotone.theme' ) || []; - const [ defaultDuotoneEnabled ] = useSetting( 'color.defaultDuotone' ); + const [ customDuotone ] = useGlobalSetting( 'color.duotone.custom' ) || []; + const [ defaultDuotone ] = + useGlobalSetting( 'color.duotone.default' ) || []; + const [ themeDuotone ] = useGlobalSetting( 'color.duotone.theme' ) || []; + const [ defaultDuotoneEnabled ] = useGlobalSetting( + 'color.defaultDuotone' + ); const duotonePalette = [ ...( customDuotone || [] ), diff --git a/packages/edit-site/src/components/global-styles/hooks.js b/packages/edit-site/src/components/global-styles/hooks.js index c767f1a488cbf..0dadd18c7827d 100644 --- a/packages/edit-site/src/components/global-styles/hooks.js +++ b/packages/edit-site/src/components/global-styles/hooks.js @@ -1,8 +1,7 @@ /** * External dependencies */ -import fastDeepEqual from 'fast-deep-equal/es6'; -import { get, set } from 'lodash'; +import { get } from 'lodash'; import { colord, extend } from 'colord'; import a11yPlugin from 'colord/plugins/a11y'; @@ -10,162 +9,23 @@ import a11yPlugin from 'colord/plugins/a11y'; * WordPress dependencies */ import { _x } from '@wordpress/i18n'; -import { useContext, useCallback, useMemo } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { getBlockType, - __EXPERIMENTAL_PATHS_WITH_MERGE as PATHS_WITH_MERGE, __EXPERIMENTAL_STYLE_PROPERTY as STYLE_PROPERTY, } from '@wordpress/blocks'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { getValueFromVariable, getPresetVariableFromValue } from './utils'; -import { GlobalStylesContext } from './context'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting } = unlock( blockEditorExperiments ); // Enable colord's a11y plugin. extend( [ a11yPlugin ] ); -const EMPTY_CONFIG = { settings: {}, styles: {} }; - -export const useGlobalStylesReset = () => { - const { user: config, setUserConfig } = useContext( GlobalStylesContext ); - const canReset = !! config && ! fastDeepEqual( config, EMPTY_CONFIG ); - return [ - canReset, - useCallback( - () => setUserConfig( () => EMPTY_CONFIG ), - [ setUserConfig ] - ), - ]; -}; - -export function useSetting( path, blockName, source = 'all' ) { - const { - merged: mergedConfig, - base: baseConfig, - user: userConfig, - setUserConfig, - } = useContext( GlobalStylesContext ); - - const fullPath = ! blockName - ? `settings.${ path }` - : `settings.blocks.${ blockName }.${ path }`; - - const setSetting = ( newValue ) => { - setUserConfig( ( currentConfig ) => { - // Deep clone `currentConfig` to avoid mutating it later. - const newUserConfig = JSON.parse( JSON.stringify( currentConfig ) ); - const pathToSet = PATHS_WITH_MERGE[ path ] - ? fullPath + '.custom' - : fullPath; - set( newUserConfig, pathToSet, newValue ); - - return newUserConfig; - } ); - }; - - const getSettingValueForContext = ( name ) => { - const currentPath = ! name - ? `settings.${ path }` - : `settings.blocks.${ name }.${ path }`; - - const getSettingValue = ( configToUse ) => { - const result = get( configToUse, currentPath ); - if ( PATHS_WITH_MERGE[ path ] ) { - return result?.custom ?? result?.theme ?? result?.default; - } - return result; - }; - - let result; - switch ( source ) { - case 'all': - result = getSettingValue( mergedConfig ); - break; - case 'user': - result = getSettingValue( userConfig ); - break; - case 'base': - result = getSettingValue( baseConfig ); - break; - default: - throw 'Unsupported source'; - } - - return result; - }; - - // Unlike styles settings get inherited from top level settings. - const resultWithFallback = - getSettingValueForContext( blockName ) ?? getSettingValueForContext(); - - return [ resultWithFallback, setSetting ]; -} - -export function useStyle( path, blockName, source = 'all' ) { - const { - merged: mergedConfig, - base: baseConfig, - user: userConfig, - setUserConfig, - } = useContext( GlobalStylesContext ); - const finalPath = ! blockName - ? `styles.${ path }` - : `styles.blocks.${ blockName }.${ path }`; - - const setStyle = ( newValue ) => { - setUserConfig( ( currentConfig ) => { - // Deep clone `currentConfig` to avoid mutating it later. - const newUserConfig = JSON.parse( JSON.stringify( currentConfig ) ); - set( - newUserConfig, - finalPath, - getPresetVariableFromValue( - mergedConfig.settings, - blockName, - path, - newValue - ) - ); - return newUserConfig; - } ); - }; - - let result; - switch ( source ) { - case 'all': - result = getValueFromVariable( - mergedConfig, - blockName, - // The stlyes.css path is allowed to be empty, so don't revert to base if undefined. - finalPath === 'styles.css' - ? get( userConfig, finalPath ) - : get( userConfig, finalPath ) ?? - get( baseConfig, finalPath ) - ); - break; - case 'user': - result = getValueFromVariable( - mergedConfig, - blockName, - get( userConfig, finalPath ) - ); - break; - case 'base': - result = getValueFromVariable( - baseConfig, - blockName, - get( baseConfig, finalPath ) - ); - break; - default: - throw 'Unsupported source'; - } - - return [ result, setStyle ]; -} - const ROOT_BLOCK_SUPPORTS = [ 'background', 'backgroundColor', @@ -247,10 +107,12 @@ export function getSupportedGlobalStylesPanels( name ) { } export function useColorsPerOrigin( name ) { - const [ customColors ] = useSetting( 'color.palette.custom', name ); - const [ themeColors ] = useSetting( 'color.palette.theme', name ); - const [ defaultColors ] = useSetting( 'color.palette.default', name ); - const [ shouldDisplayDefaultColors ] = useSetting( 'color.defaultPalette' ); + const [ customColors ] = useGlobalSetting( 'color.palette.custom', name ); + const [ themeColors ] = useGlobalSetting( 'color.palette.theme', name ); + const [ defaultColors ] = useGlobalSetting( 'color.palette.default', name ); + const [ shouldDisplayDefaultColors ] = useGlobalSetting( + 'color.defaultPalette' + ); return useMemo( () => { const result = []; @@ -290,10 +152,19 @@ export function useColorsPerOrigin( name ) { } export function useGradientsPerOrigin( name ) { - const [ customGradients ] = useSetting( 'color.gradients.custom', name ); - const [ themeGradients ] = useSetting( 'color.gradients.theme', name ); - const [ defaultGradients ] = useSetting( 'color.gradients.default', name ); - const [ shouldDisplayDefaultGradients ] = useSetting( + const [ customGradients ] = useGlobalSetting( + 'color.gradients.custom', + name + ); + const [ themeGradients ] = useGlobalSetting( + 'color.gradients.theme', + name + ); + const [ defaultGradients ] = useGlobalSetting( + 'color.gradients.default', + name + ); + const [ shouldDisplayDefaultGradients ] = useGlobalSetting( 'color.defaultGradients' ); @@ -335,7 +206,7 @@ export function useGradientsPerOrigin( name ) { } export function useColorRandomizer( name ) { - const [ themeColors, setThemeColors ] = useSetting( + const [ themeColors, setThemeColors ] = useGlobalSetting( 'color.palette.theme', name ); diff --git a/packages/edit-site/src/components/global-styles/index.js b/packages/edit-site/src/components/global-styles/index.js index 026a4fd759f32..5533852c1ac68 100644 --- a/packages/edit-site/src/components/global-styles/index.js +++ b/packages/edit-site/src/components/global-styles/index.js @@ -1,3 +1 @@ export { default as GlobalStylesUI } from './ui'; -export { useGlobalStylesReset, useStyle, useSetting } from './hooks'; -export { useGlobalStylesOutput } from './use-global-styles-output'; diff --git a/packages/edit-site/src/components/global-styles/palette.js b/packages/edit-site/src/components/global-styles/palette.js index 0b4bbbbbb7f63..09148a55bd57a 100644 --- a/packages/edit-site/src/components/global-styles/palette.js +++ b/packages/edit-site/src/components/global-styles/palette.js @@ -13,23 +13,27 @@ import { import { __, _n, sprintf } from '@wordpress/i18n'; import { shuffle } from '@wordpress/icons'; import { useMemo } from '@wordpress/element'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ import Subtitle from './subtitle'; import { NavigationButtonAsItem } from './navigation-button'; -import { useColorRandomizer, useSetting } from './hooks'; +import { useColorRandomizer } from './hooks'; import ColorIndicatorWrapper from './color-indicator-wrapper'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting } = unlock( blockEditorExperiments ); const EMPTY_COLORS = []; function Palette( { name } ) { - const [ customColors ] = useSetting( 'color.palette.custom' ); - const [ themeColors ] = useSetting( 'color.palette.theme' ); - const [ defaultColors ] = useSetting( 'color.palette.default' ); + const [ customColors ] = useGlobalSetting( 'color.palette.custom' ); + const [ themeColors ] = useGlobalSetting( 'color.palette.theme' ); + const [ defaultColors ] = useGlobalSetting( 'color.palette.default' ); - const [ defaultPaletteEnabled ] = useSetting( + const [ defaultPaletteEnabled ] = useGlobalSetting( 'color.defaultPalette', name ); diff --git a/packages/edit-site/src/components/global-styles/preview.js b/packages/edit-site/src/components/global-styles/preview.js index 14ade992f0fc7..521e0d2d7ed1b 100644 --- a/packages/edit-site/src/components/global-styles/preview.js +++ b/packages/edit-site/src/components/global-styles/preview.js @@ -4,6 +4,7 @@ import { __unstableIframe as Iframe, __unstableEditorStyles as EditorStyles, + experiments as blockEditorExperiments, } from '@wordpress/block-editor'; import { __unstableMotion as motion, @@ -16,8 +17,11 @@ import { useState, useMemo } from '@wordpress/element'; /** * Internal dependencies */ -import { useSetting, useStyle } from './hooks'; -import { useGlobalStylesOutput } from './use-global-styles-output'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle, useGlobalStylesOutput } = unlock( + blockEditorExperiments +); const firstFrame = { start: { @@ -56,23 +60,25 @@ const normalizedHeight = 152; const normalizedColorSwatchSize = 32; const StylesPreview = ( { label, isFocused, withHoverView } ) => { - const [ fontWeight ] = useStyle( 'typography.fontWeight' ); - const [ fontFamily = 'serif' ] = useStyle( 'typography.fontFamily' ); - const [ headingFontFamily = fontFamily ] = useStyle( + const [ fontWeight ] = useGlobalStyle( 'typography.fontWeight' ); + const [ fontFamily = 'serif' ] = useGlobalStyle( 'typography.fontFamily' ); + const [ headingFontFamily = fontFamily ] = useGlobalStyle( 'elements.h1.typography.fontFamily' ); - const [ headingFontWeight = fontWeight ] = useStyle( + const [ headingFontWeight = fontWeight ] = useGlobalStyle( 'elements.h1.typography.fontWeight' ); - const [ textColor = 'black' ] = useStyle( 'color.text' ); - const [ headingColor = textColor ] = useStyle( 'elements.h1.color.text' ); - const [ backgroundColor = 'white' ] = useStyle( 'color.background' ); - const [ gradientValue ] = useStyle( 'color.gradient' ); + const [ textColor = 'black' ] = useGlobalStyle( 'color.text' ); + const [ headingColor = textColor ] = useGlobalStyle( + 'elements.h1.color.text' + ); + const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' ); + const [ gradientValue ] = useGlobalStyle( 'color.gradient' ); const [ styles ] = useGlobalStylesOutput(); const disableMotion = useReducedMotion(); - const [ coreColors ] = useSetting( 'color.palette.core' ); - const [ themeColors ] = useSetting( 'color.palette.theme' ); - const [ customColors ] = useSetting( 'color.palette.custom' ); + const [ coreColors ] = useGlobalSetting( 'color.palette.core' ); + const [ themeColors ] = useGlobalSetting( 'color.palette.theme' ); + const [ customColors ] = useGlobalSetting( 'color.palette.custom' ); const [ isHovered, setIsHovered ] = useState( false ); const [ containerResizeListener, { width } ] = useResizeObserver(); const ratio = width ? width / normalizedWidth : 1; diff --git a/packages/edit-site/src/components/global-styles/screen-background-color.js b/packages/edit-site/src/components/global-styles/screen-background-color.js index d7227cc6e29ba..6ae0ece5e848e 100644 --- a/packages/edit-site/src/components/global-styles/screen-background-color.js +++ b/packages/edit-site/src/components/global-styles/screen-background-color.js @@ -7,7 +7,10 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor'; +import { + __experimentalColorGradientControl as ColorGradientControl, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; /** * Internal dependencies @@ -17,16 +20,17 @@ import { getSupportedGlobalStylesPanels, useColorsPerOrigin, useGradientsPerOrigin, - useSetting, - useStyle, } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); function ScreenBackgroundColor( { name, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ solids ] = useSetting( 'color.palette', name ); - const [ gradients ] = useSetting( 'color.gradients', name ); - const [ areCustomSolidsEnabled ] = useSetting( 'color.custom', name ); - const [ areCustomGradientsEnabled ] = useSetting( + const [ solids ] = useGlobalSetting( 'color.palette', name ); + const [ gradients ] = useGlobalSetting( 'color.gradients', name ); + const [ areCustomSolidsEnabled ] = useGlobalSetting( 'color.custom', name ); + const [ areCustomGradientsEnabled ] = useGlobalSetting( 'color.customGradient', name ); @@ -34,7 +38,10 @@ function ScreenBackgroundColor( { name, variationPath = '' } ) { const colorsPerOrigin = useColorsPerOrigin( name ); const gradientsPerOrigin = useGradientsPerOrigin( name ); - const [ isBackgroundEnabled ] = useSetting( 'color.background', name ); + const [ isBackgroundEnabled ] = useGlobalSetting( + 'color.background', + name + ); const hasBackgroundColor = supports.includes( 'backgroundColor' ) && @@ -43,20 +50,20 @@ function ScreenBackgroundColor( { name, variationPath = '' } ) { const hasGradientColor = supports.includes( 'background' ) && ( gradients.length > 0 || areCustomGradientsEnabled ); - const [ backgroundColor, setBackgroundColor ] = useStyle( + const [ backgroundColor, setBackgroundColor ] = useGlobalStyle( variationPath + 'color.background', name ); - const [ userBackgroundColor ] = useStyle( + const [ userBackgroundColor ] = useGlobalStyle( variationPath + 'color.background', name, 'user' ); - const [ gradient, setGradient ] = useStyle( + const [ gradient, setGradient ] = useGlobalStyle( variationPath + 'color.gradient', name ); - const [ userGradient ] = useStyle( + const [ userGradient ] = useGlobalStyle( variationPath + 'color.gradient', name, 'user' diff --git a/packages/edit-site/src/components/global-styles/screen-button-color.js b/packages/edit-site/src/components/global-styles/screen-button-color.js index 27ae7a0783147..bc420ac79e425 100644 --- a/packages/edit-site/src/components/global-styles/screen-button-color.js +++ b/packages/edit-site/src/components/global-styles/screen-button-color.js @@ -2,48 +2,52 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor'; +import { + __experimentalColorGradientControl as ColorGradientControl, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; /** * Internal dependencies */ import ScreenHeader from './header'; -import { - getSupportedGlobalStylesPanels, - useSetting, - useStyle, - useColorsPerOrigin, -} from './hooks'; +import { getSupportedGlobalStylesPanels, useColorsPerOrigin } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); function ScreenButtonColor( { name, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ solids ] = useSetting( 'color.palette', name ); - const [ areCustomSolidsEnabled ] = useSetting( 'color.custom', name ); + const [ solids ] = useGlobalSetting( 'color.palette', name ); + const [ areCustomSolidsEnabled ] = useGlobalSetting( 'color.custom', name ); const colorsPerOrigin = useColorsPerOrigin( name ); - const [ isBackgroundEnabled ] = useSetting( 'color.background', name ); + const [ isBackgroundEnabled ] = useGlobalSetting( + 'color.background', + name + ); const hasButtonColor = supports.includes( 'buttonColor' ) && isBackgroundEnabled && ( solids.length > 0 || areCustomSolidsEnabled ); - const [ buttonTextColor, setButtonTextColor ] = useStyle( + const [ buttonTextColor, setButtonTextColor ] = useGlobalStyle( variationPath + 'elements.button.color.text', name ); - const [ userButtonTextColor ] = useStyle( + const [ userButtonTextColor ] = useGlobalStyle( 'elements.button.color.text', name, 'user' ); - const [ buttonBgColor, setButtonBgColor ] = useStyle( + const [ buttonBgColor, setButtonBgColor ] = useGlobalStyle( 'elements.button.color.background', name ); - const [ userButtonBgColor ] = useStyle( + const [ userButtonBgColor ] = useGlobalStyle( 'elements.button.color.background', name, 'user' diff --git a/packages/edit-site/src/components/global-styles/screen-colors.js b/packages/edit-site/src/components/global-styles/screen-colors.js index 4de6056f7d767..2d863f6a2b6d2 100644 --- a/packages/edit-site/src/components/global-styles/screen-colors.js +++ b/packages/edit-site/src/components/global-styles/screen-colors.js @@ -10,6 +10,7 @@ import { FlexItem, ColorIndicator, } from '@wordpress/components'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies @@ -17,11 +18,14 @@ import { import ScreenHeader from './header'; import Palette from './palette'; import { NavigationButtonAsItem } from './navigation-button'; -import { getSupportedGlobalStylesPanels, useStyle } from './hooks'; +import { getSupportedGlobalStylesPanels } from './hooks'; import Subtitle from './subtitle'; import ColorIndicatorWrapper from './color-indicator-wrapper'; import BlockPreviewPanel from './block-preview-panel'; import { getVariationClassNameFromPath } from './utils'; +import { unlock } from '../../experiments'; + +const { useGlobalStyle } = unlock( blockEditorExperiments ); function variationPathToURL( variationPath ) { if ( ! variationPath ) { @@ -36,11 +40,11 @@ function BackgroundColorItem( { name, parentMenu, variationPath = '' } ) { const hasSupport = supports.includes( 'backgroundColor' ) || supports.includes( 'background' ); - const [ backgroundColor ] = useStyle( + const [ backgroundColor ] = useGlobalStyle( variationPath + 'color.background', name ); - const [ gradientValue ] = useStyle( + const [ gradientValue ] = useGlobalStyle( variationPath + 'color.gradient', name ); @@ -76,7 +80,7 @@ function BackgroundColorItem( { name, parentMenu, variationPath = '' } ) { function TextColorItem( { name, parentMenu, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); const hasSupport = supports.includes( 'color' ); - const [ color ] = useStyle( variationPath + 'color.text', name ); + const [ color ] = useGlobalStyle( variationPath + 'color.text', name ); if ( ! hasSupport ) { return null; @@ -109,11 +113,11 @@ function TextColorItem( { name, parentMenu, variationPath = '' } ) { function LinkColorItem( { name, parentMenu, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); const hasSupport = supports.includes( 'linkColor' ); - const [ color ] = useStyle( + const [ color ] = useGlobalStyle( variationPath + 'elements.link.color.text', name ); - const [ colorHover ] = useStyle( + const [ colorHover ] = useGlobalStyle( variationPath + 'elements.link.:hover.color.text', name ); @@ -151,11 +155,11 @@ function LinkColorItem( { name, parentMenu, variationPath = '' } ) { function HeadingColorItem( { name, parentMenu, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); const hasSupport = supports.includes( 'color' ); - const [ color ] = useStyle( + const [ color ] = useGlobalStyle( variationPath + 'elements.heading.color.text', name ); - const [ bgColor ] = useStyle( + const [ bgColor ] = useGlobalStyle( variationPath + 'elements.heading.color.background', name ); @@ -191,11 +195,11 @@ function HeadingColorItem( { name, parentMenu, variationPath = '' } ) { function ButtonColorItem( { name, parentMenu, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); const hasSupport = supports.includes( 'buttonColor' ); - const [ color ] = useStyle( + const [ color ] = useGlobalStyle( variationPath + 'elements.button.color.text', name ); - const [ bgColor ] = useStyle( + const [ bgColor ] = useGlobalStyle( variationPath + 'elements.button.color.background', name ); diff --git a/packages/edit-site/src/components/global-styles/screen-heading-color.js b/packages/edit-site/src/components/global-styles/screen-heading-color.js index c666873026811..18566051bb9bc 100644 --- a/packages/edit-site/src/components/global-styles/screen-heading-color.js +++ b/packages/edit-site/src/components/global-styles/screen-heading-color.js @@ -6,7 +6,10 @@ import { __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from '@wordpress/components'; -import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor'; +import { + __experimentalColorGradientControl as ColorGradientControl, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; import { useState } from '@wordpress/element'; /** @@ -15,25 +18,29 @@ import { useState } from '@wordpress/element'; import ScreenHeader from './header'; import { getSupportedGlobalStylesPanels, - useSetting, - useStyle, useColorsPerOrigin, useGradientsPerOrigin, } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); function ScreenHeadingColor( { name, variationPath = '' } ) { const [ selectedLevel, setCurrentTab ] = useState( 'heading' ); const supports = getSupportedGlobalStylesPanels( name ); - const [ solids ] = useSetting( 'color.palette', name ); - const [ gradients ] = useSetting( 'color.gradients', name ); - const [ areCustomSolidsEnabled ] = useSetting( 'color.custom', name ); - const [ areCustomGradientsEnabled ] = useSetting( + const [ solids ] = useGlobalSetting( 'color.palette', name ); + const [ gradients ] = useGlobalSetting( 'color.gradients', name ); + const [ areCustomSolidsEnabled ] = useGlobalSetting( 'color.custom', name ); + const [ areCustomGradientsEnabled ] = useGlobalSetting( 'color.customGradient', name ); - const [ isTextEnabled ] = useSetting( 'color.text', name ); - const [ isBackgroundEnabled ] = useSetting( 'color.background', name ); + const [ isTextEnabled ] = useGlobalSetting( 'color.text', name ); + const [ isBackgroundEnabled ] = useGlobalSetting( + 'color.background', + name + ); const colorsPerOrigin = useColorsPerOrigin( name ); const gradientsPerOrigin = useGradientsPerOrigin( name ); @@ -51,30 +58,30 @@ function ScreenHeadingColor( { name, variationPath = '' } ) { supports.includes( 'background' ) && ( gradients.length > 0 || areCustomGradientsEnabled ); - const [ color, setColor ] = useStyle( + const [ color, setColor ] = useGlobalStyle( variationPath + 'elements.' + selectedLevel + '.color.text', name ); - const [ userColor ] = useStyle( + const [ userColor ] = useGlobalStyle( variationPath + 'elements.' + selectedLevel + '.color.text', name, 'user' ); - const [ backgroundColor, setBackgroundColor ] = useStyle( + const [ backgroundColor, setBackgroundColor ] = useGlobalStyle( variationPath + 'elements.' + selectedLevel + '.color.background', name ); - const [ userBackgroundColor ] = useStyle( + const [ userBackgroundColor ] = useGlobalStyle( variationPath + 'elements.' + selectedLevel + '.color.background', name, 'user' ); - const [ gradient, setGradient ] = useStyle( + const [ gradient, setGradient ] = useGlobalStyle( variationPath + 'elements.' + selectedLevel + '.color.gradient', name ); - const [ userGradient ] = useStyle( + const [ userGradient ] = useGlobalStyle( variationPath + 'elements.' + selectedLevel + '.color.gradient', name, 'user' diff --git a/packages/edit-site/src/components/global-styles/screen-link-color.js b/packages/edit-site/src/components/global-styles/screen-link-color.js index 855e8e91c81db..049c2cc99d47a 100644 --- a/packages/edit-site/src/components/global-styles/screen-link-color.js +++ b/packages/edit-site/src/components/global-styles/screen-link-color.js @@ -2,27 +2,29 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor'; +import { + __experimentalColorGradientControl as ColorGradientControl, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; import { TabPanel } from '@wordpress/components'; + /** * Internal dependencies */ import ScreenHeader from './header'; -import { - getSupportedGlobalStylesPanels, - useSetting, - useStyle, - useColorsPerOrigin, -} from './hooks'; +import { getSupportedGlobalStylesPanels, useColorsPerOrigin } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); function ScreenLinkColor( { name, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ solids ] = useSetting( 'color.palette', name ); - const [ areCustomSolidsEnabled ] = useSetting( 'color.custom', name ); + const [ solids ] = useGlobalSetting( 'color.palette', name ); + const [ areCustomSolidsEnabled ] = useGlobalSetting( 'color.custom', name ); const colorsPerOrigin = useColorsPerOrigin( name ); - const [ isLinkEnabled ] = useSetting( 'color.link', name ); + const [ isLinkEnabled ] = useGlobalSetting( 'color.link', name ); const hasLinkColor = supports.includes( 'linkColor' ) && @@ -32,15 +34,15 @@ function ScreenLinkColor( { name, variationPath = '' } ) { const pseudoStates = { default: { label: __( 'Default' ), - value: useStyle( + value: useGlobalStyle( variationPath + 'elements.link.color.text', name )[ 0 ], - handler: useStyle( + handler: useGlobalStyle( variationPath + 'elements.link.color.text', name )[ 1 ], - userValue: useStyle( + userValue: useGlobalStyle( variationPath + 'elements.link.color.text', name, 'user' @@ -48,15 +50,15 @@ function ScreenLinkColor( { name, variationPath = '' } ) { }, hover: { label: __( 'Hover' ), - value: useStyle( + value: useGlobalStyle( variationPath + 'elements.link.:hover.color.text', name )[ 0 ], - handler: useStyle( + handler: useGlobalStyle( variationPath + 'elements.link.:hover.color.text', name )[ 1 ], - userValue: useStyle( + userValue: useGlobalStyle( variationPath + 'elements.link.:hover.color.text', name, 'user' diff --git a/packages/edit-site/src/components/global-styles/screen-style-variations.js b/packages/edit-site/src/components/global-styles/screen-style-variations.js index b88b81a0c08d1..a94edce1cf92f 100644 --- a/packages/edit-site/src/components/global-styles/screen-style-variations.js +++ b/packages/edit-site/src/components/global-styles/screen-style-variations.js @@ -23,15 +23,20 @@ import { CardBody, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { store as blockEditorStore } from '@wordpress/block-editor'; +import { + store as blockEditorStore, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; /** * Internal dependencies */ import { mergeBaseAndUserConfigs } from './global-styles-provider'; -import { GlobalStylesContext } from './context'; import StylesPreview from './preview'; import ScreenHeader from './header'; +import { unlock } from '../../experiments'; + +const { GlobalStylesContext } = unlock( blockEditorExperiments ); function compareVariations( a, b ) { return ( diff --git a/packages/edit-site/src/components/global-styles/screen-text-color.js b/packages/edit-site/src/components/global-styles/screen-text-color.js index 7521b3b68728e..d61cea759fd8a 100644 --- a/packages/edit-site/src/components/global-styles/screen-text-color.js +++ b/packages/edit-site/src/components/global-styles/screen-text-color.js @@ -2,24 +2,25 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { __experimentalColorGradientControl as ColorGradientControl } from '@wordpress/block-editor'; +import { + __experimentalColorGradientControl as ColorGradientControl, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; /** * Internal dependencies */ import ScreenHeader from './header'; -import { - getSupportedGlobalStylesPanels, - useSetting, - useStyle, - useColorsPerOrigin, -} from './hooks'; +import { getSupportedGlobalStylesPanels, useColorsPerOrigin } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); function ScreenTextColor( { name, variationPath = '' } ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ solids ] = useSetting( 'color.palette', name ); - const [ areCustomSolidsEnabled ] = useSetting( 'color.custom', name ); - const [ isTextEnabled ] = useSetting( 'color.text', name ); + const [ solids ] = useGlobalSetting( 'color.palette', name ); + const [ areCustomSolidsEnabled ] = useGlobalSetting( 'color.custom', name ); + const [ isTextEnabled ] = useGlobalSetting( 'color.text', name ); const colorsPerOrigin = useColorsPerOrigin( name ); @@ -28,8 +29,11 @@ function ScreenTextColor( { name, variationPath = '' } ) { isTextEnabled && ( solids.length > 0 || areCustomSolidsEnabled ); - const [ color, setColor ] = useStyle( variationPath + 'color.text', name ); - const [ userColor ] = useStyle( + const [ color, setColor ] = useGlobalStyle( + variationPath + 'color.text', + name + ); + const [ userColor ] = useGlobalStyle( variationPath + 'color.text', name, 'user' diff --git a/packages/edit-site/src/components/global-styles/screen-typography.js b/packages/edit-site/src/components/global-styles/screen-typography.js index a92e00361e4c7..bd56273781a3f 100644 --- a/packages/edit-site/src/components/global-styles/screen-typography.js +++ b/packages/edit-site/src/components/global-styles/screen-typography.js @@ -8,17 +8,20 @@ import { __experimentalHStack as HStack, FlexItem, } from '@wordpress/components'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ import ScreenHeader from './header'; import { NavigationButtonAsItem } from './navigation-button'; -import { useStyle } from './hooks'; import Subtitle from './subtitle'; import TypographyPanel from './typography-panel'; import BlockPreviewPanel from './block-preview-panel'; import { getVariationClassNameFromPath } from './utils'; +import { unlock } from '../../experiments'; + +const { useGlobalStyle } = unlock( blockEditorExperiments ); function Item( { name, parentMenu, element, label } ) { const hasSupport = ! name; @@ -30,16 +33,28 @@ function Item( { name, parentMenu, element, label } ) { textDecoration: 'underline', } : {}; - const [ fontFamily ] = useStyle( prefix + 'typography.fontFamily', name ); - const [ fontStyle ] = useStyle( prefix + 'typography.fontStyle', name ); - const [ fontWeight ] = useStyle( prefix + 'typography.fontWeight', name ); - const [ letterSpacing ] = useStyle( + const [ fontFamily ] = useGlobalStyle( + prefix + 'typography.fontFamily', + name + ); + const [ fontStyle ] = useGlobalStyle( + prefix + 'typography.fontStyle', + name + ); + const [ fontWeight ] = useGlobalStyle( + prefix + 'typography.fontWeight', + name + ); + const [ letterSpacing ] = useGlobalStyle( prefix + 'typography.letterSpacing', name ); - const [ backgroundColor ] = useStyle( prefix + 'color.background', name ); - const [ gradientValue ] = useStyle( prefix + 'color.gradient', name ); - const [ color ] = useStyle( prefix + 'color.text', name ); + const [ backgroundColor ] = useGlobalStyle( + prefix + 'color.background', + name + ); + const [ gradientValue ] = useGlobalStyle( prefix + 'color.gradient', name ); + const [ color ] = useGlobalStyle( prefix + 'color.text', name ); if ( ! hasSupport ) { return null; diff --git a/packages/edit-site/src/components/global-styles/typography-panel.js b/packages/edit-site/src/components/global-styles/typography-panel.js index b793d81978ef2..938605ba11c4a 100644 --- a/packages/edit-site/src/components/global-styles/typography-panel.js +++ b/packages/edit-site/src/components/global-styles/typography-panel.js @@ -8,6 +8,7 @@ import { __experimentalLetterSpacingControl as LetterSpacingControl, __experimentalTextTransformControl as TextTransformControl, __experimentalTextDecorationControl as TextDecorationControl, + experiments as blockEditorExperiments, } from '@wordpress/block-editor'; import { FontSizePicker, @@ -19,7 +20,10 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { getSupportedGlobalStylesPanels, useSetting, useStyle } from './hooks'; +import { getSupportedGlobalStylesPanels } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalSetting, useGlobalStyle } = unlock( blockEditorExperiments ); export function useHasTypographyPanel( name ) { const hasFontFamily = useHasFontFamilyControl( name ); @@ -38,14 +42,17 @@ export function useHasTypographyPanel( name ) { function useHasFontFamilyControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); - const [ fontFamilies ] = useSetting( 'typography.fontFamilies', name ); + const [ fontFamilies ] = useGlobalSetting( + 'typography.fontFamilies', + name + ); return supports.includes( 'fontFamily' ) && !! fontFamilies?.length; } function useHasLineHeightControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); return ( - useSetting( 'typography.lineHeight', name )[ 0 ] && + useGlobalSetting( 'typography.lineHeight', name )[ 0 ] && supports.includes( 'lineHeight' ) ); } @@ -53,10 +60,10 @@ function useHasLineHeightControl( name ) { function useHasAppearanceControl( name ) { const supports = getSupportedGlobalStylesPanels( name ); const hasFontStyles = - useSetting( 'typography.fontStyle', name )[ 0 ] && + useGlobalSetting( 'typography.fontStyle', name )[ 0 ] && supports.includes( 'fontStyle' ); const hasFontWeights = - useSetting( 'typography.fontWeight', name )[ 0 ] && + useGlobalSetting( 'typography.fontWeight', name )[ 0 ] && supports.includes( 'fontWeight' ); return hasFontStyles || hasFontWeights; } @@ -64,10 +71,10 @@ function useHasAppearanceControl( name ) { function useAppearanceControlLabel( name ) { const supports = getSupportedGlobalStylesPanels( name ); const hasFontStyles = - useSetting( 'typography.fontStyle', name )[ 0 ] && + useGlobalSetting( 'typography.fontStyle', name )[ 0 ] && supports.includes( 'fontStyle' ); const hasFontWeights = - useSetting( 'typography.fontWeight', name )[ 0 ] && + useGlobalSetting( 'typography.fontWeight', name )[ 0 ] && supports.includes( 'fontWeight' ); if ( ! hasFontStyles ) { return __( 'Font weight' ); @@ -79,7 +86,7 @@ function useAppearanceControlLabel( name ) { } function useHasLetterSpacingControl( name, element ) { - const setting = useSetting( 'typography.letterSpacing', name )[ 0 ]; + const setting = useGlobalSetting( 'typography.letterSpacing', name )[ 0 ]; if ( ! setting ) { return false; } @@ -91,7 +98,7 @@ function useHasLetterSpacingControl( name, element ) { } function useHasTextTransformControl( name, element ) { - const setting = useSetting( 'typography.textTransform', name )[ 0 ]; + const setting = useGlobalSetting( 'typography.textTransform', name )[ 0 ]; if ( ! setting ) { return false; } @@ -110,16 +117,16 @@ function useHasTextDecorationControl( name, element ) { } function useStyleWithReset( path, blockName ) { - const [ style, setStyle ] = useStyle( path, blockName ); - const [ userStyle ] = useStyle( path, blockName, 'user' ); + const [ style, setStyle ] = useGlobalStyle( path, blockName ); + const [ userStyle ] = useGlobalStyle( path, blockName, 'user' ); const hasStyle = () => !! userStyle; const resetStyle = () => setStyle( undefined ); return [ style, setStyle, hasStyle, resetStyle ]; } function useFontSizeWithReset( path, blockName ) { - const [ fontSize, setStyleCallback ] = useStyle( path, blockName ); - const [ userStyle ] = useStyle( path, blockName, 'user' ); + const [ fontSize, setStyleCallback ] = useGlobalStyle( path, blockName ); + const [ userStyle ] = useGlobalStyle( path, blockName, 'user' ); const hasFontSize = () => !! userStyle; const resetFontSize = () => setStyleCallback( undefined ); const setFontSize = ( newValue, metadata ) => { @@ -138,20 +145,20 @@ function useFontSizeWithReset( path, blockName ) { } function useFontAppearance( prefix, name ) { - const [ fontStyle, setFontStyle ] = useStyle( + const [ fontStyle, setFontStyle ] = useGlobalStyle( prefix + 'typography.fontStyle', name ); - const [ userFontStyle ] = useStyle( + const [ userFontStyle ] = useGlobalStyle( prefix + 'typography.fontStyle', name, 'user' ); - const [ fontWeight, setFontWeight ] = useStyle( + const [ fontWeight, setFontWeight ] = useGlobalStyle( prefix + 'typography.fontWeight', name ); - const [ userFontWeight ] = useStyle( + const [ userFontWeight ] = useGlobalStyle( prefix + 'typography.fontWeight', name, 'user' @@ -184,18 +191,21 @@ export default function TypographyPanel( { } else if ( element && element !== 'text' ) { prefix = `elements.${ element }.`; } - const [ fontSizes ] = useSetting( 'typography.fontSizes', name ); + const [ fontSizes ] = useGlobalSetting( 'typography.fontSizes', name ); - const disableCustomFontSizes = ! useSetting( + const disableCustomFontSizes = ! useGlobalSetting( 'typography.customFontSize', name )[ 0 ]; - const [ fontFamilies ] = useSetting( 'typography.fontFamilies', name ); + const [ fontFamilies ] = useGlobalSetting( + 'typography.fontFamilies', + name + ); const hasFontStyles = - useSetting( 'typography.fontStyle', name )[ 0 ] && + useGlobalSetting( 'typography.fontStyle', name )[ 0 ] && supports.includes( 'fontStyle' ); const hasFontWeights = - useSetting( 'typography.fontWeight', name )[ 0 ] && + useGlobalSetting( 'typography.fontWeight', name )[ 0 ] && supports.includes( 'fontWeight' ); const hasFontFamilyEnabled = useHasFontFamilyControl( name ); const hasLineHeightEnabled = useHasLineHeightControl( name ); diff --git a/packages/edit-site/src/components/global-styles/typography-preview.js b/packages/edit-site/src/components/global-styles/typography-preview.js index b0e134ab0cce5..49c0d4e73b95b 100644 --- a/packages/edit-site/src/components/global-styles/typography-preview.js +++ b/packages/edit-site/src/components/global-styles/typography-preview.js @@ -1,7 +1,14 @@ +/** + * WordPress dependencies + */ +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; + /** * Internal dependencies */ -import { useStyle } from './hooks'; +import { unlock } from '../../experiments'; + +const { useGlobalStyle } = unlock( blockEditorExperiments ); export default function TypographyPreview( { name, element, headingLevel } ) { let prefix = ''; @@ -11,14 +18,26 @@ export default function TypographyPreview( { name, element, headingLevel } ) { prefix = `elements.${ element }.`; } - const [ fontFamily ] = useStyle( prefix + 'typography.fontFamily', name ); - const [ gradientValue ] = useStyle( prefix + 'color.gradient', name ); - const [ backgroundColor ] = useStyle( prefix + 'color.background', name ); - const [ color ] = useStyle( prefix + 'color.text', name ); - const [ fontSize ] = useStyle( prefix + 'typography.fontSize', name ); - const [ fontStyle ] = useStyle( prefix + 'typography.fontStyle', name ); - const [ fontWeight ] = useStyle( prefix + 'typography.fontWeight', name ); - const [ letterSpacing ] = useStyle( + const [ fontFamily ] = useGlobalStyle( + prefix + 'typography.fontFamily', + name + ); + const [ gradientValue ] = useGlobalStyle( prefix + 'color.gradient', name ); + const [ backgroundColor ] = useGlobalStyle( + prefix + 'color.background', + name + ); + const [ color ] = useGlobalStyle( prefix + 'color.text', name ); + const [ fontSize ] = useGlobalStyle( prefix + 'typography.fontSize', name ); + const [ fontStyle ] = useGlobalStyle( + prefix + 'typography.fontStyle', + name + ); + const [ fontWeight ] = useGlobalStyle( + prefix + 'typography.fontWeight', + name + ); + const [ letterSpacing ] = useGlobalStyle( prefix + 'typography.letterSpacing', name ); diff --git a/packages/edit-site/src/components/global-styles/utils.js b/packages/edit-site/src/components/global-styles/utils.js index b33383451ccd3..8c20de6508fb6 100644 --- a/packages/edit-site/src/components/global-styles/utils.js +++ b/packages/edit-site/src/components/global-styles/utils.js @@ -1,370 +1,3 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - -/** - * Internal dependencies - */ -import { getTypographyFontSizeValue } from './typography-utils'; - -/* Supporting data. */ -export const ROOT_BLOCK_NAME = 'root'; -export const ROOT_BLOCK_SELECTOR = 'body'; -export const ROOT_BLOCK_SUPPORTS = [ - 'background', - 'backgroundColor', - 'color', - 'linkColor', - 'buttonColor', - 'fontFamily', - 'fontSize', - 'fontStyle', - 'fontWeight', - 'lineHeight', - 'textDecoration', - 'textTransform', - 'padding', -]; - -export const PRESET_METADATA = [ - { - path: [ 'color', 'palette' ], - valueKey: 'color', - cssVarInfix: 'color', - classes: [ - { classSuffix: 'color', propertyName: 'color' }, - { - classSuffix: 'background-color', - propertyName: 'background-color', - }, - { - classSuffix: 'border-color', - propertyName: 'border-color', - }, - ], - }, - { - path: [ 'color', 'gradients' ], - valueKey: 'gradient', - cssVarInfix: 'gradient', - classes: [ - { - classSuffix: 'gradient-background', - propertyName: 'background', - }, - ], - }, - { - path: [ 'color', 'duotone' ], - cssVarInfix: 'duotone', - valueFunc: ( { slug } ) => `url( '#wp-duotone-${ slug }' )`, - classes: [], - }, - { - path: [ 'typography', 'fontSizes' ], - valueFunc: ( preset, { typography: typographySettings } ) => - getTypographyFontSizeValue( preset, typographySettings ), - valueKey: 'size', - cssVarInfix: 'font-size', - classes: [ { classSuffix: 'font-size', propertyName: 'font-size' } ], - }, - { - path: [ 'typography', 'fontFamilies' ], - valueKey: 'fontFamily', - cssVarInfix: 'font-family', - classes: [ - { classSuffix: 'font-family', propertyName: 'font-family' }, - ], - }, - { - path: [ 'spacing', 'spacingSizes' ], - valueKey: 'size', - cssVarInfix: 'spacing', - valueFunc: ( { size } ) => size, - classes: [], - }, -]; - -export const STYLE_PATH_TO_CSS_VAR_INFIX = { - 'color.background': 'color', - 'color.text': 'color', - 'elements.link.color.text': 'color', - 'elements.link.:hover.color.text': 'color', - 'elements.link.typography.fontFamily': 'font-family', - 'elements.link.typography.fontSize': 'font-size', - 'elements.button.color.text': 'color', - 'elements.button.color.background': 'color', - 'elements.button.typography.fontFamily': 'font-family', - 'elements.button.typography.fontSize': 'font-size', - 'elements.heading.color': 'color', - 'elements.heading.color.background': 'color', - 'elements.heading.typography.fontFamily': 'font-family', - 'elements.heading.gradient': 'gradient', - 'elements.heading.color.gradient': 'gradient', - 'elements.h1.color': 'color', - 'elements.h1.color.background': 'color', - 'elements.h1.typography.fontFamily': 'font-family', - 'elements.h1.color.gradient': 'gradient', - 'elements.h2.color': 'color', - 'elements.h2.color.background': 'color', - 'elements.h2.typography.fontFamily': 'font-family', - 'elements.h2.color.gradient': 'gradient', - 'elements.h3.color': 'color', - 'elements.h3.color.background': 'color', - 'elements.h3.typography.fontFamily': 'font-family', - 'elements.h3.color.gradient': 'gradient', - 'elements.h4.color': 'color', - 'elements.h4.color.background': 'color', - 'elements.h4.typography.fontFamily': 'font-family', - 'elements.h4.color.gradient': 'gradient', - 'elements.h5.color': 'color', - 'elements.h5.color.background': 'color', - 'elements.h5.typography.fontFamily': 'font-family', - 'elements.h5.color.gradient': 'gradient', - 'elements.h6.color': 'color', - 'elements.h6.color.background': 'color', - 'elements.h6.typography.fontFamily': 'font-family', - 'elements.h6.color.gradient': 'gradient', - 'color.gradient': 'gradient', - 'typography.fontSize': 'font-size', - 'typography.fontFamily': 'font-family', -}; - -// A static list of block attributes that store global style preset slugs. -export const STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = { - 'color.background': 'backgroundColor', - 'color.text': 'textColor', - 'color.gradient': 'gradient', - 'typography.fontSize': 'fontSize', - 'typography.fontFamily': 'fontFamily', -}; - -function findInPresetsBy( - features, - blockName, - presetPath, - presetProperty, - presetValueValue -) { - // Block presets take priority above root level presets. - const orderedPresetsByOrigin = [ - get( features, [ 'blocks', blockName, ...presetPath ] ), - get( features, presetPath ), - ]; - - for ( const presetByOrigin of orderedPresetsByOrigin ) { - if ( presetByOrigin ) { - // Preset origins ordered by priority. - const origins = [ 'custom', 'theme', 'default' ]; - for ( const origin of origins ) { - const presets = presetByOrigin[ origin ]; - if ( presets ) { - const presetObject = presets.find( - ( preset ) => - preset[ presetProperty ] === presetValueValue - ); - if ( presetObject ) { - if ( presetProperty === 'slug' ) { - return presetObject; - } - // If there is a highest priority preset with the same slug but different value the preset we found was overwritten and should be ignored. - const highestPresetObjectWithSameSlug = findInPresetsBy( - features, - blockName, - presetPath, - 'slug', - presetObject.slug - ); - if ( - highestPresetObjectWithSameSlug[ - presetProperty - ] === presetObject[ presetProperty ] - ) { - return presetObject; - } - return undefined; - } - } - } - } - } -} - -export function getPresetVariableFromValue( - features, - blockName, - variableStylePath, - presetPropertyValue -) { - if ( ! presetPropertyValue ) { - return presetPropertyValue; - } - - const cssVarInfix = STYLE_PATH_TO_CSS_VAR_INFIX[ variableStylePath ]; - - const metadata = PRESET_METADATA.find( - ( data ) => data.cssVarInfix === cssVarInfix - ); - - if ( ! metadata ) { - // The property doesn't have preset data - // so the value should be returned as it is. - return presetPropertyValue; - } - const { valueKey, path } = metadata; - - const presetObject = findInPresetsBy( - features, - blockName, - path, - valueKey, - presetPropertyValue - ); - - if ( ! presetObject ) { - // Value wasn't found in the presets, - // so it must be a custom value. - return presetPropertyValue; - } - - return `var:preset|${ cssVarInfix }|${ presetObject.slug }`; -} - -function getValueFromPresetVariable( - features, - blockName, - variable, - [ presetType, slug ] -) { - const metadata = PRESET_METADATA.find( - ( data ) => data.cssVarInfix === presetType - ); - if ( ! metadata ) { - return variable; - } - - const presetObject = findInPresetsBy( - features.settings, - blockName, - metadata.path, - 'slug', - slug - ); - - if ( presetObject ) { - const { valueKey } = metadata; - const result = presetObject[ valueKey ]; - return getValueFromVariable( features, blockName, result ); - } - - return variable; -} - -function getValueFromCustomVariable( features, blockName, variable, path ) { - const result = - get( features.settings, [ 'blocks', blockName, 'custom', ...path ] ) ?? - get( features.settings, [ 'custom', ...path ] ); - if ( ! result ) { - return variable; - } - // A variable may reference another variable so we need recursion until we find the value. - return getValueFromVariable( features, blockName, result ); -} - -/** - * Attempts to fetch the value of a theme.json CSS variable. - * - * @param {Object} features GlobalStylesContext config, e.g., user, base or merged. Represents the theme.json tree. - * @param {string} blockName The name of a block as represented in the styles property. E.g., 'root' for root-level, and 'core/${blockName}' for blocks. - * @param {string|*} variable An incoming style value. A CSS var value is expected, but it could be any value. - * @return {string|*|{ref}} The value of the CSS var, if found. If not found, the passed variable argument. - */ -export function getValueFromVariable( features, blockName, variable ) { - if ( ! variable || typeof variable !== 'string' ) { - if ( variable?.ref && typeof variable?.ref === 'string' ) { - const refPath = variable.ref.split( '.' ); - variable = get( features, refPath ); - // Presence of another ref indicates a reference to another dynamic value. - // Pointing to another dynamic value is not supported. - if ( ! variable || !! variable?.ref ) { - return variable; - } - } else { - return variable; - } - } - const USER_VALUE_PREFIX = 'var:'; - const THEME_VALUE_PREFIX = 'var(--wp--'; - const THEME_VALUE_SUFFIX = ')'; - - let parsedVar; - - if ( variable.startsWith( USER_VALUE_PREFIX ) ) { - parsedVar = variable.slice( USER_VALUE_PREFIX.length ).split( '|' ); - } else if ( - variable.startsWith( THEME_VALUE_PREFIX ) && - variable.endsWith( THEME_VALUE_SUFFIX ) - ) { - parsedVar = variable - .slice( THEME_VALUE_PREFIX.length, -THEME_VALUE_SUFFIX.length ) - .split( '--' ); - } else { - // We don't know how to parse the value: either is raw of uses complex CSS such as `calc(1px * var(--wp--variable) )` - return variable; - } - - const [ type, ...path ] = parsedVar; - if ( type === 'preset' ) { - return getValueFromPresetVariable( - features, - blockName, - variable, - path - ); - } - if ( type === 'custom' ) { - return getValueFromCustomVariable( - features, - blockName, - variable, - path - ); - } - return variable; -} - -/** - * Function that scopes a selector with another one. This works a bit like - * SCSS nesting except the `&` operator isn't supported. - * - * @example - * ```js - * const scope = '.a, .b .c'; - * const selector = '> .x, .y'; - * const merged = scopeSelector( scope, selector ); - * // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y' - * ``` - * - * @param {string} scope Selector to scope to. - * @param {string} selector Original selector. - * - * @return {string} Scoped selector. - */ -export function scopeSelector( scope, selector ) { - const scopes = scope.split( ',' ); - const selectors = selector.split( ',' ); - - const selectorsScoped = []; - scopes.forEach( ( outer ) => { - selectors.forEach( ( inner ) => { - selectorsScoped.push( `${ outer.trim() } ${ inner.trim() }` ); - } ); - } ); - - return selectorsScoped.join( ', ' ); -} - /** * * @param {string} path The variation path in the Global Styles tree. diff --git a/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js b/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js index 8f6df129a4e91..d33beb68e5757 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js @@ -13,13 +13,17 @@ import { styles, moreVertical, seen } from '@wordpress/icons'; import { useDispatch, useSelect } from '@wordpress/data'; import { store as preferencesStore } from '@wordpress/preferences'; import { useState, useEffect } from '@wordpress/element'; +import { experiments as blockEditorExperiments } from '@wordpress/block-editor'; /** * Internal dependencies */ import DefaultSidebar from './default-sidebar'; -import { GlobalStylesUI, useGlobalStylesReset } from '../global-styles'; +import { GlobalStylesUI } from '../global-styles'; import { store as editSiteStore } from '../../store'; +import { unlock } from '../../experiments'; + +const { useGlobalStylesReset } = unlock( blockEditorExperiments ); export default function GlobalStylesSidebar() { const [ canReset, onReset ] = useGlobalStylesReset(); diff --git a/packages/edit-site/src/components/style-book/index.js b/packages/edit-site/src/components/style-book/index.js index b44b2b7b259b4..af38a19161ec3 100644 --- a/packages/edit-site/src/components/style-book/index.js +++ b/packages/edit-site/src/components/style-book/index.js @@ -19,7 +19,10 @@ import { getBlockFromExample, createBlock, } from '@wordpress/blocks'; -import { BlockPreview } from '@wordpress/block-editor'; +import { + BlockPreview, + experiments as blockEditorExperiments, +} from '@wordpress/block-editor'; import { closeSmall } from '@wordpress/icons'; import { useResizeObserver } from '@wordpress/compose'; import { useMemo, memo } from '@wordpress/element'; @@ -27,7 +30,9 @@ import { useMemo, memo } from '@wordpress/element'; /** * Internal dependencies */ -import { useStyle } from '../global-styles'; +import { unlock } from '../../experiments'; + +const { useGlobalStyle } = unlock( blockEditorExperiments ); const SLOT_FILL_NAME = 'EditSiteStyleBook'; const { Slot: StyleBookSlot, Fill: StyleBookFill } = @@ -81,8 +86,8 @@ function getExamples() { function StyleBook( { isSelected, onSelect, onClose } ) { const [ resizeObserver, sizes ] = useResizeObserver(); - const [ textColor ] = useStyle( 'color.text' ); - const [ backgroundColor ] = useStyle( 'color.background' ); + const [ textColor ] = useGlobalStyle( 'color.text' ); + const [ backgroundColor ] = useGlobalStyle( 'color.background' ); const examples = useMemo( getExamples, [] ); const tabs = useMemo( () => diff --git a/packages/edit-site/src/experiments.js b/packages/edit-site/src/experiments.js new file mode 100644 index 0000000000000..a5c54a29b4475 --- /dev/null +++ b/packages/edit-site/src/experiments.js @@ -0,0 +1,10 @@ +/** + * WordPress dependencies + */ +import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments'; + +export const { lock, unlock } = + __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.', + '@wordpress/edit-site' + ); diff --git a/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js b/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js index 6d29de4fdc9ee..c23b184876eb9 100644 --- a/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js +++ b/packages/edit-site/src/hooks/push-changes-to-global-styles/index.js @@ -11,6 +11,7 @@ import { createHigherOrderComponent } from '@wordpress/compose'; import { InspectorAdvancedControls, store as blockEditorStore, + experiments as blockEditorExperiments, } from '@wordpress/block-editor'; import { BaseControl, Button } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; @@ -26,11 +27,68 @@ import { store as noticesStore } from '@wordpress/notices'; * Internal dependencies */ import { getSupportedGlobalStylesPanels } from '../../components/global-styles/hooks'; -import { GlobalStylesContext } from '../../components/global-styles/context'; -import { - STYLE_PATH_TO_CSS_VAR_INFIX, - STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE, -} from '../../components/global-styles/utils'; +import { unlock } from '../../experiments'; + +const { GlobalStylesContext } = unlock( blockEditorExperiments ); + +// TODO: Temporary duplication of constant in @wordpress/block-editor. Can be +// removed by moving PushChangesToGlobalStylesControl to +// @wordpress/block-editor. +const STYLE_PATH_TO_CSS_VAR_INFIX = { + 'color.background': 'color', + 'color.text': 'color', + 'elements.link.color.text': 'color', + 'elements.link.:hover.color.text': 'color', + 'elements.link.typography.fontFamily': 'font-family', + 'elements.link.typography.fontSize': 'font-size', + 'elements.button.color.text': 'color', + 'elements.button.color.background': 'color', + 'elements.button.typography.fontFamily': 'font-family', + 'elements.button.typography.fontSize': 'font-size', + 'elements.heading.color': 'color', + 'elements.heading.color.background': 'color', + 'elements.heading.typography.fontFamily': 'font-family', + 'elements.heading.gradient': 'gradient', + 'elements.heading.color.gradient': 'gradient', + 'elements.h1.color': 'color', + 'elements.h1.color.background': 'color', + 'elements.h1.typography.fontFamily': 'font-family', + 'elements.h1.color.gradient': 'gradient', + 'elements.h2.color': 'color', + 'elements.h2.color.background': 'color', + 'elements.h2.typography.fontFamily': 'font-family', + 'elements.h2.color.gradient': 'gradient', + 'elements.h3.color': 'color', + 'elements.h3.color.background': 'color', + 'elements.h3.typography.fontFamily': 'font-family', + 'elements.h3.color.gradient': 'gradient', + 'elements.h4.color': 'color', + 'elements.h4.color.background': 'color', + 'elements.h4.typography.fontFamily': 'font-family', + 'elements.h4.color.gradient': 'gradient', + 'elements.h5.color': 'color', + 'elements.h5.color.background': 'color', + 'elements.h5.typography.fontFamily': 'font-family', + 'elements.h5.color.gradient': 'gradient', + 'elements.h6.color': 'color', + 'elements.h6.color.background': 'color', + 'elements.h6.typography.fontFamily': 'font-family', + 'elements.h6.color.gradient': 'gradient', + 'color.gradient': 'gradient', + 'typography.fontSize': 'font-size', + 'typography.fontFamily': 'font-family', +}; + +// TODO: Temporary duplication of constant in @wordpress/block-editor. Can be +// removed by moving PushChangesToGlobalStylesControl to +// @wordpress/block-editor. +const STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = { + 'color.background': 'backgroundColor', + 'color.text': 'textColor', + 'color.gradient': 'gradient', + 'typography.fontSize': 'fontSize', + 'typography.fontFamily': 'fontFamily', +}; function getChangesToPush( name, attributes ) { return getSupportedGlobalStylesPanels( name ).flatMap( ( key ) => { diff --git a/packages/experiments/src/implementation.js b/packages/experiments/src/implementation.js index bf333b7e2646f..b818a3669d8e7 100644 --- a/packages/experiments/src/implementation.js +++ b/packages/experiments/src/implementation.js @@ -13,6 +13,7 @@ const CORE_MODULES_USING_EXPERIMENTS = [ '@wordpress/data', '@wordpress/blocks', '@wordpress/block-editor', + '@wordpress/edit-site', ]; /** From 2499646e1dff9a82520749eb17d96cf85c8a0a1a Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 20 Jan 2023 07:51:22 +0000 Subject: [PATCH 03/13] Fix Link Control action button visuals (#47306) --- .../src/components/link-control/index.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/link-control/index.js b/packages/block-editor/src/components/link-control/index.js index 7ffa6b327029a..1f54ac4e196a6 100644 --- a/packages/block-editor/src/components/link-control/index.js +++ b/packages/block-editor/src/components/link-control/index.js @@ -6,13 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { - Button, - ButtonGroup, - Spinner, - Notice, - TextControl, -} from '@wordpress/components'; +import { Button, Spinner, Notice, TextControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useRef, useState, useEffect } from '@wordpress/element'; import { focus } from '@wordpress/dom'; @@ -341,7 +335,7 @@ function LinkControl( { { errorMessage } ) } - +
- +
) } From fdc180a53110b48e98be3460bb8be1b65152ea1e Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 20 Jan 2023 19:28:29 +1100 Subject: [PATCH 04/13] Stabilise BlockPreview props (#47231) * Stabilise BlockPreview props * Remove unnecessary __experimentalStyles migration * Add version to deprecated() calls * Default padding to 0, allow additionalStyles to override default styling --- .../components/block-pattern-setup/index.js | 5 +-- .../src/components/block-preview/README.md | 18 +++++----- .../src/components/block-preview/auto.js | 20 +++++------ .../src/components/block-preview/index.js | 34 ++++++++++++++++--- .../src/components/inserter/preview-panel.js | 6 ++-- .../global-styles/block-preview-panel.js | 4 +-- .../src/components/style-book/index.js | 2 +- 7 files changed, 55 insertions(+), 34 deletions(-) diff --git a/packages/block-editor/src/components/block-pattern-setup/index.js b/packages/block-editor/src/components/block-pattern-setup/index.js index b39aa070c529e..22d51466b3b6e 100644 --- a/packages/block-editor/src/components/block-pattern-setup/index.js +++ b/packages/block-editor/src/components/block-pattern-setup/index.js @@ -127,10 +127,7 @@ function BlockPatternSlide( { className, pattern, minHeight } ) { aria-label={ title } aria-describedby={ description ? descriptionId : undefined } > - + { !! description && ( { description } diff --git a/packages/block-editor/src/components/block-preview/README.md b/packages/block-editor/src/components/block-preview/README.md index 6ae8cfe97514a..5cce2e45cb54f 100644 --- a/packages/block-editor/src/components/block-preview/README.md +++ b/packages/block-editor/src/components/block-preview/README.md @@ -30,26 +30,26 @@ Width of the preview container in pixels. Controls at what size the blocks will Set `viewportWidth` to `0` to make the viewport the same width as the container. -### `__experimentalPadding` +### minHeight -- **Type** `Int` -- **Default** `undefined` +Minimum height of the preview iframe in pixels. -Padding for the preview container body. +- **Type:** `Int` +- **Default:** `undefined` -### `__experimentalStyles` +### `additionalStyles` List of additional editor styles to load into the preview iframe. Each object should contain a `css` attribute. See `EditorStyles` for more info. ```jsx ``` -- **Type** `Int` +- **Type** `Array` - **Default** `[]` diff --git a/packages/block-editor/src/components/block-preview/auto.js b/packages/block-editor/src/components/block-preview/auto.js index fb763ed466629..287bcd5b18566 100644 --- a/packages/block-editor/src/components/block-preview/auto.js +++ b/packages/block-editor/src/components/block-preview/auto.js @@ -23,9 +23,8 @@ const MAX_HEIGHT = 2000; function ScaledBlockPreview( { viewportWidth, containerWidth, - __experimentalPadding, - __experimentalMinHeight, - __experimentalStyles, + minHeight, + additionalStyles = [], } ) { if ( ! viewportWidth ) { viewportWidth = containerWidth; @@ -46,16 +45,16 @@ function ScaledBlockPreview( { if ( styles ) { return [ ...styles, - ...__experimentalStyles, { - css: 'body{height:auto;overflow:hidden;border:none;}', + css: 'body{height:auto;overflow:hidden;border:none;padding:0;}', __unstableType: 'presets', }, + ...additionalStyles, ]; } return styles; - }, [ styles, __experimentalStyles ] ); + }, [ styles, additionalStyles ] ); const svgFilters = useMemo( () => { return [ ...( duotone?.default ?? [] ), ...( duotone?.theme ?? [] ) ]; @@ -73,7 +72,7 @@ function ScaledBlockPreview( { height: contentHeight * scale, maxHeight: contentHeight > MAX_HEIGHT ? MAX_HEIGHT * scale : undefined, - minHeight: __experimentalMinHeight, + minHeight, } } >