From 97105cde4a41ece29eb1a56dd97a72e237f9d361 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Mon, 31 Oct 2022 11:57:39 +0800 Subject: [PATCH] Show nearest alignment zone label - Register zones into a slot when they mount - use `getDistanceToNearestEdge` to detect nearest zone to mouse pointer - Make Popover render behind the image and receive mouse events - Add CSS to only show highlighted zone --- .../block-alignment-visualizer/index.js | 75 +++++++++++++++++-- .../block-alignment-visualizer/style.scss | 13 +++- 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/block-alignment-visualizer/index.js b/packages/block-editor/src/components/block-alignment-visualizer/index.js index 49831ab14bfbc..89e74957ab564 100644 --- a/packages/block-editor/src/components/block-alignment-visualizer/index.js +++ b/packages/block-editor/src/components/block-alignment-visualizer/index.js @@ -8,7 +8,7 @@ import classnames from 'classnames'; */ import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks'; import { Popover } from '@wordpress/components'; -import { useRefEffect } from '@wordpress/compose'; +import { useMergeRefs, useRefEffect } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; import { createPortal, @@ -29,6 +29,31 @@ import { __unstableUseBlockElement as useBlockElement } from '../block-list/use- import useAvailableAlignments from '../block-alignment-control/use-available-alignments'; import { store as blockEditorStore } from '../../store'; import { getValidAlignments } from '../../hooks/align'; +import { getDistanceToNearestEdge } from '../../utils/math'; + +const highlightedZoneEdges = [ 'right' ]; +function detectNearestZone( mouseMoveEvent, zones ) { + const { clientX, clientY } = mouseMoveEvent; + const point = { x: clientX, y: clientY }; + + let candidateZone; + let candidateDistance; + + zones?.forEach( ( zone ) => { + const [ distance ] = getDistanceToNearestEdge( + point, + zone.node.getBoundingClientRect(), + highlightedZoneEdges + ); + + if ( ! candidateDistance || candidateDistance > distance ) { + candidateDistance = distance; + candidateZone = zone; + } + } ); + + return candidateZone; +} export default function BlockAlignmentVisualizer( { allowedAlignments, @@ -53,6 +78,8 @@ export default function BlockAlignmentVisualizer( { const [ popoverAnchor, setPopoverAnchor ] = useState( null ); const [ coverElementStyle, setCoverElementStyle ] = useState( null ); + const [ highlightedZone, setHighlightedZone ] = useState(); + const zones = useRef( new Set() ); const blockElement = useBlockElement( clientId ); const parentBlockElement = useBlockElement( parentClientId ); const rootBlockListElement = useContext( @@ -169,10 +196,18 @@ export default function BlockAlignmentVisualizer( { ref={ popoverRef } anchor={ popoverAnchor } placement="top-start" + className="block-editor__alignment-visualizer" animate={ false } focusOnMount={ false } flip={ false } resize={ false } + __unstableSlotName="" + onMouseMove={ ( event ) => { + const nearestZone = detectNearestZone( event, zones.current ); + if ( nearestZone.name !== highlightedZone ) { + setHighlightedZone( nearestZone.name ); + } + } } >