@wordpress/block-editor 15.9.1-next.8b30e05b0.0 → 15.10.0

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 (196) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +8 -0
  3. package/build/components/block-alignment-matrix-control/index.js +1 -8
  4. package/build/components/block-alignment-matrix-control/index.js.map +2 -2
  5. package/build/components/block-bindings/attribute-control.js +172 -0
  6. package/build/components/block-bindings/attribute-control.js.map +7 -0
  7. package/build/components/block-bindings/index.js +47 -0
  8. package/build/components/block-bindings/index.js.map +7 -0
  9. package/build/components/block-bindings/source-fields-list.js +135 -0
  10. package/build/components/block-bindings/source-fields-list.js.map +7 -0
  11. package/build/components/block-bindings/use-block-bindings-utils.js +66 -0
  12. package/build/components/block-bindings/use-block-bindings-utils.js.map +7 -0
  13. package/build/components/block-edit/edit.js +1 -3
  14. package/build/components/block-edit/edit.js.map +2 -2
  15. package/build/components/block-inspector/edit-contents.js +93 -14
  16. package/build/components/block-inspector/edit-contents.js.map +3 -3
  17. package/build/components/block-inspector/index.js +44 -28
  18. package/build/components/block-inspector/index.js.map +2 -2
  19. package/build/components/block-settings-menu-controls/edit-section-menu-item.js +39 -9
  20. package/build/components/block-settings-menu-controls/edit-section-menu-item.js.map +3 -3
  21. package/build/components/block-styles/preview-panel.js +3 -5
  22. package/build/components/block-styles/preview-panel.js.map +2 -2
  23. package/build/components/block-styles/use-styles-for-block.js +2 -2
  24. package/build/components/block-styles/use-styles-for-block.js.map +2 -2
  25. package/build/components/block-toolbar/index.js +1 -8
  26. package/build/components/block-toolbar/index.js.map +3 -3
  27. package/build/components/content-only-controls/index.js +2 -25
  28. package/build/components/content-only-controls/index.js.map +2 -2
  29. package/build/components/content-only-controls/link/index.js +3 -3
  30. package/build/components/content-only-controls/link/index.js.map +2 -2
  31. package/build/components/content-only-controls/media/index.js +3 -3
  32. package/build/components/content-only-controls/media/index.js.map +2 -2
  33. package/build/components/content-only-controls/rich-text/index.js +3 -2
  34. package/build/components/content-only-controls/rich-text/index.js.map +2 -2
  35. package/build/components/dimensions-tool/width-height-tool.js +4 -16
  36. package/build/components/dimensions-tool/width-height-tool.js.map +3 -3
  37. package/build/components/grid/grid-item-resizer.js +9 -5
  38. package/build/components/grid/grid-item-resizer.js.map +2 -2
  39. package/build/components/image-editor/cropper.js +3 -34
  40. package/build/components/image-editor/cropper.js.map +3 -3
  41. package/build/components/image-editor/index.js +9 -3
  42. package/build/components/image-editor/index.js.map +2 -2
  43. package/build/components/image-editor/use-transform-image.js +62 -32
  44. package/build/components/image-editor/use-transform-image.js.map +2 -2
  45. package/build/components/image-editor/zoom-dropdown.js +2 -2
  46. package/build/components/image-editor/zoom-dropdown.js.map +2 -2
  47. package/build/components/index.js +7 -3
  48. package/build/components/index.js.map +2 -2
  49. package/build/components/inserter/hooks/use-insertion-point.js +5 -2
  50. package/build/components/inserter/hooks/use-insertion-point.js.map +2 -2
  51. package/build/components/inserter-draggable-blocks/index.js +8 -4
  52. package/build/components/inserter-draggable-blocks/index.js.map +2 -2
  53. package/build/components/inspector-controls-tabs/content-tab.js +3 -2
  54. package/build/components/inspector-controls-tabs/content-tab.js.map +2 -2
  55. package/build/components/link-control/index.js +1 -1
  56. package/build/components/link-control/index.js.map +2 -2
  57. package/build/components/link-control/search-input.js +2 -2
  58. package/build/components/link-control/search-input.js.map +2 -2
  59. package/build/hooks/block-bindings.js +22 -260
  60. package/build/hooks/block-bindings.js.map +3 -3
  61. package/build/layouts/grid.js +23 -28
  62. package/build/layouts/grid.js.map +2 -2
  63. package/build/private-apis.js +1 -0
  64. package/build/private-apis.js.map +2 -2
  65. package/build/store/private-keys.js +3 -0
  66. package/build/store/private-keys.js.map +2 -2
  67. package/build/store/private-selectors.js +2 -1
  68. package/build/store/private-selectors.js.map +2 -2
  69. package/build/store/reducer.js +3 -2
  70. package/build/store/reducer.js.map +2 -2
  71. package/build/utils/block-bindings.js +2 -44
  72. package/build/utils/block-bindings.js.map +3 -3
  73. package/build/utils/index.js +2 -5
  74. package/build/utils/index.js.map +2 -2
  75. package/build-module/components/block-alignment-matrix-control/index.js +1 -8
  76. package/build-module/components/block-alignment-matrix-control/index.js.map +2 -2
  77. package/build-module/components/block-bindings/attribute-control.js +150 -0
  78. package/build-module/components/block-bindings/attribute-control.js.map +7 -0
  79. package/build-module/components/block-bindings/index.js +10 -0
  80. package/build-module/components/block-bindings/index.js.map +7 -0
  81. package/build-module/components/block-bindings/source-fields-list.js +104 -0
  82. package/build-module/components/block-bindings/source-fields-list.js.map +7 -0
  83. package/build-module/components/block-bindings/use-block-bindings-utils.js +45 -0
  84. package/build-module/components/block-bindings/use-block-bindings-utils.js.map +7 -0
  85. package/build-module/components/block-edit/edit.js +1 -3
  86. package/build-module/components/block-edit/edit.js.map +2 -2
  87. package/build-module/components/block-inspector/edit-contents.js +93 -14
  88. package/build-module/components/block-inspector/edit-contents.js.map +2 -2
  89. package/build-module/components/block-inspector/index.js +44 -28
  90. package/build-module/components/block-inspector/index.js.map +2 -2
  91. package/build-module/components/block-settings-menu-controls/edit-section-menu-item.js +39 -9
  92. package/build-module/components/block-settings-menu-controls/edit-section-menu-item.js.map +2 -2
  93. package/build-module/components/block-styles/preview-panel.js +3 -5
  94. package/build-module/components/block-styles/preview-panel.js.map +2 -2
  95. package/build-module/components/block-styles/use-styles-for-block.js +2 -2
  96. package/build-module/components/block-styles/use-styles-for-block.js.map +2 -2
  97. package/build-module/components/block-toolbar/index.js +1 -8
  98. package/build-module/components/block-toolbar/index.js.map +2 -2
  99. package/build-module/components/content-only-controls/index.js +2 -25
  100. package/build-module/components/content-only-controls/index.js.map +2 -2
  101. package/build-module/components/content-only-controls/link/index.js +3 -3
  102. package/build-module/components/content-only-controls/link/index.js.map +2 -2
  103. package/build-module/components/content-only-controls/media/index.js +3 -3
  104. package/build-module/components/content-only-controls/media/index.js.map +2 -2
  105. package/build-module/components/content-only-controls/rich-text/index.js +3 -2
  106. package/build-module/components/content-only-controls/rich-text/index.js.map +2 -2
  107. package/build-module/components/dimensions-tool/width-height-tool.js +4 -6
  108. package/build-module/components/dimensions-tool/width-height-tool.js.map +2 -2
  109. package/build-module/components/grid/grid-item-resizer.js +9 -5
  110. package/build-module/components/grid/grid-item-resizer.js.map +2 -2
  111. package/build-module/components/image-editor/cropper.js +3 -34
  112. package/build-module/components/image-editor/cropper.js.map +2 -2
  113. package/build-module/components/image-editor/index.js +9 -3
  114. package/build-module/components/image-editor/index.js.map +2 -2
  115. package/build-module/components/image-editor/use-transform-image.js +63 -33
  116. package/build-module/components/image-editor/use-transform-image.js.map +2 -2
  117. package/build-module/components/image-editor/zoom-dropdown.js +2 -2
  118. package/build-module/components/image-editor/zoom-dropdown.js.map +2 -2
  119. package/build-module/components/index.js +74 -68
  120. package/build-module/components/index.js.map +2 -2
  121. package/build-module/components/inserter/hooks/use-insertion-point.js +5 -2
  122. package/build-module/components/inserter/hooks/use-insertion-point.js.map +2 -2
  123. package/build-module/components/inserter-draggable-blocks/index.js +8 -4
  124. package/build-module/components/inserter-draggable-blocks/index.js.map +2 -2
  125. package/build-module/components/inspector-controls-tabs/content-tab.js +3 -2
  126. package/build-module/components/inspector-controls-tabs/content-tab.js.map +2 -2
  127. package/build-module/components/link-control/index.js +1 -1
  128. package/build-module/components/link-control/index.js.map +2 -2
  129. package/build-module/components/link-control/search-input.js +2 -2
  130. package/build-module/components/link-control/search-input.js.map +2 -2
  131. package/build-module/hooks/block-bindings.js +27 -270
  132. package/build-module/hooks/block-bindings.js.map +2 -2
  133. package/build-module/layouts/grid.js +23 -28
  134. package/build-module/layouts/grid.js.map +2 -2
  135. package/build-module/private-apis.js +3 -1
  136. package/build-module/private-apis.js.map +2 -2
  137. package/build-module/store/private-keys.js +2 -0
  138. package/build-module/store/private-keys.js.map +2 -2
  139. package/build-module/store/private-selectors.js +4 -2
  140. package/build-module/store/private-selectors.js.map +2 -2
  141. package/build-module/store/reducer.js +4 -3
  142. package/build-module/store/reducer.js.map +2 -2
  143. package/build-module/utils/block-bindings.js +1 -42
  144. package/build-module/utils/block-bindings.js.map +2 -2
  145. package/build-module/utils/index.js +1 -3
  146. package/build-module/utils/index.js.map +2 -2
  147. package/build-style/style-rtl.css +6 -6
  148. package/build-style/style.css +6 -6
  149. package/package.json +39 -40
  150. package/src/components/block-alignment-matrix-control/index.js +1 -5
  151. package/src/components/block-bindings/attribute-control.js +174 -0
  152. package/src/components/block-bindings/index.js +6 -0
  153. package/src/components/block-bindings/source-fields-list.js +130 -0
  154. package/src/components/block-bindings/use-block-bindings-utils.js +156 -0
  155. package/src/components/block-edit/edit.js +1 -3
  156. package/src/components/block-inspector/edit-contents.js +108 -18
  157. package/src/components/block-inspector/index.js +53 -30
  158. package/src/components/block-settings-menu-controls/edit-section-menu-item.js +50 -6
  159. package/src/components/block-styles/preview-panel.js +3 -5
  160. package/src/components/block-styles/use-styles-for-block.js +2 -2
  161. package/src/components/block-toolbar/index.js +1 -6
  162. package/src/components/block-toolbar/style.scss +6 -6
  163. package/src/components/content-only-controls/index.js +2 -27
  164. package/src/components/content-only-controls/link/index.js +3 -3
  165. package/src/components/content-only-controls/media/index.js +3 -3
  166. package/src/components/content-only-controls/rich-text/index.js +3 -2
  167. package/src/components/dimensions-tool/width-height-tool.js +6 -13
  168. package/src/components/grid/grid-item-resizer.js +18 -5
  169. package/src/components/image-editor/cropper.js +3 -32
  170. package/src/components/image-editor/index.js +34 -29
  171. package/src/components/image-editor/use-transform-image.js +80 -34
  172. package/src/components/image-editor/zoom-dropdown.js +2 -2
  173. package/src/components/index.js +5 -1
  174. package/src/components/inserter/hooks/use-insertion-point.js +3 -0
  175. package/src/components/inserter/style.scss +1 -1
  176. package/src/components/inserter-draggable-blocks/index.js +19 -8
  177. package/src/components/inspector-controls-tabs/content-tab.js +6 -2
  178. package/src/components/link-control/index.js +1 -1
  179. package/src/components/link-control/search-input.js +8 -2
  180. package/src/components/link-control/test/index.js +146 -7
  181. package/src/hooks/block-bindings.js +27 -347
  182. package/src/layouts/grid.js +40 -72
  183. package/src/layouts/test/grid.js +14 -0
  184. package/src/private-apis.js +2 -0
  185. package/src/store/private-keys.js +1 -0
  186. package/src/store/private-selectors.js +8 -1
  187. package/src/store/reducer.js +10 -3
  188. package/src/utils/block-bindings.js +0 -157
  189. package/src/utils/index.js +0 -1
  190. package/tsconfig.json +1 -0
  191. package/build/components/block-toolbar/block-name-context.js +0 -30
  192. package/build/components/block-toolbar/block-name-context.js.map +0 -7
  193. package/build-module/components/block-toolbar/block-name-context.js +0 -9
  194. package/build-module/components/block-toolbar/block-name-context.js.map +0 -7
  195. package/src/components/block-toolbar/block-name-context.js +0 -9
  196. /package/src/{utils → components/block-bindings}/test/use-block-bindings-utils.js +0 -0
@@ -1,12 +1,6 @@
1
1
  // packages/block-editor/src/utils/block-bindings.js
2
- import { useDispatch, useRegistry } from "@wordpress/data";
3
- import { store as blockEditorStore } from "../store";
4
- import { useBlockEditContext } from "../components/block-edit";
5
2
  var DEFAULT_ATTRIBUTE = "__default";
6
3
  var PATTERN_OVERRIDES_SOURCE = "core/pattern-overrides";
7
- function isObjectEmpty(object) {
8
- return !object || Object.keys(object).length === 0;
9
- }
10
4
  function hasPatternOverridesDefaultBinding(bindings) {
11
5
  return bindings?.[DEFAULT_ATTRIBUTE]?.source === PATTERN_OVERRIDES_SOURCE;
12
6
  }
@@ -21,43 +15,8 @@ function replacePatternOverridesDefaultBinding(bindings, supportedAttributes) {
21
15
  }
22
16
  return bindings;
23
17
  }
24
- function useBlockBindingsUtils(clientId) {
25
- const { clientId: contextClientId } = useBlockEditContext();
26
- const blockClientId = clientId || contextClientId;
27
- const { updateBlockAttributes } = useDispatch(blockEditorStore);
28
- const { getBlockAttributes } = useRegistry().select(blockEditorStore);
29
- const updateBlockBindings = (bindings) => {
30
- const { metadata: { bindings: currentBindings, ...metadata } = {} } = getBlockAttributes(blockClientId);
31
- const newBindings = { ...currentBindings };
32
- Object.entries(bindings).forEach(([attribute, binding]) => {
33
- if (!binding && newBindings[attribute]) {
34
- delete newBindings[attribute];
35
- return;
36
- }
37
- newBindings[attribute] = binding;
38
- });
39
- const newMetadata = {
40
- ...metadata,
41
- bindings: newBindings
42
- };
43
- if (isObjectEmpty(newMetadata.bindings)) {
44
- delete newMetadata.bindings;
45
- }
46
- updateBlockAttributes(blockClientId, {
47
- metadata: isObjectEmpty(newMetadata) ? void 0 : newMetadata
48
- });
49
- };
50
- const removeAllBlockBindings = () => {
51
- const { metadata: { bindings, ...metadata } = {} } = getBlockAttributes(blockClientId);
52
- updateBlockAttributes(blockClientId, {
53
- metadata: isObjectEmpty(metadata) ? void 0 : metadata
54
- });
55
- };
56
- return { updateBlockBindings, removeAllBlockBindings };
57
- }
58
18
  export {
59
19
  hasPatternOverridesDefaultBinding,
60
- replacePatternOverridesDefaultBinding,
61
- useBlockBindingsUtils
20
+ replacePatternOverridesDefaultBinding
62
21
  };
63
22
  //# sourceMappingURL=block-bindings.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/block-bindings.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useDispatch, useRegistry } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { store as blockEditorStore } from '../store';\nimport { useBlockEditContext } from '../components/block-edit';\n\nconst DEFAULT_ATTRIBUTE = '__default';\nconst PATTERN_OVERRIDES_SOURCE = 'core/pattern-overrides';\n\n/**\n * Checks if the given object is empty.\n *\n * @param {?Object} object The object to check.\n *\n * @return {boolean} Whether the object is empty.\n */\nfunction isObjectEmpty( object ) {\n\treturn ! object || Object.keys( object ).length === 0;\n}\n\n/**\n * Checks if the block has the `__default` binding for pattern overrides.\n *\n * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.\n *\n * @return {boolean} Whether the block has the `__default` binding for pattern overrides.\n */\nexport function hasPatternOverridesDefaultBinding( bindings ) {\n\treturn bindings?.[ DEFAULT_ATTRIBUTE ]?.source === PATTERN_OVERRIDES_SOURCE;\n}\n\n/**\n * Returns the bindings with the `__default` binding for pattern overrides\n * replaced with the full-set of supported attributes. e.g.:\n *\n * - bindings passed in: `{ __default: { source: 'core/pattern-overrides' } }`\n * - bindings returned: `{ content: { source: 'core/pattern-overrides' } }`\n *\n * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.\n * @param {string[]} supportedAttributes The block's attributes which are supported by block bindings.\n *\n * @return {Object} The bindings with default replaced for pattern overrides.\n */\nexport function replacePatternOverridesDefaultBinding(\n\tbindings,\n\tsupportedAttributes\n) {\n\t// The `__default` binding currently only works for pattern overrides.\n\tif ( hasPatternOverridesDefaultBinding( bindings ) ) {\n\t\tconst bindingsWithDefaults = {};\n\t\tfor ( const attributeName of supportedAttributes ) {\n\t\t\t// If the block has mixed binding sources, retain any non pattern override bindings.\n\t\t\tconst bindingSource = bindings[ attributeName ]\n\t\t\t\t? bindings[ attributeName ]\n\t\t\t\t: { source: PATTERN_OVERRIDES_SOURCE };\n\t\t\tbindingsWithDefaults[ attributeName ] = bindingSource;\n\t\t}\n\n\t\treturn bindingsWithDefaults;\n\t}\n\n\treturn bindings;\n}\n\n/**\n * Contains utils to update the block `bindings` metadata.\n *\n * @typedef {Object} WPBlockBindingsUtils\n *\n * @property {Function} updateBlockBindings Updates the value of the bindings connected to block attributes.\n * @property {Function} removeAllBlockBindings Removes the bindings property of the `metadata` attribute.\n */\n\n/**\n * Retrieves the existing utils needed to update the block `bindings` metadata.\n * They can be used to create, modify, or remove connections from the existing block attributes.\n *\n * It contains the following utils:\n * - `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`.\n * - `removeAllBlockBindings`: Removes the bindings property of the `metadata` attribute.\n *\n * @since 6.7.0 Introduced in WordPress core.\n *\n * @param {?string} clientId Optional block client ID. If not set, it will use the current block client ID from the context.\n *\n * @return {?WPBlockBindingsUtils} Object containing the block bindings utils.\n *\n * @example\n * ```js\n * import { useBlockBindingsUtils } from '@wordpress/block-editor'\n * const { updateBlockBindings, removeAllBlockBindings } = useBlockBindingsUtils();\n *\n * // Update url and alt attributes.\n * updateBlockBindings( {\n * url: {\n * source: 'core/post-meta',\n * args: {\n * key: 'url_custom_field',\n * },\n * },\n * alt: {\n * source: 'core/post-meta',\n * args: {\n * key: 'text_custom_field',\n * },\n * },\n * } );\n *\n * // Remove binding from url attribute.\n * updateBlockBindings( { url: undefined } );\n *\n * // Remove bindings from all attributes.\n * removeAllBlockBindings();\n * ```\n */\nexport function useBlockBindingsUtils( clientId ) {\n\tconst { clientId: contextClientId } = useBlockEditContext();\n\tconst blockClientId = clientId || contextClientId;\n\tconst { updateBlockAttributes } = useDispatch( blockEditorStore );\n\tconst { getBlockAttributes } = useRegistry().select( blockEditorStore );\n\n\t/**\n\t * Updates the value of the bindings connected to block attributes.\n\t * It removes the binding when the new value is `undefined`.\n\t *\n\t * @param {Object} bindings Bindings including the attributes to update and the new object.\n\t * @param {string} bindings.source The source name to connect to.\n\t * @param {Object} [bindings.args] Object containing the arguments needed by the source.\n\t *\n\t * @example\n\t * ```js\n\t * import { useBlockBindingsUtils } from '@wordpress/block-editor'\n\t *\n\t * const { updateBlockBindings } = useBlockBindingsUtils();\n\t * updateBlockBindings( {\n\t * url: {\n\t * source: 'core/post-meta',\n\t * args: {\n\t * key: 'url_custom_field',\n\t * },\n\t * \t },\n\t * alt: {\n\t * source: 'core/post-meta',\n\t * args: {\n\t * key: 'text_custom_field',\n\t * },\n\t * \t }\n\t * } );\n\t * ```\n\t */\n\tconst updateBlockBindings = ( bindings ) => {\n\t\tconst { metadata: { bindings: currentBindings, ...metadata } = {} } =\n\t\t\tgetBlockAttributes( blockClientId );\n\t\tconst newBindings = { ...currentBindings };\n\n\t\tObject.entries( bindings ).forEach( ( [ attribute, binding ] ) => {\n\t\t\tif ( ! binding && newBindings[ attribute ] ) {\n\t\t\t\tdelete newBindings[ attribute ];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnewBindings[ attribute ] = binding;\n\t\t} );\n\n\t\tconst newMetadata = {\n\t\t\t...metadata,\n\t\t\tbindings: newBindings,\n\t\t};\n\n\t\tif ( isObjectEmpty( newMetadata.bindings ) ) {\n\t\t\tdelete newMetadata.bindings;\n\t\t}\n\n\t\tupdateBlockAttributes( blockClientId, {\n\t\t\tmetadata: isObjectEmpty( newMetadata ) ? undefined : newMetadata,\n\t\t} );\n\t};\n\n\t/**\n\t * Removes the bindings property of the `metadata` attribute.\n\t *\n\t * @example\n\t * ```js\n\t * import { useBlockBindingsUtils } from '@wordpress/block-editor'\n\t *\n\t * const { removeAllBlockBindings } = useBlockBindingsUtils();\n\t * removeAllBlockBindings();\n\t * ```\n\t */\n\tconst removeAllBlockBindings = () => {\n\t\tconst { metadata: { bindings, ...metadata } = {} } =\n\t\t\tgetBlockAttributes( blockClientId );\n\t\tupdateBlockAttributes( blockClientId, {\n\t\t\tmetadata: isObjectEmpty( metadata ) ? undefined : metadata,\n\t\t} );\n\t};\n\n\treturn { updateBlockBindings, removeAllBlockBindings };\n}\n"],
5
- "mappings": ";AAGA,SAAS,aAAa,mBAAmB;AAKzC,SAAS,SAAS,wBAAwB;AAC1C,SAAS,2BAA2B;AAEpC,IAAM,oBAAoB;AAC1B,IAAM,2BAA2B;AASjC,SAAS,cAAe,QAAS;AAChC,SAAO,CAAE,UAAU,OAAO,KAAM,MAAO,EAAE,WAAW;AACrD;AASO,SAAS,kCAAmC,UAAW;AAC7D,SAAO,WAAY,iBAAkB,GAAG,WAAW;AACpD;AAcO,SAAS,sCACf,UACA,qBACC;AAED,MAAK,kCAAmC,QAAS,GAAI;AACpD,UAAM,uBAAuB,CAAC;AAC9B,eAAY,iBAAiB,qBAAsB;AAElD,YAAM,gBAAgB,SAAU,aAAc,IAC3C,SAAU,aAAc,IACxB,EAAE,QAAQ,yBAAyB;AACtC,2BAAsB,aAAc,IAAI;AAAA,IACzC;AAEA,WAAO;AAAA,EACR;AAEA,SAAO;AACR;AAqDO,SAAS,sBAAuB,UAAW;AACjD,QAAM,EAAE,UAAU,gBAAgB,IAAI,oBAAoB;AAC1D,QAAM,gBAAgB,YAAY;AAClC,QAAM,EAAE,sBAAsB,IAAI,YAAa,gBAAiB;AAChE,QAAM,EAAE,mBAAmB,IAAI,YAAY,EAAE,OAAQ,gBAAiB;AA+BtE,QAAM,sBAAsB,CAAE,aAAc;AAC3C,UAAM,EAAE,UAAU,EAAE,UAAU,iBAAiB,GAAG,SAAS,IAAI,CAAC,EAAE,IACjE,mBAAoB,aAAc;AACnC,UAAM,cAAc,EAAE,GAAG,gBAAgB;AAEzC,WAAO,QAAS,QAAS,EAAE,QAAS,CAAE,CAAE,WAAW,OAAQ,MAAO;AACjE,UAAK,CAAE,WAAW,YAAa,SAAU,GAAI;AAC5C,eAAO,YAAa,SAAU;AAC9B;AAAA,MACD;AACA,kBAAa,SAAU,IAAI;AAAA,IAC5B,CAAE;AAEF,UAAM,cAAc;AAAA,MACnB,GAAG;AAAA,MACH,UAAU;AAAA,IACX;AAEA,QAAK,cAAe,YAAY,QAAS,GAAI;AAC5C,aAAO,YAAY;AAAA,IACpB;AAEA,0BAAuB,eAAe;AAAA,MACrC,UAAU,cAAe,WAAY,IAAI,SAAY;AAAA,IACtD,CAAE;AAAA,EACH;AAaA,QAAM,yBAAyB,MAAM;AACpC,UAAM,EAAE,UAAU,EAAE,UAAU,GAAG,SAAS,IAAI,CAAC,EAAE,IAChD,mBAAoB,aAAc;AACnC,0BAAuB,eAAe;AAAA,MACrC,UAAU,cAAe,QAAS,IAAI,SAAY;AAAA,IACnD,CAAE;AAAA,EACH;AAEA,SAAO,EAAE,qBAAqB,uBAAuB;AACtD;",
4
+ "sourcesContent": ["const DEFAULT_ATTRIBUTE = '__default';\nconst PATTERN_OVERRIDES_SOURCE = 'core/pattern-overrides';\n\n/**\n * Checks if the block has the `__default` binding for pattern overrides.\n *\n * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.\n *\n * @return {boolean} Whether the block has the `__default` binding for pattern overrides.\n */\nexport function hasPatternOverridesDefaultBinding( bindings ) {\n\treturn bindings?.[ DEFAULT_ATTRIBUTE ]?.source === PATTERN_OVERRIDES_SOURCE;\n}\n\n/**\n * Returns the bindings with the `__default` binding for pattern overrides\n * replaced with the full-set of supported attributes. e.g.:\n *\n * - bindings passed in: `{ __default: { source: 'core/pattern-overrides' } }`\n * - bindings returned: `{ content: { source: 'core/pattern-overrides' } }`\n *\n * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.\n * @param {string[]} supportedAttributes The block's attributes which are supported by block bindings.\n *\n * @return {Object} The bindings with default replaced for pattern overrides.\n */\nexport function replacePatternOverridesDefaultBinding(\n\tbindings,\n\tsupportedAttributes\n) {\n\t// The `__default` binding currently only works for pattern overrides.\n\tif ( hasPatternOverridesDefaultBinding( bindings ) ) {\n\t\tconst bindingsWithDefaults = {};\n\t\tfor ( const attributeName of supportedAttributes ) {\n\t\t\t// If the block has mixed binding sources, retain any non pattern override bindings.\n\t\t\tconst bindingSource = bindings[ attributeName ]\n\t\t\t\t? bindings[ attributeName ]\n\t\t\t\t: { source: PATTERN_OVERRIDES_SOURCE };\n\t\t\tbindingsWithDefaults[ attributeName ] = bindingSource;\n\t\t}\n\n\t\treturn bindingsWithDefaults;\n\t}\n\n\treturn bindings;\n}\n"],
5
+ "mappings": ";AAAA,IAAM,oBAAoB;AAC1B,IAAM,2BAA2B;AAS1B,SAAS,kCAAmC,UAAW;AAC7D,SAAO,WAAY,iBAAkB,GAAG,WAAW;AACpD;AAcO,SAAS,sCACf,UACA,qBACC;AAED,MAAK,kCAAmC,QAAS,GAAI;AACpD,UAAM,uBAAuB,CAAC;AAC9B,eAAY,iBAAiB,qBAAsB;AAElD,YAAM,gBAAgB,SAAU,aAAc,IAC3C,SAAU,aAAc,IACxB,EAAE,QAAQ,yBAAyB;AACtC,2BAAsB,aAAc,IAAI;AAAA,IACzC;AAEA,WAAO;AAAA,EACR;AAEA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -1,10 +1,8 @@
1
1
  // packages/block-editor/src/utils/index.js
2
2
  import { default as default2 } from "./transform-styles";
3
3
  import { default as default3 } from "./get-px-from-css-unit";
4
- import { useBlockBindingsUtils } from "./block-bindings";
5
4
  export {
6
5
  default3 as getPxFromCssUnit,
7
- default2 as transformStyles,
8
- useBlockBindingsUtils
6
+ default2 as transformStyles
9
7
  };
10
8
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/index.js"],
4
- "sourcesContent": ["export { default as transformStyles } from './transform-styles';\nexport { default as getPxFromCssUnit } from './get-px-from-css-unit';\nexport { useBlockBindingsUtils } from './block-bindings';\n"],
5
- "mappings": ";AAAA,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAAmC;AAC5C,SAAS,6BAA6B;",
4
+ "sourcesContent": ["export { default as transformStyles } from './transform-styles';\nexport { default as getPxFromCssUnit } from './get-px-from-css-unit';\n"],
5
+ "mappings": ";AAAA,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAAmC;",
6
6
  "names": ["default"]
7
7
  }
@@ -3782,15 +3782,15 @@ div.block-editor-bindings__panel button:hover .block-editor-bindings__item span
3782
3782
  content: attr(aria-label);
3783
3783
  font-size: 12px;
3784
3784
  }
3785
- .show-icon-labels .components-accessible-toolbar .components-toolbar-group > div:first-child:last-child > .components-button.has-icon {
3786
- padding-right: 6px;
3787
- padding-left: 6px;
3788
- }
3789
- .show-icon-labels .block-editor-block-icon {
3785
+ .show-icon-labels .block-editor-block-toolbar .block-editor-block-icon {
3790
3786
  width: 0 !important;
3791
3787
  height: 0 !important;
3792
3788
  min-width: 0 !important;
3793
3789
  }
3790
+ .show-icon-labels .components-accessible-toolbar .components-toolbar-group > div:first-child:last-child > .components-button.has-icon {
3791
+ padding-right: 6px;
3792
+ padding-left: 6px;
3793
+ }
3794
3794
  .show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button {
3795
3795
  border-top-left-radius: 0;
3796
3796
  border-bottom-left-radius: 0;
@@ -4219,7 +4219,7 @@ div.block-editor-bindings__panel button:hover .block-editor-bindings__item span
4219
4219
  right: 0;
4220
4220
  bottom: 0;
4221
4221
  width: 280px;
4222
- padding: 24px 32px 32px;
4222
+ padding: 24px 24px 24px;
4223
4223
  overflow-x: visible;
4224
4224
  overflow-y: auto;
4225
4225
  }
@@ -3784,15 +3784,15 @@ div.block-editor-bindings__panel button:hover .block-editor-bindings__item span
3784
3784
  content: attr(aria-label);
3785
3785
  font-size: 12px;
3786
3786
  }
3787
- .show-icon-labels .components-accessible-toolbar .components-toolbar-group > div:first-child:last-child > .components-button.has-icon {
3788
- padding-left: 6px;
3789
- padding-right: 6px;
3790
- }
3791
- .show-icon-labels .block-editor-block-icon {
3787
+ .show-icon-labels .block-editor-block-toolbar .block-editor-block-icon {
3792
3788
  width: 0 !important;
3793
3789
  height: 0 !important;
3794
3790
  min-width: 0 !important;
3795
3791
  }
3792
+ .show-icon-labels .components-accessible-toolbar .components-toolbar-group > div:first-child:last-child > .components-button.has-icon {
3793
+ padding-left: 6px;
3794
+ padding-right: 6px;
3795
+ }
3796
3796
  .show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button {
3797
3797
  border-top-right-radius: 0;
3798
3798
  border-bottom-right-radius: 0;
@@ -4221,7 +4221,7 @@ div.block-editor-bindings__panel button:hover .block-editor-bindings__item span
4221
4221
  left: 0;
4222
4222
  bottom: 0;
4223
4223
  width: 280px;
4224
- padding: 24px 32px 32px;
4224
+ padding: 24px 24px 24px;
4225
4225
  overflow-x: visible;
4226
4226
  overflow-y: auto;
4227
4227
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "15.9.1-next.8b30e05b0.0",
3
+ "version": "15.10.0",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -52,45 +52,44 @@
52
52
  "build-module/hooks/**"
53
53
  ],
54
54
  "dependencies": {
55
- "@emotion/react": "^11.7.1",
56
- "@emotion/styled": "^11.6.0",
57
55
  "@react-spring/web": "^9.4.5",
58
- "@wordpress/a11y": "^4.36.1-next.8b30e05b0.0",
59
- "@wordpress/api-fetch": "^7.36.1-next.8b30e05b0.0",
60
- "@wordpress/base-styles": "^6.12.1-next.8b30e05b0.0",
61
- "@wordpress/blob": "^4.36.1-next.8b30e05b0.0",
62
- "@wordpress/block-serialization-default-parser": "^5.36.1-next.8b30e05b0.0",
63
- "@wordpress/blocks": "^15.9.1-next.8b30e05b0.0",
64
- "@wordpress/commands": "^1.36.1-next.8b30e05b0.0",
65
- "@wordpress/components": "^30.9.1-next.8b30e05b0.0",
66
- "@wordpress/compose": "^7.36.1-next.8b30e05b0.0",
67
- "@wordpress/data": "^10.36.1-next.8b30e05b0.0",
68
- "@wordpress/dataviews": "^11.0.1-next.8b30e05b0.0",
69
- "@wordpress/date": "^5.36.1-next.8b30e05b0.0",
70
- "@wordpress/deprecated": "^4.36.1-next.8b30e05b0.0",
71
- "@wordpress/dom": "^4.36.1-next.8b30e05b0.0",
72
- "@wordpress/element": "^6.36.1-next.8b30e05b0.0",
73
- "@wordpress/escape-html": "^3.36.1-next.8b30e05b0.0",
74
- "@wordpress/global-styles-engine": "^1.3.1-next.8b30e05b0.0",
75
- "@wordpress/hooks": "^4.36.1-next.8b30e05b0.0",
76
- "@wordpress/html-entities": "^4.36.1-next.8b30e05b0.0",
77
- "@wordpress/i18n": "^6.9.1-next.8b30e05b0.0",
78
- "@wordpress/icons": "^11.3.1-next.8b30e05b0.0",
79
- "@wordpress/interactivity": "^6.36.1-next.8b30e05b0.0",
80
- "@wordpress/is-shallow-equal": "^5.36.1-next.8b30e05b0.0",
81
- "@wordpress/keyboard-shortcuts": "^5.36.1-next.8b30e05b0.0",
82
- "@wordpress/keycodes": "^4.36.1-next.8b30e05b0.0",
83
- "@wordpress/notices": "^5.36.1-next.8b30e05b0.0",
84
- "@wordpress/preferences": "^4.36.1-next.8b30e05b0.0",
85
- "@wordpress/priority-queue": "^3.36.1-next.8b30e05b0.0",
86
- "@wordpress/private-apis": "^1.36.1-next.8b30e05b0.0",
87
- "@wordpress/rich-text": "^7.36.1-next.8b30e05b0.0",
88
- "@wordpress/style-engine": "^2.36.1-next.8b30e05b0.0",
89
- "@wordpress/token-list": "^3.36.1-next.8b30e05b0.0",
90
- "@wordpress/upload-media": "^0.21.1-next.8b30e05b0.0",
91
- "@wordpress/url": "^4.36.1-next.8b30e05b0.0",
92
- "@wordpress/warning": "^3.36.1-next.8b30e05b0.0",
93
- "@wordpress/wordcount": "^4.36.1-next.8b30e05b0.0",
56
+ "@wordpress/a11y": "^4.37.0",
57
+ "@wordpress/api-fetch": "^7.37.0",
58
+ "@wordpress/base-styles": "^6.13.0",
59
+ "@wordpress/blob": "^4.37.0",
60
+ "@wordpress/block-serialization-default-parser": "^5.37.0",
61
+ "@wordpress/blocks": "^15.10.0",
62
+ "@wordpress/commands": "^1.37.0",
63
+ "@wordpress/components": "^31.0.0",
64
+ "@wordpress/compose": "^7.37.0",
65
+ "@wordpress/data": "^10.37.0",
66
+ "@wordpress/dataviews": "^11.1.0",
67
+ "@wordpress/date": "^5.37.0",
68
+ "@wordpress/deprecated": "^4.37.0",
69
+ "@wordpress/dom": "^4.37.0",
70
+ "@wordpress/element": "^6.37.0",
71
+ "@wordpress/escape-html": "^3.37.0",
72
+ "@wordpress/global-styles-engine": "^1.4.0",
73
+ "@wordpress/hooks": "^4.37.0",
74
+ "@wordpress/html-entities": "^4.37.0",
75
+ "@wordpress/i18n": "^6.10.0",
76
+ "@wordpress/icons": "^11.4.0",
77
+ "@wordpress/image-cropper": "^1.1.0",
78
+ "@wordpress/interactivity": "^6.37.0",
79
+ "@wordpress/is-shallow-equal": "^5.37.0",
80
+ "@wordpress/keyboard-shortcuts": "^5.37.0",
81
+ "@wordpress/keycodes": "^4.37.0",
82
+ "@wordpress/notices": "^5.37.0",
83
+ "@wordpress/preferences": "^4.37.0",
84
+ "@wordpress/priority-queue": "^3.37.0",
85
+ "@wordpress/private-apis": "^1.37.0",
86
+ "@wordpress/rich-text": "^7.37.0",
87
+ "@wordpress/style-engine": "^2.37.0",
88
+ "@wordpress/token-list": "^3.37.0",
89
+ "@wordpress/upload-media": "^0.22.0",
90
+ "@wordpress/url": "^4.37.0",
91
+ "@wordpress/warning": "^3.37.0",
92
+ "@wordpress/wordcount": "^4.37.0",
94
93
  "change-case": "^4.1.2",
95
94
  "clsx": "^2.1.1",
96
95
  "colord": "^2.7.0",
@@ -113,5 +112,5 @@
113
112
  "publishConfig": {
114
113
  "access": "public"
115
114
  },
116
- "gitHead": "2466f6bc223f8be98c55e1ac7270e8c3e413eaaf"
115
+ "gitHead": "2cf13ec6cf86153c9b3cf369bf5c59046f5cd950"
117
116
  }
@@ -77,11 +77,7 @@ function BlockAlignmentMatrixControl( props ) {
77
77
  );
78
78
  } }
79
79
  renderContent={ () => (
80
- <AlignmentMatrixControl
81
- hasFocusBorder={ false }
82
- onChange={ onChange }
83
- value={ value }
84
- />
80
+ <AlignmentMatrixControl onChange={ onChange } value={ value } />
85
81
  ) }
86
82
  />
87
83
  );
@@ -0,0 +1,174 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import fastDeepEqual from 'fast-deep-equal/es6';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { __ } from '@wordpress/i18n';
10
+ import {
11
+ getBlockBindingsSource,
12
+ store as blocksStore,
13
+ } from '@wordpress/blocks';
14
+ import {
15
+ __experimentalItem as Item,
16
+ __experimentalText as Text,
17
+ __experimentalToolsPanelItem as ToolsPanelItem,
18
+ __experimentalVStack as VStack,
19
+ privateApis as componentsPrivateApis,
20
+ } from '@wordpress/components';
21
+ import { useSelect } from '@wordpress/data';
22
+ import { useContext } from '@wordpress/element';
23
+ import { useViewportMatch } from '@wordpress/compose';
24
+
25
+ /**
26
+ * Internal dependencies
27
+ */
28
+ import BlockContext from '../block-context';
29
+ import BlockBindingsSourceFieldsList from './source-fields-list';
30
+ import useBlockBindingsUtils from './use-block-bindings-utils';
31
+ import { unlock } from '../../lock-unlock';
32
+ import { store as blockEditorStore } from '../../store';
33
+
34
+ const { Menu } = unlock( componentsPrivateApis );
35
+
36
+ export default function BlockBindingsAttributeControl( {
37
+ attribute,
38
+ binding,
39
+ blockName,
40
+ } ) {
41
+ const { updateBlockBindings } = useBlockBindingsUtils();
42
+ const isMobile = useViewportMatch( 'medium', '<' );
43
+
44
+ const blockContext = useContext( BlockContext );
45
+ const compatibleFields = useSelect(
46
+ ( select ) => {
47
+ const {
48
+ getAllBlockBindingsSources,
49
+ getBlockBindingsSourceFieldsList,
50
+ getBlockType,
51
+ } = unlock( select( blocksStore ) );
52
+
53
+ const _attributeType =
54
+ getBlockType( blockName ).attributes?.[ attribute ]?.type;
55
+ const attributeType =
56
+ _attributeType === 'rich-text' ? 'string' : _attributeType;
57
+
58
+ const sourceFields = {};
59
+ Object.entries( getAllBlockBindingsSources() ).forEach(
60
+ ( [ sourceName, source ] ) => {
61
+ const fieldsList = getBlockBindingsSourceFieldsList(
62
+ source,
63
+ blockContext
64
+ );
65
+ if ( ! fieldsList?.length ) {
66
+ return;
67
+ }
68
+ const compatibleFieldsList = fieldsList.filter(
69
+ ( field ) => field.type === attributeType
70
+ );
71
+ if ( compatibleFieldsList.length ) {
72
+ sourceFields[ sourceName ] = compatibleFieldsList;
73
+ }
74
+ }
75
+ );
76
+ return sourceFields;
77
+ },
78
+ [ attribute, blockName, blockContext ]
79
+ );
80
+
81
+ const { canUpdateBlockBindings } = useSelect( ( select ) => ( {
82
+ canUpdateBlockBindings:
83
+ select( blockEditorStore ).getSettings().canUpdateBlockBindings,
84
+ } ) );
85
+
86
+ const hasCompatibleFields = Object.keys( compatibleFields ).length > 0;
87
+
88
+ // Lock the UI when the user can't update bindings or there are no fields to connect to.
89
+ const isAttributeReadOnly =
90
+ ! canUpdateBlockBindings || ! hasCompatibleFields;
91
+
92
+ const { source: boundSourceName, args } = binding || {};
93
+ const source = getBlockBindingsSource( boundSourceName );
94
+
95
+ let displayText;
96
+ let isValid = true;
97
+
98
+ if ( binding === undefined ) {
99
+ if ( ! hasCompatibleFields ) {
100
+ displayText = __( 'No sources available' );
101
+ } else {
102
+ displayText = __( 'Not connected' );
103
+ }
104
+ isValid = true;
105
+ } else if ( ! source ) {
106
+ // If there's a binding but the source is not found, it's invalid.
107
+ isValid = false;
108
+ displayText = __( 'Source not registered' );
109
+ } else {
110
+ displayText =
111
+ compatibleFields?.[ boundSourceName ]?.find( ( field ) =>
112
+ fastDeepEqual( field.args, args )
113
+ )?.label ||
114
+ source?.label ||
115
+ boundSourceName;
116
+ }
117
+
118
+ return (
119
+ <ToolsPanelItem
120
+ hasValue={ () => !! binding }
121
+ label={ attribute }
122
+ onDeselect={
123
+ !! hasCompatibleFields &&
124
+ ( () => {
125
+ updateBlockBindings( {
126
+ [ attribute ]: undefined,
127
+ } );
128
+ } )
129
+ }
130
+ >
131
+ <Menu placement={ isMobile ? 'bottom-start' : 'left-start' }>
132
+ <Menu.TriggerButton
133
+ render={ <Item /> }
134
+ disabled={ ! hasCompatibleFields }
135
+ >
136
+ <VStack
137
+ className="block-editor-bindings__item"
138
+ spacing={ 0 }
139
+ >
140
+ <Text truncate>{ attribute }</Text>
141
+ <Text
142
+ truncate
143
+ variant={ isValid ? 'muted' : undefined }
144
+ isDestructive={ ! isValid }
145
+ >
146
+ { displayText }
147
+ </Text>
148
+ </VStack>
149
+ </Menu.TriggerButton>
150
+ { ! isAttributeReadOnly && (
151
+ <Menu.Popover gutter={ isMobile ? 8 : 36 }>
152
+ <Menu
153
+ placement={
154
+ isMobile ? 'bottom-start' : 'left-start'
155
+ }
156
+ >
157
+ { Object.entries( compatibleFields ).map(
158
+ ( [ sourceKey, fields ] ) => (
159
+ <BlockBindingsSourceFieldsList
160
+ key={ sourceKey }
161
+ args={ binding?.args }
162
+ attribute={ attribute }
163
+ sourceKey={ sourceKey }
164
+ fields={ fields }
165
+ />
166
+ )
167
+ ) }
168
+ </Menu>
169
+ </Menu.Popover>
170
+ ) }
171
+ </Menu>
172
+ </ToolsPanelItem>
173
+ );
174
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ export { default as BlockBindingsAttributeControl } from './attribute-control';
5
+ export { default as BlockBindingsSourceFieldsList } from './source-fields-list';
6
+ export { default as useBlockBindingsUtils } from './use-block-bindings-utils';
@@ -0,0 +1,130 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import fastDeepEqual from 'fast-deep-equal/es6';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { getBlockBindingsSource } from '@wordpress/blocks';
10
+ import { privateApis as componentsPrivateApis } from '@wordpress/components';
11
+ import { useSelect } from '@wordpress/data';
12
+ import { useContext, useMemo } from '@wordpress/element';
13
+ import { useViewportMatch } from '@wordpress/compose';
14
+
15
+ /**
16
+ * Internal dependencies
17
+ */
18
+ import useBlockBindingsUtils from './use-block-bindings-utils';
19
+ import { unlock } from '../../lock-unlock';
20
+ import BlockContext from '../block-context';
21
+
22
+ const { Menu } = unlock( componentsPrivateApis );
23
+
24
+ function BlockBindingsSourceFieldsListItem( {
25
+ args,
26
+ attribute,
27
+ field,
28
+ source,
29
+ sourceKey,
30
+ } ) {
31
+ const itemBindings = useMemo(
32
+ () => ( {
33
+ source: sourceKey,
34
+ args: field.args || {
35
+ key: field.key,
36
+ },
37
+ } ),
38
+ [ field.args, field.key, sourceKey ]
39
+ );
40
+
41
+ const blockContext = useContext( BlockContext );
42
+ const values = useSelect(
43
+ ( select ) =>
44
+ source.getValues( {
45
+ select,
46
+ context: blockContext,
47
+ bindings: {
48
+ [ attribute ]: itemBindings,
49
+ },
50
+ } ),
51
+ [ attribute, blockContext, itemBindings, source ]
52
+ );
53
+ const { updateBlockBindings } = useBlockBindingsUtils();
54
+
55
+ return (
56
+ <Menu.CheckboxItem
57
+ onChange={ () => {
58
+ const isCurrentlySelected =
59
+ fastDeepEqual( args, field.args ) ??
60
+ // Deprecate key dependency in 7.0.
61
+ field.key === args?.key;
62
+
63
+ if ( isCurrentlySelected ) {
64
+ // Unset if the same field is selected again.
65
+ updateBlockBindings( {
66
+ [ attribute ]: undefined,
67
+ } );
68
+ } else {
69
+ updateBlockBindings( {
70
+ [ attribute ]: itemBindings,
71
+ } );
72
+ }
73
+ } }
74
+ name={ attribute + '-binding' }
75
+ value={ values[ attribute ] }
76
+ checked={
77
+ fastDeepEqual( args, field.args ) ??
78
+ // Deprecate key dependency in 7.0.
79
+ field.key === args?.key
80
+ }
81
+ >
82
+ <Menu.ItemLabel>{ field.label }</Menu.ItemLabel>
83
+ <Menu.ItemHelpText>{ values[ attribute ] }</Menu.ItemHelpText>
84
+ </Menu.CheckboxItem>
85
+ );
86
+ }
87
+
88
+ export default function BlockBindingsSourceFieldsList( {
89
+ args,
90
+ attribute,
91
+ sourceKey,
92
+ fields,
93
+ } ) {
94
+ const isMobile = useViewportMatch( 'medium', '<' );
95
+
96
+ // Only render source if it has compatible fields.
97
+ if ( ! fields || fields.length === 0 ) {
98
+ return null;
99
+ }
100
+
101
+ const source = getBlockBindingsSource( sourceKey );
102
+
103
+ return (
104
+ <Menu
105
+ key={ sourceKey }
106
+ placement={ isMobile ? 'bottom-start' : 'left-start' }
107
+ >
108
+ <Menu.SubmenuTriggerItem>
109
+ <Menu.ItemLabel>{ source.label }</Menu.ItemLabel>
110
+ </Menu.SubmenuTriggerItem>
111
+ <Menu.Popover gutter={ 8 }>
112
+ <Menu.Group>
113
+ { fields.map( ( field ) => (
114
+ <BlockBindingsSourceFieldsListItem
115
+ key={
116
+ sourceKey + JSON.stringify( field.args ) ||
117
+ field.key
118
+ }
119
+ args={ args }
120
+ attribute={ attribute }
121
+ field={ field }
122
+ source={ source }
123
+ sourceKey={ sourceKey }
124
+ />
125
+ ) ) }
126
+ </Menu.Group>
127
+ </Menu.Popover>
128
+ </Menu>
129
+ );
130
+ }