From 86c6b499d1a01903517c591966a67b9df41cc5bf Mon Sep 17 00:00:00 2001 From: Carlos Bravo <37012961+cbravobernal@users.noreply.github.com> Date: Sat, 30 Nov 2024 21:18:08 +0100 Subject: [PATCH 1/2] Initial commit --- .../block-editor/src/hooks/block-bindings.js | 131 +++++++++--------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/packages/block-editor/src/hooks/block-bindings.js b/packages/block-editor/src/hooks/block-bindings.js index 615804a311c0f..54a9af0bafd2f 100644 --- a/packages/block-editor/src/hooks/block-bindings.js +++ b/packages/block-editor/src/hooks/block-bindings.js @@ -1,11 +1,10 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { getBlockBindingsSource, getBlockBindingsSources, - getBlockType, } from '@wordpress/blocks'; import { __experimentalItemGroup as ItemGroup, @@ -15,9 +14,10 @@ import { __experimentalToolsPanelItem as ToolsPanelItem, __experimentalVStack as VStack, privateApis as componentsPrivateApis, + ComboboxControl, } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; -import { useContext, Fragment } from '@wordpress/element'; +import { useContext, useState } from '@wordpress/element'; import { useViewportMatch } from '@wordpress/compose'; /** @@ -30,7 +30,6 @@ import { import { unlock } from '../lock-unlock'; import InspectorControls from '../components/inspector-controls'; import BlockContext from '../components/block-context'; -import { useBlockEditContext } from '../components/block-edit'; import { useBlockBindingsUtils } from '../utils/block-bindings'; import { store as blockEditorStore } from '../store'; @@ -51,65 +50,73 @@ const useToolsPanelDropdownMenuProps = () => { : {}; }; -function BlockBindingsPanelDropdown( { fieldsList, attribute, binding } ) { - const { clientId } = useBlockEditContext(); - const registeredSources = getBlockBindingsSources(); +function BlockBindingsPanelDropdown( { fieldsList, attribute } ) { const { updateBlockBindings } = useBlockBindingsUtils(); - const currentKey = binding?.args?.key; - const attributeType = useSelect( - ( select ) => { - const { name: blockName } = - select( blockEditorStore ).getBlock( clientId ); - const _attributeType = - getBlockType( blockName ).attributes?.[ attribute ]?.type; - return _attributeType === 'rich-text' ? 'string' : _attributeType; - }, - [ clientId, attribute ] + // Transform fieldsList into array of options. + const transformFieldsToOptions = ( fields ) => { + return Object.entries( fields ).flatMap( + ( [ sourceName, sourceFields ] ) => + Object.entries( sourceFields ).map( ( [ key, field ] ) => ( { + key, + label: field.label || key, + source: sourceName, + value: + field.value === '' + ? sprintf( 'Add %1s', field.label || key ) + : field.value, + } ) ) + ); + }; + const [ filteredOptions, setFilteredOptions ] = useState( + transformFieldsToOptions( fieldsList ) ); + return ( - <> - { Object.entries( fieldsList ).map( ( [ name, fields ], i ) => ( - - - { Object.keys( fieldsList ).length > 1 && ( - - { registeredSources[ name ].label } - - ) } - { Object.entries( fields ) - .filter( - ( [ , args ] ) => args?.type === attributeType - ) - .map( ( [ key, args ] ) => ( - - updateBlockBindings( { - [ attribute ]: { - source: name, - args: { key }, - }, - } ) - } - name={ attribute + '-binding' } - value={ key } - checked={ key === currentKey } - > - - { args?.label } - - - { args?.value } - - - ) ) } - - { i !== Object.keys( fieldsList ).length - 1 && ( - - ) } - - ) ) } - + { + const { label, source, value } = element.item; + return ( +
+
+ { label } +
+ + { sprintf( 'Value: %1s', value ) },{ ' ' } + { sprintf( 'Source: %1s', source ) } + +
+ ); + } } + onFilterValueChange={ ( value ) => { + const allOptions = transformFieldsToOptions( fieldsList ); + setFilteredOptions( + allOptions.filter( ( option ) => + option.label + .toLowerCase() + .startsWith( value.toLowerCase() ) + ) + ); + } } + onChange={ ( value ) => { + const allOptions = transformFieldsToOptions( fieldsList ); + const optionSelected = allOptions.find( + ( option ) => option.value === value + ); + + updateBlockBindings( { + [ attribute ]: { + source: optionSelected.source, + args: { key: optionSelected.key }, + }, + } ); + } } + /> ); } @@ -176,9 +183,7 @@ function EditableBlockBindingsPanelItems( { } } > From a19285f6c24cd94cbcc794459f9a15da88787c67 Mon Sep 17 00:00:00 2001 From: Carlos Bravo <37012961+cbravobernal@users.noreply.github.com> Date: Tue, 3 Dec 2024 14:57:50 +0100 Subject: [PATCH 2/2] Add height --- packages/block-editor/src/hooks/block-bindings.js | 3 ++- packages/block-editor/src/hooks/block-bindings.scss | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/block-bindings.js b/packages/block-editor/src/hooks/block-bindings.js index 54a9af0bafd2f..57c7216731555 100644 --- a/packages/block-editor/src/hooks/block-bindings.js +++ b/packages/block-editor/src/hooks/block-bindings.js @@ -76,9 +76,10 @@ function BlockBindingsPanelDropdown( { fieldsList, attribute } ) { __next40pxDefaultSize __nextHasNoMarginBottom allowReset - expandOnFocus={ false } + expandOnFocus label={ __( 'Connect attributes' ) } options={ filteredOptions } + className="block-editor-bindings__combobox" __experimentalRenderItem={ ( element ) => { const { label, source, value } = element.item; return ( diff --git a/packages/block-editor/src/hooks/block-bindings.scss b/packages/block-editor/src/hooks/block-bindings.scss index e8f05895922f0..703b56e9f287d 100644 --- a/packages/block-editor/src/hooks/block-bindings.scss +++ b/packages/block-editor/src/hooks/block-bindings.scss @@ -4,3 +4,6 @@ div.block-editor-bindings__panel { color: inherit; } } +.block-editor-bindings__combobox .components-form-token-field__suggestions-list { + max-height: 400px; +}