Skip to content
Prev Previous commit
Next Next commit
Extract to dedicated files
  • Loading branch information
getdave committed Oct 25, 2023
commit 03bfef06b84bbc3dd2de446120abbaf28955d163
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* WordPress dependencies
*/
import { MenuItem } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import { useBlockDisplayInformation } from '..';
import { emptyString } from './empty-string';
import { RenameModal } from './modal';

export function BlockRenameControl( { clientId } ) {
const [ renamingBlock, setRenamingBlock ] = useState( false );

const { metadata } = useSelect(
( select ) => {
const { getBlockAttributes } = select( blockEditorStore );

const _metadata = getBlockAttributes( clientId )?.metadata;
return {
metadata: _metadata,
};
},
[ clientId ]
);

const { updateBlockAttributes } = useDispatch( blockEditorStore );

const customName = metadata?.name;

function onChange( newName ) {
updateBlockAttributes( [ clientId ], {
metadata: {
...( metadata && metadata ),
name: newName,
},
} );
}

const blockInformation = useBlockDisplayInformation( clientId );

return (
<>
<MenuItem
onClick={ () => {
setRenamingBlock( true );
} }
aria-expanded={ renamingBlock }
aria-haspopup="dialog"
>
{ __( 'Rename' ) }
</MenuItem>
{ renamingBlock && (
<RenameModal
blockName={ customName || '' }
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 ||
emptyString( newName )
) {
newName = undefined;
}

onChange( newName );
} }
/>
) }
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const emptyString = ( testString ) => testString?.trim()?.length === 0;
114 changes: 114 additions & 0 deletions packages/block-editor/src/components/block-rename/modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* WordPress dependencies
*/
import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
Button,
TextControl,
Modal,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { __, sprintf } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { speak } from '@wordpress/a11y';
/**
* Internal dependencies
*/
import { emptyString } from './empty-string';

export function RenameModal( {
blockName,
originalBlockName,
onClose,
onSave,
} ) {
const [ editedBlockName, setEditedBlockName ] = useState( blockName );

const nameHasChanged = editedBlockName !== blockName;
const nameIsOriginal = editedBlockName === originalBlockName;
const nameIsEmpty = emptyString( editedBlockName );

const isNameValid = nameHasChanged || nameIsOriginal;

const autoSelectInputText = ( event ) => event.target.select();

const dialogDescription = useInstanceId(
RenameModal,
`block-editor-rename-modal__description`
);

const handleSubmit = () => {
const message =
nameIsOriginal || nameIsEmpty
? sprintf(
/* translators: %s: new name/label for the block */
__( 'Block name reset to: "%s".' ),
editedBlockName
)
: sprintf(
/* translators: %s: new name/label for the block */
__( 'Block name changed to: "%s".' ),
editedBlockName
);

// Must be assertive to immediately announce change.
speak( message, 'assertive' );
onSave( editedBlockName );

// Immediate close avoids ability to hit save multiple times.
onClose();
};

return (
<Modal
title={ __( 'Rename' ) }
onRequestClose={ onClose }
overlayClassName="block-editor-block-rename-modal"
aria={ {
describedby: dialogDescription,
} }
focusOnMount="firstContentElement"
>
<p id={ dialogDescription }>
{ __( 'Enter a custom name for this block.' ) }
</p>
<form
onSubmit={ ( e ) => {
e.preventDefault();

if ( ! isNameValid ) {
return;
}

handleSubmit();
} }
>
<VStack spacing="3">
<TextControl
__nextHasNoMarginBottom
value={ editedBlockName }
label={ __( 'Block name' ) }
hideLabelFromVision={ true }
placeholder={ originalBlockName }
onChange={ setEditedBlockName }
onFocus={ autoSelectInputText }
/>
<HStack justify="right">
<Button variant="tertiary" onClick={ onClose }>
{ __( 'Cancel' ) }
</Button>

<Button
aria-disabled={ ! isNameValid }
variant="primary"
type="submit"
>
{ __( 'Save' ) }
</Button>
</HStack>
</VStack>
</form>
</Modal>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';

export function useBlockRename( name ) {
const metaDataSupport = getBlockSupport(
name,
'__experimentalMetadata',
false
);

const supportsBlockNaming = !! (
true === metaDataSupport || metaDataSupport?.name
);

return {
canRename: supportsBlockNaming,
};
}
Loading