Skip to content

Commit

Permalink
Don't use global 'select' in the Behaviors controls component
Browse files Browse the repository at this point in the history
  • Loading branch information
Mamaduka committed May 27, 2023
1 parent da158af commit c780e1c
Showing 1 changed file with 77 additions and 62 deletions.
139 changes: 77 additions & 62 deletions packages/block-editor/src/hooks/behaviors.js
Expand Up @@ -5,7 +5,7 @@ import { addFilter } from '@wordpress/hooks';
import { SelectControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { createHigherOrderComponent } from '@wordpress/compose';
import { select } from '@wordpress/data';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -18,6 +18,66 @@ import { store as blockEditorStore } from '../store';
*/
import merge from 'deepmerge';

function BehaviorsControl( { blockName, blockBehaviors, onChange } ) {
const { settings, themeBehaviors } = useSelect(
( select ) => {
const { getBehaviors, getSettings } = select( blockEditorStore );

return {
settings:
getSettings()?.__experimentalFeatures?.blocks?.[ blockName ]
?.behaviors,
themeBehaviors: getBehaviors()?.blocks?.[ blockName ],
};
},
[ blockName ]
);

if (
! settings ||
// If every behavior is disabled, do not show the behaviors inspector control.
Object.entries( settings ).every( ( [ , value ] ) => ! value )
) {
return null;
}

// Block behaviors take precedence over theme behaviors.
const behaviors = merge( themeBehaviors, blockBehaviors || {} );

const noBehaviorsOption = {
value: '',
label: __( 'No behaviors' ),
};

const behaviorsOptions = Object.entries( settings )
.filter( ( [ , behaviorValue ] ) => behaviorValue ) // Filter out behaviors that are disabled.
.map( ( [ behaviorName ] ) => ( {
value: behaviorName,
label:
// Capitalize the first letter of the behavior name.
behaviorName[ 0 ].toUpperCase() +
behaviorName.slice( 1 ).toLowerCase(),
} ) );

const options = [ noBehaviorsOption, ...behaviorsOptions ];

return (
<InspectorControls group="advanced">
<SelectControl
__nextHasNoMarginBottom
label={ __( 'Behaviors' ) }
// At the moment we are only supporting one behavior (Lightbox)
value={ behaviors?.lightbox ? 'lightbox' : '' }
options={ options }
onChange={ onChange }
hideCancelButton={ true }
help={ __( 'Add behaviors.' ) }
size="__unstable-large"
/>
</InspectorControls>
);
}

/**
* Override the default edit UI to include a new block inspector control for
* assigning behaviors to blocks if behaviors are enabled in the theme.json.
Expand All @@ -30,73 +90,28 @@ import merge from 'deepmerge';
*/
export const withBehaviors = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
const blockEdit = <BlockEdit key="edit" { ...props } />;
// Only add behaviors to the core/image block.
if ( props.name !== 'core/image' ) {
return <BlockEdit { ...props } />;
return blockEdit;
}

const settings =
select( blockEditorStore ).getSettings()?.__experimentalFeatures
?.blocks?.[ props.name ]?.behaviors;

if (
! settings ||
// If every behavior is disabled, do not show the behaviors inspector control.
Object.entries( settings ).every( ( [ , value ] ) => ! value )
) {
return <BlockEdit { ...props } />;
}

const { behaviors: blockBehaviors } = props.attributes;

// Get the theme behaviors for the block from the theme.json.
const themeBehaviors =
select( blockEditorStore ).getBehaviors()?.blocks?.[ props.name ];

// Block behaviors take precedence over theme behaviors.
const behaviors = merge( themeBehaviors, blockBehaviors || {} );

const noBehaviorsOption = {
value: '',
label: __( 'No behaviors' ),
};

const behaviorsOptions = Object.entries( settings )
.filter( ( [ , behaviorValue ] ) => behaviorValue ) // Filter out behaviors that are disabled.
.map( ( [ behaviorName ] ) => ( {
value: behaviorName,
label:
// Capitalize the first letter of the behavior name.
behaviorName[ 0 ].toUpperCase() +
behaviorName.slice( 1 ).toLowerCase(),
} ) );

const options = [ noBehaviorsOption, ...behaviorsOptions ];

return (
<>
<BlockEdit { ...props } />
<InspectorControls group="advanced">
<SelectControl
__nextHasNoMarginBottom
label={ __( 'Behaviors' ) }
// At the moment we are only supporting one behavior (Lightbox)
value={ behaviors?.lightbox ? 'lightbox' : '' }
options={ options }
onChange={ ( nextValue ) => {
// If the user selects something, it means that they want to
// change the default value (true) so we save it in the attributes.
props.setAttributes( {
behaviors: {
lightbox: nextValue === 'lightbox',
},
} );
} }
hideCancelButton={ true }
help={ __( 'Add behaviors.' ) }
size="__unstable-large"
/>
</InspectorControls>
{ blockEdit }
<BehaviorsControl
blockName={ props.name }
blockBehaviors={ props.attributes.behaviors }
onChange={ ( nextValue ) => {
// If the user selects something, it means that they want to
// change the default value (true) so we save it in the attributes.
props.setAttributes( {
behaviors: {
lightbox: nextValue === 'lightbox',
},
} );
} }
/>
</>
);
};
Expand Down

0 comments on commit c780e1c

Please sign in to comment.