Skip to content

Commit

Permalink
Show nearest alignment zone label
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
talldan committed Oct 31, 2022
1 parent 4984b82 commit 97105cd
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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(
Expand Down Expand Up @@ -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 );
}
} }
>
<Iframe
style={ coverElementStyle }
Expand All @@ -196,7 +231,6 @@ export default function BlockAlignmentVisualizer( {
right: 0;
bottom: 0;
left: 0;
pointer-events: none !important;
background-color: var(--contrast-color);
opacity: 0.1;
}
Expand All @@ -210,7 +244,6 @@ export default function BlockAlignmentVisualizer( {
}
.block-editor__alignment-visualizer-zone-inner {
pointer-events: none !important;
height: 100%;
max-width: 100%;
margin: 0 auto;
Expand All @@ -233,6 +266,11 @@ export default function BlockAlignmentVisualizer( {
alignment={ alignment }
justification={ layout.justifyContent }
color={ contrastColor }
isHighlighted={ alignment.name === highlightedZone }
addZone={ ( zone ) => zones.current.add( zone ) }
removeZone={ ( zone ) =>
zones.current.delete( zone )
}
/>
) ) }
</body>
Expand All @@ -241,8 +279,30 @@ export default function BlockAlignmentVisualizer( {
);
}

function BlockAlignmentVisualizerZone( { alignment, justification, color } ) {
function BlockAlignmentVisualizerZone( {
alignment,
justification,
color,
isHighlighted,
addZone,
removeZone,
} ) {
const [ popoverAnchor, setPopoverAnchor ] = useState( null );
const { name } = alignment;

const updateZonesRef = useRefEffect(
( node ) => {
const zone = {
name,
node,
};
addZone( zone );
return () => removeZone( zone );
},
[ name ]
);

const zoneInnerRefs = useMergeRefs( [ updateZonesRef, setPopoverAnchor ] );

return (
<>
Expand All @@ -260,7 +320,7 @@ function BlockAlignmentVisualizerZone( { alignment, justification, color } ) {
'block-editor__alignment-visualizer-zone-inner',
alignment.className
) }
ref={ setPopoverAnchor }
ref={ zoneInnerRefs }
/>
</div>
<Popover
Expand All @@ -271,7 +331,10 @@ function BlockAlignmentVisualizerZone( { alignment, justification, color } ) {
flip
>
<div
className="block-editor__alignment-visualizer-zone-label"
className={ classnames(
'block-editor__alignment-visualizer-zone-label',
{ 'is-highlighted': isHighlighted }
) }
style={ { color } }
>
{ alignment.label }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@

.block-editor__alignment-visualizer {
z-index: 0;
}

.block-editor__alignment-visualizer-iframe {
pointer-events: none;
overflow: hidden;
}

Expand All @@ -9,5 +13,10 @@
text-transform: uppercase;
white-space: nowrap;
margin: $grid-unit-05 0;
opacity: 0.7;
opacity: 0;
transition: opacity 0.1s linear;

&.is-highlighted {
opacity: 0.7;
}
}

0 comments on commit 97105cd

Please sign in to comment.