UNPKG

@wordpress/block-editor

Version:
8 lines (7 loc) 10.3 kB
{ "version": 3, "sources": ["../../../src/components/block-draggable/index.js"], "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { store as blocksStore } from '@wordpress/blocks';\nimport { Draggable } from '@wordpress/components';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useEffect, useRef } from '@wordpress/element';\nimport { throttle } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport BlockDraggableChip from './draggable-chip';\nimport useScrollWhenDragging from './use-scroll-when-dragging';\nimport { store as blockEditorStore } from '../../store';\nimport { useBlockElement } from '../block-list/use-block-props/use-block-refs';\nimport { isDropTargetValid } from '../use-block-drop-zone';\n\nconst BlockDraggable = ( {\n\tappendToOwnerDocument,\n\tchildren,\n\tclientIds,\n\tcloneClassname,\n\telementId,\n\tonDragStart,\n\tonDragEnd,\n\tfadeWhenDisabled = false,\n\tdragComponent,\n} ) => {\n\tconst {\n\t\tsrcRootClientId,\n\t\tisDraggable,\n\t\ticon,\n\t\tvisibleInserter,\n\t\tgetBlockType,\n\t} = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\tcanMoveBlocks,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t\tgetBlockName,\n\t\t\t\tgetBlockAttributes,\n\t\t\t\tisBlockInsertionPointVisible,\n\t\t\t} = select( blockEditorStore );\n\t\t\tconst { getBlockType: _getBlockType, getActiveBlockVariation } =\n\t\t\t\tselect( blocksStore );\n\t\t\tconst rootClientId = getBlockRootClientId( clientIds[ 0 ] );\n\t\t\tconst blockName = getBlockName( clientIds[ 0 ] );\n\t\t\tconst variation = getActiveBlockVariation(\n\t\t\t\tblockName,\n\t\t\t\tgetBlockAttributes( clientIds[ 0 ] )\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tsrcRootClientId: rootClientId,\n\t\t\t\tisDraggable: canMoveBlocks( clientIds ),\n\t\t\t\ticon: variation?.icon || _getBlockType( blockName )?.icon,\n\t\t\t\tvisibleInserter: isBlockInsertionPointVisible(),\n\t\t\t\tgetBlockType: _getBlockType,\n\t\t\t};\n\t\t},\n\t\t[ clientIds ]\n\t);\n\n\tconst isDraggingRef = useRef( false );\n\tconst [ startScrolling, scrollOnDragOver, stopScrolling ] =\n\t\tuseScrollWhenDragging();\n\n\tconst { getAllowedBlocks, getBlockNamesByClientId, getBlockRootClientId } =\n\t\tuseSelect( blockEditorStore );\n\n\tconst { startDraggingBlocks, stopDraggingBlocks } =\n\t\tuseDispatch( blockEditorStore );\n\n\t// Stop dragging blocks if the block draggable is unmounted.\n\tuseEffect( () => {\n\t\treturn () => {\n\t\t\tif ( isDraggingRef.current ) {\n\t\t\t\tstopDraggingBlocks();\n\t\t\t}\n\t\t};\n\t}, [] );\n\n\t// Find the root of the editor iframe.\n\tconst blockEl = useBlockElement( clientIds[ 0 ] );\n\tconst editorRoot = blockEl?.closest( 'body' );\n\n\t/*\n\t * Add a dragover event listener to the editor root to track the blocks being dragged over.\n\t * The listener has to be inside the editor iframe otherwise the target isn't accessible.\n\t */\n\tuseEffect( () => {\n\t\tif ( ! editorRoot || ! fadeWhenDisabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst onDragOver = ( event ) => {\n\t\t\tif ( ! event.target.closest( '[data-block]' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst draggedBlockNames = getBlockNamesByClientId( clientIds );\n\t\t\tconst targetClientId = event.target\n\t\t\t\t.closest( '[data-block]' )\n\t\t\t\t.getAttribute( 'data-block' );\n\n\t\t\tconst allowedBlocks = getAllowedBlocks( targetClientId );\n\t\t\tconst targetBlockName = getBlockNamesByClientId( [\n\t\t\t\ttargetClientId,\n\t\t\t] )[ 0 ];\n\n\t\t\t/*\n\t\t\t * Check if the target is valid to drop in.\n\t\t\t * If the target's allowedBlocks is an empty array,\n\t\t\t * it isn't a container block, in which case we check\n\t\t\t * its parent's validity instead.\n\t\t\t */\n\t\t\tlet dropTargetValid;\n\t\t\tif ( allowedBlocks?.length === 0 ) {\n\t\t\t\tconst targetRootClientId =\n\t\t\t\t\tgetBlockRootClientId( targetClientId );\n\t\t\t\tconst targetRootBlockName = getBlockNamesByClientId( [\n\t\t\t\t\ttargetRootClientId,\n\t\t\t\t] )[ 0 ];\n\t\t\t\tconst rootAllowedBlocks =\n\t\t\t\t\tgetAllowedBlocks( targetRootClientId );\n\t\t\t\tdropTargetValid = isDropTargetValid(\n\t\t\t\t\tgetBlockType,\n\t\t\t\t\trootAllowedBlocks,\n\t\t\t\t\tdraggedBlockNames,\n\t\t\t\t\ttargetRootBlockName\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tdropTargetValid = isDropTargetValid(\n\t\t\t\t\tgetBlockType,\n\t\t\t\t\tallowedBlocks,\n\t\t\t\t\tdraggedBlockNames,\n\t\t\t\t\ttargetBlockName\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Update the body class to reflect if drop target is valid.\n\t\t\t * This has to be done on the document body because the draggable\n\t\t\t * chip is rendered outside of the editor iframe.\n\t\t\t */\n\t\t\tif ( ! dropTargetValid && ! visibleInserter ) {\n\t\t\t\twindow?.document?.body?.classList?.add(\n\t\t\t\t\t'block-draggable-invalid-drag-token'\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\twindow?.document?.body?.classList?.remove(\n\t\t\t\t\t'block-draggable-invalid-drag-token'\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst throttledOnDragOver = throttle( onDragOver, 200 );\n\n\t\teditorRoot.addEventListener( 'dragover', throttledOnDragOver );\n\n\t\treturn () => {\n\t\t\teditorRoot.removeEventListener( 'dragover', throttledOnDragOver );\n\t\t};\n\t}, [\n\t\tclientIds,\n\t\teditorRoot,\n\t\tfadeWhenDisabled,\n\t\tgetAllowedBlocks,\n\t\tgetBlockNamesByClientId,\n\t\tgetBlockRootClientId,\n\t\tgetBlockType,\n\t\tvisibleInserter,\n\t] );\n\n\tif ( ! isDraggable ) {\n\t\treturn children( { draggable: false } );\n\t}\n\n\tconst transferData = {\n\t\ttype: 'block',\n\t\tsrcClientIds: clientIds,\n\t\tsrcRootClientId,\n\t};\n\n\treturn (\n\t\t<Draggable\n\t\t\tappendToOwnerDocument={ appendToOwnerDocument }\n\t\t\tcloneClassname={ cloneClassname }\n\t\t\t__experimentalTransferDataType=\"wp-blocks\"\n\t\t\ttransferData={ transferData }\n\t\t\tonDragStart={ ( event ) => {\n\t\t\t\t// Defer hiding the dragged source element to the next\n\t\t\t\t// frame to enable dragging.\n\t\t\t\twindow.requestAnimationFrame( () => {\n\t\t\t\t\tstartDraggingBlocks( clientIds );\n\t\t\t\t\tisDraggingRef.current = true;\n\n\t\t\t\t\tstartScrolling( event );\n\n\t\t\t\t\tif ( onDragStart ) {\n\t\t\t\t\t\tonDragStart();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} }\n\t\t\tonDragOver={ scrollOnDragOver }\n\t\t\tonDragEnd={ () => {\n\t\t\t\tstopDraggingBlocks();\n\t\t\t\tisDraggingRef.current = false;\n\n\t\t\t\tstopScrolling();\n\n\t\t\t\tif ( onDragEnd ) {\n\t\t\t\t\tonDragEnd();\n\t\t\t\t}\n\t\t\t} }\n\t\t\t__experimentalDragComponent={\n\t\t\t\t// Check against `undefined` so that `null` can be used to disable\n\t\t\t\t// the default drag component.\n\t\t\t\tdragComponent !== undefined ? (\n\t\t\t\t\tdragComponent\n\t\t\t\t) : (\n\t\t\t\t\t<BlockDraggableChip\n\t\t\t\t\t\tcount={ clientIds.length }\n\t\t\t\t\t\ticon={ icon }\n\t\t\t\t\t\tfadeWhenDisabled\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t}\n\t\t\telementId={ elementId }\n\t\t>\n\t\t\t{ ( { onDraggableStart, onDraggableEnd } ) => {\n\t\t\t\treturn children( {\n\t\t\t\t\tdraggable: true,\n\t\t\t\t\tonDragStart: onDraggableStart,\n\t\t\t\t\tonDragEnd: onDraggableEnd,\n\t\t\t\t} );\n\t\t\t} }\n\t\t</Draggable>\n\t);\n};\n\nexport default BlockDraggable;\n"], "mappings": "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", "names": ["getBlockRootClientId"] }