migrations
2 years ago
index.js
1 year ago
withButtonContainerLegacyMigration.js
2 years ago
withButtonLegacyMigration.js
2 years ago
withContainerLegacyMigration.js
2 years ago
withDeviceType.js
3 years ago
withDynamicTag.js
1 year ago
withGridLegacyMigration.js
2 years ago
withHeadlineLegacyMigration.js
2 years ago
withHtmlAttributes.js
1 year ago
withImageLegacyMigration.js
2 years ago
withSetAttributes.js
2 years ago
withStyles.js
1 year ago
withUniqueId.js
2 years ago
withSetAttributes.js
64 lines
| 1 | import { useDispatch, useSelect } from '@wordpress/data'; |
| 2 | import { useMemo } from '@wordpress/element'; |
| 3 | import { isPlainObject } from 'lodash'; |
| 4 | |
| 5 | /** |
| 6 | * Deep merge attributes. |
| 7 | * |
| 8 | * @param {Object} current The current attributes. |
| 9 | * @param {Object} attrs The new attributes. |
| 10 | * @return {Object} The merged attributes. |
| 11 | */ |
| 12 | export function deepMergeAttributes( current, attrs ) { |
| 13 | const result = { }; |
| 14 | |
| 15 | for ( const [ key, value ] of Object.entries( attrs ) ) { |
| 16 | if ( isPlainObject( value ) && isPlainObject( current[ key ] ) ) { |
| 17 | result[ key ] = { |
| 18 | ...current[ key ], |
| 19 | ...deepMergeAttributes( current[ key ], value ), |
| 20 | }; |
| 21 | } else { |
| 22 | result[ key ] = value; |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | return result; |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * This HOC replaces the core "setAttributes" for an enhanced version. |
| 31 | * |
| 32 | * @param {Function} WrappedComponent The component. |
| 33 | * @return {Function} The wrapped component. |
| 34 | */ |
| 35 | export default ( WrappedComponent ) => ( ( props ) => { |
| 36 | const multiSelectedBlocks = useSelect( ( select ) => ( |
| 37 | select( 'core/block-editor' )?.getMultiSelectedBlocks() || [] |
| 38 | ), [] ); |
| 39 | |
| 40 | const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); |
| 41 | |
| 42 | const setAttributes = useMemo( () => { |
| 43 | if ( multiSelectedBlocks.length === 0 ) { |
| 44 | return function setDeepAttributes( attrs ) { |
| 45 | props.setAttributes( deepMergeAttributes( props.attributes, attrs ) ); |
| 46 | }; |
| 47 | } |
| 48 | |
| 49 | return function setDeepMultiAttributes( attrs ) { |
| 50 | const blocks = multiSelectedBlocks.reduce( ( result, block ) => { |
| 51 | result.clientIds.push( block.clientId ); |
| 52 | |
| 53 | result.blockAttrs[ block.clientId ] = deepMergeAttributes( block.attributes, attrs ); |
| 54 | |
| 55 | return result; |
| 56 | }, { clientIds: [], blockAttrs: {} } ); |
| 57 | |
| 58 | updateBlockAttributes( blocks.clientIds, blocks.blockAttrs, true ); |
| 59 | }; |
| 60 | }, [ multiSelectedBlocks.length, JSON.stringify( props.attributes ) ] ); |
| 61 | |
| 62 | return ( <WrappedComponent { ...props } setAttributes={ setAttributes } /> ); |
| 63 | } ); |
| 64 |