diff --git a/packages/block-editor/src/hooks/auto-inspector-controls.js b/packages/block-editor/src/hooks/auto-inspector-controls.js index 8e15d56f9f1efa..ee38558ecb83a2 100644 --- a/packages/block-editor/src/hooks/auto-inspector-controls.js +++ b/packages/block-editor/src/hooks/auto-inspector-controls.js @@ -1,11 +1,11 @@ /** * WordPress dependencies */ -import { getBlockType } from '@wordpress/blocks'; +import { getBlockType, store as blocksStore } from '@wordpress/blocks'; import { PanelBody } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { DataForm } from '@wordpress/dataviews'; -import { useMemo } from '@wordpress/element'; +import { useContext, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** @@ -14,6 +14,8 @@ import { __ } from '@wordpress/i18n'; import InspectorControls from '../components/inspector-controls'; import { useBlockEditingMode } from '../components/block-editing-mode'; import { store as blockEditorStore } from '../store'; +import { unlock } from '../lock-unlock'; +import BlockContext from '../components/block-context'; import { generateFieldsFromAttributes } from './generate-fields-from-attributes'; /** @@ -45,9 +47,34 @@ function hasAutoGenerateControl( blockTypeAttributes ) { function AutoRegisterControls( { name, clientId, setAttributes } ) { const blockEditingMode = useBlockEditingMode(); + const blockContext = useContext( BlockContext ); + const attributes = useSelect( - ( select ) => select( blockEditorStore ).getBlockAttributes( clientId ), - [ clientId ] + ( select ) => { + const _attributes = + select( blockEditorStore ).getBlockAttributes( clientId ); + if ( ! _attributes?.metadata?.bindings ) { + return _attributes; + } + + const { getBlockBindingsSource } = unlock( select( blocksStore ) ); + return Object.entries( _attributes.metadata.bindings ).reduce( + ( acc, [ attribute, binding ] ) => { + const source = getBlockBindingsSource( binding.source ); + if ( ! source ) { + return acc; + } + const values = source.getValues( { + select, + context: blockContext, + bindings: { [ attribute ]: binding }, + } ); + return { ...acc, ...values }; + }, + _attributes + ); + }, + [ blockContext, clientId ] ); const blockType = getBlockType( name ); diff --git a/packages/e2e-tests/plugins/block-bindings.php b/packages/e2e-tests/plugins/block-bindings.php index 92331d2b654d27..1d51c8c6bff15c 100644 --- a/packages/e2e-tests/plugins/block-bindings.php +++ b/packages/e2e-tests/plugins/block-bindings.php @@ -172,7 +172,7 @@ function gutenberg_test_block_bindings_registration() { 'type' => 'number', 'show_in_rest' => true, 'single' => true, - 'default' => 5.5, + 'default' => 0.5, ) ); register_meta( @@ -183,7 +183,7 @@ function gutenberg_test_block_bindings_registration() { 'type' => 'integer', 'show_in_rest' => true, 'single' => true, - 'default' => 5, + 'default' => 3, ) ); register_meta( diff --git a/packages/e2e-tests/plugins/server-side-rendered-block.php b/packages/e2e-tests/plugins/server-side-rendered-block.php index 5f34a703fb5a90..29962e90798318 100644 --- a/packages/e2e-tests/plugins/server-side-rendered-block.php +++ b/packages/e2e-tests/plugins/server-side-rendered-block.php @@ -87,6 +87,14 @@ static function () { ) ); + // Add binding support for the auto-register-with-controls block. + add_filter( + 'block_bindings_supported_attributes_test/auto-register-with-controls', + static function () { + return array( 'title', 'count', 'spacing', 'showEmojis' ); + } + ); + // PHP-only block with auto-generated controls from various attribute types register_block_type( 'test/auto-register-with-controls', diff --git a/test/e2e/specs/editor/plugins/server-side-rendered-block.spec.js b/test/e2e/specs/editor/plugins/server-side-rendered-block.spec.js index 8975a7691e0169..cf5bbb7bdbd6fa 100644 --- a/test/e2e/specs/editor/plugins/server-side-rendered-block.spec.js +++ b/test/e2e/specs/editor/plugins/server-side-rendered-block.spec.js @@ -263,4 +263,61 @@ test.describe( 'PHP-only auto-register blocks', () => { page.getByLabel( 'Emoji', { exact: true } ) ).toBeVisible(); } ); + + test.describe( 'with block bindings', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( + 'gutenberg-test-block-bindings' + ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-block-bindings' + ); + } ); + + test( 'generated inspector controls should reflect bound attribute values', async ( { + editor, + page, + } ) => { + // Insert the block with bindings on multiple attributes. + await editor.insertBlock( { + name: 'test/auto-register-with-controls', + attributes: { + metadata: { + bindings: { + title: { + source: 'core/post-meta', + args: { key: 'text_custom_field' }, + }, + count: { + source: 'core/post-meta', + args: { key: 'integer' }, + }, + spacing: { + source: 'core/post-meta', + args: { key: 'number_custom_field' }, + }, + showEmojis: { + source: 'core/post-meta', + args: { key: 'boolean' }, + }, + }, + }, + }, + } ); + + await editor.openDocumentSettingsSidebar(); + + // Controls should show bound values from the source, + // not the block attribute defaults. + await expect( page.getByLabel( 'Title' ) ).toHaveValue( + 'Value of the text custom field' + ); + await expect( page.getByLabel( 'Count' ) ).toHaveValue( '3' ); + await expect( page.getByLabel( 'Spacing' ) ).toHaveValue( '0.5' ); + await expect( page.getByLabel( 'Show Emojis' ) ).toBeChecked(); + } ); + } ); } );