diff --git a/packages/block-editor/src/hooks/block-bindings.js b/packages/block-editor/src/hooks/block-bindings.js index a6b41a0780a7e2..be850b2a3cd318 100644 --- a/packages/block-editor/src/hooks/block-bindings.js +++ b/packages/block-editor/src/hooks/block-bindings.js @@ -342,9 +342,20 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => { ( select ) => { const { __experimentalBlockBindingsSupportedAttributes } = select( blockEditorStore ).getSettings(); - const _bindableAttributes = + const supportedAttributes = __experimentalBlockBindingsSupportedAttributes?.[ blockName ]; - if ( ! _bindableAttributes || _bindableAttributes.length === 0 ) { + if ( ! supportedAttributes || supportedAttributes.length === 0 ) { + return EMPTY_OBJECT; + } + + // Filter to only include attributes that have a source (UI compatible). + const blockAttributes = getBlockType( blockName ).attributes; + const _bindableAttributes = supportedAttributes.filter( + ( attribute ) => + blockAttributes[ attribute ]?.bindings?.ui === 'active' + ); + + if ( _bindableAttributes.length === 0 ) { return EMPTY_OBJECT; } diff --git a/packages/block-library/src/button/block.json b/packages/block-library/src/button/block.json index 6fcb7aca4c5923..9ee74d6b44012a 100644 --- a/packages/block-library/src/button/block.json +++ b/packages/block-library/src/button/block.json @@ -26,7 +26,10 @@ "source": "attribute", "selector": "a", "attribute": "href", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "title": { "type": "string", @@ -39,21 +42,30 @@ "type": "rich-text", "source": "rich-text", "selector": "a,button", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "linkTarget": { "type": "string", "source": "attribute", "selector": "a", "attribute": "target", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "rel": { "type": "string", "source": "attribute", "selector": "a", "attribute": "rel", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "placeholder": { "type": "string" diff --git a/packages/block-library/src/heading/block.json b/packages/block-library/src/heading/block.json index d9488a3156528d..df14d8b4b8ef21 100644 --- a/packages/block-library/src/heading/block.json +++ b/packages/block-library/src/heading/block.json @@ -15,7 +15,10 @@ "type": "rich-text", "source": "rich-text", "selector": "h1,h2,h3,h4,h5,h6", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "level": { "type": "number", diff --git a/packages/block-library/src/image/block.json b/packages/block-library/src/image/block.json index 26835df9e856cd..08b11754a22062 100644 --- a/packages/block-library/src/image/block.json +++ b/packages/block-library/src/image/block.json @@ -25,7 +25,10 @@ "source": "attribute", "selector": "img", "attribute": "src", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "alt": { "type": "string", @@ -33,7 +36,10 @@ "selector": "img", "attribute": "alt", "default": "", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "caption": { "type": "rich-text", @@ -52,7 +58,10 @@ "source": "attribute", "selector": "img", "attribute": "title", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "href": { "type": "string", @@ -75,7 +84,10 @@ }, "id": { "type": "number", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "width": { "type": "string" diff --git a/packages/block-library/src/paragraph/block.json b/packages/block-library/src/paragraph/block.json index 9617627ef5d0da..a795f34f5f31df 100644 --- a/packages/block-library/src/paragraph/block.json +++ b/packages/block-library/src/paragraph/block.json @@ -15,7 +15,10 @@ "type": "rich-text", "source": "rich-text", "selector": "p", - "role": "content" + "role": "content", + "bindings": { + "ui": "active" + } }, "dropCap": { "type": "boolean", diff --git a/schemas/json/block.json b/schemas/json/block.json index fc810bbc5eec14..2e9b0c47fb67a2 100644 --- a/schemas/json/block.json +++ b/schemas/json/block.json @@ -144,6 +144,18 @@ } ] }, + "bindings": { + "type": "object", + "description": "Defines if the attribute can be bound.", + "properties": { + "ui": { + "description": "Defines the bindings UI state for the attribute.", + "type": "string", + "enum": [ "hidden", "active" ], + "default": "hidden" + } + } + }, "enum": { "description": "An attribute can be defined as one of a fixed set of values. This is specified by an enum, which contains an array of allowed values:", "type": "array", diff --git a/test/e2e/specs/editor/various/block-bindings/post-data.spec.js b/test/e2e/specs/editor/various/block-bindings/post-data.spec.js deleted file mode 100644 index ff9f2289633703..00000000000000 --- a/test/e2e/specs/editor/various/block-bindings/post-data.spec.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * WordPress dependencies - */ -const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); - -test.describe( 'Post Data source', () => { - test.beforeAll( async ( { requestUtils } ) => { - await requestUtils.activateTheme( - 'gutenberg-test-themes/block-bindings' - ); - await requestUtils.activatePlugin( 'gutenberg-test-block-bindings' ); - } ); - - test.beforeEach( async ( { admin } ) => { - await admin.createNewPost( { title: 'Test bindings' } ); - } ); - - test.afterEach( async ( { requestUtils } ) => { - await requestUtils.deleteAllPosts(); - } ); - - test.afterEach( async ( { requestUtils } ) => { - await requestUtils.deleteAllPosts(); - } ); - - test.afterAll( async ( { requestUtils } ) => { - await requestUtils.activateTheme( 'twentytwentyone' ); - await requestUtils.deactivatePlugin( 'gutenberg-test-block-bindings' ); - } ); - test.describe( 'Post Data bindings UI.', () => { - test( 'should not include post data fields in UI to connect attributes on non date blocks', async ( { - editor, - page, - } ) => { - await editor.insertBlock( { - name: 'core/paragraph', - attributes: { - content: 'fallback content', - metadata: { - bindings: { - content: { - source: 'core/post-data', - args: { - field: 'modified', - }, - }, - }, - }, - }, - } ); - await page - .getByRole( 'button', { - name: 'content', - } ) - .click(); - const postDataMenuItem = page.getByRole( 'menuitem', { - name: 'Post Data', - } ); - await expect( postDataMenuItem ).toBeHidden(); - // Check the fields registered by other sources are there. - } ); - - test( 'should include post data fields in UI to connect attributes on date blocks', async ( { - editor, - page, - } ) => { - await editor.insertBlock( { - name: 'core/post-date', - attributes: { - metadata: { - bindings: { - datetime: { - source: 'core/post-data', - args: { field: 'date' }, - }, - }, - }, - }, - } ); - await page - .getByRole( 'button', { - name: 'datetime', - } ) - .click(); - const postDataMenuItem = page.getByRole( 'menuitem', { - name: 'Post Data', - } ); - await expect( postDataMenuItem ).toBeVisible(); - } ); - } ); -} );