1
1
/**
2
2
* External dependencies
3
3
*/
4
- import { useDispatch , useSelect } from '@wordpress/data' ;
4
+ import { useDispatch , useRegistry , useSelect } from '@wordpress/data' ;
5
5
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' ;
7
7
8
8
export const useSharedFieldAttributes = ( {
9
9
attributes,
10
10
clientId,
11
11
setAttributes,
12
12
sharedAttributes,
13
13
} ) => {
14
- const { updateBlockAttributes } = useDispatch ( 'core/block-editor' ) ;
14
+ const registry = useRegistry ( ) ;
15
+ const { updateBlockAttributes, __unstableMarkNextChangeAsNotPersistent } =
16
+ useDispatch ( 'core/block-editor' ) ;
15
17
16
- const siblings = useSelect (
17
- select => {
18
- const blockEditor = select ( 'core/block-editor' ) ;
18
+ const { getBlockParentsByBlockName, getClientIdsOfDescendants, getBlocksByClientId } =
19
+ useSelect ( 'core/block-editor' ) ;
19
20
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' ) ) ;
23
23
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 ] ) ;
31
37
32
38
useEffect ( ( ) => {
39
+ const siblings = getSiblings ( ) ;
40
+
33
41
if ( ! isEmpty ( siblings ) && attributes . shareFieldAttributes ) {
34
42
const newSharedAttributes = pick ( first ( siblings ) . attributes , sharedAttributes ) ;
35
- updateBlockAttributes ( [ clientId ] , newSharedAttributes ) ;
43
+ registry . batch ( ( ) => {
44
+ __unstableMarkNextChangeAsNotPersistent ( ) ;
45
+ updateBlockAttributes ( [ clientId ] , newSharedAttributes ) ;
46
+ } ) ;
36
47
}
37
48
// eslint-disable-next-line react-hooks/exhaustive-deps
38
49
} , [ ] ) ;
39
50
40
- return useCallback (
51
+ const updateAttributes = useCallback (
41
52
newAttributes => {
42
- let blocksToUpdate ;
43
- let newSharedAttributes ;
53
+ const siblings = getSiblings ( ) ;
54
+
55
+ let blocksToUpdate = [ ] ;
56
+ let newSharedAttributes = { } ;
44
57
45
58
if ( attributes . shareFieldAttributes && isNil ( newAttributes . shareFieldAttributes ) ) {
46
59
blocksToUpdate = map ( siblings , block => block . clientId ) ;
@@ -50,14 +63,26 @@ export const useSharedFieldAttributes = ( {
50
63
newSharedAttributes = pick ( first ( siblings ) . attributes , sharedAttributes ) ;
51
64
}
52
65
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
+ }
56
70
57
- setAttributes ( newAttributes ) ;
71
+ setAttributes ( newAttributes ) ;
72
+ } ) ;
58
73
} ,
59
- [ attributes , clientId , setAttributes , sharedAttributes , siblings , updateBlockAttributes ]
74
+ [
75
+ attributes ,
76
+ clientId ,
77
+ getSiblings ,
78
+ registry ,
79
+ setAttributes ,
80
+ sharedAttributes ,
81
+ updateBlockAttributes ,
82
+ ]
60
83
) ;
84
+
85
+ return updateAttributes ;
61
86
} ;
62
87
63
88
export const withSharedFieldAttributes =
0 commit comments