Skip to content

Commit

Permalink
Refactor block settings dropdown to controlled mode. This helps with:
Browse files Browse the repository at this point in the history
- stopping the propagation of the ESC keydown, so that only the dropdown closes and the toolbar stays open
- restoring passing an onClose callback to slotfills, including the create reusable pattern modal
  • Loading branch information
ciampo committed Jun 14, 2023
1 parent 94d9285 commit 654d7eb
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ export function BlockSettingsDropdown( {
const parentBlockIsSelected =
selectedBlockClientIds?.includes( firstParentClientId );

const [ isDropdownOpen, setIsDropdownOpen ] = useState( false );

const closeDropdown = useCallback( () => {
setIsDropdownOpen( false );
}, [] );

return (
<BlockActions
clientIds={ clientIds }
Expand All @@ -332,6 +338,10 @@ export function BlockSettingsDropdown( {
blocks,
} ) => (
<DropdownMenuV2
open={ isDropdownOpen }
onOpenChange={ ( open ) => {
setIsDropdownOpen( open );
} }
trigger={
<Button
{ ...toggleProps }
Expand Down Expand Up @@ -359,6 +369,11 @@ export function BlockSettingsDropdown( {
onKeyDown={ ( event ) => {
if ( event.defaultPrevented ) return;

if ( event.key === 'Escape' ) {
setIsDropdownOpen( false );
event.preventDefault();
}

if (
isMatch( 'core/block-editor/remove', event ) &&
canRemove
Expand Down Expand Up @@ -395,7 +410,9 @@ export function BlockSettingsDropdown( {
{ ...props }
>
<DropdownMenuGroupV2>
<__unstableBlockSettingsMenuFirstItem.Slot />
<__unstableBlockSettingsMenuFirstItem.Slot
fillProps={ { onClose: closeDropdown } }
/>
{ ! parentBlockIsSelected && !! firstParentClientId && (
<DropdownMenuItemV2
{ ...showParentOutlineGestures }
Expand Down Expand Up @@ -472,6 +489,7 @@ export function BlockSettingsDropdown( {

<BlockSettingsMenuControls.Slot
fillProps={ {
onClose: closeDropdown,
canMove,
onMoveTo,
onlyBlock,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,67 +112,67 @@ export default function ReusableBlockConvertButton( {
/* TODO: check if this used in other legacy dropdown menus */
return (
<BlockSettingsMenuControls>
<>
<DropdownMenuItemV2
prefix={ <Icon icon={ symbol } size={ 24 } /> }
onSelect={ ( event ) => {
setIsModalOpen( true );
// Keep the dropdown menu open
event.preventDefault();
} }
>
{ __( 'Create Reusable block' ) }
</DropdownMenuItemV2>
{ isModalOpen && (
<Modal
title={ __( 'Create Reusable block' ) }
onRequestClose={ () => {
setIsModalOpen( false );
setTitle( '' );
{ ( { onClose } ) => (
<>
<DropdownMenuItemV2
prefix={ <Icon icon={ symbol } size={ 24 } /> }
onSelect={ ( event ) => {
setIsModalOpen( true );
// Keep the dropdown menu open
event.preventDefault();
} }
overlayClassName="reusable-blocks-menu-items__convert-modal"
>
<form
onSubmit={ ( event ) => {
event.preventDefault();
onConvert( title );
{ __( 'Create Reusable block' ) }
</DropdownMenuItemV2>
{ isModalOpen && (
<Modal
title={ __( 'Create Reusable block' ) }
onRequestClose={ () => {
setIsModalOpen( false );
setTitle( '' );
// TODO: the modal is expected to close the dropdown!
// - can we keep it open?
// - can we close the dropdown when the modal is opened instead?
// - otherwise, how do we go about it? We'd need to switch to
// controlled mode at the root, and pass `onClose` around
// onClose();
} }
overlayClassName="reusable-blocks-menu-items__convert-modal"
>
<VStack spacing="5">
<TextControl
__nextHasNoMarginBottom
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
/>
<HStack justify="right">
<Button
variant="tertiary"
onClick={ () => {
setIsModalOpen( false );
setTitle( '' );
} }
>
{ __( 'Cancel' ) }
</Button>
<form
onSubmit={ ( event ) => {
event.preventDefault();
onConvert( title );
setIsModalOpen( false );
setTitle( '' );
// The dropdown seems to close automatically due to the old
// regular block being replaced by the new block, although
// I've kept this line around for now.
onClose();
} }
>
<VStack spacing="5">
<TextControl
__nextHasNoMarginBottom
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
/>
<HStack justify="right">
<Button
variant="tertiary"
onClick={ () => {
setIsModalOpen( false );
setTitle( '' );
} }
>
{ __( 'Cancel' ) }
</Button>

<Button variant="primary" type="submit">
{ __( 'Save' ) }
</Button>
</HStack>
</VStack>
</form>
</Modal>
) }
</>
<Button variant="primary" type="submit">
{ __( 'Save' ) }
</Button>
</HStack>
</VStack>
</form>
</Modal>
) }
</>
) }
</BlockSettingsMenuControls>
);
}

0 comments on commit 654d7eb

Please sign in to comment.