@wordpress/block-editor
Version:
8 lines (7 loc) • 11.6 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/components/block-popover/inbetween.js"],
"sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { useSelect } from '@wordpress/data';\nimport { useMemo, useReducer, useLayoutEffect } from '@wordpress/element';\nimport { Popover } from '@wordpress/components';\nimport { isRTL } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { store as blockEditorStore } from '../../store';\nimport { useBlockElement } from '../block-list/use-block-props/use-block-refs';\nimport usePopoverScroll from './use-popover-scroll';\n\nconst MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER;\n\nfunction BlockPopoverInbetween( {\n\tpreviousClientId,\n\tnextClientId,\n\tchildren,\n\t__unstablePopoverSlot,\n\t__unstableContentRef,\n\toperation = 'insert',\n\tnearestSide = 'right',\n\t...props\n} ) {\n\t// This is a temporary hack to get the inbetween inserter to recompute properly.\n\tconst [ popoverRecomputeCounter, forcePopoverRecompute ] = useReducer(\n\t\t// Module is there to make sure that the counter doesn't overflow.\n\t\t( s ) => ( s + 1 ) % MAX_POPOVER_RECOMPUTE_COUNTER,\n\t\t0\n\t);\n\n\tconst { orientation, rootClientId, isVisible } = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\tgetBlockListSettings,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t\tisBlockVisible,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst _rootClientId = getBlockRootClientId(\n\t\t\t\tpreviousClientId ?? nextClientId\n\t\t\t);\n\t\t\treturn {\n\t\t\t\torientation:\n\t\t\t\t\tgetBlockListSettings( _rootClientId )?.orientation ||\n\t\t\t\t\t'vertical',\n\t\t\t\trootClientId: _rootClientId,\n\t\t\t\tisVisible:\n\t\t\t\t\tisBlockVisible( previousClientId ) &&\n\t\t\t\t\tisBlockVisible( nextClientId ),\n\t\t\t};\n\t\t},\n\t\t[ previousClientId, nextClientId ]\n\t);\n\tconst previousElement = useBlockElement( previousClientId );\n\tconst nextElement = useBlockElement( nextClientId );\n\tconst isVertical = orientation === 'vertical';\n\n\tconst popoverAnchor = useMemo( () => {\n\t\tif (\n\t\t\t// popoverRecomputeCounter is by definition always equal or greater than 0.\n\t\t\t// This check is only there to satisfy the correctness of the\n\t\t\t// exhaustive-deps rule for the `useMemo` hook.\n\t\t\tpopoverRecomputeCounter < 0 ||\n\t\t\t( ! previousElement && ! nextElement ) ||\n\t\t\t! isVisible\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst contextElement =\n\t\t\toperation === 'group'\n\t\t\t\t? nextElement || previousElement\n\t\t\t\t: previousElement || nextElement;\n\n\t\treturn {\n\t\t\tcontextElement,\n\t\t\tgetBoundingClientRect() {\n\t\t\t\tconst previousRect = previousElement\n\t\t\t\t\t? previousElement.getBoundingClientRect()\n\t\t\t\t\t: null;\n\t\t\t\tconst nextRect = nextElement\n\t\t\t\t\t? nextElement.getBoundingClientRect()\n\t\t\t\t\t: null;\n\n\t\t\t\tlet left = 0;\n\t\t\t\tlet top = 0;\n\t\t\t\tlet width = 0;\n\t\t\t\tlet height = 0;\n\n\t\t\t\tif ( operation === 'group' ) {\n\t\t\t\t\tconst targetRect = nextRect || previousRect;\n\t\t\t\t\ttop = targetRect.top;\n\t\t\t\t\t// No spacing is likely around blocks in this operation.\n\t\t\t\t\t// So width of the inserter containing rect is set to 0.\n\t\t\t\t\twidth = 0;\n\t\t\t\t\theight = targetRect.bottom - targetRect.top;\n\t\t\t\t\t// Popover calculates its distance from mid-block so some\n\t\t\t\t\t// adjustments are needed to make it appear in the right place.\n\t\t\t\t\tleft =\n\t\t\t\t\t\tnearestSide === 'left'\n\t\t\t\t\t\t\t? targetRect.left - 2\n\t\t\t\t\t\t\t: targetRect.right - 2;\n\t\t\t\t} else if ( isVertical ) {\n\t\t\t\t\t// vertical\n\t\t\t\t\ttop = previousRect ? previousRect.bottom : nextRect.top;\n\t\t\t\t\twidth = previousRect ? previousRect.width : nextRect.width;\n\t\t\t\t\theight =\n\t\t\t\t\t\tnextRect && previousRect\n\t\t\t\t\t\t\t? nextRect.top - previousRect.bottom\n\t\t\t\t\t\t\t: 0;\n\t\t\t\t\tleft = previousRect ? previousRect.left : nextRect.left;\n\t\t\t\t} else {\n\t\t\t\t\ttop = previousRect ? previousRect.top : nextRect.top;\n\t\t\t\t\theight = previousRect\n\t\t\t\t\t\t? previousRect.height\n\t\t\t\t\t\t: nextRect.height;\n\n\t\t\t\t\tif ( isRTL() ) {\n\t\t\t\t\t\t// non vertical, rtl\n\t\t\t\t\t\tleft = nextRect ? nextRect.right : previousRect.left;\n\t\t\t\t\t\twidth =\n\t\t\t\t\t\t\tpreviousRect && nextRect\n\t\t\t\t\t\t\t\t? previousRect.left - nextRect.right\n\t\t\t\t\t\t\t\t: 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// non vertical, ltr\n\t\t\t\t\t\tleft = previousRect\n\t\t\t\t\t\t\t? previousRect.right\n\t\t\t\t\t\t\t: nextRect.left;\n\t\t\t\t\t\twidth =\n\t\t\t\t\t\t\tpreviousRect && nextRect\n\t\t\t\t\t\t\t\t? nextRect.left - previousRect.right\n\t\t\t\t\t\t\t\t: 0;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Avoid a negative width which happens when the next rect\n\t\t\t\t\t// is on the next line.\n\t\t\t\t\twidth = Math.max( width, 0 );\n\t\t\t\t}\n\n\t\t\t\treturn new window.DOMRect( left, top, width, height );\n\t\t\t},\n\t\t};\n\t}, [\n\t\tpreviousElement,\n\t\tnextElement,\n\t\tpopoverRecomputeCounter,\n\t\tisVertical,\n\t\tisVisible,\n\t\toperation,\n\t\tnearestSide,\n\t] );\n\n\tconst popoverScrollRef = usePopoverScroll( __unstableContentRef );\n\n\t// This is only needed for a smooth transition when moving blocks.\n\t// When blocks are moved up/down, their position can be set by\n\t// updating the `transform` property manually (i.e. without using CSS\n\t// transitions or animations). The animation, which can also scroll the block\n\t// editor, can sometimes cause the position of the Popover to get out of sync.\n\t// A MutationObserver is therefore used to make sure that changes to the\n\t// selectedElement's attribute (i.e. `transform`) can be tracked and used to\n\t// trigger the Popover to rerender.\n\tuseLayoutEffect( () => {\n\t\tif ( ! previousElement ) {\n\t\t\treturn;\n\t\t}\n\t\tconst observer = new window.MutationObserver( forcePopoverRecompute );\n\t\tobserver.observe( previousElement, { attributes: true } );\n\n\t\treturn () => {\n\t\t\tobserver.disconnect();\n\t\t};\n\t}, [ previousElement ] );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! nextElement ) {\n\t\t\treturn;\n\t\t}\n\t\tconst observer = new window.MutationObserver( forcePopoverRecompute );\n\t\tobserver.observe( nextElement, { attributes: true } );\n\n\t\treturn () => {\n\t\t\tobserver.disconnect();\n\t\t};\n\t}, [ nextElement ] );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! previousElement ) {\n\t\t\treturn;\n\t\t}\n\t\tpreviousElement.ownerDocument.defaultView.addEventListener(\n\t\t\t'resize',\n\t\t\tforcePopoverRecompute\n\t\t);\n\t\treturn () => {\n\t\t\tpreviousElement.ownerDocument.defaultView?.removeEventListener(\n\t\t\t\t'resize',\n\t\t\t\tforcePopoverRecompute\n\t\t\t);\n\t\t};\n\t}, [ previousElement ] );\n\n\t// If there's either a previous or a next element, show the inbetween popover.\n\t// Note that drag and drop uses the inbetween popover to show the drop indicator\n\t// before the first block and after the last block.\n\tif ( ( ! previousElement && ! nextElement ) || ! isVisible ) {\n\t\treturn null;\n\t}\n\n\t// While ideally it would be enough to capture the\n\t// bubbling focus event from the Inserter, due to the\n\t// characteristics of click focusing of `button`s in\n\t// Firefox and Safari, it is not reliable.\n\t//\n\t// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus\n\treturn (\n\t\t<Popover\n\t\t\tref={ popoverScrollRef }\n\t\t\tanimate={ false }\n\t\t\tanchor={ popoverAnchor }\n\t\t\tfocusOnMount={ false }\n\t\t\t// Render in the old slot if needed for backward compatibility,\n\t\t\t// otherwise render in place (not in the default popover slot).\n\t\t\t__unstableSlotName={ __unstablePopoverSlot }\n\t\t\tinline={ ! __unstablePopoverSlot }\n\t\t\t// Forces a remount of the popover when its position changes\n\t\t\t// This makes sure the popover doesn't animate from its previous position.\n\t\t\tkey={ nextClientId + '--' + rootClientId }\n\t\t\t{ ...props }\n\t\t\tclassName={ clsx(\n\t\t\t\t'block-editor-block-popover',\n\t\t\t\t'block-editor-block-popover__inbetween',\n\t\t\t\tprops.className\n\t\t\t) }\n\t\t\tresize={ false }\n\t\t\tflip={ false }\n\t\t\tplacement=\"overlay\"\n\t\t\tvariant=\"unstyled\"\n\t\t>\n\t\t\t<div className=\"block-editor-block-popover__inbetween-container\">\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</Popover>\n\t);\n}\n\nexport default BlockPopoverInbetween;\n"],
"mappings": "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",
"names": []
}