UNPKG

@wordpress/block-editor

Version:
102 lines (90 loc) 2.48 kB
/** * WordPress dependencies */ import { isTextField } from '@wordpress/dom'; import { ENTER, BACKSPACE, DELETE } from '@wordpress/keycodes'; import { useSelect, useDispatch } from '@wordpress/data'; import { useRefEffect } from '@wordpress/compose'; /** * Internal dependencies */ import { store as blockEditorStore } from '../../../store'; /** * Adds block behaviour: * - Removes the block on BACKSPACE. * - Inserts a default block on ENTER. * - Disables dragging of block contents. * * @param {string} clientId Block client ID. */ export function useEventHandlers( clientId ) { const isSelected = useSelect( ( select ) => select( blockEditorStore ).isBlockSelected( clientId ), [ clientId ] ); const { getBlockRootClientId, getBlockIndex } = useSelect( blockEditorStore ); const { insertDefaultBlock, removeBlock } = useDispatch( blockEditorStore ); return useRefEffect( ( node ) => { if ( ! isSelected ) { return; } /** * Interprets keydown event intent to remove or insert after block if * key event occurs on wrapper node. This can occur when the block has * no text fields of its own, particularly after initial insertion, to * allow for easy deletion and continuous writing flow to add additional * content. * * @param {KeyboardEvent} event Keydown event. */ function onKeyDown( event ) { const { keyCode, target } = event; if ( keyCode !== ENTER && keyCode !== BACKSPACE && keyCode !== DELETE ) { return; } if ( target !== node || isTextField( target ) ) { return; } event.preventDefault(); if ( keyCode === ENTER ) { insertDefaultBlock( {}, getBlockRootClientId( clientId ), getBlockIndex( clientId ) + 1 ); } else { removeBlock( clientId ); } } /** * Prevents default dragging behavior within a block. To do: we must * handle this in the future and clean up the drag target. * * @param {DragEvent} event Drag event. */ function onDragStart( event ) { event.preventDefault(); } node.addEventListener( 'keydown', onKeyDown ); node.addEventListener( 'dragstart', onDragStart ); return () => { node.removeEventListener( 'keydown', onKeyDown ); node.removeEventListener( 'dragstart', onDragStart ); }; }, [ clientId, isSelected, getBlockRootClientId, getBlockIndex, insertDefaultBlock, removeBlock, ] ); }