Skip to content

Commit

Permalink
Add useSettings hook for reading multiple settings at once (#55337)
Browse files Browse the repository at this point in the history
* useSetting: optimize by not constructing path strings

* useSetting: handle the case where clientId is null

* getValueFromObjectPath: memoize splitting path into array, like lodash.get does

* useSetting: memoize results of PATHS_WITH_MERGE transforms

* Add useSettings hook for batched setting retrieval

* Rewrite usages of useSetting to useSettings

* Fix unit tests for useSetting, run hooks inside React render

* Fix docs plural/singular

* Refactor to vararg paths

* Group block: remove unused usedLayout variable

* Migrate all remaining usages of useSetting

* Update docs

* Rename use-setting to use-settings

* Update unit tests

* Add jsdoc for the mergeOrigins helper

* Fixup customFontSize variable name

* Deprecate useSetting for real

* Unit test for deprecated useSetting
  • Loading branch information
jsnajdr authored Oct 19, 2023
1 parent 9d3e76b commit d70f278
Show file tree
Hide file tree
Showing 59 changed files with 704 additions and 540 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions packages/block-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
Expand All @@ -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)).
Expand Down Expand Up @@ -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)

Expand Down
24 changes: 23 additions & 1 deletion packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_

Expand All @@ -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_
Expand Down
1 change: 1 addition & 0 deletions packages/block-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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 ),
Expand Down Expand Up @@ -257,7 +257,7 @@ function BlockListBlock( {
attributes,
defaultColors,
name,
fontSizes
fontSizes || EMPTY_ARRAY
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/block-list/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' };

Expand All @@ -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 ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
17 changes: 10 additions & 7 deletions packages/block-editor/src/components/colors-gradients/control.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
/**
* Internal dependencies
*/
import useSetting from '../use-setting';
import { useSettings } from '../use-settings';

const colorsAndGradientKeys = [
'colors',
Expand Down Expand Up @@ -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 (
<ColorGradientControlInner
{ ...{ ...colorGradientSettings, ...props } }
colors={ colors }
gradients={ gradients }
disableCustomColors={ ! customColors }
disableCustomGradients={ ! customGradients }
{ ...props }
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 = [];
Expand Down Expand Up @@ -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 ) {
Expand Down
13 changes: 6 additions & 7 deletions packages/block-editor/src/components/colors/with-colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
getColorObjectByAttributeValues,
getMostReadableColor,
} from './utils';
import useSetting from '../use-setting';
import { useSettings } from '../use-settings';
import { kebabCase } from '../../utils/object';

/**
Expand Down Expand Up @@ -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 || [] ),
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/font-family/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import useSetting from '../use-setting';
import { useSettings } from '../use-settings';

export default function FontFamilyControl( {
value = '',
onChange,
fontFamilies,
...props
} ) {
const blockLevelFontFamilies = useSetting( 'typography.fontFamilies' );
const [ blockLevelFontFamilies ] = useSettings( 'typography.fontFamilies' );
if ( ! fontFamilies ) {
fontFamilies = blockLevelFontFamilies;
}
Expand Down
Loading

0 comments on commit d70f278

Please sign in to comment.