Skip to content

Commit d9110e8

Browse files
Forms: Fix syncing of shared styles for nested fields and related undo issue (#41708)
* Forms: Fix syncing of shared styles for nested fields * changelog * Try reducing repeated collections of siblings * Prevent current block being included in siblings * Try batching the block update attributes * Switch approach to using block editor selectors * Try preventing syncing of styles from breaking undo of dropped field
1 parent 1c2e7f1 commit d9110e8

File tree

2 files changed

+54
-25
lines changed

2 files changed

+54
-25
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fixed
3+
4+
Forms: Fix syncing of shared styles for nested fields

projects/packages/forms/src/blocks/contact-form/util/with-shared-field-attributes.js

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,59 @@
11
/**
22
* External dependencies
33
*/
4-
import { useDispatch, useSelect } from '@wordpress/data';
4+
import { useDispatch, useRegistry, useSelect } from '@wordpress/data';
55
import { useCallback, useEffect } from '@wordpress/element';
6-
import { isEmpty, filter, first, map, pick, isNil } from 'lodash';
6+
import { isEmpty, first, map, pick, isNil } from 'lodash';
77

88
export const useSharedFieldAttributes = ( {
99
attributes,
1010
clientId,
1111
setAttributes,
1212
sharedAttributes,
1313
} ) => {
14-
const { updateBlockAttributes } = useDispatch( 'core/block-editor' );
14+
const registry = useRegistry();
15+
const { updateBlockAttributes, __unstableMarkNextChangeAsNotPersistent } =
16+
useDispatch( 'core/block-editor' );
1517

16-
const siblings = useSelect(
17-
select => {
18-
const blockEditor = select( 'core/block-editor' );
18+
const { getBlockParentsByBlockName, getClientIdsOfDescendants, getBlocksByClientId } =
19+
useSelect( 'core/block-editor' );
1920

20-
const parentId = first(
21-
blockEditor.getBlockParentsByBlockName( clientId, 'jetpack/contact-form' )
22-
);
21+
const getSiblings = useCallback( () => {
22+
const parentId = first( getBlockParentsByBlockName( clientId, 'jetpack/contact-form' ) );
2323

24-
return filter(
25-
blockEditor.getBlocks( parentId ),
26-
block => block.name.indexOf( 'jetpack/field' ) > -1 && block.attributes.shareFieldAttributes
27-
);
28-
},
29-
[ clientId ]
30-
);
24+
if ( ! parentId ) {
25+
return [];
26+
}
27+
28+
const formDescendants = getClientIdsOfDescendants( parentId );
29+
30+
return getBlocksByClientId( formDescendants ).filter(
31+
block =>
32+
block?.name?.includes( 'jetpack/field' ) &&
33+
block?.attributes?.shareFieldAttributes &&
34+
block?.clientId !== clientId
35+
);
36+
}, [ clientId, getBlockParentsByBlockName, getClientIdsOfDescendants, getBlocksByClientId ] );
3137

3238
useEffect( () => {
39+
const siblings = getSiblings();
40+
3341
if ( ! isEmpty( siblings ) && attributes.shareFieldAttributes ) {
3442
const newSharedAttributes = pick( first( siblings ).attributes, sharedAttributes );
35-
updateBlockAttributes( [ clientId ], newSharedAttributes );
43+
registry.batch( () => {
44+
__unstableMarkNextChangeAsNotPersistent();
45+
updateBlockAttributes( [ clientId ], newSharedAttributes );
46+
} );
3647
}
3748
// eslint-disable-next-line react-hooks/exhaustive-deps
3849
}, [] );
3950

40-
return useCallback(
51+
const updateAttributes = useCallback(
4152
newAttributes => {
42-
let blocksToUpdate;
43-
let newSharedAttributes;
53+
const siblings = getSiblings();
54+
55+
let blocksToUpdate = [];
56+
let newSharedAttributes = {};
4457

4558
if ( attributes.shareFieldAttributes && isNil( newAttributes.shareFieldAttributes ) ) {
4659
blocksToUpdate = map( siblings, block => block.clientId );
@@ -50,14 +63,26 @@ export const useSharedFieldAttributes = ( {
5063
newSharedAttributes = pick( first( siblings ).attributes, sharedAttributes );
5164
}
5265

53-
if ( ! isEmpty( blocksToUpdate ) && ! isEmpty( newSharedAttributes ) ) {
54-
updateBlockAttributes( blocksToUpdate, newSharedAttributes );
55-
}
66+
registry.batch( () => {
67+
if ( ! isEmpty( blocksToUpdate ) && ! isEmpty( newSharedAttributes ) ) {
68+
updateBlockAttributes( blocksToUpdate, newSharedAttributes );
69+
}
5670

57-
setAttributes( newAttributes );
71+
setAttributes( newAttributes );
72+
} );
5873
},
59-
[ attributes, clientId, setAttributes, sharedAttributes, siblings, updateBlockAttributes ]
74+
[
75+
attributes,
76+
clientId,
77+
getSiblings,
78+
registry,
79+
setAttributes,
80+
sharedAttributes,
81+
updateBlockAttributes,
82+
]
6083
);
84+
85+
return updateAttributes;
6186
};
6287

6388
export const withSharedFieldAttributes =

0 commit comments

Comments
 (0)