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(