diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md index f5e06d6fe86739..14f92a5cf9fddb 100644 --- a/packages/block-editor/CHANGELOG.md +++ b/packages/block-editor/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Breaking Changes + +- 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) diff --git a/packages/block-editor/src/components/global-styles/color-panel.js b/packages/block-editor/src/components/global-styles/color-panel.js index ba8a97b1708584..b5f73f2340f64f 100644 --- a/packages/block-editor/src/components/global-styles/color-panel.js +++ b/packages/block-editor/src/components/global-styles/color-panel.js @@ -28,7 +28,7 @@ import { __ } from '@wordpress/i18n'; import ColorGradientControl from '../colors-gradients/control'; import { useColorsPerOrigin, useGradientsPerOrigin } from './hooks'; import { getValueFromVariable } from './utils'; -import { immutableSet } from '../../utils/object'; +import { setImmutably } from '../../utils/object'; export function useHasColorPanel( settings ) { const hasTextPanel = useHasTextPanel( settings ); @@ -330,7 +330,7 @@ export default function ColorPanel( { const hasTextColor = () => !! userTextColor; const setTextColor = ( newColor ) => { onChange( - immutableSet( + setImmutably( value, [ 'color', 'text' ], encodeColorValue( newColor ) @@ -347,7 +347,7 @@ export default function ColorPanel( { const userGradient = decodeValue( value?.color?.gradient ); const hasBackground = () => !! userBackgroundColor || !! userGradient; const setBackgroundColor = ( newColor ) => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'color', 'background' ], encodeColorValue( newColor ) @@ -356,7 +356,7 @@ export default function ColorPanel( { onChange( newValue ); }; const setGradient = ( newGradient ) => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'color', 'gradient' ], encodeGradientValue( newGradient ) @@ -365,7 +365,7 @@ export default function ColorPanel( { onChange( newValue ); }; const resetBackground = () => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'color', 'background' ], undefined @@ -382,7 +382,7 @@ export default function ColorPanel( { const userLinkColor = decodeValue( value?.elements?.link?.color?.text ); const setLinkColor = ( newColor ) => { onChange( - immutableSet( + setImmutably( value, [ 'elements', 'link', 'color', 'text' ], encodeColorValue( newColor ) @@ -397,7 +397,7 @@ export default function ColorPanel( { ); const setHoverLinkColor = ( newColor ) => { onChange( - immutableSet( + setImmutably( value, [ 'elements', 'link', ':hover', 'color', 'text' ], encodeColorValue( newColor ) @@ -406,12 +406,12 @@ export default function ColorPanel( { }; const hasLink = () => !! userLinkColor || !! userHoverLinkColor; const resetLink = () => { - let newValue = immutableSet( + let newValue = setImmutably( value, [ 'elements', 'link', ':hover', 'color', 'text' ], undefined ); - newValue = immutableSet( + newValue = setImmutably( newValue, [ 'elements', 'link', 'color', 'text' ], undefined @@ -591,7 +591,7 @@ export default function ColorPanel( { elementGradientUserColor ); const resetElement = () => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'elements', name, 'color', 'background' ], undefined @@ -603,7 +603,7 @@ export default function ColorPanel( { const setElementTextColor = ( newTextColor ) => { onChange( - immutableSet( + setImmutably( value, [ 'elements', name, 'color', 'text' ], encodeColorValue( newTextColor ) @@ -611,7 +611,7 @@ export default function ColorPanel( { ); }; const setElementBackgroundColor = ( newBackgroundColor ) => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'elements', name, 'color', 'background' ], encodeColorValue( newBackgroundColor ) @@ -620,7 +620,7 @@ export default function ColorPanel( { onChange( newValue ); }; const setElementGradient = ( newGradient ) => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'elements', name, 'color', 'gradient' ], encodeGradientValue( newGradient ) diff --git a/packages/block-editor/src/components/global-styles/color-panel.native.js b/packages/block-editor/src/components/global-styles/color-panel.native.js index f329ad0369b468..c69c9e26f902c0 100644 --- a/packages/block-editor/src/components/global-styles/color-panel.native.js +++ b/packages/block-editor/src/components/global-styles/color-panel.native.js @@ -13,7 +13,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import PanelColorGradientSettings from '../colors-gradients/panel-color-gradient-settings'; import { useColorsPerOrigin, useGradientsPerOrigin } from './hooks'; import { getValueFromVariable } from './utils'; -import { immutableSet } from '../../utils/object'; +import { setImmutably } from '../../utils/object'; import ContrastChecker from '../contrast-checker'; import InspectorControls from '../inspector-controls'; import { @@ -80,7 +80,7 @@ const ColorPanel = ( { const setTextColor = useCallback( ( newColor ) => { onChange( - immutableSet( + setImmutably( value, [ 'color', 'text' ], encodeColorValue( newColor ) @@ -100,7 +100,7 @@ const ColorPanel = ( { const gradient = decodeValue( inheritedValue?.color?.gradient ); const setBackgroundColor = useCallback( ( newColor ) => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'color', 'background' ], encodeColorValue( newColor ) @@ -112,7 +112,7 @@ const ColorPanel = ( { ); const setGradient = useCallback( ( newGradient ) => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'color', 'gradient' ], encodeGradientValue( newGradient ) @@ -123,7 +123,7 @@ const ColorPanel = ( { [ encodeGradientValue, onChange, value ] ); const resetBackground = useCallback( () => { - const newValue = immutableSet( + const newValue = setImmutably( value, [ 'color', 'background' ], undefined diff --git a/packages/block-editor/src/components/global-styles/dimensions-panel.js b/packages/block-editor/src/components/global-styles/dimensions-panel.js index e0a7508ef5584b..bd748ccc6c1f9c 100644 --- a/packages/block-editor/src/components/global-styles/dimensions-panel.js +++ b/packages/block-editor/src/components/global-styles/dimensions-panel.js @@ -28,7 +28,7 @@ import SpacingSizesControl from '../spacing-sizes-control'; import HeightControl from '../height-control'; import ChildLayoutControl from '../child-layout-control'; import { cleanEmptyObject } from '../../hooks/utils'; -import { immutableSet } from '../../utils/object'; +import { setImmutably } from '../../utils/object'; const AXIAL_SIDES = [ 'horizontal', 'vertical' ]; @@ -226,7 +226,7 @@ export default function DimensionsPanel( { const contentSizeValue = decodeValue( inheritedValue?.layout?.contentSize ); const setContentSizeValue = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'layout', 'contentSize' ], newValue || undefined @@ -242,7 +242,7 @@ export default function DimensionsPanel( { const wideSizeValue = decodeValue( inheritedValue?.layout?.wideSize ); const setWideSizeValue = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'layout', 'wideSize' ], newValue || undefined @@ -264,7 +264,7 @@ export default function DimensionsPanel( { paddingSides.some( ( side ) => AXIAL_SIDES.includes( side ) ); const setPaddingValues = ( newPaddingValues ) => { const padding = filterValuesBySides( newPaddingValues, paddingSides ); - onChange( immutableSet( value, [ 'spacing', 'padding' ], padding ) ); + onChange( setImmutably( value, [ 'spacing', 'padding' ], padding ) ); }; const hasPaddingValue = () => !! value?.spacing?.padding && @@ -284,7 +284,7 @@ export default function DimensionsPanel( { marginSides.some( ( side ) => AXIAL_SIDES.includes( side ) ); const setMarginValues = ( newMarginValues ) => { const margin = filterValuesBySides( newMarginValues, marginSides ); - onChange( immutableSet( value, [ 'spacing', 'margin' ], margin ) ); + onChange( setImmutably( value, [ 'spacing', 'margin' ], margin ) ); }; const hasMarginValue = () => !! value?.spacing?.margin && @@ -303,7 +303,7 @@ export default function DimensionsPanel( { gapSides && gapSides.some( ( side ) => AXIAL_SIDES.includes( side ) ); const setGapValue = ( newGapValue ) => { onChange( - immutableSet( value, [ 'spacing', 'blockGap' ], newGapValue ) + setImmutably( value, [ 'spacing', 'blockGap' ], newGapValue ) ); }; const setGapValues = ( nextBoxGapValue ) => { @@ -328,7 +328,7 @@ export default function DimensionsPanel( { const minHeightValue = decodeValue( inheritedValue?.dimensions?.minHeight ); const setMinHeightValue = ( newValue ) => { onChange( - immutableSet( value, [ 'dimensions', 'minHeight' ], newValue ) + setImmutably( value, [ 'dimensions', 'minHeight' ], newValue ) ); }; const resetMinHeightValue = () => { diff --git a/packages/block-editor/src/components/global-styles/effects-panel.js b/packages/block-editor/src/components/global-styles/effects-panel.js index f2ba7899f32ca9..cda641e0fb17a0 100644 --- a/packages/block-editor/src/components/global-styles/effects-panel.js +++ b/packages/block-editor/src/components/global-styles/effects-panel.js @@ -27,7 +27,7 @@ import { shadow as shadowIcon, Icon, check } from '@wordpress/icons'; * Internal dependencies */ import { getValueFromVariable } from './utils'; -import { immutableSet } from '../../utils/object'; +import { setImmutably } from '../../utils/object'; export function useHasEffectsPanel( settings ) { const hasShadowControl = useHasShadowControl( settings ); @@ -81,7 +81,7 @@ export default function EffectsPanel( { const hasShadowEnabled = useHasShadowControl( settings ); const shadow = decodeValue( inheritedValue?.shadow ); const setShadow = ( newValue ) => { - onChange( immutableSet( value, [ 'shadow' ], newValue ) ); + onChange( setImmutably( value, [ 'shadow' ], newValue ) ); }; const hasShadow = () => !! value?.shadow; const resetShadow = () => setShadow( undefined ); diff --git a/packages/block-editor/src/components/global-styles/filters-panel.js b/packages/block-editor/src/components/global-styles/filters-panel.js index 000daf92a8dd59..e2ee95696d5d49 100644 --- a/packages/block-editor/src/components/global-styles/filters-panel.js +++ b/packages/block-editor/src/components/global-styles/filters-panel.js @@ -29,7 +29,7 @@ import { useCallback, useMemo } from '@wordpress/element'; * Internal dependencies */ import { getValueFromVariable } from './utils'; -import { immutableSet } from '../../utils/object'; +import { setImmutably } from '../../utils/object'; const EMPTY_ARRAY = []; function useMultiOriginColorPresets( @@ -143,7 +143,7 @@ export default function FiltersPanel( { const settedValue = duotonePreset ? `var:preset|duotone|${ duotonePreset.slug }` : newValue; - onChange( immutableSet( value, [ 'filter', 'duotone' ], settedValue ) ); + onChange( setImmutably( value, [ 'filter', 'duotone' ], settedValue ) ); }; const hasDuotone = () => !! value?.filter?.duotone; const resetDuotone = () => setDuotone( undefined ); diff --git a/packages/block-editor/src/components/global-styles/typography-panel.js b/packages/block-editor/src/components/global-styles/typography-panel.js index d52be6431432e3..d7ae30b84caf1f 100644 --- a/packages/block-editor/src/components/global-styles/typography-panel.js +++ b/packages/block-editor/src/components/global-styles/typography-panel.js @@ -20,7 +20,7 @@ import LetterSpacingControl from '../letter-spacing-control'; import TextTransformControl from '../text-transform-control'; import TextDecorationControl from '../text-decoration-control'; import { getValueFromVariable } from './utils'; -import { immutableSet } from '../../utils/object'; +import { setImmutably } from '../../utils/object'; const MIN_TEXT_COLUMNS = 1; const MAX_TEXT_COLUMNS = 6; @@ -163,7 +163,7 @@ export default function TypographyPanel( { ( { fontFamily: f } ) => f === newValue )?.slug; onChange( - immutableSet( + setImmutably( value, [ 'typography', 'fontFamily' ], slug @@ -190,7 +190,7 @@ export default function TypographyPanel( { : newValue; onChange( - immutableSet( + setImmutably( value, [ 'typography', 'fontSize' ], actualValue || undefined @@ -231,7 +231,7 @@ export default function TypographyPanel( { const lineHeight = decodeValue( inheritedValue?.typography?.lineHeight ); const setLineHeight = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'typography', 'lineHeight' ], newValue || undefined @@ -248,7 +248,7 @@ export default function TypographyPanel( { ); const setLetterSpacing = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'typography', 'letterSpacing' ], newValue || undefined @@ -263,7 +263,7 @@ export default function TypographyPanel( { const textColumns = decodeValue( inheritedValue?.typography?.textColumns ); const setTextColumns = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'typography', 'textColumns' ], newValue || undefined @@ -280,7 +280,7 @@ export default function TypographyPanel( { ); const setTextTransform = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'typography', 'textTransform' ], newValue || undefined @@ -297,7 +297,7 @@ export default function TypographyPanel( { ); const setTextDecoration = ( newValue ) => { onChange( - immutableSet( + setImmutably( value, [ 'typography', 'textDecoration' ], newValue || undefined diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 6779962ac1bae6..e38eedc80c6358 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -14,7 +14,7 @@ import { useMemo } from '@wordpress/element'; */ import { useSetting } from '../components'; import { useSettingsForBlockElement } from '../components/global-styles/hooks'; -import { immutableSet } from '../utils/object'; +import { setImmutably } from '../utils/object'; /** * Removed falsy values from nested object. @@ -82,7 +82,7 @@ export function transformStyles( if ( styleValue ) { returnBlock = { ...returnBlock, - attributes: immutableSet( + attributes: setImmutably( returnBlock.attributes, path, styleValue diff --git a/packages/block-editor/src/utils/object.js b/packages/block-editor/src/utils/object.js index 5fe357e5e9f610..a7496bd593923c 100644 --- a/packages/block-editor/src/utils/object.js +++ b/packages/block-editor/src/utils/object.js @@ -42,16 +42,16 @@ function cloneObject( object ) { } /** - * Perform an immutable set. - * Handles nullish initial values. - * Clones all nested objects in the specified object. + * Immutably sets a value inside an object. Like `lodash#set`, but returning a + * new object. Treats nullish initial values as empty objects. Clones any + * nested objects. * * @param {Object} object Object to set a value in. * @param {number|string|Array} path Path in the object to modify. * @param {*} value New value to set. * @return {Object} Cloned object with the new value set. */ -export function immutableSet( object, path, value ) { +export function setImmutably( object, path, value ) { const normalizedPath = normalizePath( path ); const newObject = object ? cloneObject( object ) : {}; diff --git a/packages/block-editor/src/utils/test/object.js b/packages/block-editor/src/utils/test/object.js index 14562400741b5b..8e363e1511db2f 100644 --- a/packages/block-editor/src/utils/test/object.js +++ b/packages/block-editor/src/utils/test/object.js @@ -1,42 +1,42 @@ /** * Internal dependencies */ -import { immutableSet } from '../object'; +import { setImmutably } from '../object'; -describe( 'immutableSet', () => { +describe( 'setImmutably', () => { describe( 'handling falsy values properly', () => { it( 'should create a new object if `undefined` is passed', () => { - const result = immutableSet( undefined, 'test', 1 ); + const result = setImmutably( undefined, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'should create a new object if `null` is passed', () => { - const result = immutableSet( null, 'test', 1 ); + const result = setImmutably( null, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'should create a new object if `false` is passed', () => { - const result = immutableSet( false, 'test', 1 ); + const result = setImmutably( false, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'should create a new object if `0` is passed', () => { - const result = immutableSet( 0, 'test', 1 ); + const result = setImmutably( 0, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'should create a new object if an empty string is passed', () => { - const result = immutableSet( '', 'test', 1 ); + const result = setImmutably( '', 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'should create a new object if a NaN is passed', () => { - const result = immutableSet( NaN, 'test', 1 ); + const result = setImmutably( NaN, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); @@ -44,26 +44,26 @@ describe( 'immutableSet', () => { describe( 'manages data assignment properly', () => { it( 'assigns value properly when it does not exist', () => { - const result = immutableSet( {}, 'test', 1 ); + const result = setImmutably( {}, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'overrides existing values', () => { - const result = immutableSet( { test: 1 }, 'test', 2 ); + const result = setImmutably( { test: 1 }, 'test', 2 ); expect( result ).toEqual( { test: 2 } ); } ); describe( 'with array notation access', () => { it( 'assigns values at deeper levels', () => { - const result = immutableSet( {}, [ 'foo', 'bar', 'baz' ], 5 ); + const result = setImmutably( {}, [ 'foo', 'bar', 'baz' ], 5 ); expect( result ).toEqual( { foo: { bar: { baz: 5 } } } ); } ); it( 'overrides existing values at deeper levels', () => { - const result = immutableSet( + const result = setImmutably( { foo: { bar: { baz: 1 } } }, [ 'foo', 'bar', 'baz' ], 5 @@ -73,7 +73,7 @@ describe( 'immutableSet', () => { } ); it( 'keeps other properties intact', () => { - const result = immutableSet( + const result = setImmutably( { foo: { bar: { baz: 1 } } }, [ 'foo', 'bar', 'test' ], 5 @@ -87,37 +87,37 @@ describe( 'immutableSet', () => { describe( 'for nested falsey values', () => { it( 'overwrites undefined values', () => { - const result = immutableSet( { test: undefined }, 'test', 1 ); + const result = setImmutably( { test: undefined }, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'overwrites null values', () => { - const result = immutableSet( { test: null }, 'test', 1 ); + const result = setImmutably( { test: null }, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'overwrites false values', () => { - const result = immutableSet( { test: false }, 'test', 1 ); + const result = setImmutably( { test: false }, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'overwrites `0` values', () => { - const result = immutableSet( { test: 0 }, 'test', 1 ); + const result = setImmutably( { test: 0 }, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'overwrites empty string values', () => { - const result = immutableSet( { test: '' }, 'test', 1 ); + const result = setImmutably( { test: '' }, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); it( 'overwrites NaN values', () => { - const result = immutableSet( { test: NaN }, 'test', 1 ); + const result = setImmutably( { test: NaN }, 'test', 1 ); expect( result ).toEqual( { test: 1 } ); } ); @@ -127,14 +127,14 @@ describe( 'immutableSet', () => { describe( 'does not mutate the original object', () => { it( 'clones the object at the first level', () => { const input = {}; - const result = immutableSet( input, 'test', 1 ); + const result = setImmutably( input, 'test', 1 ); expect( result ).not.toBe( input ); } ); it( 'clones the object at deeper levels', () => { const input = { foo: { bar: { baz: 1 } } }; - const result = immutableSet( input, [ 'foo', 'bar', 'baz' ], 2 ); + const result = setImmutably( input, [ 'foo', 'bar', 'baz' ], 2 ); expect( result ).not.toBe( input ); expect( result.foo ).not.toBe( input.foo );