@wordpress/block-editor 15.4.1-next.f56bd8138.0 → 15.5.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 (106) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/background-image-control/index.js +51 -24
  3. package/build/components/background-image-control/index.js.map +1 -1
  4. package/build/components/block-edit/edit.js +13 -5
  5. package/build/components/block-edit/edit.js.map +1 -1
  6. package/build/components/block-list/block.js +14 -4
  7. package/build/components/block-list/block.js.map +1 -1
  8. package/build/components/block-list/use-block-props/index.js +5 -4
  9. package/build/components/block-list/use-block-props/index.js.map +1 -1
  10. package/build/components/block-settings-menu-controls/index.js +10 -2
  11. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  12. package/build/components/block-toolbar/index.js +5 -0
  13. package/build/components/block-toolbar/index.js.map +1 -1
  14. package/build/components/block-visibility/index.js +21 -0
  15. package/build/components/block-visibility/index.js.map +1 -0
  16. package/build/components/block-visibility/menu-item.js +52 -0
  17. package/build/components/block-visibility/menu-item.js.map +1 -0
  18. package/build/components/block-visibility/toolbar.js +88 -0
  19. package/build/components/block-visibility/toolbar.js.map +1 -0
  20. package/build/components/inspector-controls-tabs/index.js +23 -0
  21. package/build/components/inspector-controls-tabs/index.js.map +1 -1
  22. package/build/components/link-control/index.js +1 -1
  23. package/build/components/link-control/index.js.map +1 -1
  24. package/build/components/list-view/block-select-button.js +23 -4
  25. package/build/components/list-view/block-select-button.js.map +1 -1
  26. package/build/components/list-view/block.js +9 -3
  27. package/build/components/list-view/block.js.map +1 -1
  28. package/build/components/rich-text/index.js +4 -2
  29. package/build/components/rich-text/index.js.map +1 -1
  30. package/build/components/use-block-drop-zone/index.js +5 -1
  31. package/build/components/use-block-drop-zone/index.js.map +1 -1
  32. package/build/hooks/block-bindings.js +9 -4
  33. package/build/hooks/block-bindings.js.map +1 -1
  34. package/build/store/private-selectors.js +19 -1
  35. package/build/store/private-selectors.js.map +1 -1
  36. package/build/store/reducer.js +1 -5
  37. package/build/store/reducer.js.map +1 -1
  38. package/build/utils/block-bindings.js +3 -48
  39. package/build/utils/block-bindings.js.map +1 -1
  40. package/build-module/components/background-image-control/index.js +52 -25
  41. package/build-module/components/background-image-control/index.js.map +1 -1
  42. package/build-module/components/block-edit/edit.js +14 -6
  43. package/build-module/components/block-edit/edit.js.map +1 -1
  44. package/build-module/components/block-list/block.js +14 -4
  45. package/build-module/components/block-list/block.js.map +1 -1
  46. package/build-module/components/block-list/use-block-props/index.js +5 -4
  47. package/build-module/components/block-list/use-block-props/index.js.map +1 -1
  48. package/build-module/components/block-settings-menu-controls/index.js +10 -2
  49. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  50. package/build-module/components/block-toolbar/index.js +5 -0
  51. package/build-module/components/block-toolbar/index.js.map +1 -1
  52. package/build-module/components/block-visibility/index.js +3 -0
  53. package/build-module/components/block-visibility/index.js.map +1 -0
  54. package/build-module/components/block-visibility/menu-item.js +45 -0
  55. package/build-module/components/block-visibility/menu-item.js.map +1 -0
  56. package/build-module/components/block-visibility/toolbar.js +81 -0
  57. package/build-module/components/block-visibility/toolbar.js.map +1 -0
  58. package/build-module/components/inspector-controls-tabs/index.js +23 -0
  59. package/build-module/components/inspector-controls-tabs/index.js.map +1 -1
  60. package/build-module/components/link-control/index.js +1 -1
  61. package/build-module/components/link-control/index.js.map +1 -1
  62. package/build-module/components/list-view/block-select-button.js +24 -5
  63. package/build-module/components/list-view/block-select-button.js.map +1 -1
  64. package/build-module/components/list-view/block.js +9 -3
  65. package/build-module/components/list-view/block.js.map +1 -1
  66. package/build-module/components/rich-text/index.js +4 -2
  67. package/build-module/components/rich-text/index.js.map +1 -1
  68. package/build-module/components/use-block-drop-zone/index.js +6 -2
  69. package/build-module/components/use-block-drop-zone/index.js.map +1 -1
  70. package/build-module/hooks/block-bindings.js +10 -5
  71. package/build-module/hooks/block-bindings.js.map +1 -1
  72. package/build-module/store/private-selectors.js +18 -1
  73. package/build-module/store/private-selectors.js.map +1 -1
  74. package/build-module/store/reducer.js +1 -5
  75. package/build-module/store/reducer.js.map +1 -1
  76. package/build-module/utils/block-bindings.js +3 -45
  77. package/build-module/utils/block-bindings.js.map +1 -1
  78. package/build-style/content-rtl.css +13 -0
  79. package/build-style/content.css +13 -0
  80. package/build-style/style-rtl.css +27 -0
  81. package/build-style/style.css +27 -0
  82. package/package.json +34 -34
  83. package/src/components/background-image-control/index.js +54 -27
  84. package/src/components/background-image-control/style.scss +28 -0
  85. package/src/components/block-edit/edit.js +23 -5
  86. package/src/components/block-list/block.js +16 -0
  87. package/src/components/block-list/content.scss +19 -0
  88. package/src/components/block-list/use-block-props/index.js +9 -9
  89. package/src/components/block-settings-menu-controls/index.js +21 -1
  90. package/src/components/block-toolbar/index.js +9 -0
  91. package/src/components/block-visibility/index.js +2 -0
  92. package/src/components/block-visibility/menu-item.js +53 -0
  93. package/src/components/block-visibility/toolbar.js +88 -0
  94. package/src/components/inspector-controls-tabs/index.js +33 -1
  95. package/src/components/link-control/index.js +1 -1
  96. package/src/components/link-control/test/index.js +4 -4
  97. package/src/components/list-view/block-select-button.js +32 -9
  98. package/src/components/list-view/block.js +24 -14
  99. package/src/components/list-view/style.scss +1 -0
  100. package/src/components/media-replace-flow/test/index.js +1 -1
  101. package/src/components/rich-text/index.js +6 -2
  102. package/src/components/use-block-drop-zone/index.js +14 -1
  103. package/src/hooks/block-bindings.js +49 -43
  104. package/src/store/private-selectors.js +21 -1
  105. package/src/store/reducer.js +1 -6
  106. package/src/utils/block-bindings.js +6 -48
@@ -10,13 +10,6 @@ import { store as blockEditorStore } from '../store';
10
10
  import { useBlockEditContext } from '../components/block-edit';
11
11
  const DEFAULT_ATTRIBUTE = '__default';
12
12
  const PATTERN_OVERRIDES_SOURCE = 'core/pattern-overrides';
13
- const BLOCK_BINDINGS_ALLOWED_BLOCKS = {
14
- 'core/paragraph': ['content'],
15
- 'core/heading': ['content'],
16
- 'core/image': ['id', 'url', 'title', 'alt', 'caption'],
17
- 'core/button': ['url', 'text', 'linkTarget', 'rel'],
18
- 'core/post-date': ['datetime']
19
- };
20
13
 
21
14
  /**
22
15
  * Checks if the given object is empty.
@@ -29,40 +22,6 @@ function isObjectEmpty(object) {
29
22
  return !object || Object.keys(object).length === 0;
30
23
  }
31
24
 
32
- /**
33
- * Based on the given block name, checks if it is possible to bind the block.
34
- *
35
- * @param {string} blockName The name of the block.
36
- *
37
- * @return {boolean} Whether it is possible to bind the block to sources.
38
- */
39
- export function canBindBlock(blockName) {
40
- return blockName in BLOCK_BINDINGS_ALLOWED_BLOCKS;
41
- }
42
-
43
- /**
44
- * Based on the given block name and attribute name, checks if it is possible to bind the block attribute.
45
- *
46
- * @param {string} blockName The name of the block.
47
- * @param {string} attributeName The name of attribute.
48
- *
49
- * @return {boolean} Whether it is possible to bind the block attribute.
50
- */
51
- export function canBindAttribute(blockName, attributeName) {
52
- return canBindBlock(blockName) && BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName].includes(attributeName);
53
- }
54
-
55
- /**
56
- * Gets the bindable attributes for a given block.
57
- *
58
- * @param {string} blockName The name of the block.
59
- *
60
- * @return {string[]} The bindable attributes for the block.
61
- */
62
- export function getBindableAttributes(blockName) {
63
- return BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName];
64
- }
65
-
66
25
  /**
67
26
  * Checks if the block has the `__default` binding for pattern overrides.
68
27
  *
@@ -81,15 +40,14 @@ export function hasPatternOverridesDefaultBinding(bindings) {
81
40
  * - bindings passed in: `{ __default: { source: 'core/pattern-overrides' } }`
82
41
  * - bindings returned: `{ content: { source: 'core/pattern-overrides' } }`
83
42
  *
84
- * @param {string} blockName The block name (e.g. 'core/paragraph').
85
- * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.
43
+ * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.
44
+ * @param {string[]} supportedAttributes The block's attributes which are supported by block bindings.
86
45
  *
87
46
  * @return {Object} The bindings with default replaced for pattern overrides.
88
47
  */
89
- export function replacePatternOverridesDefaultBinding(blockName, bindings) {
48
+ export function replacePatternOverridesDefaultBinding(bindings, supportedAttributes) {
90
49
  // The `__default` binding currently only works for pattern overrides.
91
50
  if (hasPatternOverridesDefaultBinding(bindings)) {
92
- const supportedAttributes = BLOCK_BINDINGS_ALLOWED_BLOCKS[blockName];
93
51
  const bindingsWithDefaults = {};
94
52
  for (const attributeName of supportedAttributes) {
95
53
  // If the block has mixed binding sources, retain any non pattern override bindings.
@@ -1 +1 @@
1
- {"version":3,"names":["useDispatch","useRegistry","store","blockEditorStore","useBlockEditContext","DEFAULT_ATTRIBUTE","PATTERN_OVERRIDES_SOURCE","BLOCK_BINDINGS_ALLOWED_BLOCKS","isObjectEmpty","object","Object","keys","length","canBindBlock","blockName","canBindAttribute","attributeName","includes","getBindableAttributes","hasPatternOverridesDefaultBinding","bindings","source","replacePatternOverridesDefaultBinding","supportedAttributes","bindingsWithDefaults","bindingSource","useBlockBindingsUtils","clientId","contextClientId","blockClientId","updateBlockAttributes","getBlockAttributes","select","updateBlockBindings","metadata","currentBindings","newBindings","entries","forEach","attribute","binding","newMetadata","undefined","removeAllBlockBindings"],"sources":["@wordpress/block-editor/src/utils/block-bindings.js"],"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';\nconst BLOCK_BINDINGS_ALLOWED_BLOCKS = {\n\t'core/paragraph': [ 'content' ],\n\t'core/heading': [ 'content' ],\n\t'core/image': [ 'id', 'url', 'title', 'alt', 'caption' ],\n\t'core/button': [ 'url', 'text', 'linkTarget', 'rel' ],\n\t'core/post-date': [ 'datetime' ],\n};\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 * Based on the given block name, checks if it is possible to bind the block.\n *\n * @param {string} blockName The name of the block.\n *\n * @return {boolean} Whether it is possible to bind the block to sources.\n */\nexport function canBindBlock( blockName ) {\n\treturn blockName in BLOCK_BINDINGS_ALLOWED_BLOCKS;\n}\n\n/**\n * Based on the given block name and attribute name, checks if it is possible to bind the block attribute.\n *\n * @param {string} blockName The name of the block.\n * @param {string} attributeName The name of attribute.\n *\n * @return {boolean} Whether it is possible to bind the block attribute.\n */\nexport function canBindAttribute( blockName, attributeName ) {\n\treturn (\n\t\tcanBindBlock( blockName ) &&\n\t\tBLOCK_BINDINGS_ALLOWED_BLOCKS[ blockName ].includes( attributeName )\n\t);\n}\n\n/**\n * Gets the bindable attributes for a given block.\n *\n * @param {string} blockName The name of the block.\n *\n * @return {string[]} The bindable attributes for the block.\n */\nexport function getBindableAttributes( blockName ) {\n\treturn BLOCK_BINDINGS_ALLOWED_BLOCKS[ blockName ];\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 {string} blockName The block name (e.g. 'core/paragraph').\n * @param {?Record<string, object>} bindings A block's bindings from the metadata attribute.\n *\n * @return {Object} The bindings with default replaced for pattern overrides.\n */\nexport function replacePatternOverridesDefaultBinding( blockName, bindings ) {\n\t// The `__default` binding currently only works for pattern overrides.\n\tif ( hasPatternOverridesDefaultBinding( bindings ) ) {\n\t\tconst supportedAttributes = BLOCK_BINDINGS_ALLOWED_BLOCKS[ blockName ];\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"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useDispatch","useRegistry","store","blockEditorStore","useBlockEditContext","DEFAULT_ATTRIBUTE","PATTERN_OVERRIDES_SOURCE","isObjectEmpty","object","Object","keys","length","hasPatternOverridesDefaultBinding","bindings","source","replacePatternOverridesDefaultBinding","supportedAttributes","bindingsWithDefaults","attributeName","bindingSource","useBlockBindingsUtils","clientId","contextClientId","blockClientId","updateBlockAttributes","getBlockAttributes","select","updateBlockBindings","metadata","currentBindings","newBindings","entries","forEach","attribute","binding","newMetadata","undefined","removeAllBlockBindings"],"sources":["@wordpress/block-editor/src/utils/block-bindings.js"],"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"],"mappings":"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","ignoreList":[]}
@@ -330,6 +330,19 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection=true] .blo
330
330
  outline-offset: calc(1 * ((-1 * var(--wp-admin-border-width-focus) ) / var(--wp-block-editor-iframe-zoom-out-scale, 1)));
331
331
  z-index: 1;
332
332
  }
333
+ .block-editor-block-list__layout .block-editor-block-list__block.is-block-hidden {
334
+ visibility: hidden;
335
+ overflow: hidden;
336
+ height: 0;
337
+ border: none !important;
338
+ padding: 0 !important;
339
+ }
340
+ .block-editor-block-list__layout.is-layout-flex:not(.is-vertical) > .is-block-hidden {
341
+ width: 0;
342
+ height: auto;
343
+ align-self: stretch;
344
+ white-space: nowrap !important;
345
+ }
333
346
  .block-editor-block-list__layout [class^=components-] {
334
347
  -webkit-user-select: text;
335
348
  user-select: text;
@@ -330,6 +330,19 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection=true] .blo
330
330
  outline-offset: calc(1 * ((-1 * var(--wp-admin-border-width-focus) ) / var(--wp-block-editor-iframe-zoom-out-scale, 1)));
331
331
  z-index: 1;
332
332
  }
333
+ .block-editor-block-list__layout .block-editor-block-list__block.is-block-hidden {
334
+ visibility: hidden;
335
+ overflow: hidden;
336
+ height: 0;
337
+ border: none !important;
338
+ padding: 0 !important;
339
+ }
340
+ .block-editor-block-list__layout.is-layout-flex:not(.is-vertical) > .is-block-hidden {
341
+ width: 0;
342
+ height: auto;
343
+ align-self: stretch;
344
+ white-space: nowrap !important;
345
+ }
333
346
  .block-editor-block-list__layout [class^=components-] {
334
347
  -webkit-user-select: text;
335
348
  user-select: text;
@@ -258,6 +258,7 @@
258
258
  border: 1px solid #ddd;
259
259
  border-radius: 2px;
260
260
  grid-column: 1/-1;
261
+ position: relative;
261
262
  }
262
263
  .block-editor-global-styles-background-panel__inspector-media-replace-container.is-open {
263
264
  background-color: #f0f0f0;
@@ -319,6 +320,31 @@
319
320
  height: 100%;
320
321
  width: 100%;
321
322
  padding-right: 12px;
323
+ padding-left: 32px;
324
+ }
325
+
326
+ .block-editor-global-styles-background-panel__reset {
327
+ position: absolute;
328
+ left: 0;
329
+ top: 8px;
330
+ margin: auto 8px auto;
331
+ opacity: 0;
332
+ }
333
+ @media not (prefers-reduced-motion) {
334
+ .block-editor-global-styles-background-panel__reset {
335
+ transition: opacity 0.1s ease-in-out;
336
+ }
337
+ }
338
+ .block-editor-global-styles-background-panel__reset.block-editor-global-styles-background-panel__reset {
339
+ border-radius: 2px;
340
+ }
341
+ .block-editor-global-styles-background-panel__dropdown-toggle:hover + .block-editor-global-styles-background-panel__reset, .block-editor-global-styles-background-panel__reset:focus, .block-editor-global-styles-background-panel__reset:hover {
342
+ opacity: 1;
343
+ }
344
+ @media (hover: none) {
345
+ .block-editor-global-styles-background-panel__reset {
346
+ opacity: 1;
347
+ }
322
348
  }
323
349
 
324
350
  .block-editor-global-styles-background-panel__inspector-media-replace-title {
@@ -2994,6 +3020,7 @@ iframe[name=editor-canvas] {
2994
3020
  background: rgba(0, 0, 0, 0.3);
2995
3021
  color: #fff;
2996
3022
  }
3023
+ .block-editor-list-view-leaf .block-editor-list-view-block-select-button__block-visibility,
2997
3024
  .block-editor-list-view-leaf .block-editor-list-view-block-select-button__lock,
2998
3025
  .block-editor-list-view-leaf .block-editor-list-view-block-select-button__sticky {
2999
3026
  line-height: 0;
@@ -258,6 +258,7 @@
258
258
  border: 1px solid #ddd;
259
259
  border-radius: 2px;
260
260
  grid-column: 1/-1;
261
+ position: relative;
261
262
  }
262
263
  .block-editor-global-styles-background-panel__inspector-media-replace-container.is-open {
263
264
  background-color: #f0f0f0;
@@ -319,6 +320,31 @@
319
320
  height: 100%;
320
321
  width: 100%;
321
322
  padding-left: 12px;
323
+ padding-right: 32px;
324
+ }
325
+
326
+ .block-editor-global-styles-background-panel__reset {
327
+ position: absolute;
328
+ right: 0;
329
+ top: 8px;
330
+ margin: auto 8px auto;
331
+ opacity: 0;
332
+ }
333
+ @media not (prefers-reduced-motion) {
334
+ .block-editor-global-styles-background-panel__reset {
335
+ transition: opacity 0.1s ease-in-out;
336
+ }
337
+ }
338
+ .block-editor-global-styles-background-panel__reset.block-editor-global-styles-background-panel__reset {
339
+ border-radius: 2px;
340
+ }
341
+ .block-editor-global-styles-background-panel__dropdown-toggle:hover + .block-editor-global-styles-background-panel__reset, .block-editor-global-styles-background-panel__reset:focus, .block-editor-global-styles-background-panel__reset:hover {
342
+ opacity: 1;
343
+ }
344
+ @media (hover: none) {
345
+ .block-editor-global-styles-background-panel__reset {
346
+ opacity: 1;
347
+ }
322
348
  }
323
349
 
324
350
  .block-editor-global-styles-background-panel__inspector-media-replace-title {
@@ -2995,6 +3021,7 @@ iframe[name=editor-canvas] {
2995
3021
  background: rgba(0, 0, 0, 0.3);
2996
3022
  color: #fff;
2997
3023
  }
3024
+ .block-editor-list-view-leaf .block-editor-list-view-block-select-button__block-visibility,
2998
3025
  .block-editor-list-view-leaf .block-editor-list-view-block-select-button__lock,
2999
3026
  .block-editor-list-view-leaf .block-editor-list-view-block-select-button__sticky {
3000
3027
  line-height: 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "15.4.1-next.f56bd8138.0",
3
+ "version": "15.5.0",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -37,38 +37,38 @@
37
37
  "@emotion/react": "^11.7.1",
38
38
  "@emotion/styled": "^11.6.0",
39
39
  "@react-spring/web": "^9.4.5",
40
- "@wordpress/a11y": "^4.31.1-next.f56bd8138.0",
41
- "@wordpress/api-fetch": "^7.31.1-next.f56bd8138.0",
42
- "@wordpress/blob": "^4.31.1-next.f56bd8138.0",
43
- "@wordpress/block-serialization-default-parser": "^5.31.1-next.f56bd8138.0",
44
- "@wordpress/blocks": "^15.4.1-next.f56bd8138.0",
45
- "@wordpress/commands": "^1.31.1-next.f56bd8138.0",
46
- "@wordpress/components": "^30.5.1-next.f56bd8138.0",
47
- "@wordpress/compose": "^7.31.1-next.f56bd8138.0",
48
- "@wordpress/data": "^10.31.1-next.f56bd8138.0",
49
- "@wordpress/date": "^5.31.1-next.f56bd8138.0",
50
- "@wordpress/deprecated": "^4.31.1-next.f56bd8138.0",
51
- "@wordpress/dom": "^4.31.1-next.f56bd8138.0",
52
- "@wordpress/element": "^6.31.1-next.f56bd8138.0",
53
- "@wordpress/escape-html": "^3.31.1-next.f56bd8138.0",
54
- "@wordpress/hooks": "^4.31.1-next.f56bd8138.0",
55
- "@wordpress/html-entities": "^4.31.1-next.f56bd8138.0",
56
- "@wordpress/i18n": "^6.4.1-next.f56bd8138.0",
57
- "@wordpress/icons": "^10.31.1-next.f56bd8138.0",
58
- "@wordpress/is-shallow-equal": "^5.31.1-next.f56bd8138.0",
59
- "@wordpress/keyboard-shortcuts": "^5.31.1-next.f56bd8138.0",
60
- "@wordpress/keycodes": "^4.31.1-next.f56bd8138.0",
61
- "@wordpress/notices": "^5.31.1-next.f56bd8138.0",
62
- "@wordpress/preferences": "^4.31.1-next.f56bd8138.0",
63
- "@wordpress/priority-queue": "^3.31.1-next.f56bd8138.0",
64
- "@wordpress/private-apis": "^1.31.1-next.f56bd8138.0",
65
- "@wordpress/rich-text": "^7.31.1-next.f56bd8138.0",
66
- "@wordpress/style-engine": "^2.31.1-next.f56bd8138.0",
67
- "@wordpress/token-list": "^3.31.1-next.f56bd8138.0",
68
- "@wordpress/upload-media": "^0.16.1-next.f56bd8138.0",
69
- "@wordpress/url": "^4.31.1-next.f56bd8138.0",
70
- "@wordpress/warning": "^3.31.1-next.f56bd8138.0",
71
- "@wordpress/wordcount": "^4.31.1-next.f56bd8138.0",
40
+ "@wordpress/a11y": "^4.32.0",
41
+ "@wordpress/api-fetch": "^7.32.0",
42
+ "@wordpress/blob": "^4.32.0",
43
+ "@wordpress/block-serialization-default-parser": "^5.32.0",
44
+ "@wordpress/blocks": "^15.5.0",
45
+ "@wordpress/commands": "^1.32.0",
46
+ "@wordpress/components": "^30.5.0",
47
+ "@wordpress/compose": "^7.32.0",
48
+ "@wordpress/data": "^10.32.0",
49
+ "@wordpress/date": "^5.32.0",
50
+ "@wordpress/deprecated": "^4.32.0",
51
+ "@wordpress/dom": "^4.32.0",
52
+ "@wordpress/element": "^6.32.0",
53
+ "@wordpress/escape-html": "^3.32.0",
54
+ "@wordpress/hooks": "^4.32.0",
55
+ "@wordpress/html-entities": "^4.32.0",
56
+ "@wordpress/i18n": "^6.5.0",
57
+ "@wordpress/icons": "^10.32.0",
58
+ "@wordpress/is-shallow-equal": "^5.32.0",
59
+ "@wordpress/keyboard-shortcuts": "^5.32.0",
60
+ "@wordpress/keycodes": "^4.32.0",
61
+ "@wordpress/notices": "^5.32.0",
62
+ "@wordpress/preferences": "^4.32.0",
63
+ "@wordpress/priority-queue": "^3.32.0",
64
+ "@wordpress/private-apis": "^1.32.0",
65
+ "@wordpress/rich-text": "^7.32.0",
66
+ "@wordpress/style-engine": "^2.32.0",
67
+ "@wordpress/token-list": "^3.32.0",
68
+ "@wordpress/upload-media": "^0.17.0",
69
+ "@wordpress/url": "^4.32.0",
70
+ "@wordpress/warning": "^3.32.0",
71
+ "@wordpress/wordcount": "^4.32.0",
72
72
  "change-case": "^4.1.2",
73
73
  "clsx": "^2.1.1",
74
74
  "colord": "^2.7.0",
@@ -91,5 +91,5 @@
91
91
  "publishConfig": {
92
92
  "access": "public"
93
93
  },
94
- "gitHead": "ea4a281fd857f48338877590de8c8eb9b9a8cef4"
94
+ "gitHead": "a030b4c0e0695239b942c7dc18511782b64f10ed"
95
95
  }
@@ -25,6 +25,7 @@ import {
25
25
  __experimentalDropdownContentWrapper as DropdownContentWrapper,
26
26
  Button,
27
27
  } from '@wordpress/components';
28
+ import { reset as resetIcon } from '@wordpress/icons';
28
29
  import { __, _x, sprintf } from '@wordpress/i18n';
29
30
  import { store as noticesStore } from '@wordpress/notices';
30
31
  import { getFilename } from '@wordpress/url';
@@ -57,6 +58,24 @@ const BACKGROUND_POPOVER_PROPS = {
57
58
  };
58
59
  const noop = () => {};
59
60
 
61
+ /**
62
+ * Focuses the toggle button.
63
+ * @param {Object} containerRef - ref object containing current element
64
+ */
65
+ const focusToggleButton = ( containerRef ) => {
66
+ // Use requestAnimationFrame to ensure DOM updates are complete
67
+ window.requestAnimationFrame( () => {
68
+ const [ toggleButton ] = focus.tabbable.find( containerRef?.current );
69
+ if ( ! toggleButton ) {
70
+ return;
71
+ }
72
+ // Focus the toggle button and close the dropdown menu.
73
+ // This ensures similar behaviour as to selecting an image, where the dropdown is
74
+ // closed and focus is redirected to the dropdown toggle button.
75
+ toggleButton.focus();
76
+ } );
77
+ };
78
+
60
79
  /**
61
80
  * Get the help text for the background size control.
62
81
  *
@@ -182,6 +201,8 @@ function BackgroundControlsPanel( {
182
201
  children,
183
202
  onToggle: onToggleCallback = noop,
184
203
  hasImageValue,
204
+ onReset,
205
+ containerRef,
185
206
  } ) {
186
207
  if ( ! hasImageValue ) {
187
208
  return;
@@ -205,14 +226,34 @@ function BackgroundControlsPanel( {
205
226
  isOpen,
206
227
  };
207
228
  return (
208
- <InspectorImagePreviewItem
209
- imgUrl={ imgUrl }
210
- filename={ filename }
211
- label={ imgLabel }
212
- toggleProps={ toggleProps }
213
- as="button"
214
- onToggleCallback={ onToggleCallback }
215
- />
229
+ <>
230
+ <InspectorImagePreviewItem
231
+ imgUrl={ imgUrl }
232
+ filename={ filename }
233
+ label={ imgLabel }
234
+ toggleProps={ toggleProps }
235
+ as="button"
236
+ onToggleCallback={ onToggleCallback }
237
+ />
238
+ { onReset && (
239
+ <Button
240
+ __next40pxDefaultSize
241
+ label={ __( 'Reset' ) }
242
+ className="block-editor-global-styles-background-panel__reset"
243
+ size="small"
244
+ icon={ resetIcon }
245
+ onClick={ () => {
246
+ onReset();
247
+ // Close the dropdown if open.
248
+ if ( isOpen ) {
249
+ onToggle();
250
+ }
251
+ // Focus the toggle button.
252
+ focusToggleButton( containerRef );
253
+ } }
254
+ />
255
+ ) }
256
+ </>
216
257
  );
217
258
  } }
218
259
  renderContent={ () => (
@@ -319,7 +360,7 @@ function BackgroundImageControls( {
319
360
  );
320
361
  setIsUploading( false );
321
362
  // Close the dropdown and focus the toggle button.
322
- closeAndFocus();
363
+ focusToggleButton( containerRef );
323
364
  };
324
365
 
325
366
  // Drag and drop callback, restricting image to one.
@@ -337,22 +378,6 @@ function BackgroundImageControls( {
337
378
 
338
379
  const hasValue = hasBackgroundImageValue( style );
339
380
 
340
- const closeAndFocus = () => {
341
- // Use requestAnimationFrame to ensure DOM updates are complete
342
- window.requestAnimationFrame( () => {
343
- const [ toggleButton ] = focus.tabbable.find(
344
- containerRef?.current
345
- );
346
- if ( ! toggleButton ) {
347
- return;
348
- }
349
- // Focus the toggle button and close the dropdown menu.
350
- // This ensures similar behaviour as to selecting an image, where the dropdown is
351
- // closed and focus is redirected to the dropdown toggle button.
352
- toggleButton.focus();
353
- } );
354
- };
355
-
356
381
  const onRemove = () =>
357
382
  onChange(
358
383
  setImmutably( style, [ 'background' ], {
@@ -390,14 +415,14 @@ function BackgroundImageControls( {
390
415
  ) }
391
416
  onError={ onUploadError }
392
417
  onReset={ () => {
393
- closeAndFocus();
418
+ focusToggleButton( containerRef );
394
419
  onResetImage();
395
420
  } }
396
421
  >
397
422
  { canRemove && (
398
423
  <MenuItem
399
424
  onClick={ () => {
400
- closeAndFocus();
425
+ focusToggleButton( containerRef );
401
426
  onRemove();
402
427
  onRemoveImage();
403
428
  } }
@@ -713,6 +738,8 @@ export default function BackgroundImagePanel( {
713
738
  url={ url }
714
739
  onToggle={ setIsDropDownOpen }
715
740
  hasImageValue={ hasImageValue }
741
+ onReset={ resetBackground }
742
+ containerRef={ containerRef }
716
743
  >
717
744
  <VStack spacing={ 3 } className="single-column">
718
745
  <BackgroundImageControls
@@ -3,6 +3,7 @@
3
3
  border-radius: $radius-small;
4
4
  // Full width. ToolsPanel lays out children in a grid.
5
5
  grid-column: 1 / -1;
6
+ position: relative;
6
7
 
7
8
  &.is-open {
8
9
  background-color: $gray-100;
@@ -83,6 +84,33 @@
83
84
  height: 100%;
84
85
  width: 100%;
85
86
  padding-left: $grid-unit-15;
87
+ padding-right: $grid-unit-40;
88
+ }
89
+
90
+ .block-editor-global-styles-background-panel__reset {
91
+ position: absolute;
92
+ right: 0;
93
+ top: $grid-unit;
94
+ margin: auto $grid-unit auto;
95
+ opacity: 0;
96
+ @media not ( prefers-reduced-motion ) {
97
+ transition: opacity 0.1s ease-in-out;
98
+ }
99
+
100
+ &.block-editor-global-styles-background-panel__reset {
101
+ border-radius: $radius-small;
102
+ }
103
+
104
+ .block-editor-global-styles-background-panel__dropdown-toggle:hover + &,
105
+ &:focus,
106
+ &:hover {
107
+ opacity: 1;
108
+ }
109
+
110
+ @media (hover: none) {
111
+ // Show reset button on devices that do not support hover.
112
+ opacity: 1;
113
+ }
86
114
  }
87
115
 
88
116
  .block-editor-global-styles-background-panel__inspector-media-replace-title {
@@ -22,10 +22,10 @@ import { useCallback, useContext, useMemo } from '@wordpress/element';
22
22
  import BlockContext from '../block-context';
23
23
  import isURLLike from '../link-control/is-url-like';
24
24
  import {
25
- canBindAttribute,
26
25
  hasPatternOverridesDefaultBinding,
27
26
  replacePatternOverridesDefaultBinding,
28
27
  } from '../../utils/block-bindings';
28
+ import { store as blockEditorStore } from '../../store';
29
29
  import { unlock } from '../../lock-unlock';
30
30
 
31
31
  /**
@@ -56,6 +56,8 @@ const Edit = ( props ) => {
56
56
 
57
57
  const EditWithFilters = withFilters( 'editor.BlockEdit' )( Edit );
58
58
 
59
+ const EMPTY_ARRAY = [];
60
+
59
61
  const EditWithGeneratedProps = ( props ) => {
60
62
  const { name, clientId, attributes, setAttributes } = props;
61
63
  const registry = useRegistry();
@@ -66,6 +68,17 @@ const EditWithGeneratedProps = ( props ) => {
66
68
  unlock( select( blocksStore ) ).getAllBlockBindingsSources(),
67
69
  []
68
70
  );
71
+ const bindableAttributes = useSelect(
72
+ ( select ) => {
73
+ const { __experimentalBlockBindingsSupportedAttributes } =
74
+ select( blockEditorStore ).getSettings();
75
+ return (
76
+ __experimentalBlockBindingsSupportedAttributes?.[ name ] ||
77
+ EMPTY_ARRAY
78
+ );
79
+ },
80
+ [ name ]
81
+ );
69
82
 
70
83
  const { blockBindings, context, hasPatternOverrides } = useMemo( () => {
71
84
  // Assign context values using the block type's declared context needs.
@@ -90,8 +103,8 @@ const EditWithGeneratedProps = ( props ) => {
90
103
  }
91
104
  return {
92
105
  blockBindings: replacePatternOverridesDefaultBinding(
93
- name,
94
- attributes?.metadata?.bindings
106
+ attributes?.metadata?.bindings,
107
+ bindableAttributes
95
108
  ),
96
109
  context: computedContext,
97
110
  hasPatternOverrides: hasPatternOverridesDefaultBinding(
@@ -120,7 +133,10 @@ const EditWithGeneratedProps = ( props ) => {
120
133
  ) ) {
121
134
  const { source: sourceName, args: sourceArgs } = binding;
122
135
  const source = registeredSources[ sourceName ];
123
- if ( ! source || ! canBindAttribute( name, attributeName ) ) {
136
+ if (
137
+ ! source ||
138
+ ! bindableAttributes.includes( attributeName )
139
+ ) {
124
140
  continue;
125
141
  }
126
142
 
@@ -172,6 +188,7 @@ const EditWithGeneratedProps = ( props ) => {
172
188
  },
173
189
  [
174
190
  attributes,
191
+ bindableAttributes,
175
192
  blockBindings,
176
193
  clientId,
177
194
  context,
@@ -197,7 +214,7 @@ const EditWithGeneratedProps = ( props ) => {
197
214
  ) ) {
198
215
  if (
199
216
  ! blockBindings[ attributeName ] ||
200
- ! canBindAttribute( name, attributeName )
217
+ ! bindableAttributes.includes( attributeName )
201
218
  ) {
202
219
  continue;
203
220
  }
@@ -250,6 +267,7 @@ const EditWithGeneratedProps = ( props ) => {
250
267
  } );
251
268
  },
252
269
  [
270
+ bindableAttributes,
253
271
  blockBindings,
254
272
  clientId,
255
273
  context,