@@ -15,7 +15,12 @@ import {
15
15
hasBlockSupport ,
16
16
} from '@wordpress/blocks' ;
17
17
import { withFilters } from '@wordpress/components' ;
18
- import { withDispatch , withSelect , useDispatch } from '@wordpress/data' ;
18
+ import {
19
+ withDispatch ,
20
+ withSelect ,
21
+ useDispatch ,
22
+ useSelect ,
23
+ } from '@wordpress/data' ;
19
24
import { compose , pure , ifCondition } from '@wordpress/compose' ;
20
25
21
26
/**
@@ -83,6 +88,21 @@ function BlockListBlock( {
83
88
} ) {
84
89
const { removeBlock } = useDispatch ( blockEditorStore ) ;
85
90
const onRemove = useCallback ( ( ) => removeBlock ( clientId ) , [ clientId ] ) ;
91
+ const isTypingWithinBlock = useSelect (
92
+ ( select ) => {
93
+ const { isTyping, hasSelectedInnerBlock } = select (
94
+ blockEditorStore
95
+ ) ;
96
+ return (
97
+ // We only care about this prop when the block is selected
98
+ // Thus to avoid unnecessary rerenders we avoid updating the
99
+ // prop if the block is not selected.
100
+ ( isSelected || hasSelectedInnerBlock ( clientId , true ) ) &&
101
+ isTyping ( )
102
+ ) ;
103
+ } ,
104
+ [ clientId , isSelected ]
105
+ ) ;
86
106
87
107
// We wrap the BlockEdit component in a div that hides it when editing in
88
108
// HTML mode. This allows us to render all of the ancillary pieces
@@ -163,7 +183,10 @@ function BlockListBlock( {
163
183
isSelected,
164
184
index,
165
185
// The wp-block className is important for editor styles.
166
- className : classnames ( className , { 'wp-block' : ! isAligned } ) ,
186
+ className : classnames ( className , {
187
+ 'wp-block' : ! isAligned ,
188
+ 'is-typing' : isTypingWithinBlock ,
189
+ } ) ,
167
190
wrapperProps : omit ( wrapperProps , [ 'data-align' ] ) ,
168
191
} ;
169
192
const memoizedValue = useMemo ( ( ) => value , Object . values ( value ) ) ;
0 commit comments