Skip to content

Commit

Permalink
Pattern Overrides: Memoize controls component
Browse files Browse the repository at this point in the history
  • Loading branch information
Mamaduka committed Jul 9, 2024
1 parent 8784fe9 commit cc989c1
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 75 deletions.
134 changes: 75 additions & 59 deletions packages/editor/src/hooks/pattern-overrides.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { privateApis as patternsPrivateApis } from '@wordpress/patterns';
import { createHigherOrderComponent } from '@wordpress/compose';
import { useBlockEditingMode } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { memo } from '@wordpress/element';
import { store as blocksStore } from '@wordpress/blocks';

/**
Expand All @@ -25,6 +26,68 @@ const {
PATTERN_SYNC_TYPES,
} = unlock( patternsPrivateApis );

// Split into a separate component to avoid a store subscription
// on every block.
const MemoizedControlsWithStoreSubscription = memo(
function ControlsWithStoreSubscription( props ) {
const blockEditingMode = useBlockEditingMode();
const { hasPatternOverridesSource, isEditingSyncedPattern } = useSelect(
( select ) => {
const { getBlockBindingsSource } = unlock(
select( blocksStore )
);
const { getCurrentPostType, getEditedPostAttribute } =
select( editorStore );

return {
// For editing link to the site editor if the theme and user permissions support it.
hasPatternOverridesSource: !! getBlockBindingsSource(
'core/pattern-overrides'
),
isEditingSyncedPattern:
getCurrentPostType() === PATTERN_TYPES.user &&
getEditedPostAttribute( 'meta' )
?.wp_pattern_sync_status !==
PATTERN_SYNC_TYPES.unsynced &&
getEditedPostAttribute( 'wp_pattern_sync_status' ) !==
PATTERN_SYNC_TYPES.unsynced,
};
},
[]
);

const bindings = props.metadata?.bindings;
const hasPatternBindings =
!! bindings &&
Object.values( bindings ).some(
( binding ) => binding.source === 'core/pattern-overrides'
);

const shouldShowPatternOverridesControls =
isEditingSyncedPattern && blockEditingMode === 'default';
const shouldShowResetOverridesControl =
! isEditingSyncedPattern &&
!! props.metadata?.name &&
blockEditingMode !== 'disabled' &&
hasPatternBindings;

if ( ! hasPatternOverridesSource ) {
return null;
}

return (
<>
{ shouldShowPatternOverridesControls && (
<PatternOverridesControls { ...props } />
) }
{ shouldShowResetOverridesControl && (
<ResetOverridesControl { ...props } />
) }
</>
);
}
);

/**
* Override the default edit UI to include a new block inspector control for
* assigning a partial syncing controls to supported blocks in the pattern editor.
Expand All @@ -41,9 +104,19 @@ const withPatternOverrideControls = createHigherOrderComponent(

return (
<>
<BlockEdit { ...props } />
<BlockEdit key="edit" { ...props } />
{ props.isSelected && isSupportedBlock && (
<ControlsWithStoreSubscription { ...props } />
<MemoizedControlsWithStoreSubscription
clientId={ props.clientId }
name={ props.name }
metadata={ props.attributes.metadata }
setAttributes={ props.setAttributes }
hasUnsupportedAttributes={
props.name === 'core/image' &&
( !! props.attributes.caption?.length ||
!! props.attributes.href?.length )
}
/>
) }
{ isSupportedBlock && <PatternOverridesBlockControls /> }
</>
Expand All @@ -52,63 +125,6 @@ const withPatternOverrideControls = createHigherOrderComponent(
'withPatternOverrideControls'
);

// Split into a separate component to avoid a store subscription
// on every block.
function ControlsWithStoreSubscription( props ) {
const blockEditingMode = useBlockEditingMode();
const { hasPatternOverridesSource, isEditingSyncedPattern } = useSelect(
( select ) => {
const { getBlockBindingsSource } = unlock( select( blocksStore ) );
const { getCurrentPostType, getEditedPostAttribute } =
select( editorStore );

return {
// For editing link to the site editor if the theme and user permissions support it.
hasPatternOverridesSource: !! getBlockBindingsSource(
'core/pattern-overrides'
),
isEditingSyncedPattern:
getCurrentPostType() === PATTERN_TYPES.user &&
getEditedPostAttribute( 'meta' )?.wp_pattern_sync_status !==
PATTERN_SYNC_TYPES.unsynced &&
getEditedPostAttribute( 'wp_pattern_sync_status' ) !==
PATTERN_SYNC_TYPES.unsynced,
};
},
[]
);

const bindings = props.attributes.metadata?.bindings;
const hasPatternBindings =
!! bindings &&
Object.values( bindings ).some(
( binding ) => binding.source === 'core/pattern-overrides'
);

const shouldShowPatternOverridesControls =
isEditingSyncedPattern && blockEditingMode === 'default';
const shouldShowResetOverridesControl =
! isEditingSyncedPattern &&
!! props.attributes.metadata?.name &&
blockEditingMode !== 'disabled' &&
hasPatternBindings;

if ( ! hasPatternOverridesSource ) {
return null;
}

return (
<>
{ shouldShowPatternOverridesControls && (
<PatternOverridesControls { ...props } />
) }
{ shouldShowResetOverridesControl && (
<ResetOverridesControl { ...props } />
) }
</>
);
}

addFilter(
'editor.BlockEdit',
'core/editor/with-pattern-override-controls',
Expand Down
24 changes: 9 additions & 15 deletions packages/patterns/src/components/pattern-overrides-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,32 @@ function addBindings( bindings ) {
}

function PatternOverridesControls( {
attributes,
metadata,
setAttributes,
name: blockName,
hasUnsupportedAttributes,
} ) {
const controlId = useId();
const [ showAllowOverridesModal, setShowAllowOverridesModal ] =
useState( false );
const [ showDisallowOverridesModal, setShowDisallowOverridesModal ] =
useState( false );

const hasName = !! attributes.metadata?.name;
const defaultBindings = attributes.metadata?.bindings?.__default;
const hasName = !! metadata?.name;
const defaultBindings = metadata?.bindings?.__default;
const hasOverrides =
hasName && defaultBindings?.source === PATTERN_OVERRIDES_BINDING_SOURCE;
const isConnectedToOtherSources =
defaultBindings?.source &&
defaultBindings.source !== PATTERN_OVERRIDES_BINDING_SOURCE;

function updateBindings( isChecked, customName ) {
const prevBindings = attributes?.metadata?.bindings;
const prevBindings = metadata?.bindings;
const updatedBindings = isChecked
? addBindings( prevBindings )
: removeBindings( prevBindings );

const updatedMetadata = {
...attributes.metadata,
...metadata,
bindings: updatedBindings,
};

Expand All @@ -75,12 +75,8 @@ function PatternOverridesControls( {
return null;
}

const hasUnsupportedImageAttributes =
blockName === 'core/image' &&
( !! attributes.caption?.length || !! attributes.href?.length );

const helpText =
! hasOverrides && hasUnsupportedImageAttributes
! hasOverrides && hasUnsupportedAttributes
? __(
`Overrides currently don't support image captions or links. Remove the caption or link first before enabling overrides.`
)
Expand Down Expand Up @@ -108,9 +104,7 @@ function PatternOverridesControls( {
setShowAllowOverridesModal( true );
}
} }
disabled={
! hasOverrides && hasUnsupportedImageAttributes
}
disabled={ ! hasOverrides && hasUnsupportedAttributes }
accessibleWhenDisabled
>
{ hasOverrides
Expand All @@ -122,7 +116,7 @@ function PatternOverridesControls( {

{ showAllowOverridesModal && (
<AllowOverridesModal
initialName={ attributes.metadata?.name }
initialName={ metadata?.name }
onClose={ () => setShowAllowOverridesModal( false ) }
onSave={ ( newName ) => {
updateBindings( true, newName );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n';
const CONTENT = 'content';

export default function ResetOverridesControl( props ) {
const name = props.attributes.metadata?.name;
const name = props.metadata?.name;
const registry = useRegistry();
const isOverriden = useSelect(
( select ) => {
Expand Down

0 comments on commit cc989c1

Please sign in to comment.