@wordpress/block-editor 14.3.4 → 14.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +4 -0
  2. package/build/components/block-list/block.js +0 -3
  3. package/build/components/block-list/block.js.map +1 -1
  4. package/build/components/block-list/use-block-props/index.js +1 -4
  5. package/build/components/block-list/use-block-props/index.js.map +1 -1
  6. package/build/components/block-list/use-block-props/use-zoom-out-mode-exit.js +9 -12
  7. package/build/components/block-list/use-block-props/use-zoom-out-mode-exit.js.map +1 -1
  8. package/build/components/block-variation-picker/index.js +2 -4
  9. package/build/components/block-variation-picker/index.js.map +1 -1
  10. package/build/components/block-variation-transforms/index.js +3 -4
  11. package/build/components/block-variation-transforms/index.js.map +1 -1
  12. package/build/components/button-block-appender/index.js +2 -4
  13. package/build/components/button-block-appender/index.js.map +1 -1
  14. package/build/components/colors-gradients/dropdown.js +2 -4
  15. package/build/components/colors-gradients/dropdown.js.map +1 -1
  16. package/build/components/global-styles/color-panel.js +2 -4
  17. package/build/components/global-styles/color-panel.js.map +1 -1
  18. package/build/components/global-styles/filters-panel.js +2 -4
  19. package/build/components/global-styles/filters-panel.js.map +1 -1
  20. package/build/components/global-styles/shadow-panel-components.js +24 -29
  21. package/build/components/global-styles/shadow-panel-components.js.map +1 -1
  22. package/build/components/iframe/index.js +6 -1
  23. package/build/components/iframe/index.js.map +1 -1
  24. package/build/components/inserter/menu.js +3 -0
  25. package/build/components/inserter/menu.js.map +1 -1
  26. package/build/components/inspector-controls-tabs/index.js +11 -8
  27. package/build/components/inspector-controls-tabs/index.js.map +1 -1
  28. package/build/components/inspector-popover-header/index.js +4 -8
  29. package/build/components/inspector-popover-header/index.js.map +1 -1
  30. package/build/components/link-control/index.js +4 -8
  31. package/build/components/link-control/index.js.map +1 -1
  32. package/build/components/link-control/settings-drawer.js +2 -4
  33. package/build/components/link-control/settings-drawer.js.map +1 -1
  34. package/build/components/list-view/block-select-button.js +1 -4
  35. package/build/components/list-view/block-select-button.js.map +1 -1
  36. package/build/components/media-placeholder/index.js +12 -24
  37. package/build/components/media-placeholder/index.js.map +1 -1
  38. package/build/components/skip-to-selected-block/index.js +2 -4
  39. package/build/components/skip-to-selected-block/index.js.map +1 -1
  40. package/build/components/tool-selector/index.js +7 -5
  41. package/build/components/tool-selector/index.js.map +1 -1
  42. package/build/components/url-input/button.js +14 -16
  43. package/build/components/url-input/button.js.map +1 -1
  44. package/build/components/url-input/index.js +2 -4
  45. package/build/components/url-input/index.js.map +1 -1
  46. package/build/components/use-resize-canvas/index.js +1 -2
  47. package/build/components/use-resize-canvas/index.js.map +1 -1
  48. package/build/hooks/grid-visualizer.js +13 -11
  49. package/build/hooks/grid-visualizer.js.map +1 -1
  50. package/build/hooks/layout-child.js +41 -3
  51. package/build/hooks/layout-child.js.map +1 -1
  52. package/build/layouts/flex.js +6 -38
  53. package/build/layouts/flex.js.map +1 -1
  54. package/build/private-apis.js +2 -0
  55. package/build/private-apis.js.map +1 -1
  56. package/build/utils/block-bindings.js +9 -6
  57. package/build/utils/block-bindings.js.map +1 -1
  58. package/build-module/components/block-list/block.js +0 -3
  59. package/build-module/components/block-list/block.js.map +1 -1
  60. package/build-module/components/block-list/use-block-props/index.js +1 -4
  61. package/build-module/components/block-list/use-block-props/index.js.map +1 -1
  62. package/build-module/components/block-list/use-block-props/use-zoom-out-mode-exit.js +9 -12
  63. package/build-module/components/block-list/use-block-props/use-zoom-out-mode-exit.js.map +1 -1
  64. package/build-module/components/block-variation-picker/index.js +2 -4
  65. package/build-module/components/block-variation-picker/index.js.map +1 -1
  66. package/build-module/components/block-variation-transforms/index.js +3 -4
  67. package/build-module/components/block-variation-transforms/index.js.map +1 -1
  68. package/build-module/components/button-block-appender/index.js +2 -4
  69. package/build-module/components/button-block-appender/index.js.map +1 -1
  70. package/build-module/components/colors-gradients/dropdown.js +2 -4
  71. package/build-module/components/colors-gradients/dropdown.js.map +1 -1
  72. package/build-module/components/global-styles/color-panel.js +2 -4
  73. package/build-module/components/global-styles/color-panel.js.map +1 -1
  74. package/build-module/components/global-styles/filters-panel.js +2 -4
  75. package/build-module/components/global-styles/filters-panel.js.map +1 -1
  76. package/build-module/components/global-styles/shadow-panel-components.js +25 -30
  77. package/build-module/components/global-styles/shadow-panel-components.js.map +1 -1
  78. package/build-module/components/iframe/index.js +6 -1
  79. package/build-module/components/iframe/index.js.map +1 -1
  80. package/build-module/components/inserter/menu.js +3 -0
  81. package/build-module/components/inserter/menu.js.map +1 -1
  82. package/build-module/components/inspector-controls-tabs/index.js +12 -9
  83. package/build-module/components/inspector-controls-tabs/index.js.map +1 -1
  84. package/build-module/components/inspector-popover-header/index.js +4 -8
  85. package/build-module/components/inspector-popover-header/index.js.map +1 -1
  86. package/build-module/components/link-control/index.js +4 -8
  87. package/build-module/components/link-control/index.js.map +1 -1
  88. package/build-module/components/link-control/settings-drawer.js +2 -4
  89. package/build-module/components/link-control/settings-drawer.js.map +1 -1
  90. package/build-module/components/list-view/block-select-button.js +2 -5
  91. package/build-module/components/list-view/block-select-button.js.map +1 -1
  92. package/build-module/components/media-placeholder/index.js +12 -24
  93. package/build-module/components/media-placeholder/index.js.map +1 -1
  94. package/build-module/components/skip-to-selected-block/index.js +2 -4
  95. package/build-module/components/skip-to-selected-block/index.js.map +1 -1
  96. package/build-module/components/tool-selector/index.js +7 -5
  97. package/build-module/components/tool-selector/index.js.map +1 -1
  98. package/build-module/components/url-input/button.js +15 -17
  99. package/build-module/components/url-input/button.js.map +1 -1
  100. package/build-module/components/url-input/index.js +2 -4
  101. package/build-module/components/url-input/index.js.map +1 -1
  102. package/build-module/components/use-resize-canvas/index.js +1 -2
  103. package/build-module/components/use-resize-canvas/index.js.map +1 -1
  104. package/build-module/hooks/grid-visualizer.js +13 -11
  105. package/build-module/hooks/grid-visualizer.js.map +1 -1
  106. package/build-module/hooks/layout-child.js +41 -3
  107. package/build-module/hooks/layout-child.js.map +1 -1
  108. package/build-module/layouts/flex.js +7 -39
  109. package/build-module/layouts/flex.js.map +1 -1
  110. package/build-module/private-apis.js +2 -0
  111. package/build-module/private-apis.js.map +1 -1
  112. package/build-module/utils/block-bindings.js +9 -6
  113. package/build-module/utils/block-bindings.js.map +1 -1
  114. package/build-style/content-rtl.css +6 -10
  115. package/build-style/content.css +6 -10
  116. package/build-style/style-rtl.css +27 -26
  117. package/build-style/style.css +27 -26
  118. package/package.json +5 -5
  119. package/src/components/block-inspector/style.scss +2 -0
  120. package/src/components/block-list/block.js +0 -3
  121. package/src/components/block-list/use-block-props/index.js +1 -2
  122. package/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js +19 -11
  123. package/src/components/block-tools/style.scss +5 -0
  124. package/src/components/block-variation-picker/index.js +1 -2
  125. package/src/components/block-variation-transforms/index.js +2 -2
  126. package/src/components/button-block-appender/content.scss +0 -5
  127. package/src/components/button-block-appender/index.js +1 -2
  128. package/src/components/colors-gradients/dropdown.js +1 -5
  129. package/src/components/global-styles/color-panel.js +1 -5
  130. package/src/components/global-styles/filters-panel.js +1 -2
  131. package/src/components/global-styles/shadow-panel-components.js +28 -33
  132. package/src/components/global-styles/style.scss +5 -0
  133. package/src/components/iframe/content.scss +7 -8
  134. package/src/components/iframe/index.js +7 -1
  135. package/src/components/iframe/style.scss +17 -0
  136. package/src/components/inserter/menu.js +5 -0
  137. package/src/components/inspector-controls-tabs/index.js +21 -20
  138. package/src/components/inspector-popover-header/index.js +2 -4
  139. package/src/components/inspector-popover-header/style.scss +0 -13
  140. package/src/components/link-control/index.js +2 -4
  141. package/src/components/link-control/settings-drawer.js +1 -2
  142. package/src/components/list-view/block-select-button.js +2 -5
  143. package/src/components/list-view/style.scss +18 -0
  144. package/src/components/media-placeholder/index.js +6 -12
  145. package/src/components/skip-to-selected-block/index.js +1 -2
  146. package/src/components/skip-to-selected-block/style.scss +0 -9
  147. package/src/components/tool-selector/index.js +6 -4
  148. package/src/components/url-input/button.js +16 -12
  149. package/src/components/url-input/index.js +1 -2
  150. package/src/components/url-input/style.scss +0 -6
  151. package/src/components/use-resize-canvas/index.js +1 -3
  152. package/src/hooks/grid-visualizer.js +23 -9
  153. package/src/hooks/layout-child.js +48 -3
  154. package/src/layouts/flex.js +10 -53
  155. package/src/private-apis.js +2 -0
  156. package/src/utils/block-bindings.js +9 -6
  157. package/src/utils/test/use-block-bindings-utils.js +174 -0
@@ -3,18 +3,9 @@
3
3
  top: -9999em;
4
4
 
5
5
  &:focus {
6
- height: auto;
7
- width: auto;
8
- display: block;
9
6
  font-size: 14px;
10
7
  font-weight: 600;
11
- padding: 15px 23px 14px;
12
8
  background: #f1f1f1;
13
- color: var(--wp-admin-theme-color);
14
- line-height: normal;
15
- box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
16
- text-decoration: none;
17
- outline: none;
18
9
  z-index: z-index(".skip-to-selected-block");
19
10
  }
20
11
  }
@@ -36,7 +36,7 @@ function ToolSelector( props, ref ) {
36
36
  ( select ) => select( blockEditorStore ).__unstableGetEditorMode(),
37
37
  []
38
38
  );
39
- const { __unstableSetEditorMode } = unlock(
39
+ const { resetZoomLevel, __unstableSetEditorMode } = unlock(
40
40
  useDispatch( blockEditorStore )
41
41
  );
42
42
 
@@ -44,8 +44,7 @@ function ToolSelector( props, ref ) {
44
44
  <Dropdown
45
45
  renderToggle={ ( { isOpen, onToggle } ) => (
46
46
  <Button
47
- // TODO: Switch to `true` (40px size) if possible
48
- __next40pxDefaultSize={ false }
47
+ size="compact"
49
48
  { ...props }
50
49
  ref={ ref }
51
50
  icon={ mode === 'navigation' ? selectIcon : editIcon }
@@ -64,7 +63,10 @@ function ToolSelector( props, ref ) {
64
63
  value={
65
64
  mode === 'navigation' ? 'navigation' : 'edit'
66
65
  }
67
- onSelect={ __unstableSetEditorMode }
66
+ onSelect={ ( newMode ) => {
67
+ resetZoomLevel();
68
+ __unstableSetEditorMode( newMode );
69
+ } }
68
70
  choices={ [
69
71
  {
70
72
  value: 'edit',
@@ -3,7 +3,10 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { Component } from '@wordpress/element';
6
- import { Button } from '@wordpress/components';
6
+ import {
7
+ Button,
8
+ __experimentalInputControlSuffixWrapper as InputControlSuffixWrapper,
9
+ } from '@wordpress/components';
7
10
  import { link, keyboardReturn, arrowLeft } from '@wordpress/icons';
8
11
 
9
12
  /**
@@ -38,8 +41,7 @@ class URLInputButton extends Component {
38
41
  return (
39
42
  <div className="block-editor-url-input__button">
40
43
  <Button
41
- // TODO: Switch to `true` (40px size) if possible
42
- __next40pxDefaultSize={ false }
44
+ size="compact"
43
45
  icon={ link }
44
46
  label={ buttonLabel }
45
47
  onClick={ this.toggle }
@@ -53,8 +55,7 @@ class URLInputButton extends Component {
53
55
  >
54
56
  <div className="block-editor-url-input__button-modal-line">
55
57
  <Button
56
- // TODO: Switch to `true` (40px size) if possible
57
- __next40pxDefaultSize={ false }
58
+ __next40pxDefaultSize
58
59
  className="block-editor-url-input__back"
59
60
  icon={ arrowLeft }
60
61
  label={ __( 'Close' ) }
@@ -63,13 +64,16 @@ class URLInputButton extends Component {
63
64
  <URLInput
64
65
  value={ url || '' }
65
66
  onChange={ onChange }
66
- />
67
- <Button
68
- // TODO: Switch to `true` (40px size) if possible
69
- __next40pxDefaultSize={ false }
70
- icon={ keyboardReturn }
71
- label={ __( 'Submit' ) }
72
- type="submit"
67
+ suffix={
68
+ <InputControlSuffixWrapper variant="control">
69
+ <Button
70
+ size="small"
71
+ icon={ keyboardReturn }
72
+ label={ __( 'Submit' ) }
73
+ type="submit"
74
+ />
75
+ </InputControlSuffixWrapper>
76
+ }
73
77
  />
74
78
  </div>
75
79
  </form>
@@ -540,8 +540,7 @@ class URLInput extends Component {
540
540
  >
541
541
  { suggestions.map( ( suggestion, index ) => (
542
542
  <Button
543
- // TODO: Switch to `true` (40px size) if possible
544
- __next40pxDefaultSize={ false }
543
+ __next40pxDefaultSize
545
544
  { ...buildSuggestionItemProps( suggestion, index ) }
546
545
  key={ suggestion.id }
547
546
  className={ clsx(
@@ -109,10 +109,4 @@ $input-size: 300px;
109
109
  flex-shrink: 1;
110
110
  min-width: 0;
111
111
  align-items: flex-start;
112
-
113
- .components-button {
114
- flex-shrink: 0;
115
- width: $button-size;
116
- height: $button-size;
117
- }
118
112
  }
@@ -43,11 +43,9 @@ export default function useResizeCanvas( deviceType ) {
43
43
  return deviceWidth < actualWidth ? deviceWidth : actualWidth;
44
44
  };
45
45
 
46
- const marginValue = () => ( window.innerHeight < 800 ? 36 : 64 );
47
-
48
46
  const contentInlineStyles = ( device ) => {
49
47
  const height = device === 'Mobile' ? '768px' : '1024px';
50
- const marginVertical = marginValue() + 'px';
48
+ const marginVertical = '40px';
51
49
  const marginHorizontal = 'auto';
52
50
 
53
51
  switch ( device ) {
@@ -16,20 +16,34 @@ function GridLayoutSync( props ) {
16
16
  }
17
17
 
18
18
  function GridTools( { clientId, layout } ) {
19
- const { isSelected, isDragging } = useSelect( ( select ) => {
20
- const { isBlockSelected, isDraggingBlocks } =
21
- select( blockEditorStore );
19
+ const isVisible = useSelect(
20
+ ( select ) => {
21
+ const {
22
+ isBlockSelected,
23
+ isDraggingBlocks,
24
+ getTemplateLock,
25
+ getBlockEditingMode,
26
+ } = select( blockEditorStore );
22
27
 
23
- return {
24
- isSelected: isBlockSelected( clientId ),
25
- isDragging: isDraggingBlocks(),
26
- };
27
- } );
28
+ // These calls are purposely ordered from least expensive to most expensive.
29
+ // Hides the visualizer in cases where the user is not or cannot interact with it.
30
+ if (
31
+ ( ! isDraggingBlocks() && ! isBlockSelected( clientId ) ) ||
32
+ getTemplateLock( clientId ) ||
33
+ getBlockEditingMode( clientId ) !== 'default'
34
+ ) {
35
+ return false;
36
+ }
37
+
38
+ return true;
39
+ },
40
+ [ clientId ]
41
+ );
28
42
 
29
43
  return (
30
44
  <>
31
45
  <GridLayoutSync clientId={ clientId } />
32
- { ( isSelected || isDragging ) && (
46
+ { isVisible && (
33
47
  <GridVisualizer clientId={ clientId } parentLayout={ layout } />
34
48
  ) }
35
49
  </>
@@ -172,9 +172,54 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) {
172
172
  isManualPlacement,
173
173
  } = parentLayout;
174
174
 
175
- const rootClientId = useSelect(
175
+ if ( parentLayoutType !== 'grid' ) {
176
+ return null;
177
+ }
178
+
179
+ return (
180
+ <GridTools
181
+ clientId={ clientId }
182
+ style={ style }
183
+ setAttributes={ setAttributes }
184
+ allowSizingOnChildren={ allowSizingOnChildren }
185
+ isManualPlacement={ isManualPlacement }
186
+ parentLayout={ parentLayout }
187
+ />
188
+ );
189
+ }
190
+
191
+ function GridTools( {
192
+ clientId,
193
+ style,
194
+ setAttributes,
195
+ allowSizingOnChildren,
196
+ isManualPlacement,
197
+ parentLayout,
198
+ } ) {
199
+ const { rootClientId, isVisible } = useSelect(
176
200
  ( select ) => {
177
- return select( blockEditorStore ).getBlockRootClientId( clientId );
201
+ const {
202
+ getBlockRootClientId,
203
+ getBlockEditingMode,
204
+ getTemplateLock,
205
+ } = select( blockEditorStore );
206
+
207
+ const _rootClientId = getBlockRootClientId( clientId );
208
+
209
+ if (
210
+ getTemplateLock( _rootClientId ) ||
211
+ getBlockEditingMode( _rootClientId ) !== 'default'
212
+ ) {
213
+ return {
214
+ rootClientId: _rootClientId,
215
+ isVisible: false,
216
+ };
217
+ }
218
+
219
+ return {
220
+ rootClientId: _rootClientId,
221
+ isVisible: true,
222
+ };
178
223
  },
179
224
  [ clientId ]
180
225
  );
@@ -182,7 +227,7 @@ function ChildLayoutControlsPure( { clientId, style, setAttributes } ) {
182
227
  // Use useState() instead of useRef() so that GridItemResizer updates when ref is set.
183
228
  const [ resizerBounds, setResizerBounds ] = useState();
184
229
 
185
- if ( parentLayoutType !== 'grid' ) {
230
+ if ( ! isVisible ) {
186
231
  return null;
187
232
  }
188
233
 
@@ -12,7 +12,6 @@ import {
12
12
  arrowDown,
13
13
  } from '@wordpress/icons';
14
14
  import {
15
- Button,
16
15
  ToggleControl,
17
16
  Flex,
18
17
  FlexItem,
@@ -110,7 +109,6 @@ export default {
110
109
  <FlexLayoutVerticalAlignmentControl
111
110
  layout={ layout }
112
111
  onChange={ onChange }
113
- isToolbar
114
112
  />
115
113
  ) }
116
114
  </BlockControls>
@@ -190,11 +188,7 @@ export default {
190
188
  },
191
189
  };
192
190
 
193
- function FlexLayoutVerticalAlignmentControl( {
194
- layout,
195
- onChange,
196
- isToolbar = false,
197
- } ) {
191
+ function FlexLayoutVerticalAlignmentControl( { layout, onChange } ) {
198
192
  const { orientation = 'horizontal' } = layout;
199
193
 
200
194
  const defaultVerticalAlignment =
@@ -210,54 +204,17 @@ function FlexLayoutVerticalAlignmentControl( {
210
204
  verticalAlignment: value,
211
205
  } );
212
206
  };
213
- if ( isToolbar ) {
214
- return (
215
- <BlockVerticalAlignmentControl
216
- onChange={ onVerticalAlignmentChange }
217
- value={ verticalAlignment }
218
- controls={
219
- orientation === 'horizontal'
220
- ? [ 'top', 'center', 'bottom', 'stretch' ]
221
- : [ 'top', 'center', 'bottom', 'space-between' ]
222
- }
223
- />
224
- );
225
- }
226
-
227
- const verticalAlignmentOptions = [
228
- {
229
- value: 'flex-start',
230
- label: __( 'Align items top' ),
231
- },
232
- {
233
- value: 'center',
234
- label: __( 'Align items center' ),
235
- },
236
- {
237
- value: 'flex-end',
238
- label: __( 'Align items bottom' ),
239
- },
240
- ];
241
207
 
242
208
  return (
243
- <fieldset className="block-editor-hooks__flex-layout-vertical-alignment-control">
244
- <legend>{ __( 'Vertical alignment' ) }</legend>
245
- <div>
246
- { verticalAlignmentOptions.map( ( value, icon, label ) => {
247
- return (
248
- <Button
249
- // TODO: Switch to `true` (40px size) if possible
250
- __next40pxDefaultSize={ false }
251
- key={ value }
252
- label={ label }
253
- icon={ icon }
254
- isPressed={ verticalAlignment === value }
255
- onClick={ () => onVerticalAlignmentChange( value ) }
256
- />
257
- );
258
- } ) }
259
- </div>
260
- </fieldset>
209
+ <BlockVerticalAlignmentControl
210
+ onChange={ onVerticalAlignmentChange }
211
+ value={ verticalAlignment }
212
+ controls={
213
+ orientation === 'horizontal'
214
+ ? [ 'top', 'center', 'bottom', 'stretch' ]
215
+ : [ 'top', 'center', 'bottom', 'space-between' ]
216
+ }
217
+ />
261
218
  );
262
219
  }
263
220
 
@@ -32,6 +32,7 @@ import { usesContextKey } from './components/rich-text/format-edit';
32
32
  import { ExperimentalBlockCanvas } from './components/block-canvas';
33
33
  import { getDuotoneFilter } from './components/duotone/utils';
34
34
  import { useFlashEditableBlocks } from './components/use-flash-editable-blocks';
35
+ import { useZoomOutModeExit } from './components/block-list/use-block-props/use-zoom-out-mode-exit';
35
36
  import {
36
37
  selectBlockPatternsKey,
37
38
  reusableBlocksSelectKey,
@@ -78,6 +79,7 @@ lock( privateApis, {
78
79
  TextAlignmentControl,
79
80
  usesContextKey,
80
81
  useFlashEditableBlocks,
82
+ useZoomOutModeExit,
81
83
  globalStylesDataKey,
82
84
  globalStylesLinksDataKey,
83
85
  selectBlockPatternsKey,
@@ -30,6 +30,8 @@ function isObjectEmpty( object ) {
30
30
  * - `updateBlockBindings`: Updates the value of the bindings connected to block attributes. It can be used to remove a specific binding by setting the value to `undefined`.
31
31
  * - `removeAllBlockBindings`: Removes the bindings property of the `metadata` attribute.
32
32
  *
33
+ * @param {?string} clientId Optional block client ID. If not set, it will use the current block client ID from the context.
34
+ *
33
35
  * @return {?WPBlockBindingsUtils} Object containing the block bindings utils.
34
36
  *
35
37
  * @example
@@ -60,8 +62,9 @@ function isObjectEmpty( object ) {
60
62
  * removeAllBlockBindings();
61
63
  * ```
62
64
  */
63
- export function useBlockBindingsUtils() {
64
- const { clientId } = useBlockEditContext();
65
+ export function useBlockBindingsUtils( clientId ) {
66
+ const { clientId: contextClientId } = useBlockEditContext();
67
+ const blockClientId = clientId || contextClientId;
65
68
  const { updateBlockAttributes } = useDispatch( blockEditorStore );
66
69
  const { getBlockAttributes } = useRegistry().select( blockEditorStore );
67
70
 
@@ -96,7 +99,7 @@ export function useBlockBindingsUtils() {
96
99
  */
97
100
  const updateBlockBindings = ( bindings ) => {
98
101
  const { metadata: { bindings: currentBindings, ...metadata } = {} } =
99
- getBlockAttributes( clientId );
102
+ getBlockAttributes( blockClientId );
100
103
  const newBindings = { ...currentBindings };
101
104
 
102
105
  Object.entries( bindings ).forEach( ( [ attribute, binding ] ) => {
@@ -116,7 +119,7 @@ export function useBlockBindingsUtils() {
116
119
  delete newMetadata.bindings;
117
120
  }
118
121
 
119
- updateBlockAttributes( clientId, {
122
+ updateBlockAttributes( blockClientId, {
120
123
  metadata: isObjectEmpty( newMetadata ) ? undefined : newMetadata,
121
124
  } );
122
125
  };
@@ -134,8 +137,8 @@ export function useBlockBindingsUtils() {
134
137
  */
135
138
  const removeAllBlockBindings = () => {
136
139
  const { metadata: { bindings, ...metadata } = {} } =
137
- getBlockAttributes( clientId );
138
- updateBlockAttributes( clientId, {
140
+ getBlockAttributes( blockClientId );
141
+ updateBlockAttributes( blockClientId, {
139
142
  metadata: isObjectEmpty( metadata ) ? undefined : metadata,
140
143
  } );
141
144
  };
@@ -0,0 +1,174 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { renderHook } from '@testing-library/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { store as blockEditorStore } from '@wordpress/block-editor';
10
+ import { dispatch, select } from '@wordpress/data';
11
+ import {
12
+ createBlock,
13
+ getBlockTypes,
14
+ unregisterBlockType,
15
+ } from '@wordpress/blocks';
16
+ import { registerCoreBlocks } from '@wordpress/block-library';
17
+
18
+ /**
19
+ * Internal dependencies
20
+ */
21
+ import { useBlockBindingsUtils } from '../';
22
+
23
+ describe( 'useBlockBindingsUtils', () => {
24
+ beforeAll( () => {
25
+ // Register all core blocks
26
+ registerCoreBlocks();
27
+ } );
28
+
29
+ let clientId;
30
+ beforeEach( async () => {
31
+ const block = createBlock( 'core/paragraph', {
32
+ metadata: {
33
+ name: 'Block name',
34
+ bindings: {
35
+ prop1: {
36
+ source: 'core/post-meta',
37
+ args: {
38
+ key: 'initial_key',
39
+ },
40
+ },
41
+ prop2: {
42
+ source: 'core/post-meta',
43
+ args: {
44
+ key: 'initial_key',
45
+ },
46
+ },
47
+ },
48
+ },
49
+ } );
50
+ await dispatch( blockEditorStore ).resetBlocks( [ block ] );
51
+ clientId = block.clientId;
52
+ } );
53
+
54
+ afterAll( () => {
55
+ // Remove blocks after all tests.
56
+ dispatch( blockEditorStore ).resetBlocks( [] );
57
+
58
+ // Clean up registered blocks
59
+ getBlockTypes().forEach( ( block ) => {
60
+ unregisterBlockType( block.name );
61
+ } );
62
+ } );
63
+
64
+ it( 'should be possible to update just one connection', async () => {
65
+ renderHook( () => {
66
+ const { updateBlockBindings } = useBlockBindingsUtils( clientId );
67
+ updateBlockBindings( {
68
+ prop1: {
69
+ source: 'core/post-meta',
70
+ args: {
71
+ key: 'new_key',
72
+ },
73
+ },
74
+ } );
75
+ } );
76
+ const { metadata } =
77
+ await select( blockEditorStore ).getBlockAttributes( clientId );
78
+ expect( metadata ).toMatchObject( {
79
+ // Other metadata properties shouldn't change.
80
+ name: 'Block name',
81
+ bindings: {
82
+ prop1: {
83
+ source: 'core/post-meta',
84
+ args: {
85
+ key: 'new_key',
86
+ },
87
+ },
88
+ prop2: {
89
+ source: 'core/post-meta',
90
+ args: {
91
+ key: 'initial_key',
92
+ },
93
+ },
94
+ },
95
+ } );
96
+ } );
97
+
98
+ it( 'should be possible to update multiple connections at once', async () => {
99
+ renderHook( () => {
100
+ const { updateBlockBindings } = useBlockBindingsUtils( clientId );
101
+ updateBlockBindings( {
102
+ prop1: {
103
+ source: 'core/post-meta',
104
+ args: {
105
+ key: 'new_key',
106
+ },
107
+ },
108
+ prop2: {
109
+ source: 'core/post-meta',
110
+ args: {
111
+ key: 'new_key',
112
+ },
113
+ },
114
+ } );
115
+ } );
116
+ const { metadata } =
117
+ await select( blockEditorStore ).getBlockAttributes( clientId );
118
+ expect( metadata ).toMatchObject( {
119
+ // Other metadata properties shouldn't change.
120
+ name: 'Block name',
121
+ bindings: {
122
+ prop1: {
123
+ source: 'core/post-meta',
124
+ args: {
125
+ key: 'new_key',
126
+ },
127
+ },
128
+ prop2: {
129
+ source: 'core/post-meta',
130
+ args: {
131
+ key: 'new_key',
132
+ },
133
+ },
134
+ },
135
+ } );
136
+ } );
137
+
138
+ it( 'should be possible to remove connections', async () => {
139
+ renderHook( () => {
140
+ const { updateBlockBindings } = useBlockBindingsUtils( clientId );
141
+ updateBlockBindings( {
142
+ prop2: undefined,
143
+ } );
144
+ } );
145
+ const { metadata } =
146
+ await select( blockEditorStore ).getBlockAttributes( clientId );
147
+ expect( metadata ).toMatchObject( {
148
+ // Other metadata properties shouldn't change.
149
+ name: 'Block name',
150
+ bindings: {
151
+ prop1: {
152
+ source: 'core/post-meta',
153
+ args: {
154
+ key: 'initial_key',
155
+ },
156
+ },
157
+ },
158
+ } );
159
+ } );
160
+
161
+ it( 'should be possible to remove all connections', async () => {
162
+ renderHook( () => {
163
+ const { removeAllBlockBindings } =
164
+ useBlockBindingsUtils( clientId );
165
+ removeAllBlockBindings();
166
+ } );
167
+ const { metadata } =
168
+ await select( blockEditorStore ).getBlockAttributes( clientId );
169
+ expect( metadata ).toMatchObject( {
170
+ // Other metadata properties shouldn't change.
171
+ name: 'Block name',
172
+ } );
173
+ } );
174
+ } );