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

List view: Trigger rename block on double click #68546

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 118 additions & 87 deletions packages/block-editor/src/components/list-view/block-select-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
__experimentalTruncate as Truncate,
} from '@wordpress/components';
import { forwardRef } from '@wordpress/element';
import { Icon, lockSmall as lock, pinSmall } from '@wordpress/icons';
import { SPACE, ENTER } from '@wordpress/keycodes';
import { useSelect } from '@wordpress/data';

import { useState } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { hasBlockSupport } from '@wordpress/blocks';
/**
* Internal dependencies
*/
Expand All @@ -25,6 +25,8 @@ import ListViewExpander from './expander';
import { useBlockLock } from '../block-lock';
import useListViewImages from './use-list-view-images';
import { store as blockEditorStore } from '../../store';
import isEmptyString from '../block-rename/is-empty-string';
import BlockRenameModal from '../block-rename/modal';

function ListViewBlockSelectButton(
{
Expand All @@ -44,6 +46,17 @@ function ListViewBlockSelectButton(
},
ref
) {
const { metadata } = useSelect(
( select ) => {
const { getBlockAttributes } = select( blockEditorStore );

const _metadata = getBlockAttributes( clientId )?.metadata;
return {
metadata: _metadata,
};
},
[ clientId ]
);
const blockInformation = useBlockDisplayInformation( clientId );
const blockTitle = useBlockDisplayTitle( {
clientId,
Expand All @@ -58,103 +71,121 @@ function ListViewBlockSelectButton(
} ),
[ clientId ]
);
const shouldShowLockIcon = isLocked && ! isContentOnly;
const shouldShowLockIcon = isLocked && !isContentOnly;
const isSticky = blockInformation?.positionType === 'sticky';
const images = useListViewImages( { clientId, isExpanded } );
const images = useListViewImages({ clientId, isExpanded });
const { updateBlockAttributes } = useDispatch( blockEditorStore );

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

// The `href` attribute triggers the browser's native HTML drag operations.
// When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html.
// We need to clear any HTML drag data to prevent `pasteHandler` from firing
// inside the `useOnBlockDrop` hook.
const onDragStartHandler = ( event ) => {
return {
blockName: getBlockName( clientId ),
allowRightClickOverrides:
getSettings().allowRightClickOverrides,
};
},
[ clientId ]
);
// State for renaming modal
const [renamingBlock, setRenamingBlock] = useState(false);
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 );
const onDragStartHandler = (event) => {
event.dataTransfer.clearData();
onDragStart?.( event );
onDragStart?.(event);
};

/**
* @param {KeyboardEvent} event
*/
function onKeyDown( event ) {
if ( event.keyCode === ENTER || event.keyCode === SPACE ) {
onClick( event );
function onKeyDown(event) {
if (event.keyCode === ENTER || event.keyCode === SPACE) {
onClick(event);
}
}

function onChange( newName ) {
updateBlockAttributes( [ clientId ], {
metadata: {
...metadata,
name: newName,
},
} );
}
return (
<a
className={ clsx(
'block-editor-list-view-block-select-button',
className
) }
onClick={ onClick }
onContextMenu={ onContextMenu }
onKeyDown={ onKeyDown }
onMouseDown={ onMouseDown }
ref={ ref }
tabIndex={ tabIndex }
onFocus={ onFocus }
onDragStart={ onDragStartHandler }
onDragEnd={ onDragEnd }
draggable={ draggable }
href={ `#block-${ clientId }` }
aria-describedby={ ariaDescribedBy }
aria-expanded={ isExpanded }
>
<ListViewExpander onClick={ onToggleExpanded } />
<BlockIcon
icon={ blockInformation?.icon }
showColors
context="list-view"
/>
<HStack
alignment="center"
className="block-editor-list-view-block-select-button__label-wrapper"
justify="flex-start"
spacing={ 1 }
<>
<a
className={clsx(
'block-editor-list-view-block-select-button',
className
)}
onClick={onClick}
onContextMenu={onContextMenu}
onKeyDown={onKeyDown}
onMouseDown={onMouseDown}
ref={ref}
tabIndex={tabIndex}
onFocus={onFocus}
onDragStart={onDragStartHandler}
onDragEnd={onDragEnd}
draggable={draggable}
href={`#block-${clientId}`}
aria-describedby={ariaDescribedBy}
aria-expanded={isExpanded}
>
<span className="block-editor-list-view-block-select-button__title">
<Truncate ellipsizeMode="auto">{ blockTitle }</Truncate>
</span>
{ blockInformation?.anchor && (
<span className="block-editor-list-view-block-select-button__anchor-wrapper">
<Truncate
className="block-editor-list-view-block-select-button__anchor"
ellipsizeMode="auto"
>
{ blockInformation.anchor }
</Truncate>
</span>
) }
{ isSticky && (
<span className="block-editor-list-view-block-select-button__sticky">
<Icon icon={ pinSmall } />
</span>
) }
{ images.length ? (
<ListViewExpander onClick={onToggleExpanded} />
<BlockIcon
icon={blockInformation?.icon}
showColors
context="list-view"
/>
<HStack
alignment="center"
className="block-editor-list-view-block-select-button__label-wrapper"
justify="flex-start"
spacing={1}
>
<span
className="block-editor-list-view-block-select-button__images"
aria-hidden
className="block-editor-list-view-block-select-button__title"
onDoubleClick={() => {
console.log('showBlockActions:', showBlockActions);
console.log('allowRightClickOverrides:', allowRightClickOverrides);
if (showBlockActions && allowRightClickOverrides) {
setRenamingBlock(true);
}
}}
>
{ images.map( ( image, index ) => (
<span
className="block-editor-list-view-block-select-button__image"
key={ image.clientId }
style={ {
backgroundImage: `url(${ image.url })`,
zIndex: images.length - index, // Ensure the first image is on top, and subsequent images are behind.
} }
/>
) ) }
</span>
) : null }
{ shouldShowLockIcon && (
<span className="block-editor-list-view-block-select-button__lock">
<Icon icon={ lock } />
<Truncate ellipsizeMode="auto">{blockTitle}</Truncate>
</span>
) }
</HStack>
</a>
{/* Additional UI Elements */}
</HStack>
</a>
{/* Render Rename Modal */}
{renamingBlock && (
<BlockRenameModal
blockName={blockTitle}
originalBlockName={blockInformation?.title}
onClose={() => setRenamingBlock(false)}
onSave={ ( newName ) => {
// If the new value is the block's original name (e.g. `Group`)
// or it is an empty string then assume the intent is to reset
// the value. Therefore reset the metadata.
if (
newName === blockInformation?.title ||
isEmptyString( newName )
) {
newName = undefined;
}

onChange( newName );
} }
/>
)}
</>
);
}


export default forwardRef( ListViewBlockSelectButton );
Loading