Skip to content

Commit

Permalink
Allow opt-out of pattern overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Mar 21, 2024
1 parent 74a06c7 commit 35f955a
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 5 deletions.
2 changes: 2 additions & 0 deletions packages/block-editor/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useFlashEditableBlocks } from './components/use-flash-editable-blocks';
import { selectBlockPatternsKey } from './store/private-keys';
import { requiresWrapperOnCopy } from './components/writing-flow/utils';
import { PrivateRichText } from './components/rich-text/';
import { BlockRenameModal } from './components/block-rename';

/**
* Private @wordpress/block-editor APIs.
Expand Down Expand Up @@ -62,4 +63,5 @@ lock( privateApis, {
selectBlockPatternsKey,
requiresWrapperOnCopy,
PrivateRichText,
BlockRenameModal,
} );
28 changes: 25 additions & 3 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 { store as blocksStore } from '@wordpress/blocks';

/**
* Internal dependencies
Expand All @@ -15,6 +16,7 @@ import { unlock } from '../lock-unlock';

const {
useSetPatternBindings,
PatternOverridesControls,
ResetOverridesControl,
PATTERN_TYPES,
PARTIAL_SYNCING_SUPPORTED_BLOCKS,
Expand Down Expand Up @@ -60,9 +62,20 @@ function BindingUpdater( props ) {
// on every block.
function ControlsWithStoreSubscription( props ) {
const blockEditingMode = useBlockEditingMode();
const isEditingPattern = useSelect(
( select ) =>
select( editorStore ).getCurrentPostType() === PATTERN_TYPES.user,
const { hasPatternOverridesSource, isEditingPattern } = useSelect(
( select ) => {
const { getBlockBindingsSource } = unlock( select( blocksStore ) );

return {
// For editing link to the site editor if the theme and user permissions support it.
hasPatternOverridesSource: !! getBlockBindingsSource(
'core/pattern-overrides'
),
isEditingPattern:
select( editorStore ).getCurrentPostType() ===
PATTERN_TYPES.user,
};
},
[]
);

Expand All @@ -73,14 +86,23 @@ function ControlsWithStoreSubscription( props ) {
( binding ) => binding.source === 'core/pattern-overrides'
);

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

if ( ! hasPatternOverridesSource ) {
return null;
}

return (
<>
{ shouldShowPatternOverridesControls && (
<PatternOverridesControls { ...props } />
) }
{ shouldShowResetOverridesControl && (
<ResetOverridesControl { ...props } />
) }
Expand Down
93 changes: 93 additions & 0 deletions packages/patterns/src/components/pattern-overrides-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import {
InspectorControls,
privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';
import { ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { addBindings } from './use-set-pattern-bindings';
import { PARTIAL_SYNCING_SUPPORTED_BLOCKS } from '../constants';
import { unlock } from '../lock-unlock';

const { BlockRenameModal } = unlock( blockEditorPrivateApis );

function PatternOverridesControls( { attributes, name, setAttributes } ) {
const [ showBlockNameModal, setShowBlockNameModal ] = useState( false );

const syncedAttributes = PARTIAL_SYNCING_SUPPORTED_BLOCKS[ name ];
const attributeSources = syncedAttributes.map(
( attributeName ) =>
attributes.metadata?.bindings?.[ attributeName ]?.source
);
const isConnectedToOtherSources = attributeSources.every(
( source ) => source && source !== 'core/pattern-overrides'
);

function updateBindings( isChecked, customName ) {
if ( isChecked && ! attributes.metadata?.name && ! customName ) {
setShowBlockNameModal( true );
return;
}

const prevBindings = attributes?.metadata?.bindings;
const updatedBindings = isChecked
? addBindings( prevBindings, syncedAttributes )
: // Explicitly set to false to disable pattern overrides.
false;

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

if ( customName ) {
updatedMetadata.name = customName;
}

setAttributes( {
metadata: updatedMetadata,
} );
}

// Avoid overwriting other (e.g. meta) bindings.
if ( isConnectedToOtherSources ) return null;

return (
<>
<InspectorControls group="advanced">
<ToggleControl
__nextHasNoMarginBottom
label={ __( 'Allow pattern overrides' ) }
checked={ attributeSources.some(
( source ) => source === 'core/pattern-overrides'
) }
help={ __(
'Allow attributes within this block to be overridden by pattern instances.'
) }
onChange={ ( isChecked ) => {
updateBindings( isChecked );
} }
/>
</InspectorControls>

{ showBlockNameModal && (
<BlockRenameModal
blockName={ attributes.metadata?.name || '' }
onClose={ () => setShowBlockNameModal( false ) }
onSave={ ( newName ) => {
updateBindings( true, newName );
} }
/>
) }
</>
);
}

export default PatternOverridesControls;
6 changes: 4 additions & 2 deletions packages/patterns/src/components/use-set-pattern-bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function removeBindings( bindings, syncedAttributes ) {
return updatedBindings;
}

function addBindings( bindings, syncedAttributes ) {
export function addBindings( bindings, syncedAttributes ) {
const updatedBindings = { ...bindings };
for ( const attributeName of syncedAttributes ) {
if ( ! bindings?.[ attributeName ] ) {
Expand Down Expand Up @@ -64,7 +64,9 @@ export default function useSetPatternBindings(
if (
! hasPatternOverridesSource ||
currentPostType !== 'wp_block' ||
metadataName === prevMetadataName
metadataName === prevMetadataName ||
// Don't update the bindings if it's explicitly set to false.
bindings === false
) {
return;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/patterns/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import RenamePatternModal from './components/rename-pattern-modal';
import PatternsMenuItems from './components';
import RenamePatternCategoryModal from './components/rename-pattern-category-modal';
import useSetPatternBindings from './components/use-set-pattern-bindings';
import PatternOverridesControls from './components/pattern-overrides-controls';
import ResetOverridesControl from './components/reset-overrides-control';
import { useAddPatternCategory } from './private-hooks';
import {
Expand All @@ -35,6 +36,7 @@ lock( privateApis, {
PatternsMenuItems,
RenamePatternCategoryModal,
useSetPatternBindings,
PatternOverridesControls,
ResetOverridesControl,
useAddPatternCategory,
PATTERN_TYPES,
Expand Down

0 comments on commit 35f955a

Please sign in to comment.