diff --git a/package-lock.json b/package-lock.json index 535b581ec3870b..4987c088829b75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56019,6 +56019,7 @@ "dom-scroll-into-view": "^1.2.1", "fast-deep-equal": "^3.1.3", "inherits": "^2.0.3", + "memize": "^2.1.0", "react-autosize-textarea": "^7.1.0", "react-easy-crop": "^4.5.1", "rememo": "^4.0.2", @@ -69429,6 +69430,7 @@ "dom-scroll-into-view": "^1.2.1", "fast-deep-equal": "^3.1.3", "inherits": "^2.0.3", + "memize": "^2.1.0", "react-autosize-textarea": "^7.1.0", "react-easy-crop": "^4.5.1", "rememo": "^4.0.2", diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index df264090d6f0d7..5c6e9a5602add6 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -2,23 +2,25 @@ ## Unreleased +- Deprecated the `useSetting` function in favor of new `useSettings` one that can retrieve multiple settings at once ([#55337](https://github.com/WordPress/gutenberg/pull/55337)). + ## 12.12.0 (2023-10-18) ## 12.11.0 (2023-10-05) -- Deprecated `CopyHandler`, absorbed into `WritingFlow`. +- Deprecated `CopyHandler`, absorbed into `WritingFlow`. ## 12.10.0 (2023-09-20) -- The Deprecated multiline prop on RichText will now fall back to using multiple - rich text instances instead of a single multiline instance. The prop remains - deprecated. +- The Deprecated multiline prop on RichText will now fall back to using multiple + rich text instances instead of a single multiline instance. The prop remains + deprecated. ## 12.9.0 (2023-08-31) ### Enhancements -- Embed the `ObserveTyping` behavior within the `BlockList` component making to simplify instanciations of third-party block editors. +- Embed the `ObserveTyping` behavior within the `BlockList` component making to simplify instanciations of third-party block editors. ## 12.8.0 (2023-08-16) @@ -32,13 +34,12 @@ ### Enhancements -- Add `HeadingLevelDropdown` component for selecting H1-H6 and paragraph HTML tags from the block toolbar. +- Add `HeadingLevelDropdown` component for selecting H1-H6 and paragraph HTML tags from the block toolbar. ### Bug Fix - Fluid typography: custom font-sizes should use max viewport width ([#51516](https://github.com/WordPress/gutenberg/pull/51516)). - ## 12.3.0 (2023-06-07) ## 12.2.0 (2023-05-24) @@ -51,11 +52,10 @@ ### Breaking Changes -- Renamed utility function `immutableSet` to `setImmutably` ([#50040](https://github.com/WordPress/gutenberg/pull/50040)). +- Renamed utility function `immutableSet` to `setImmutably` ([#50040](https://github.com/WordPress/gutenberg/pull/50040)). ## 11.8.0 (2023-04-12) - ## 11.7.0 (2023-03-29) - `ImageSizeControl`: Update image size label ([#49112](https://github.com/WordPress/gutenberg/pull/49112)). @@ -102,7 +102,7 @@ ### Bug Fix - `SpacingSizesControl`: Change ARIA role from `region` to `group` to avoid unwanted ARIA landmark regions ([#46530](https://github.com/WordPress/gutenberg/pull/46530)). -- `FocalPointPicker`: Fix layout misalignment when placed in the `BlockInspector` ([#46631](https://github.com/WordPress/gutenberg/pull/46631)). +- `FocalPointPicker`: Fix layout misalignment when placed in the `BlockInspector` ([#46631](https://github.com/WordPress/gutenberg/pull/46631)). ## 10.5.0 (2022-11-16) diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 063a96384708cb..02671d5dca0e3c 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -944,9 +944,11 @@ _Parameters_ ### useSetting +> **Deprecated** 6.4.0 Use useSettings instead. + Hook that retrieves the given setting for the block instance in use. -It looks up the settings first in the block instance hierarchy. If none is found, it'll look it up in the block editor store. +It looks up the setting first in the block instance hierarchy. If none is found, it'll look it up in the block editor settings. _Usage_ @@ -962,6 +964,26 @@ _Returns_ - `any`: Returns the value defined for the setting. +### useSettings + +Hook that retrieves the given settings for the block instance in use. + +It looks up the settings first in the block instance hierarchy. If none are found, it'll look them up in the block editor settings. + +_Usage_ + +```js +const [ fixed, sticky ] = useSettings( 'position.fixed', 'position.sticky' ); +``` + +_Parameters_ + +- _paths_ `string[]`: The paths to the settings. + +_Returns_ + +- `any[]`: Returns the values defined for the settings. + ### Warning _Related_ diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index feafe8f16e82ef..225d9c987638af 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -72,6 +72,7 @@ "dom-scroll-into-view": "^1.2.1", "fast-deep-equal": "^3.1.3", "inherits": "^2.0.3", + "memize": "^2.1.0", "react-autosize-textarea": "^7.1.0", "react-easy-crop": "^4.5.1", "rememo": "^4.0.2", diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 405a883ed3b231..c6cce290985c22 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -38,9 +38,9 @@ import BlockInvalidWarning from './block-invalid-warning'; import BlockOutline from './block-outline'; import { store as blockEditorStore } from '../../store'; import { useLayout } from './layout'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; -const emptyArray = []; +const EMPTY_ARRAY = []; // Helper function to memoize the wrapperProps since getEditWrapperProps always returns a new reference. const wrapperPropsCache = new WeakMap(); @@ -215,7 +215,7 @@ function BlockListBlock( { const parentLayout = useLayout() || {}; const defaultColors = useMobileGlobalStylesColors(); const globalStyle = useGlobalStyles(); - const fontSizes = useSetting( 'typography.fontSizes' ) || emptyArray; + const [ fontSizes ] = useSettings( 'typography.fontSizes' ); const onRemove = useCallback( () => removeBlock( clientId ), @@ -257,7 +257,7 @@ function BlockListBlock( { attributes, defaultColors, name, - fontSizes + fontSizes || EMPTY_ARRAY ); // eslint-disable-next-line react-hooks/exhaustive-deps }, [ diff --git a/packages/block-editor/src/components/block-list/layout.js b/packages/block-editor/src/components/block-list/layout.js index d7a9113ebfa0f3..a7de26cc5a0fa8 100644 --- a/packages/block-editor/src/components/block-list/layout.js +++ b/packages/block-editor/src/components/block-list/layout.js @@ -7,7 +7,7 @@ import { createContext, useContext } from '@wordpress/element'; * Internal dependencies */ import { getLayoutType } from '../../layouts'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; export const defaultLayout = { type: 'default' }; @@ -27,7 +27,7 @@ export function useLayout() { export function LayoutStyle( { layout = {}, css, ...props } ) { const layoutType = getLayoutType( layout.type ); - const blockGapSupport = useSetting( 'spacing.blockGap' ); + const [ blockGapSupport ] = useSettings( 'spacing.blockGap' ); const hasBlockGapSupport = blockGapSupport !== null; if ( layoutType ) { diff --git a/packages/block-editor/src/components/border-radius-control/index.js b/packages/block-editor/src/components/border-radius-control/index.js index 0f9041389f244a..4c614084a7e200 100644 --- a/packages/block-editor/src/components/border-radius-control/index.js +++ b/packages/block-editor/src/components/border-radius-control/index.js @@ -16,7 +16,7 @@ import { __ } from '@wordpress/i18n'; import AllInputControl from './all-input-control'; import InputControls from './input-controls'; import LinkedButton from './linked-button'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; import { getAllValue, getAllUnit, @@ -67,8 +67,9 @@ export default function BorderRadiusControl( { onChange, values } ) { )[ 1 ], } ); + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ 'px', 'em', 'rem' ], + availableUnits: availableUnits || [ 'px', 'em', 'rem' ], } ); const unit = getAllUnit( selectedUnits ); diff --git a/packages/block-editor/src/components/color-palette/with-color-context.js b/packages/block-editor/src/components/color-palette/with-color-context.js index 4c60a44b9348ea..62b8c1bc4b6181 100644 --- a/packages/block-editor/src/components/color-palette/with-color-context.js +++ b/packages/block-editor/src/components/color-palette/with-color-context.js @@ -6,18 +6,18 @@ import { createHigherOrderComponent } from '@wordpress/compose'; /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; export default createHigherOrderComponent( ( WrappedComponent ) => { return ( props ) => { - const colorsFeature = useSetting( 'color.palette' ); - const disableCustomColorsFeature = ! useSetting( 'color.custom' ); - const colors = - props.colors === undefined ? colorsFeature : props.colors; - const disableCustomColors = - props.disableCustomColors === undefined - ? disableCustomColorsFeature - : props.disableCustomColors; + const [ colorsFeature, enableCustomColors ] = useSettings( + 'color.palette', + 'color.custom' + ); + const { + colors = colorsFeature, + disableCustomColors = ! enableCustomColors, + } = props; const hasColorsToChoose = ( colors && colors.length > 0 ) || ! disableCustomColors; return ( diff --git a/packages/block-editor/src/components/colors-gradients/control.js b/packages/block-editor/src/components/colors-gradients/control.js index 14fb9841e5f921..51912e0a74e9d1 100644 --- a/packages/block-editor/src/components/colors-gradients/control.js +++ b/packages/block-editor/src/components/colors-gradients/control.js @@ -18,7 +18,7 @@ import { /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; const colorsAndGradientKeys = [ 'colors', @@ -160,17 +160,20 @@ function ColorGradientControlInner( { } function ColorGradientControlSelect( props ) { - const colorGradientSettings = {}; - colorGradientSettings.colors = useSetting( 'color.palette' ); - colorGradientSettings.gradients = useSetting( 'color.gradients' ); - colorGradientSettings.disableCustomColors = ! useSetting( 'color.custom' ); - colorGradientSettings.disableCustomGradients = ! useSetting( + const [ colors, gradients, customColors, customGradients ] = useSettings( + 'color.palette', + 'color.gradients', + 'color.custom', 'color.customGradient' ); return ( ); } diff --git a/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js b/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js index 917ca04783de18..ee27960529ede3 100644 --- a/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +++ b/packages/block-editor/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js @@ -7,7 +7,7 @@ import { _x } from '@wordpress/i18n'; /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; /** * Retrieves color and gradient related settings. @@ -18,14 +18,34 @@ import useSetting from '../use-setting'; * @return {Object} Color and gradient related settings. */ export default function useMultipleOriginColorsAndGradients() { + const [ + enableCustomColors, + customColors, + themeColors, + defaultColors, + shouldDisplayDefaultColors, + enableCustomGradients, + customGradients, + themeGradients, + defaultGradients, + shouldDisplayDefaultGradients, + ] = useSettings( + 'color.custom', + 'color.palette.custom', + 'color.palette.theme', + 'color.palette.default', + 'color.defaultPalette', + 'color.customGradient', + 'color.gradients.custom', + 'color.gradients.theme', + 'color.gradients.default', + 'color.defaultGradients' + ); + const colorGradientSettings = { - disableCustomColors: ! useSetting( 'color.custom' ), - disableCustomGradients: ! useSetting( 'color.customGradient' ), + disableCustomColors: ! enableCustomColors, + disableCustomGradients: ! enableCustomGradients, }; - const customColors = useSetting( 'color.palette.custom' ); - const themeColors = useSetting( 'color.palette.theme' ); - const defaultColors = useSetting( 'color.palette.default' ); - const shouldDisplayDefaultColors = useSetting( 'color.defaultPalette' ); colorGradientSettings.colors = useMemo( () => { const result = []; @@ -62,18 +82,12 @@ export default function useMultipleOriginColorsAndGradients() { } return result; }, [ - defaultColors, - themeColors, customColors, + themeColors, + defaultColors, shouldDisplayDefaultColors, ] ); - const customGradients = useSetting( 'color.gradients.custom' ); - const themeGradients = useSetting( 'color.gradients.theme' ); - const defaultGradients = useSetting( 'color.gradients.default' ); - const shouldDisplayDefaultGradients = useSetting( - 'color.defaultGradients' - ); colorGradientSettings.gradients = useMemo( () => { const result = []; if ( themeGradients && themeGradients.length ) { diff --git a/packages/block-editor/src/components/colors/with-colors.js b/packages/block-editor/src/components/colors/with-colors.js index e2fbd0b89b5ada..5946ca90d8bbde 100644 --- a/packages/block-editor/src/components/colors/with-colors.js +++ b/packages/block-editor/src/components/colors/with-colors.js @@ -13,7 +13,7 @@ import { getColorObjectByAttributeValues, getMostReadableColor, } from './utils'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; import { kebabCase } from '../../utils/object'; /** @@ -51,12 +51,11 @@ const withCustomColorPalette = ( colorsArray ) => const withEditorColorPalette = () => createHigherOrderComponent( ( WrappedComponent ) => ( props ) => { - // Some color settings have a special handling for deprecated flags in `useSetting`, - // so we can't unwrap them by doing const { ... } = useSetting('color') - // until https://github.com/WordPress/gutenberg/issues/37094 is fixed. - const userPalette = useSetting( 'color.palette.custom' ); - const themePalette = useSetting( 'color.palette.theme' ); - const defaultPalette = useSetting( 'color.palette.default' ); + const [ userPalette, themePalette, defaultPalette ] = useSettings( + 'color.palette.custom', + 'color.palette.theme', + 'color.palette.default' + ); const allColors = useMemo( () => [ ...( userPalette || [] ), diff --git a/packages/block-editor/src/components/font-family/index.js b/packages/block-editor/src/components/font-family/index.js index 08e17313368a61..4a40a880e537cb 100644 --- a/packages/block-editor/src/components/font-family/index.js +++ b/packages/block-editor/src/components/font-family/index.js @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; export default function FontFamilyControl( { value = '', @@ -15,7 +15,7 @@ export default function FontFamilyControl( { fontFamilies, ...props } ) { - const blockLevelFontFamilies = useSetting( 'typography.fontFamilies' ); + const [ blockLevelFontFamilies ] = useSettings( 'typography.fontFamilies' ); if ( ! fontFamilies ) { fontFamilies = blockLevelFontFamilies; } diff --git a/packages/block-editor/src/components/font-sizes/font-size-picker.js b/packages/block-editor/src/components/font-sizes/font-size-picker.js index 9f195310367fc1..959b2c23806ded 100644 --- a/packages/block-editor/src/components/font-sizes/font-size-picker.js +++ b/packages/block-editor/src/components/font-sizes/font-size-picker.js @@ -6,17 +6,19 @@ import { FontSizePicker as BaseFontSizePicker } from '@wordpress/components'; /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; function FontSizePicker( props ) { - const fontSizes = useSetting( 'typography.fontSizes' ); - const disableCustomFontSizes = ! useSetting( 'typography.customFontSize' ); + const [ fontSizes, customFontSize ] = useSettings( + 'typography.fontSizes', + 'typography.customFontSize' + ); return ( ); } diff --git a/packages/block-editor/src/components/font-sizes/with-font-sizes.js b/packages/block-editor/src/components/font-sizes/with-font-sizes.js index 50f3ea77828170..8402a2c23afeb3 100644 --- a/packages/block-editor/src/components/font-sizes/with-font-sizes.js +++ b/packages/block-editor/src/components/font-sizes/with-font-sizes.js @@ -8,7 +8,7 @@ import { Component } from '@wordpress/element'; * Internal dependencies */ import { getFontSize, getFontSizeClass } from './utils'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; const DEFAULT_FONT_SIZES = []; @@ -52,13 +52,11 @@ export default ( ...fontSizeNames ) => { compose( [ createHigherOrderComponent( ( WrappedComponent ) => ( props ) => { - const fontSizes = - useSetting( 'typography.fontSizes' ) || - DEFAULT_FONT_SIZES; + const [ fontSizes ] = useSettings( 'typography.fontSizes' ); return ( ); }, diff --git a/packages/block-editor/src/components/gradients/use-gradient.js b/packages/block-editor/src/components/gradients/use-gradient.js index e899f9c9197708..938a60143d7670 100644 --- a/packages/block-editor/src/components/gradients/use-gradient.js +++ b/packages/block-editor/src/components/gradients/use-gradient.js @@ -8,7 +8,7 @@ import { useSelect, useDispatch } from '@wordpress/data'; * Internal dependencies */ import { useBlockEditContext } from '../block-edit'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; import { store as blockEditorStore } from '../../store'; export function __experimentalGetGradientClass( gradientSlug ) { @@ -60,9 +60,15 @@ export function __experimentalUseGradient( { } = {} ) { const { clientId } = useBlockEditContext(); - const userGradientPalette = useSetting( 'color.gradients.custom' ); - const themeGradientPalette = useSetting( 'color.gradients.theme' ); - const defaultGradientPalette = useSetting( 'color.gradients.default' ); + const [ + userGradientPalette, + themeGradientPalette, + defaultGradientPalette, + ] = useSettings( + 'color.gradients.custom', + 'color.gradients.theme', + 'color.gradients.default' + ); const allGradients = useMemo( () => [ ...( userGradientPalette || [] ), diff --git a/packages/block-editor/src/components/height-control/index.js b/packages/block-editor/src/components/height-control/index.js index 538662c7626fcc..e1797522497447 100644 --- a/packages/block-editor/src/components/height-control/index.js +++ b/packages/block-editor/src/components/height-control/index.js @@ -17,7 +17,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; const RANGE_CONTROL_CUSTOM_SETTINGS = { px: { max: 1000, step: 1 }, @@ -69,8 +69,9 @@ export default function HeightControl( { } ) { const customRangeValue = parseFloat( value ); + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ + availableUnits: availableUnits || [ '%', 'px', 'em', diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 1622cecc150ed4..08247d8cdb014a 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -165,7 +165,7 @@ export { useBlockEditingMode } from './block-editing-mode'; */ export { default as BlockEditorProvider } from './provider'; -export { default as useSetting } from './use-setting'; +export { useSettings, useSetting } from './use-settings'; export { useBlockCommands } from './use-block-commands'; /* diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index a89fdb9d6ac637..de134f1b5e3bc4 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -59,7 +59,7 @@ export { default as BlockCaption } from './block-caption'; export { default as Caption } from './caption'; export { default as PanelColorSettings } from './panel-color-settings'; export { default as __experimentalPanelColorGradientSettings } from './colors-gradients/panel-color-gradient-settings'; -export { default as useSetting } from './use-setting'; +export { useSettings, default as useSetting } from './use-settings'; export { RecursionProvider as __experimentalRecursionProvider, useHasRecursion as __experimentalUseHasRecursion, diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js index 9e0e4f19cfc7ea..f5f216d6072e4b 100644 --- a/packages/block-editor/src/components/inner-blocks/index.js +++ b/packages/block-editor/src/components/inner-blocks/index.js @@ -29,7 +29,7 @@ import { useBlockEditContext } from '../block-edit/context'; import useBlockSync from '../provider/use-block-sync'; import { store as blockEditorStore } from '../../store'; import useBlockDropZone from '../use-block-drop-zone'; -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; const EMPTY_OBJECT = {}; @@ -98,7 +98,7 @@ function UncontrolledInnerBlocks( props ) { const { allowSizingOnChildren = false } = defaultLayoutBlockSupport; - const defaultLayout = useSetting( 'layout' ) || EMPTY_OBJECT; + const [ defaultLayout ] = useSettings( 'layout' ); const usedLayout = layout || defaultLayoutBlockSupport; diff --git a/packages/block-editor/src/components/letter-spacing-control/index.js b/packages/block-editor/src/components/letter-spacing-control/index.js index 757eab60e50ae0..2c36e59cd8241c 100644 --- a/packages/block-editor/src/components/letter-spacing-control/index.js +++ b/packages/block-editor/src/components/letter-spacing-control/index.js @@ -10,7 +10,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import useSetting from '../../components/use-setting'; +import { useSettings } from '../../components/use-settings'; /** * Control for letter-spacing. @@ -28,8 +28,9 @@ export default function LetterSpacingControl( { __unstableInputWidth = '60px', ...otherProps } ) { + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ 'px', 'em', 'rem' ], + availableUnits: availableUnits || [ 'px', 'em', 'rem' ], defaultValues: { px: 2, em: 0.2, rem: 0.2 }, } ); return ( diff --git a/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js b/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js index 4a24482f3b1e42..e75f3519a1ca6c 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js +++ b/packages/block-editor/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js @@ -6,13 +6,15 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import useSetting from '../../use-setting'; +import { useSettings } from '../../use-settings'; export default function useSpacingSizes() { - const spacingSizes = [ - { name: 0, slug: '0', size: 0 }, - ...( useSetting( 'spacing.spacingSizes' ) || [] ), - ]; + const spacingSizes = [ { name: 0, slug: '0', size: 0 } ]; + + const [ settingsSizes ] = useSettings( 'spacing.spacingSizes' ); + if ( settingsSizes ) { + spacingSizes.push( ...settingsSizes ); + } if ( spacingSizes.length > 8 ) { spacingSizes.unshift( { diff --git a/packages/block-editor/src/components/spacing-sizes-control/input-controls/spacing-input-control.js b/packages/block-editor/src/components/spacing-sizes-control/input-controls/spacing-input-control.js index 1b324835e362dc..a7efd10bce7125 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/input-controls/spacing-input-control.js +++ b/packages/block-editor/src/components/spacing-sizes-control/input-controls/spacing-input-control.js @@ -20,7 +20,7 @@ import { settings } from '@wordpress/icons'; /** * Internal dependencies */ -import useSetting from '../../use-setting'; +import { useSettings } from '../../use-settings'; import { store as blockEditorStore } from '../../../store'; import { ALL_SIDES, @@ -102,8 +102,9 @@ export default function SpacingInputControl( { setShowCustomValueControl( true ); } + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ 'px', 'em', 'rem' ], + availableUnits: availableUnits || [ 'px', 'em', 'rem' ], } ); let currentValue = null; diff --git a/packages/block-editor/src/components/unit-control/index.js b/packages/block-editor/src/components/unit-control/index.js index 5af8830dc48c25..a1ce0281759c04 100644 --- a/packages/block-editor/src/components/unit-control/index.js +++ b/packages/block-editor/src/components/unit-control/index.js @@ -9,17 +9,12 @@ import { /** * Internal dependencies */ -import useSetting from '../use-setting'; +import { useSettings } from '../use-settings'; export default function UnitControl( { units: unitsProp, ...props } ) { + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - '%', - 'px', - 'em', - 'rem', - 'vw', - ], + availableUnits: availableUnits || [ '%', 'px', 'em', 'rem', 'vw' ], units: unitsProp, } ); diff --git a/packages/block-editor/src/components/use-setting/index.js b/packages/block-editor/src/components/use-setting/index.js deleted file mode 100644 index 1ae672103015ce..00000000000000 --- a/packages/block-editor/src/components/use-setting/index.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * WordPress dependencies - */ -import { useSelect } from '@wordpress/data'; -import { - __EXPERIMENTAL_PATHS_WITH_MERGE as PATHS_WITH_MERGE, - hasBlockSupport, -} from '@wordpress/blocks'; -import { applyFilters } from '@wordpress/hooks'; - -/** - * Internal dependencies - */ -import { useBlockEditContext } from '../block-edit'; -import { store as blockEditorStore } from '../../store'; -import { getValueFromObjectPath } from '../../utils/object'; - -const blockedPaths = [ - 'color', - 'border', - 'dimensions', - 'typography', - 'spacing', -]; - -const deprecatedFlags = { - 'color.palette': ( settings ) => settings.colors, - 'color.gradients': ( settings ) => settings.gradients, - 'color.custom': ( settings ) => - settings.disableCustomColors === undefined - ? undefined - : ! settings.disableCustomColors, - 'color.customGradient': ( settings ) => - settings.disableCustomGradients === undefined - ? undefined - : ! settings.disableCustomGradients, - 'typography.fontSizes': ( settings ) => settings.fontSizes, - 'typography.customFontSize': ( settings ) => - settings.disableCustomFontSizes === undefined - ? undefined - : ! settings.disableCustomFontSizes, - 'typography.lineHeight': ( settings ) => settings.enableCustomLineHeight, - 'spacing.units': ( settings ) => { - if ( settings.enableCustomUnits === undefined ) { - return; - } - - if ( settings.enableCustomUnits === true ) { - return [ 'px', 'em', 'rem', 'vh', 'vw', '%' ]; - } - - return settings.enableCustomUnits; - }, - 'spacing.padding': ( settings ) => settings.enableCustomSpacing, -}; - -const prefixedFlags = { - /* - * These were only available in the plugin - * and can be removed when the minimum WordPress version - * for the plugin is 5.9. - */ - 'border.customColor': 'border.color', - 'border.customStyle': 'border.style', - 'border.customWidth': 'border.width', - 'typography.customFontStyle': 'typography.fontStyle', - 'typography.customFontWeight': 'typography.fontWeight', - 'typography.customLetterSpacing': 'typography.letterSpacing', - 'typography.customTextDecorations': 'typography.textDecoration', - 'typography.customTextTransforms': 'typography.textTransform', - /* - * These were part of WordPress 5.8 and we need to keep them. - */ - 'border.customRadius': 'border.radius', - 'spacing.customMargin': 'spacing.margin', - 'spacing.customPadding': 'spacing.padding', - 'typography.customLineHeight': 'typography.lineHeight', -}; - -/** - * Remove `custom` prefixes for flags that did not land in 5.8. - * - * This provides continued support for `custom` prefixed properties. It will - * be removed once third party devs have had sufficient time to update themes, - * plugins, etc. - * - * @see https://github.com/WordPress/gutenberg/pull/34485 - * - * @param {string} path Path to desired value in settings. - * @return {string} The value for defined setting. - */ -const removeCustomPrefixes = ( path ) => { - return prefixedFlags[ path ] || path; -}; - -/** - * Hook that retrieves the given setting for the block instance in use. - * - * It looks up the settings first in the block instance hierarchy. - * If none is found, it'll look it up in the block editor store. - * - * @param {string} path The path to the setting. - * @return {any} Returns the value defined for the setting. - * @example - * ```js - * const isEnabled = useSetting( 'typography.dropCap' ); - * ``` - */ -export default function useSetting( path ) { - const { name: blockName, clientId } = useBlockEditContext(); - - return useSelect( - ( select ) => { - if ( blockedPaths.includes( path ) ) { - // eslint-disable-next-line no-console - console.warn( - 'Top level useSetting paths are disabled. Please use a subpath to query the information needed.' - ); - return undefined; - } - - // 0. Allow third parties to filter the block's settings at runtime. - let result = applyFilters( - 'blockEditor.useSetting.before', - undefined, - path, - clientId, - blockName - ); - - if ( undefined !== result ) { - return result; - } - - const normalizedPath = removeCustomPrefixes( path ); - - // 1. Take settings from the block instance or its ancestors. - // Start from the current block and work our way up the ancestors. - const candidates = [ - clientId, - ...select( blockEditorStore ).getBlockParents( - clientId, - /* ascending */ true - ), - ]; - - for ( const candidateClientId of candidates ) { - const candidateBlockName = - select( blockEditorStore ).getBlockName( - candidateClientId - ); - if ( - hasBlockSupport( - candidateBlockName, - '__experimentalSettings', - false - ) - ) { - const candidateAtts = - select( blockEditorStore ).getBlockAttributes( - candidateClientId - ); - result = - getValueFromObjectPath( - candidateAtts, - `settings.blocks.${ blockName }.${ normalizedPath }` - ) ?? - getValueFromObjectPath( - candidateAtts, - `settings.${ normalizedPath }` - ); - if ( result !== undefined ) { - // Stop the search for more distant ancestors and move on. - break; - } - } - } - - // 2. Fall back to the settings from the block editor store (__experimentalFeatures). - const settings = select( blockEditorStore ).getSettings(); - if ( result === undefined ) { - const defaultsPath = `__experimentalFeatures.${ normalizedPath }`; - const blockPath = `__experimentalFeatures.blocks.${ blockName }.${ normalizedPath }`; - result = - getValueFromObjectPath( settings, blockPath ) ?? - getValueFromObjectPath( settings, defaultsPath ); - } - - // Return if the setting was found in either the block instance or the store. - if ( result !== undefined ) { - if ( PATHS_WITH_MERGE[ normalizedPath ] ) { - return [ 'default', 'theme', 'custom' ].reduce( - ( acc, key ) => { - return acc.concat( result[ key ] ?? [] ); - }, - [] - ); - } - return result; - } - - // 3. Otherwise, use deprecated settings. - const deprecatedSettingsValue = deprecatedFlags[ normalizedPath ] - ? deprecatedFlags[ normalizedPath ]( settings ) - : undefined; - if ( deprecatedSettingsValue !== undefined ) { - return deprecatedSettingsValue; - } - - // 4. Fallback for typography.dropCap: - // This is only necessary to support typography.dropCap. - // when __experimentalFeatures are not present (core without plugin). - // To remove when __experimentalFeatures are ported to core. - return normalizedPath === 'typography.dropCap' ? true : undefined; - }, - [ blockName, clientId, path ] - ); -} diff --git a/packages/block-editor/src/components/use-setting/README.md b/packages/block-editor/src/components/use-settings/README.md similarity index 67% rename from packages/block-editor/src/components/use-setting/README.md rename to packages/block-editor/src/components/use-settings/README.md index 96f3c68fbcfade..83ab802edea83c 100644 --- a/packages/block-editor/src/components/use-setting/README.md +++ b/packages/block-editor/src/components/use-settings/README.md @@ -1,8 +1,8 @@ -## Use Setting +## Use Settings -`useSetting` is a hook that will retrive the setting for the block instance that's in use. +`useSettings` is a hook that will retrieve the settings for the block instance that's in use. -It does the lookup of the setting in the following order: +It does the lookup of the settings in the following order: 1. Third parties can provide the settings for the block using the filter `blockEditor.useSetting.before`. 2. If no third parties have provided this setting, then it looks up in the block instance hierachy starting from the current block and working its way upwards to its ancestors. @@ -20,20 +20,19 @@ It does the lookup of the setting in the following order: This will fetch the default color palette based on the block instance. ```jsx -import { useSetting } from '@wordpress/block-editor'; +import { useSettings } from '@wordpress/block-editor'; -const defaultColorPalette = useSetting( 'color.palette.default' ); +const [ defaultColorPalette ] = useSettings( 'color.palette.default' ); ``` Refer [here](https://github.com/WordPress/gutenberg/blob/HEAD/docs/how-to-guides/curating-the-editor-experience.md?plain=1#L330) in order to understand how the filter mentioned above `blockEditor.useSetting.before` can be used. ### Props -This hooks accepts the following props. +This hooks accepts the following arguments. -#### `path` +#### `paths` -- **Type:** `String` -- **Default:** `undefined` +- **Type:** `Array` -The path to the setting that is to be used for a block. Ex: `typography.fontSizes` \ No newline at end of file +Array of paths to the settings to be retrieved. E.g., `[ 'typography.fontSizes' ]` diff --git a/packages/block-editor/src/components/use-settings/index.js b/packages/block-editor/src/components/use-settings/index.js new file mode 100644 index 00000000000000..12a442c5c98f37 --- /dev/null +++ b/packages/block-editor/src/components/use-settings/index.js @@ -0,0 +1,272 @@ +/** + * WordPress dependencies + */ +import { + __EXPERIMENTAL_PATHS_WITH_MERGE as PATHS_WITH_MERGE, + hasBlockSupport, +} from '@wordpress/blocks'; +import { useSelect } from '@wordpress/data'; +import deprecated from '@wordpress/deprecated'; +import { useMemo } from '@wordpress/element'; +import { applyFilters } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import { useBlockEditContext } from '../block-edit'; +import { store as blockEditorStore } from '../../store'; +import { getValueFromObjectPath } from '../../utils/object'; + +const blockedPaths = [ + 'color', + 'border', + 'dimensions', + 'typography', + 'spacing', +]; + +const deprecatedFlags = { + 'color.palette': ( settings ) => settings.colors, + 'color.gradients': ( settings ) => settings.gradients, + 'color.custom': ( settings ) => + settings.disableCustomColors === undefined + ? undefined + : ! settings.disableCustomColors, + 'color.customGradient': ( settings ) => + settings.disableCustomGradients === undefined + ? undefined + : ! settings.disableCustomGradients, + 'typography.fontSizes': ( settings ) => settings.fontSizes, + 'typography.customFontSize': ( settings ) => + settings.disableCustomFontSizes === undefined + ? undefined + : ! settings.disableCustomFontSizes, + 'typography.lineHeight': ( settings ) => settings.enableCustomLineHeight, + 'spacing.units': ( settings ) => { + if ( settings.enableCustomUnits === undefined ) { + return; + } + + if ( settings.enableCustomUnits === true ) { + return [ 'px', 'em', 'rem', 'vh', 'vw', '%' ]; + } + + return settings.enableCustomUnits; + }, + 'spacing.padding': ( settings ) => settings.enableCustomSpacing, +}; + +const prefixedFlags = { + /* + * These were only available in the plugin + * and can be removed when the minimum WordPress version + * for the plugin is 5.9. + */ + 'border.customColor': 'border.color', + 'border.customStyle': 'border.style', + 'border.customWidth': 'border.width', + 'typography.customFontStyle': 'typography.fontStyle', + 'typography.customFontWeight': 'typography.fontWeight', + 'typography.customLetterSpacing': 'typography.letterSpacing', + 'typography.customTextDecorations': 'typography.textDecoration', + 'typography.customTextTransforms': 'typography.textTransform', + /* + * These were part of WordPress 5.8 and we need to keep them. + */ + 'border.customRadius': 'border.radius', + 'spacing.customMargin': 'spacing.margin', + 'spacing.customPadding': 'spacing.padding', + 'typography.customLineHeight': 'typography.lineHeight', +}; + +/** + * Remove `custom` prefixes for flags that did not land in 5.8. + * + * This provides continued support for `custom` prefixed properties. It will + * be removed once third party devs have had sufficient time to update themes, + * plugins, etc. + * + * @see https://github.com/WordPress/gutenberg/pull/34485 + * + * @param {string} path Path to desired value in settings. + * @return {string} The value for defined setting. + */ +const removeCustomPrefixes = ( path ) => { + return prefixedFlags[ path ] || path; +}; + +/** + * For settings like `color.palette`, which have a value that is an object + * with `default`, `theme`, `custom`, with field values that are arrays of + * items, merge these three arrays into one and return it. The calculation + * is memoized so that identical input values produce identical output. + * @param {Object} value Object to merge + * @return {Array} Array of merged items + */ +function mergeOrigins( value ) { + let result = mergeCache.get( value ); + if ( ! result ) { + result = [ 'default', 'theme', 'custom' ].flatMap( + ( key ) => value[ key ] ?? [] + ); + mergeCache.set( value, result ); + } + return result; +} +const mergeCache = new WeakMap(); + +/** + * Hook that retrieves the given settings for the block instance in use. + * + * It looks up the settings first in the block instance hierarchy. + * If none are found, it'll look them up in the block editor settings. + * + * @param {string[]} paths The paths to the settings. + * @return {any[]} Returns the values defined for the settings. + * @example + * ```js + * const [ fixed, sticky ] = useSettings( 'position.fixed', 'position.sticky' ); + * ``` + */ +export function useSettings( ...paths ) { + const { name: blockName, clientId = null } = useBlockEditContext(); + + // eslint-disable-next-line react-hooks/exhaustive-deps + paths = useMemo( () => paths, paths ); + + return useSelect( + ( select ) => { + const candidates = clientId + ? [ + clientId, + ...select( blockEditorStore ).getBlockParents( + clientId, + /* ascending */ true + ), + ].filter( ( candidateClientId ) => { + const candidateBlockName = + select( blockEditorStore ).getBlockName( + candidateClientId + ); + return hasBlockSupport( + candidateBlockName, + '__experimentalSettings', + false + ); + } ) + : []; + + return paths.map( ( path ) => { + if ( blockedPaths.includes( path ) ) { + // eslint-disable-next-line no-console + console.warn( + 'Top level useSetting paths are disabled. Please use a subpath to query the information needed.' + ); + return undefined; + } + + // 0. Allow third parties to filter the block's settings at runtime. + let result = applyFilters( + 'blockEditor.useSetting.before', + undefined, + path, + clientId, + blockName + ); + + if ( undefined !== result ) { + return result; + } + + const normalizedPath = removeCustomPrefixes( path ); + + // 1. Take settings from the block instance or its ancestors. + // Start from the current block and work our way up the ancestors. + for ( const candidateClientId of candidates ) { + const candidateAtts = + select( blockEditorStore ).getBlockAttributes( + candidateClientId + ); + result = + getValueFromObjectPath( + candidateAtts.settings?.blocks?.[ blockName ], + normalizedPath + ) ?? + getValueFromObjectPath( + candidateAtts.settings, + normalizedPath + ); + if ( result !== undefined ) { + // Stop the search for more distant ancestors and move on. + break; + } + } + + // 2. Fall back to the settings from the block editor store (__experimentalFeatures). + const settings = select( blockEditorStore ).getSettings(); + if ( result === undefined && blockName ) { + result = getValueFromObjectPath( + settings.__experimentalFeatures?.blocks?.[ blockName ], + normalizedPath + ); + } + + if ( result === undefined ) { + result = getValueFromObjectPath( + settings.__experimentalFeatures, + normalizedPath + ); + } + + // Return if the setting was found in either the block instance or the store. + if ( result !== undefined ) { + if ( PATHS_WITH_MERGE[ normalizedPath ] ) { + return mergeOrigins( result ); + } + return result; + } + + // 3. Otherwise, use deprecated settings. + const deprecatedSettingsValue = + deprecatedFlags[ normalizedPath ]?.( settings ); + if ( deprecatedSettingsValue !== undefined ) { + return deprecatedSettingsValue; + } + + // 4. Fallback for typography.dropCap: + // This is only necessary to support typography.dropCap. + // when __experimentalFeatures are not present (core without plugin). + // To remove when __experimentalFeatures are ported to core. + return normalizedPath === 'typography.dropCap' + ? true + : undefined; + } ); + }, + [ blockName, clientId, paths ] + ); +} + +/** + * Hook that retrieves the given setting for the block instance in use. + * + * It looks up the setting first in the block instance hierarchy. + * If none is found, it'll look it up in the block editor settings. + * + * @param {string} path The path to the setting. + * @return {any} Returns the value defined for the setting. + * @deprecated 6.4.0 Use useSettings instead. + * @example + * ```js + * const isEnabled = useSetting( 'typography.dropCap' ); + * ``` + */ +export function useSetting( path ) { + deprecated( 'wp.blockEditor.useSetting', { + since: '6.4', + alternative: 'wp.blockEditor.useSettings', + note: 'The new useSettings function can retrieve multiple settings at once, with better performance.', + } ); + + const [ value ] = useSettings( path ); + return value; +} diff --git a/packages/block-editor/src/components/use-setting/test/index.js b/packages/block-editor/src/components/use-settings/test/index.js similarity index 58% rename from packages/block-editor/src/components/use-setting/test/index.js rename to packages/block-editor/src/components/use-settings/test/index.js index 1c625c8a1969c4..89de12655338f0 100644 --- a/packages/block-editor/src/components/use-setting/test/index.js +++ b/packages/block-editor/src/components/use-settings/test/index.js @@ -1,16 +1,22 @@ +/** + * External dependencies + */ +import { render } from '@testing-library/react'; + /** * WordPress dependencies */ import { addFilter, removeFilter } from '@wordpress/hooks'; import { useSelect } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import useSetting from '..'; +import { useSettings, useSetting } from '..'; import * as BlockEditContext from '../../block-edit/context'; -// Mock useSelect() functions used by useSetting() +// Mock useSelect() functions used by useSettings() jest.mock( '@wordpress/data/src/components/use-select' ); let selectMock = {}; @@ -38,7 +44,19 @@ const mockCurrentBlockContext = ( ); }; -describe( 'useSetting', () => { +function runHook( hookCb ) { + let storedResult; + function TestHook() { + const result = hookCb(); + useEffect( () => { + storedResult = result; + }, [ result ] ); + } + render( ); + return storedResult; +} + +describe( 'useSettings', () => { beforeEach( () => { setupSelectMock(); mockCurrentBlockContext(); @@ -59,7 +77,8 @@ describe( 'useSetting', () => { name: 'core/test-block', } ); - expect( useSetting( 'layout.contentSize' ) ).toBe( '840px' ); + const result = runHook( () => useSettings( 'layout.contentSize' ) ); + expect( result ).toEqual( [ '840px' ] ); } ); it( 'uses blockEditor.useSetting.before hook override', () => { @@ -89,11 +108,34 @@ describe( 'useSetting', () => { } ); - expect( useSetting( 'layout.contentSize' ) ).toBe( '960px' ); + const result = runHook( () => useSettings( 'layout.contentSize' ) ); + expect( result ).toEqual( [ '960px' ] ); removeFilter( 'blockEditor.useSetting.before', 'test/useSetting.before' ); } ); + + it( 'supports also the deprecated useSetting function', () => { + mockSettings( { + blocks: { + 'core/test-block': { + layout: { + contentSize: '840px', + }, + }, + }, + } ); + + mockCurrentBlockContext( { + name: 'core/test-block', + } ); + + const result = runHook( () => useSetting( 'layout.contentSize' ) ); + expect( result ).toBe( '840px' ); + expect( console ).toHaveWarnedWith( + 'wp.blockEditor.useSetting is deprecated since version 6.4. Please use wp.blockEditor.useSettings instead.' + ); + } ); } ); diff --git a/packages/block-editor/src/hooks/background.js b/packages/block-editor/src/hooks/background.js index 4c2849eb8cef2b..f78341e16df8e0 100644 --- a/packages/block-editor/src/hooks/background.js +++ b/packages/block-editor/src/hooks/background.js @@ -29,7 +29,7 @@ import { getFilename } from '@wordpress/url'; */ import InspectorControls from '../components/inspector-controls'; import MediaReplaceFlow from '../components/media-replace-flow'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; import { cleanEmptyObject } from './utils'; import { store as blockEditorStore } from '../store'; @@ -281,19 +281,17 @@ function BackgroundImagePanelItem( props ) { } export function BackgroundImagePanel( props ) { - const isBackgroundImageSupported = - useSetting( 'background.backgroundImage' ) && - hasBackgroundSupport( props.name, 'backgroundImage' ); - - if ( ! isBackgroundImageSupported ) { + const [ backgroundImage ] = useSettings( 'background.backgroundImage' ); + if ( + ! backgroundImage || + ! hasBackgroundSupport( props.name, 'backgroundImage' ) + ) { return null; } return ( - { isBackgroundImageSupported && ( - - ) } + ); } diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js index a20c2a98b5f1d7..19fe4b0ea5ecd4 100644 --- a/packages/block-editor/src/hooks/color.js +++ b/packages/block-editor/src/hooks/color.js @@ -25,7 +25,7 @@ import { shouldSkipSerialization, useBlockSettings, } from './utils'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; import InspectorControls from '../components/inspector-controls'; import { useHasColorPanel, @@ -368,9 +368,12 @@ export const withColorPaletteStyles = createHigherOrderComponent( ( BlockListBlock ) => ( props ) => { const { name, attributes } = props; const { backgroundColor, textColor } = attributes; - const userPalette = useSetting( 'color.palette.custom' ); - const themePalette = useSetting( 'color.palette.theme' ); - const defaultPalette = useSetting( 'color.palette.default' ); + const [ userPalette, themePalette, defaultPalette ] = useSettings( + 'color.palette.custom', + 'color.palette.theme', + 'color.palette.default' + ); + const colors = useMemo( () => [ ...( userPalette || [] ), diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js index 39a8979782a0c6..1c46246d106414 100644 --- a/packages/block-editor/src/hooks/duotone.js +++ b/packages/block-editor/src/hooks/duotone.js @@ -25,7 +25,7 @@ import { BlockControls, InspectorControls, __experimentalDuotoneControl as DuotoneControl, - useSetting, + useSettings, } from '../components'; import { getDuotoneFilter, @@ -56,20 +56,20 @@ const isSafari = extend( [ namesPlugin ] ); function useMultiOriginPresets( { presetSetting, defaultSetting } ) { - const disableDefault = ! useSetting( defaultSetting ); - const userPresets = - useSetting( `${ presetSetting }.custom` ) || EMPTY_ARRAY; - const themePresets = - useSetting( `${ presetSetting }.theme` ) || EMPTY_ARRAY; - const defaultPresets = - useSetting( `${ presetSetting }.default` ) || EMPTY_ARRAY; + const [ enableDefault, userPresets, themePresets, defaultPresets ] = + useSettings( + defaultSetting, + `${ presetSetting }.custom`, + `${ presetSetting }.theme`, + `${ presetSetting }.default` + ); return useMemo( () => [ - ...userPresets, - ...themePresets, - ...( disableDefault ? EMPTY_ARRAY : defaultPresets ), + ...( userPresets || EMPTY_ARRAY ), + ...( themePresets || EMPTY_ARRAY ), + ...( ( enableDefault && defaultPresets ) || EMPTY_ARRAY ), ], - [ disableDefault, userPresets, themePresets, defaultPresets ] + [ enableDefault, userPresets, themePresets, defaultPresets ] ); } @@ -111,9 +111,13 @@ function DuotonePanel( { attributes, setAttributes, name } ) { presetSetting: 'color.palette', defaultSetting: 'color.defaultPalette', } ); - const disableCustomColors = ! useSetting( 'color.custom' ); + const [ enableCustomColors, enableCustomDuotone ] = useSettings( + 'color.custom', + 'color.customDuotone' + ); + const disableCustomColors = ! enableCustomColors; const disableCustomDuotone = - ! useSetting( 'color.customDuotone' ) || + ! enableCustomDuotone || ( colorPalette?.length === 0 && disableCustomColors ); if ( duotonePalette?.length === 0 && disableCustomDuotone ) { diff --git a/packages/block-editor/src/hooks/font-size.js b/packages/block-editor/src/hooks/font-size.js index a9d2facfa26702..146abe1d1f72f6 100644 --- a/packages/block-editor/src/hooks/font-size.js +++ b/packages/block-editor/src/hooks/font-size.js @@ -22,7 +22,7 @@ import { transformStyles, shouldSkipSerialization, } from './utils'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; import { store as blockEditorStore } from '../store'; import { getTypographyFontSizeValue, @@ -122,7 +122,7 @@ export function FontSizeEdit( props ) { attributes: { fontSize, style }, setAttributes, } = props; - const fontSizes = useSetting( 'typography.fontSizes' ); + const [ fontSizes ] = useSettings( 'typography.fontSizes' ); const onChange = ( value ) => { const fontSizeSlug = getFontSizeObjectByValue( fontSizes, value ).slug; @@ -167,7 +167,7 @@ export function FontSizeEdit( props ) { * @return {boolean} Whether setting is disabled. */ export function useIsFontSizeDisabled( { name: blockName } = {} ) { - const fontSizes = useSetting( 'typography.fontSizes' ); + const [ fontSizes ] = useSettings( 'typography.fontSizes' ); const hasFontSizes = !! fontSizes?.length; return ( @@ -186,7 +186,7 @@ export function useIsFontSizeDisabled( { name: blockName } = {} ) { */ const withFontSizeInlineStyles = createHigherOrderComponent( ( BlockListBlock ) => ( props ) => { - const fontSizes = useSetting( 'typography.fontSizes' ); + const [ fontSizes ] = useSettings( 'typography.fontSizes' ); const { name: blockName, attributes: { fontSize, style }, diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js index c194e0a2c5f789..95fc90fc0446fe 100644 --- a/packages/block-editor/src/hooks/layout.js +++ b/packages/block-editor/src/hooks/layout.js @@ -24,7 +24,7 @@ import { useEffect } from '@wordpress/element'; */ import { store as blockEditorStore } from '../store'; import { InspectorControls } from '../components'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; import { getLayoutType, getLayoutTypes } from '../layouts'; import { useBlockEditingMode } from '../components/block-editing-mode'; import { LAYOUT_DEFINITIONS } from '../layouts/definitions'; @@ -123,7 +123,7 @@ export function useLayoutStyles( blockAttributes = {}, blockName, selector ) { ? { ...layout, type: 'constrained' } : layout || {}; const fullLayoutType = getLayoutType( usedLayout?.type || 'default' ); - const blockGapSupport = useSetting( 'spacing.blockGap' ); + const [ blockGapSupport ] = useSettings( 'spacing.blockGap' ); const hasBlockGapSupport = blockGapSupport !== null; const css = fullLayoutType?.getLayoutStyle?.( { blockName, @@ -142,7 +142,7 @@ function LayoutPanel( { setAttributes, attributes, name: blockName } ) { } = settings; const { layout } = attributes; - const defaultThemeLayout = useSetting( 'layout' ); + const [ defaultThemeLayout ] = useSettings( 'layout' ); const { themeSupportsLayout } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); return { @@ -375,7 +375,7 @@ export const withLayoutStyles = createHigherOrderComponent( : null; // Higher specificity to override defaults from theme.json. const selector = `.wp-container-${ id }.wp-container-${ id }`; - const blockGapSupport = useSetting( 'spacing.blockGap' ); + const [ blockGapSupport ] = useSettings( 'spacing.blockGap' ); const hasBlockGapSupport = blockGapSupport !== null; // Get CSS string for the current layout type. diff --git a/packages/block-editor/src/hooks/line-height.js b/packages/block-editor/src/hooks/line-height.js index b835f54a12b6c4..5f8df2549cc4b1 100644 --- a/packages/block-editor/src/hooks/line-height.js +++ b/packages/block-editor/src/hooks/line-height.js @@ -8,7 +8,7 @@ import { hasBlockSupport } from '@wordpress/blocks'; */ import LineHeightControl from '../components/line-height-control'; import { cleanEmptyObject } from './utils'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; export const LINE_HEIGHT_SUPPORT_KEY = 'typography.lineHeight'; @@ -54,9 +54,9 @@ export function LineHeightEdit( props ) { * @return {boolean} Whether setting is disabled. */ export function useIsLineHeightDisabled( { name: blockName } = {} ) { - const isDisabled = ! useSetting( 'typography.lineHeight' ); + const [ isEnabled ] = useSettings( 'typography.lineHeight' ); return ( - ! hasBlockSupport( blockName, LINE_HEIGHT_SUPPORT_KEY ) || isDisabled + ! isEnabled || ! hasBlockSupport( blockName, LINE_HEIGHT_SUPPORT_KEY ) ); } diff --git a/packages/block-editor/src/hooks/position.js b/packages/block-editor/src/hooks/position.js index 7c1bff6e99692f..d040a2c39d21d0 100644 --- a/packages/block-editor/src/hooks/position.js +++ b/packages/block-editor/src/hooks/position.js @@ -26,7 +26,7 @@ import { addFilter } from '@wordpress/hooks'; * Internal dependencies */ import BlockList from '../components/block-list'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; import InspectorControls from '../components/inspector-controls'; import useBlockDisplayInformation from '../components/use-block-display-information'; import { cleanEmptyObject } from './utils'; @@ -197,8 +197,10 @@ export function resetPosition( { attributes = {}, setAttributes } ) { * @return {boolean} Whether padding setting is disabled. */ export function useIsPositionDisabled( { name: blockName } = {} ) { - const allowFixed = useSetting( 'position.fixed' ); - const allowSticky = useSetting( 'position.sticky' ); + const [ allowFixed, allowSticky ] = useSettings( + 'position.fixed', + 'position.sticky' + ); const isDisabled = ! allowFixed && ! allowSticky; return ! hasPositionSupport( blockName ) || isDisabled; diff --git a/packages/block-editor/src/hooks/use-color-props.js b/packages/block-editor/src/hooks/use-color-props.js index 77dedf19a28bde..679f0b7accbf71 100644 --- a/packages/block-editor/src/hooks/use-color-props.js +++ b/packages/block-editor/src/hooks/use-color-props.js @@ -20,7 +20,7 @@ import { __experimentalGetGradientClass, getGradientValueBySlug, } from '../components/gradients'; -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; // The code in this file has largely been lifted from the color block support // hook. @@ -73,8 +73,6 @@ export function getColorClassesAndStyles( attributes ) { }; } -const EMPTY_OBJECT = {}; - /** * Determines the color related props for a block derived from its color block * support attributes. @@ -89,13 +87,22 @@ const EMPTY_OBJECT = {}; export function useColorProps( attributes ) { const { backgroundColor, textColor, gradient } = attributes; - // Some color settings have a special handling for deprecated flags in `useSetting`, - // so we can't unwrap them by doing const { ... } = useSetting('color') - // until https://github.com/WordPress/gutenberg/issues/37094 is fixed. - const userPalette = useSetting( 'color.palette.custom' ); - const themePalette = useSetting( 'color.palette.theme' ); - const defaultPalette = useSetting( 'color.palette.default' ); - const gradientsPerOrigin = useSetting( 'color.gradients' ) || EMPTY_OBJECT; + const [ + userPalette, + themePalette, + defaultPalette, + userGradients, + themeGradients, + defaultGradients, + ] = useSettings( + 'color.palette.custom', + 'color.palette.theme', + 'color.palette.default', + 'color.gradients.custom', + 'color.gradients.theme', + 'color.gradients.default' + ); + const colors = useMemo( () => [ ...( userPalette || [] ), @@ -106,11 +113,11 @@ export function useColorProps( attributes ) { ); const gradients = useMemo( () => [ - ...( gradientsPerOrigin?.custom || [] ), - ...( gradientsPerOrigin?.theme || [] ), - ...( gradientsPerOrigin?.default || [] ), + ...( userGradients || [] ), + ...( themeGradients || [] ), + ...( defaultGradients || [] ), ], - [ gradientsPerOrigin ] + [ userGradients, themeGradients, defaultGradients ] ); const colorProps = getColorClassesAndStyles( attributes ); diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 8e0d422c5fbec8..e7c71ea5551f8f 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -7,7 +7,7 @@ import { useMemo } from '@wordpress/element'; /** * Internal dependencies */ -import { useSetting } from '../components'; +import { useSettings } from '../components'; import { useSettingsForBlockElement } from '../components/global-styles/hooks'; import { getValueFromObjectPath, setImmutably } from '../utils/object'; @@ -126,48 +126,93 @@ export function shouldSkipSerialization( blockType, featureSet, feature ) { * @return {Object} Settings object. */ export function useBlockSettings( name, parentLayout ) { - const fontFamilies = useSetting( 'typography.fontFamilies' ); - const fontSizes = useSetting( 'typography.fontSizes' ); - const customFontSize = useSetting( 'typography.customFontSize' ); - const fontStyle = useSetting( 'typography.fontStyle' ); - const fontWeight = useSetting( 'typography.fontWeight' ); - const lineHeight = useSetting( 'typography.lineHeight' ); - const textColumns = useSetting( 'typography.textColumns' ); - const textDecoration = useSetting( 'typography.textDecoration' ); - const writingMode = useSetting( 'typography.writingMode' ); - const textTransform = useSetting( 'typography.textTransform' ); - const letterSpacing = useSetting( 'typography.letterSpacing' ); - const padding = useSetting( 'spacing.padding' ); - const margin = useSetting( 'spacing.margin' ); - const blockGap = useSetting( 'spacing.blockGap' ); - const spacingSizes = useSetting( 'spacing.spacingSizes' ); - const units = useSetting( 'spacing.units' ); - const minHeight = useSetting( 'dimensions.minHeight' ); - const layout = useSetting( 'layout' ); - const borderColor = useSetting( 'border.color' ); - const borderRadius = useSetting( 'border.radius' ); - const borderStyle = useSetting( 'border.style' ); - const borderWidth = useSetting( 'border.width' ); - const customColorsEnabled = useSetting( 'color.custom' ); - const customColors = useSetting( 'color.palette.custom' ); - const customDuotone = useSetting( 'color.customDuotone' ); - const themeColors = useSetting( 'color.palette.theme' ); - const defaultColors = useSetting( 'color.palette.default' ); - const defaultPalette = useSetting( 'color.defaultPalette' ); - const defaultDuotone = useSetting( 'color.defaultDuotone' ); - const userDuotonePalette = useSetting( 'color.duotone.custom' ); - const themeDuotonePalette = useSetting( 'color.duotone.theme' ); - const defaultDuotonePalette = useSetting( 'color.duotone.default' ); - const userGradientPalette = useSetting( 'color.gradients.custom' ); - const themeGradientPalette = useSetting( 'color.gradients.theme' ); - const defaultGradientPalette = useSetting( 'color.gradients.default' ); - const defaultGradients = useSetting( 'color.defaultGradients' ); - const areCustomGradientsEnabled = useSetting( 'color.customGradient' ); - const isBackgroundEnabled = useSetting( 'color.background' ); - const isLinkEnabled = useSetting( 'color.link' ); - const isTextEnabled = useSetting( 'color.text' ); - const isHeadingEnabled = useSetting( 'color.heading' ); - const isButtonEnabled = useSetting( 'color.button' ); + const [ + fontFamilies, + fontSizes, + customFontSize, + fontStyle, + fontWeight, + lineHeight, + textColumns, + textDecoration, + writingMode, + textTransform, + letterSpacing, + padding, + margin, + blockGap, + spacingSizes, + units, + minHeight, + layout, + borderColor, + borderRadius, + borderStyle, + borderWidth, + customColorsEnabled, + customColors, + customDuotone, + themeColors, + defaultColors, + defaultPalette, + defaultDuotone, + userDuotonePalette, + themeDuotonePalette, + defaultDuotonePalette, + userGradientPalette, + themeGradientPalette, + defaultGradientPalette, + defaultGradients, + areCustomGradientsEnabled, + isBackgroundEnabled, + isLinkEnabled, + isTextEnabled, + isHeadingEnabled, + isButtonEnabled, + ] = useSettings( + 'typography.fontFamilies', + 'typography.fontSizes', + 'typography.customFontSize', + 'typography.fontStyle', + 'typography.fontWeight', + 'typography.lineHeight', + 'typography.textColumns', + 'typography.textDecoration', + 'typography.writingMode', + 'typography.textTransform', + 'typography.letterSpacing', + 'spacing.padding', + 'spacing.margin', + 'spacing.blockGap', + 'spacing.spacingSizes', + 'spacing.units', + 'dimensions.minHeight', + 'layout', + 'border.color', + 'border.radius', + 'border.style', + 'border.width', + 'color.custom', + 'color.palette.custom', + 'color.customDuotone', + 'color.palette.theme', + 'color.palette.default', + 'color.defaultPalette', + 'color.defaultDuotone', + 'color.duotone.custom', + 'color.duotone.theme', + 'color.duotone.default', + 'color.gradients.custom', + 'color.gradients.theme', + 'color.gradients.default', + 'color.defaultGradients', + 'color.customGradient', + 'color.background', + 'color.link', + 'color.text', + 'color.heading', + 'color.button' + ); const rawSettings = useMemo( () => { return { diff --git a/packages/block-editor/src/layouts/constrained.js b/packages/block-editor/src/layouts/constrained.js index 9e4bdee1dfa96a..7fe0d5ff0b5268 100644 --- a/packages/block-editor/src/layouts/constrained.js +++ b/packages/block-editor/src/layouts/constrained.js @@ -21,7 +21,7 @@ import { getCSSRules } from '@wordpress/style-engine'; /** * Internal dependencies */ -import useSetting from '../components/use-setting'; +import { useSettings } from '../components/use-settings'; import { appendSelectors, getBlockGapCSS, getAlignmentsInfo } from './utils'; import { getGapCSSValue } from '../hooks/gap'; import { shouldSkipSerialization } from '../hooks/utils'; @@ -60,14 +60,9 @@ export default { label: __( 'Justify items right' ), }, ]; + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - '%', - 'px', - 'em', - 'rem', - 'vw', - ], + availableUnits: availableUnits || [ '%', 'px', 'em', 'rem', 'vw' ], } ); return ( <> diff --git a/packages/block-editor/src/utils/object.js b/packages/block-editor/src/utils/object.js index ed81450e49ab93..e54990db1d0666 100644 --- a/packages/block-editor/src/utils/object.js +++ b/packages/block-editor/src/utils/object.js @@ -2,6 +2,7 @@ * External dependencies */ import { paramCase } from 'change-case'; +import memoize from 'memize'; /** * Converts a path to an array of its fragments. @@ -112,6 +113,8 @@ export function setImmutably( object, path, value ) { return newObject; } +const stringToPath = memoize( ( path ) => path.split( '.' ) ); + /** * Helper util to return a value from a certain path of the object. * Path is specified as either: @@ -125,7 +128,7 @@ export function setImmutably( object, path, value ) { * @return {*} Value of the object property at the specified path. */ export const getValueFromObjectPath = ( object, path, defaultValue ) => { - const normalizedPath = Array.isArray( path ) ? path : path.split( '.' ); + const normalizedPath = Array.isArray( path ) ? path : stringToPath( path ); let value = object; normalizedPath.forEach( ( fieldName ) => { value = value?.[ fieldName ]; diff --git a/packages/block-library/src/column/edit.js b/packages/block-library/src/column/edit.js index 88169b655a787c..8fed5e85f00cbc 100644 --- a/packages/block-library/src/column/edit.js +++ b/packages/block-library/src/column/edit.js @@ -12,7 +12,7 @@ import { BlockVerticalAlignmentToolbar, InspectorControls, useBlockProps, - useSetting, + useSettings, useInnerBlocksProps, store as blockEditorStore, } from '@wordpress/block-editor'; @@ -33,14 +33,9 @@ function ColumnEdit( { [ `is-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment, } ); + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - '%', - 'px', - 'em', - 'rem', - 'vw', - ], + availableUnits: availableUnits || [ '%', 'px', 'em', 'rem', 'vw' ], } ); const { columnsIds, hasChildBlocks, rootClientId } = useSelect( diff --git a/packages/block-library/src/column/edit.native.js b/packages/block-library/src/column/edit.native.js index 7e18e73a9b14ae..50528ca0855e2c 100644 --- a/packages/block-library/src/column/edit.native.js +++ b/packages/block-library/src/column/edit.native.js @@ -15,7 +15,7 @@ import { BlockVerticalAlignmentToolbar, InspectorControls, store as blockEditorStore, - useSetting, + useSettings, } from '@wordpress/block-editor'; import { PanelBody, @@ -60,14 +60,9 @@ function ColumnEdit( { const [ widthUnit, setWidthUnit ] = useState( valueUnit || '%' ); + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - '%', - 'px', - 'em', - 'rem', - 'vw', - ], + availableUnits: availableUnits || [ '%', 'px', 'em', 'rem', 'vw' ], } ); const updateAlignment = ( alignment ) => { diff --git a/packages/block-library/src/columns/edit.native.js b/packages/block-library/src/columns/edit.native.js index aa862c815b9281..2782085e5e55fc 100644 --- a/packages/block-library/src/columns/edit.native.js +++ b/packages/block-library/src/columns/edit.native.js @@ -23,7 +23,7 @@ import { BlockControls, BlockVerticalAlignmentToolbar, BlockVariationPicker, - useSetting, + useSettings, store as blockEditorStore, } from '@wordpress/block-editor'; import { withDispatch, useSelect } from '@wordpress/data'; @@ -106,14 +106,9 @@ function ColumnsEditContainer( { const { verticalAlignment, align } = attributes; const { width } = sizes || {}; + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - '%', - 'px', - 'em', - 'rem', - 'vw', - ], + availableUnits: availableUnits || [ '%', 'px', 'em', 'rem', 'vw' ], } ); useEffect( () => { diff --git a/packages/block-library/src/cover/controls.native.js b/packages/block-library/src/cover/controls.native.js index 558db2ec87d61b..252211bfcf17bb 100644 --- a/packages/block-library/src/cover/controls.native.js +++ b/packages/block-library/src/cover/controls.native.js @@ -22,7 +22,7 @@ import { import { plus } from '@wordpress/icons'; import { useState, useCallback, useRef } from '@wordpress/element'; import { usePreferredColorSchemeStyle } from '@wordpress/compose'; -import { useSetting, MediaUpload } from '@wordpress/block-editor'; +import { useSettings, MediaUpload } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; /** @@ -68,14 +68,9 @@ function Controls( { [ minHeight ] ); + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - 'px', - 'em', - 'rem', - 'vw', - 'vh', - ], + availableUnits: availableUnits || [ 'px', 'em', 'rem', 'vw', 'vh' ], defaultValues: { px: 430, em: 20, rem: 20, vw: 20, vh: 50 }, } ); diff --git a/packages/block-library/src/cover/edit/index.js b/packages/block-library/src/cover/edit/index.js index b5bcaee6d3b786..ab49d58b766b09 100644 --- a/packages/block-library/src/cover/edit/index.js +++ b/packages/block-library/src/cover/edit/index.js @@ -14,7 +14,7 @@ import { withColors, ColorPalette, useBlockProps, - useSetting, + useSettings, useInnerBlocksProps, __experimentalUseGradient, store as blockEditorStore, @@ -318,7 +318,8 @@ function CoverEdit( { const blockProps = useBlockProps( { ref } ); // Check for fontSize support before we pass a fontSize attribute to the innerBlocks. - const hasFontSizes = !! useSetting( 'typography.fontSizes' )?.length; + const [ fontSizes ] = useSettings( 'typography.fontSizes' ); + const hasFontSizes = fontSizes?.length > 0; const innerBlocksTemplate = getInnerBlocksTemplate( { fontSize: hasFontSizes ? 'large' : undefined, } ); diff --git a/packages/block-library/src/cover/edit/inspector-controls.js b/packages/block-library/src/cover/edit/inspector-controls.js index d0e0695ebf6859..3ed0ae872f9337 100644 --- a/packages/block-library/src/cover/edit/inspector-controls.js +++ b/packages/block-library/src/cover/edit/inspector-controls.js @@ -20,7 +20,7 @@ import { import { useInstanceId } from '@wordpress/compose'; import { InspectorControls, - useSetting, + useSettings, __experimentalColorGradientSettingsDropdown as ColorGradientSettingsDropdown, __experimentalUseGradient, __experimentalUseMultipleOriginColorsAndGradients as useMultipleOriginColorsAndGradients, @@ -42,14 +42,9 @@ function CoverHeightInput( { const inputId = `block-cover-height-input-${ instanceId }`; const isPx = unit === 'px'; + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - 'px', - 'em', - 'rem', - 'vw', - 'vh', - ], + availableUnits: availableUnits || [ 'px', 'em', 'rem', 'vw', 'vh' ], defaultValues: { px: 430, '%': 20, em: 20, rem: 20, vw: 20, vh: 50 }, } ); diff --git a/packages/block-library/src/group/edit.js b/packages/block-library/src/group/edit.js index 0f24efe3b0233d..4d5354eff0180f 100644 --- a/packages/block-library/src/group/edit.js +++ b/packages/block-library/src/group/edit.js @@ -7,7 +7,6 @@ import { useBlockProps, InspectorControls, useInnerBlocksProps, - useSetting, store as blockEditorStore, } from '@wordpress/block-editor'; import { SelectControl } from '@wordpress/components'; @@ -98,11 +97,7 @@ function GroupEdit( { } = attributes; // Layout settings. - const defaultLayout = useSetting( 'layout' ) || {}; - const usedLayout = ! layout?.type - ? { ...defaultLayout, ...layout, type: 'default' } - : { ...defaultLayout, ...layout }; - const { type = 'default' } = usedLayout; + const { type = 'default' } = layout; const layoutSupportEnabled = themeSupportsLayout || type === 'flex' || type === 'grid'; @@ -112,7 +107,7 @@ function GroupEdit( { } ); const [ showPlaceholder, setShowPlaceholder ] = useShouldShowPlaceHolder( { attributes, - usedLayoutType: usedLayout?.type, + usedLayoutType: type, hasInnerBlocks, } ); diff --git a/packages/block-library/src/image/image.js b/packages/block-library/src/image/image.js index 1f602c4380e880..5167916ff259b5 100644 --- a/packages/block-library/src/image/image.js +++ b/packages/block-library/src/image/image.js @@ -24,7 +24,7 @@ import { __experimentalImageURLInputUI as ImageURLInputUI, MediaReplaceFlow, store as blockEditorStore, - useSetting, + useSettings, BlockAlignmentControl, __experimentalImageEditor as ImageEditor, __experimentalGetElementClassName, @@ -369,7 +369,7 @@ export default function Image( { availableUnits: [ 'px' ], } ); - const lightboxSetting = useSetting( 'lightbox' ); + const [ lightboxSetting ] = useSettings( 'lightbox' ); const showLightboxToggle = !! lightbox || lightboxSetting?.allowEditing === true; diff --git a/packages/block-library/src/paragraph/edit.js b/packages/block-library/src/paragraph/edit.js index 21f692bd25b263..37a9c2ab9b10a9 100644 --- a/packages/block-library/src/paragraph/edit.js +++ b/packages/block-library/src/paragraph/edit.js @@ -18,7 +18,7 @@ import { InspectorControls, RichText, useBlockProps, - useSetting, + useSettings, } from '@wordpress/block-editor'; import { createBlock } from '@wordpress/blocks'; import { formatLtr } from '@wordpress/icons'; @@ -58,7 +58,7 @@ function ParagraphBlock( { clientId, } ) { const { align, content, direction, dropCap, placeholder } = attributes; - const isDropCapFeatureEnabled = useSetting( 'typography.dropCap' ); + const [ isDropCapFeatureEnabled ] = useSettings( 'typography.dropCap' ); const blockProps = useBlockProps( { ref: useOnEnter( { clientId, content } ), className: classnames( { diff --git a/packages/block-library/src/post-featured-image/dimension-controls.js b/packages/block-library/src/post-featured-image/dimension-controls.js index 5e1204922880c6..03a2d2849dae36 100644 --- a/packages/block-library/src/post-featured-image/dimension-controls.js +++ b/packages/block-library/src/post-featured-image/dimension-controls.js @@ -10,7 +10,7 @@ import { __experimentalUseCustomUnits as useCustomUnits, __experimentalToolsPanelItem as ToolsPanelItem, } from '@wordpress/components'; -import { InspectorControls, useSetting } from '@wordpress/block-editor'; +import { InspectorControls, useSettings } from '@wordpress/block-editor'; const SCALE_OPTIONS = ( <> @@ -53,9 +53,9 @@ const DimensionControls = ( { setAttributes, imageSizeOptions = [], } ) => { - const defaultUnits = [ 'px', '%', 'vw', 'em', 'rem' ]; + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || defaultUnits, + availableUnits: availableUnits || [ 'px', '%', 'vw', 'em', 'rem' ], } ); const onDimensionChange = ( dimension, nextValue ) => { const parsedValue = parseFloat( nextValue ); diff --git a/packages/block-library/src/search/edit.js b/packages/block-library/src/search/edit.js index 616478d8013f72..52f89d344cdf02 100644 --- a/packages/block-library/src/search/edit.js +++ b/packages/block-library/src/search/edit.js @@ -16,7 +16,7 @@ import { getTypographyClassesAndStyles as useTypographyProps, store as blockEditorStore, __experimentalGetElementClassName, - useSetting, + useSettings, } from '@wordpress/block-editor'; import { useDispatch, useSelect } from '@wordpress/data'; import { useEffect, useRef } from '@wordpress/element'; @@ -125,8 +125,10 @@ export default function SearchEdit( { } const colorProps = useColorProps( attributes ); - const fluidTypographySettings = useSetting( 'typography.fluid' ); - const layout = useSetting( 'layout' ); + const [ fluidTypographySettings, layout ] = useSettings( + 'typography.fluid', + 'layout' + ); const typographyProps = useTypographyProps( attributes, { typography: { fluid: fluidTypographySettings, diff --git a/packages/block-library/src/spacer/controls.js b/packages/block-library/src/spacer/controls.js index d999550f16f331..91a1e79be173eb 100644 --- a/packages/block-library/src/spacer/controls.js +++ b/packages/block-library/src/spacer/controls.js @@ -4,7 +4,7 @@ import { __ } from '@wordpress/i18n'; import { InspectorControls, - useSetting, + useSettings, __experimentalSpacingSizesControl as SpacingSizesControl, isValueSpacingPreset, } from '@wordpress/block-editor'; @@ -25,22 +25,19 @@ import { MIN_SPACER_SIZE } from './constants'; function DimensionInput( { label, onChange, isResizing, value = '' } ) { const inputId = useInstanceId( UnitControl, 'block-spacer-height-input' ); - const spacingSizes = useSetting( 'spacing.spacingSizes' ); + const [ spacingSizes, spacingUnits ] = useSettings( + 'spacing.spacingSizes', + 'spacing.units' + ); // In most contexts the spacer size cannot meaningfully be set to a // percentage, since this is relative to the parent container. This // unit is disabled from the UI. - const availableUnitSettings = ( - useSetting( 'spacing.units' ) || undefined - )?.filter( ( availableUnit ) => availableUnit !== '%' ); + const availableUnits = spacingUnits + ? spacingUnits.filter( ( unit ) => unit !== '%' ) + : [ 'px', 'em', 'rem', 'vw', 'vh' ]; const units = useCustomUnits( { - availableUnits: availableUnitSettings || [ - 'px', - 'em', - 'rem', - 'vw', - 'vh', - ], + availableUnits, defaultValues: { px: 100, em: 10, rem: 10, vw: 10, vh: 25 }, } ); diff --git a/packages/block-library/src/spacer/controls.native.js b/packages/block-library/src/spacer/controls.native.js index 644359b1072751..6aacfae19fa82a 100644 --- a/packages/block-library/src/spacer/controls.native.js +++ b/packages/block-library/src/spacer/controls.native.js @@ -8,7 +8,7 @@ import { __experimentalUseCustomUnits as useCustomUnits, } from '@wordpress/components'; import { useCallback } from '@wordpress/element'; -import { useSetting } from '@wordpress/block-editor'; +import { useSettings } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; /** @@ -59,14 +59,9 @@ function Controls( { [ height, width ] ); + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - 'px', - 'em', - 'rem', - 'vw', - 'vh', - ], + availableUnits: availableUnits || [ 'px', 'em', 'rem', 'vw', 'vh' ], defaultValues: DEFAULT_VALUES, } ); diff --git a/packages/block-library/src/spacer/edit.js b/packages/block-library/src/spacer/edit.js index 1786c435ebbf23..11133732042d3f 100644 --- a/packages/block-library/src/spacer/edit.js +++ b/packages/block-library/src/spacer/edit.js @@ -8,7 +8,7 @@ import classnames from 'classnames'; */ import { useBlockProps, - useSetting, + useSettings, getCustomValueFromPreset, getSpacingPresetCssVar, store as blockEditorStore, @@ -107,7 +107,7 @@ const SpacerEdit = ( { const { layout = {} } = blockStyle; const { selfStretch, flexSize } = layout; - const spacingSizes = useSetting( 'spacing.spacingSizes' ); + const [ spacingSizes ] = useSettings( 'spacing.spacingSizes' ); const [ isResizing, setIsResizing ] = useState( false ); const [ temporaryHeight, setTemporaryHeight ] = useState( null ); diff --git a/packages/block-library/src/spacer/edit.native.js b/packages/block-library/src/spacer/edit.native.js index ca5cfa409939bf..614624570a6d95 100644 --- a/packages/block-library/src/spacer/edit.native.js +++ b/packages/block-library/src/spacer/edit.native.js @@ -11,7 +11,7 @@ import { withPreferredColorScheme } from '@wordpress/compose'; import { InspectorControls, isValueSpacingPreset, - useSetting, + useSettings, getCustomValueFromPreset, getPxFromCssUnit, } from '@wordpress/block-editor'; @@ -39,10 +39,11 @@ const Spacer = ( { fontSize: DEFAULT_FONT_SIZE, }; const { height, width } = attributes; - const spacingSizes = [ - { name: 0, slug: '0', size: 0 }, - ...( useSetting( 'spacing.spacingSizes' ) || [] ), - ]; + const spacingSizes = [ { name: 0, slug: '0', size: 0 } ]; + const [ settingsSizes ] = useSettings( 'spacing.spacingSizes' ); + if ( settingsSizes ) { + spacingSizes.push( ...settingsSizes ); + } const { orientation } = context; const defaultStyle = getStylesFromColorScheme( styles.staticSpacer, diff --git a/packages/block-library/src/tag-cloud/edit.js b/packages/block-library/src/tag-cloud/edit.js index 4dbec86fff520c..a52c68bc6a7390 100644 --- a/packages/block-library/src/tag-cloud/edit.js +++ b/packages/block-library/src/tag-cloud/edit.js @@ -18,7 +18,7 @@ import { __ } from '@wordpress/i18n'; import { InspectorControls, useBlockProps, - useSetting, + useSettings, } from '@wordpress/block-editor'; import ServerSideRender from '@wordpress/server-side-render'; import { store as coreStore } from '@wordpress/core-data'; @@ -49,13 +49,9 @@ function TagCloudEdit( { attributes, setAttributes, taxonomies } ) { largestFontSize, } = attributes; + const [ availableUnits ] = useSettings( 'spacing.units' ); const units = useCustomUnits( { - availableUnits: useSetting( 'spacing.units' ) || [ - '%', - 'px', - 'em', - 'rem', - ], + availableUnits: availableUnits || [ '%', 'px', 'em', 'rem' ], } ); const getTaxonomyOptions = () => { diff --git a/packages/block-library/src/template-part/edit/inner-blocks.js b/packages/block-library/src/template-part/edit/inner-blocks.js index b17428bbdbb40e..146877ee0287cc 100644 --- a/packages/block-library/src/template-part/edit/inner-blocks.js +++ b/packages/block-library/src/template-part/edit/inner-blocks.js @@ -5,7 +5,7 @@ import { useEntityBlockEditor } from '@wordpress/core-data'; import { InnerBlocks, useInnerBlocksProps, - useSetting, + useSettings, store as blockEditorStore, } from '@wordpress/block-editor'; import { useSelect } from '@wordpress/data'; @@ -21,8 +21,8 @@ export default function TemplatePartInnerBlocks( { const { getSettings } = select( blockEditorStore ); return getSettings()?.supportsLayout; }, [] ); - const defaultLayout = useSetting( 'layout' ) || {}; - const usedLayout = !! layout && layout.inherit ? defaultLayout : layout; + const [ defaultLayout ] = useSettings( 'layout' ); + const usedLayout = layout?.inherit ? defaultLayout || {} : layout; const [ blocks, onInput, onChange ] = useEntityBlockEditor( 'postType', diff --git a/packages/components/src/mobile/global-styles-context/utils.native.js b/packages/components/src/mobile/global-styles-context/utils.native.js index d494ca3cedbdbf..8b0e92e70f5ae3 100644 --- a/packages/components/src/mobile/global-styles-context/utils.native.js +++ b/packages/components/src/mobile/global-styles-context/utils.native.js @@ -9,7 +9,7 @@ import { Dimensions } from 'react-native'; */ import { getPxFromCssUnit, - useSetting, + useSettings, useMultipleOriginColorsAndGradients, } from '@wordpress/block-editor'; @@ -357,7 +357,7 @@ export function useMobileGlobalStylesColors( type = 'colors' ) { // Default editor colors/gradients if it's not a block-based theme. const colorPalette = type === 'colors' ? 'color.palette' : 'color.gradients'; - const editorDefaultPalette = useSetting( colorPalette ); + const [ editorDefaultPalette ] = useSettings( colorPalette ); return availableThemeColors.length >= 1 ? availableThemeColors diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index 14b6bf475045e1..bd236551c7cf14 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -14,7 +14,7 @@ import { __unstableUseTypewriter as useTypewriter, __unstableUseTypingObserver as useTypingObserver, __experimentalUseResizeCanvas as useResizeCanvas, - useSetting, + useSettings, __experimentalRecursionProvider as RecursionProvider, privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; @@ -171,7 +171,7 @@ export default function VisualEditor( { styles } ) { borderBottom: 0, }; const resizedCanvasStyles = useResizeCanvas( deviceType, isTemplateMode ); - const globalLayoutSettings = useSetting( 'layout' ); + const [ globalLayoutSettings ] = useSettings( 'layout' ); const previewMode = 'is-' + deviceType.toLowerCase() + '-preview'; let animatedStyles = isTemplateMode diff --git a/packages/format-library/src/text-color/index.js b/packages/format-library/src/text-color/index.js index a0545a3dbc2473..630431dc50fa0e 100644 --- a/packages/format-library/src/text-color/index.js +++ b/packages/format-library/src/text-color/index.js @@ -3,7 +3,7 @@ */ import { __ } from '@wordpress/i18n'; import { useCallback, useMemo, useState } from '@wordpress/element'; -import { RichTextToolbarButton, useSetting } from '@wordpress/block-editor'; +import { RichTextToolbarButton, useSettings } from '@wordpress/block-editor'; import { Icon, color as colorIcon, @@ -61,8 +61,10 @@ function TextColorEdit( { activeAttributes, contentRef, } ) { - const allowCustomControl = useSetting( 'color.custom' ); - const colors = useSetting( 'color.palette' ) || EMPTY_ARRAY; + const [ allowCustomControl, colors = EMPTY_ARRAY ] = useSettings( + 'color.custom', + 'color.palette' + ); const [ isAddingColor, setIsAddingColor ] = useState( false ); const enableIsAddingColor = useCallback( () => setIsAddingColor( true ), diff --git a/packages/format-library/src/text-color/index.native.js b/packages/format-library/src/text-color/index.native.js index 5f133383ae1d1d..21db4c2a444f30 100644 --- a/packages/format-library/src/text-color/index.native.js +++ b/packages/format-library/src/text-color/index.native.js @@ -8,7 +8,7 @@ import { StyleSheet, View } from 'react-native'; */ import { __ } from '@wordpress/i18n'; import { useCallback, useMemo, useState } from '@wordpress/element'; -import { BlockControls, useSetting } from '@wordpress/block-editor'; +import { BlockControls, useSettings } from '@wordpress/block-editor'; import { ToolbarGroup, ToolbarButton, @@ -72,7 +72,7 @@ function TextColorEdit( { activeAttributes, contentRef, } ) { - const allowCustomControl = useSetting( 'color.custom' ); + const [ allowCustomControl ] = useSettings( 'color.custom' ); const colors = useMobileGlobalStylesColors(); const [ isAddingColor, setIsAddingColor ] = useState( false ); const enableIsAddingColor = useCallback(