Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add content only descriptions in dropdown menus for patterns and templates #61127

Merged
merged 16 commits into from May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -31,10 +31,12 @@ export default function BlockActions( {
getDirectInsertBlock,
canMoveBlocks,
canRemoveBlocks,
getBlockEditingMode,
} = select( blockEditorStore );

const blocks = getBlocksByClientId( clientIds );
const rootClientId = getBlockRootClientId( clientIds[ 0 ] );
const rootBlockEditingMode = getBlockEditingMode( rootClientId );
const canInsertDefaultBlock = canInsertBlockType(
getDefaultBlockName(),
rootClientId
Expand All @@ -46,7 +48,9 @@ export default function BlockActions( {
return {
canMove: canMoveBlocks( clientIds, rootClientId ),
canRemove: canRemoveBlocks( clientIds, rootClientId ),
canInsertBlock: canInsertDefaultBlock || !! directInsertBlock,
canInsertBlock:
( canInsertDefaultBlock || !! directInsertBlock ) &&
rootBlockEditingMode === 'default',
canCopyStyles: blocks.every( ( block ) => {
return (
!! block &&
Expand Down
Expand Up @@ -27,24 +27,31 @@ import { BlockRenameControl, useBlockRename } from '../block-rename';
const { Fill, Slot } = createSlotFill( 'BlockSettingsMenuControls' );

const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => {
const { selectedBlocks, selectedClientIds } = useSelect(
const { selectedBlocks, selectedClientIds, isContentOnly } = useSelect(
( select ) => {
const { getBlockNamesByClientId, getSelectedBlockClientIds } =
select( blockEditorStore );
const {
getBlockNamesByClientId,
getSelectedBlockClientIds,
getBlockEditingMode,
} = select( blockEditorStore );
const ids =
clientIds !== null ? clientIds : getSelectedBlockClientIds();
return {
selectedBlocks: getBlockNamesByClientId( ids ),
selectedClientIds: ids,
isContentOnly:
getBlockEditingMode( ids[ 0 ] ) === 'contentOnly',
};
},
[ clientIds ]
);

const { canLock } = useBlockLock( selectedClientIds[ 0 ] );
const { canRename } = useBlockRename( selectedBlocks[ 0 ] );
const showLockButton = selectedClientIds.length === 1 && canLock;
const showRenameButton = selectedClientIds.length === 1 && canRename;
const showLockButton =
selectedClientIds.length === 1 && canLock && ! isContentOnly;
const showRenameButton =
selectedClientIds.length === 1 && canRename && ! isContentOnly;

// Check if current selection of blocks is Groupable or Ungroupable
// and pass this props down to ConvertToGroupButton.
Expand Down Expand Up @@ -89,17 +96,19 @@ const BlockSettingsMenuControlsSlot = ( { fillProps, clientIds = null } ) => {
/>
) }
{ fills }
{ fillProps?.canMove && ! fillProps?.onlyBlock && (
<MenuItem
onClick={ pipe(
fillProps?.onClose,
fillProps?.onMoveTo
) }
>
{ __( 'Move to' ) }
</MenuItem>
) }
{ fillProps?.count === 1 && (
{ fillProps?.canMove &&
! fillProps?.onlyBlock &&
! isContentOnly && (
<MenuItem
onClick={ pipe(
fillProps?.onClose,
fillProps?.onMoveTo
) }
>
{ __( 'Move to' ) }
</MenuItem>
) }
{ fillProps?.count === 1 && ! isContentOnly && (
<BlockModeToggle
clientId={ fillProps?.firstBlockClientId }
onToggle={ fillProps?.onClose }
Expand Down
Expand Up @@ -63,6 +63,7 @@ export function BlockSettingsDropdown( {
previousBlockClientId,
selectedBlockClientIds,
openedBlockSettingsMenu,
isContentOnly,
} = useSelect(
( select ) => {
const {
Expand All @@ -73,6 +74,7 @@ export function BlockSettingsDropdown( {
getSelectedBlockClientIds,
getBlockAttributes,
getOpenedBlockSettingsMenu,
getBlockEditingMode,
} = unlock( select( blockEditorStore ) );

const { getActiveBlockVariation } = select( blocksStore );
Expand All @@ -96,6 +98,8 @@ export function BlockSettingsDropdown( {
getPreviousBlockClientId( firstBlockClientId ),
selectedBlockClientIds: getSelectedBlockClientIds(),
openedBlockSettingsMenu: getOpenedBlockSettingsMenu(),
isContentOnly:
getBlockEditingMode( firstBlockClientId ) === 'contentOnly',
};
},
[ firstBlockClientId ]
Expand Down Expand Up @@ -231,11 +235,15 @@ export function BlockSettingsDropdown( {
clientId={ firstBlockClientId }
/>
) }
<CopyMenuItem
clientIds={ clientIds }
onCopy={ onCopy }
shortcut={ displayShortcut.primary( 'c' ) }
/>
{ ! isContentOnly && (
<CopyMenuItem
clientIds={ clientIds }
onCopy={ onCopy }
shortcut={ displayShortcut.primary(
'c'
) }
/>
) }
{ canDuplicate && (
<MenuItem
onClick={ pipe(
Expand Down Expand Up @@ -271,7 +279,7 @@ export function BlockSettingsDropdown( {
</>
) }
</MenuGroup>
{ canCopyStyles && (
{ canCopyStyles && ! isContentOnly && (
<MenuGroup>
<CopyMenuItem
clientIds={ clientIds }
Expand Down
Expand Up @@ -16,6 +16,7 @@ import { forwardRef } from '@wordpress/element';
import { Icon, lockSmall as lock, pinSmall } from '@wordpress/icons';
import { SPACE, ENTER } from '@wordpress/keycodes';
import { __, sprintf } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -26,6 +27,7 @@ import useBlockDisplayTitle from '../block-title/use-block-display-title';
import ListViewExpander from './expander';
import { useBlockLock } from '../block-lock';
import useListViewImages from './use-list-view-images';
import { store as blockEditorStore } from '../../store';

function ListViewBlockSelectButton(
{
Expand All @@ -51,6 +53,15 @@ function ListViewBlockSelectButton(
context: 'list-view',
} );
const { isLocked } = useBlockLock( clientId );
const { isContentOnly } = useSelect(
( select ) => ( {
isContentOnly:
select( blockEditorStore ).getBlockEditingMode( clientId ) ===
'contentOnly',
} ),
[ clientId ]
);
const shouldShowLockIcon = isLocked && ! isContentOnly;
const isSticky = blockInformation?.positionType === 'sticky';
const images = useListViewImages( { clientId, isExpanded } );

Expand Down Expand Up @@ -147,7 +158,7 @@ function ListViewBlockSelectButton(
) ) }
</span>
) : null }
{ isLocked && (
{ shouldShowLockIcon && (
<span className="block-editor-list-view-block-select-button__lock">
<Icon icon={ lock } />
</span>
Expand Down
38 changes: 15 additions & 23 deletions packages/block-editor/src/components/list-view/block.js
Expand Up @@ -104,34 +104,26 @@ function ListViewBlock( {

const blockInformation = useBlockDisplayInformation( clientId );

const { block, blockName, blockEditingMode, allowRightClickOverrides } =
useSelect(
( select ) => {
const {
getBlock,
getBlockName,
getBlockEditingMode,
getSettings,
} = select( blockEditorStore );

return {
block: getBlock( clientId ),
blockName: getBlockName( clientId ),
blockEditingMode: getBlockEditingMode( clientId ),
allowRightClickOverrides:
getSettings().allowRightClickOverrides,
};
},
[ clientId ]
);
const { block, blockName, allowRightClickOverrides } = useSelect(
( select ) => {
const { getBlock, getBlockName, getSettings } =
select( blockEditorStore );

return {
block: getBlock( clientId ),
blockName: getBlockName( clientId ),
allowRightClickOverrides:
getSettings().allowRightClickOverrides,
};
},
[ clientId ]
);

const showBlockActions =
// When a block hides its toolbar it also hides the block settings menu,
// since that menu is part of the toolbar in the editor canvas.
// List View respects this by also hiding the block settings menu.
hasBlockSupport( blockName, '__experimentalToolbar', true ) &&
// Don't show the settings menu if block is disabled or content only.
blockEditingMode === 'default';
hasBlockSupport( blockName, '__experimentalToolbar', true );
const instanceId = useInstanceId( ListViewBlock );
const descriptionId = `list-view-block-select-button__description-${ instanceId }`;

Expand Down
49 changes: 16 additions & 33 deletions packages/block-editor/src/hooks/content-lock-ui.js
Expand Up @@ -20,7 +20,6 @@ import { unlock } from '../lock-unlock';
// also includes artifacts on the store (actions, reducers, and selector).

function ContentLockControlsPure( { clientId, isSelected } ) {
const { getBlockListSettings, getSettings } = useSelect( blockEditorStore );
const { templateLock, isLockedByParent, isEditingAsBlocks } = useSelect(
( select ) => {
const {
Expand All @@ -37,16 +36,11 @@ function ContentLockControlsPure( { clientId, isSelected } ) {
[ clientId ]
);

const {
updateSettings,
updateBlockListSettings,
__unstableSetTemporarilyEditingAsBlocks,
} = useDispatch( blockEditorStore );
const { stopEditingAsBlocks } = unlock( useDispatch( blockEditorStore ) );
const { stopEditingAsBlocks, modifyContentLockBlock } = unlock(
useDispatch( blockEditorStore )
);
const isContentLocked =
! isLockedByParent && templateLock === 'contentOnly';
const { __unstableMarkNextChangeAsNotPersistent, updateBlockAttributes } =
useDispatch( blockEditorStore );

const stopEditingAsBlockCallback = useCallback( () => {
stopEditingAsBlocks( clientId );
Expand All @@ -73,30 +67,19 @@ function ContentLockControlsPure( { clientId, isSelected } ) {
) }
{ showStartEditingAsBlocks && (
<BlockSettingsMenuControls>
{ ( { onClose } ) => (
<MenuItem
onClick={ () => {
__unstableMarkNextChangeAsNotPersistent();
updateBlockAttributes( clientId, {
templateLock: undefined,
} );
updateBlockListSettings( clientId, {
...getBlockListSettings( clientId ),
templateLock: false,
} );
const focusModeToRevert =
getSettings().focusMode;
updateSettings( { focusMode: true } );
__unstableSetTemporarilyEditingAsBlocks(
clientId,
focusModeToRevert
);
onClose();
} }
>
{ __( 'Modify' ) }
</MenuItem>
) }
{ ( { selectedClientIds, onClose } ) =>
selectedClientIds.length === 1 &&
selectedClientIds[ 0 ] === clientId && (
<MenuItem
onClick={ () => {
modifyContentLockBlock( clientId );
onClose();
} }
>
{ __( 'Modify' ) }
</MenuItem>
)
}
</BlockSettingsMenuControls>
) }
</>
Expand Down
24 changes: 24 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Expand Up @@ -391,3 +391,27 @@ export function expandBlock( clientId ) {
clientId,
};
}

/**
* Temporarily modify/unlock the content-only block for editions.
*
* @param {string} clientId The client id of the block.
*/
export const modifyContentLockBlock =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be good to add a docblock

( clientId ) =>
( { select, dispatch } ) => {
dispatch.__unstableMarkNextChangeAsNotPersistent();
dispatch.updateBlockAttributes( clientId, {
templateLock: undefined,
} );
dispatch.updateBlockListSettings( clientId, {
...select.getBlockListSettings( clientId ),
templateLock: false,
} );
const focusModeToRevert = select.getSettings().focusMode;
dispatch.updateSettings( { focusMode: true } );
dispatch.__unstableSetTemporarilyEditingAsBlocks(
clientId,
focusModeToRevert
);
};
6 changes: 4 additions & 2 deletions packages/block-editor/src/store/selectors.js
Expand Up @@ -1759,14 +1759,16 @@ export function canMoveBlock( state, clientId, rootClientId = null ) {
if ( attributes === null ) {
return true;
}
if ( getBlockEditingMode( state, rootClientId ) !== 'default' ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the block editing check earlier so that blocks in the page editor won't be moved (which is expected.)

return false;
}
if ( attributes.lock?.move !== undefined ) {
return ! attributes.lock.move;
}
if ( getTemplateLock( state, rootClientId ) === 'all' ) {
return false;
}

return getBlockEditingMode( state, rootClientId ) !== 'disabled';
return true;
}

/**
Expand Down
19 changes: 16 additions & 3 deletions packages/edit-site/src/components/template-part-converter/index.js
Expand Up @@ -27,12 +27,25 @@ export default function TemplatePartConverter() {
}

function TemplatePartConverterMenuItem( { clientIds, onClose } ) {
const blocks = useSelect(
( select ) =>
select( blockEditorStore ).getBlocksByClientId( clientIds ),
const { isContentOnly, blocks } = useSelect(
( select ) => {
const { getBlocksByClientId, getBlockEditingMode } =
select( blockEditorStore );
return {
blocks: getBlocksByClientId( clientIds ),
isContentOnly:
clientIds.length === 1 &&
getBlockEditingMode( clientIds[ 0 ] ) === 'contentOnly',
};
},
[ clientIds ]
);

// Do not show the convert button if the block is in content-only mode.
if ( isContentOnly ) {
return null;
}

// Allow converting a single template part to standard blocks.
if ( blocks.length === 1 && blocks[ 0 ]?.name === 'core/template-part' ) {
return (
Expand Down