diff --git a/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx b/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx index aa3836d7d1..4ecb885bc3 100644 --- a/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx +++ b/src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx @@ -116,11 +116,12 @@ function PeakAnnotationsSpreadMode(props: PeakAnnotationsSpreadModeProps) { {showSignals && ( - - - { - assignment?.highlight(); - highlight.show(); - }} - onMouseLeave={() => { - assignment?.clearHighlight(); - highlight.hide(); - }} - key={signal.id} - cx={scaleX(signal.x.delta || 0)} - cy={scaleY(signal.y.delta || 0)} - r={isHighlighted ? 6 : 4} - fill={isHighlighted ? 'green' : 'darkgreen'} - /> - + { + assignment?.highlight(); + highlight.show(); + }} + onMouseLeave={() => { + assignment?.clearHighlight(); + highlight.hide(); + }} + key={signal.id} + cx={scaleX(signal.x.delta || 0)} + cy={scaleY(signal.y.delta || 0)} + r={isHighlighted ? 6 : 4} + fill={isHighlighted ? 'green' : 'darkgreen'} + /> )} {showPeaks && diff --git a/src/component/2d/zones/SignalCrosshair.tsx b/src/component/2d/zones/SignalCrosshair.tsx index d61425518e..34b6c2611d 100644 --- a/src/component/2d/zones/SignalCrosshair.tsx +++ b/src/component/2d/zones/SignalCrosshair.tsx @@ -9,7 +9,7 @@ interface SignalCrosshairProps { signal: Signal2D; } -function SignalCrosshair({ signal }: SignalCrosshairProps) { +export function SignalCrosshair({ signal }: SignalCrosshairProps) { const highlightIDsX = useMemo(() => { return [buildID(signal.id, 'Crosshair'), buildID(signal.id, 'Crosshair_X')]; }, [signal.id]); @@ -39,5 +39,3 @@ function SignalCrosshair({ signal }: SignalCrosshairProps) { ); } - -export default SignalCrosshair; diff --git a/src/component/2d/zones/Zone.tsx b/src/component/2d/zones/Zone.tsx index b08b181eb2..ccd1760b72 100644 --- a/src/component/2d/zones/Zone.tsx +++ b/src/component/2d/zones/Zone.tsx @@ -12,6 +12,7 @@ import { useActiveSpectrumZonesViewState } from '../../hooks/useActiveSpectrumZo import { useScale2DX, useScale2DY } from '../utilities/scale.js'; import Signal from './Signal.js'; +import { SignalCrosshair } from './SignalCrosshair.tsx'; interface ZoneProps { zoneData: ZoneType; @@ -54,21 +55,25 @@ function Zone({ zoneData }: ZoneProps) { ]; return ( - { + assignmentZone.highlight(); + highlightZone.show(); + }} + onMouseLeave={() => { + assignmentZone.clearHighlight(); + highlightZone.hide(); + }} > - { - assignmentZone.highlight(); - highlightZone.show(); - }} - onMouseLeave={() => { - assignmentZone.clearHighlight(); - highlightZone.hide(); - }} + {signals.map((signal) => ( + + ))} + + {showZones && ( @@ -87,8 +92,8 @@ function Zone({ zoneData }: ZoneProps) { // eslint-disable-next-line react/no-array-index-key ))} - - + + ); } diff --git a/src/component/elements/ActionsButtonsPopover.tsx b/src/component/elements/ActionsButtonsPopover.tsx index 7835016764..8c13e090bb 100644 --- a/src/component/elements/ActionsButtonsPopover.tsx +++ b/src/component/elements/ActionsButtonsPopover.tsx @@ -63,8 +63,10 @@ export interface ActionsButtonsPopoverProps offsetX?: number; offsetY?: number; offsetYMode?: 'fixed' | 'cursor'; + offsetXMode?: 'fixed' | 'cursor'; x?: number; y?: number; + autoFlip?: boolean; } function ActionButton(props: ButtonProps) { @@ -80,30 +82,37 @@ export function ActionsButtonsPopover(props: ActionsButtonsPopoverProps) { space, direction = 'column', contentStyle = {}, - offsetX = 0, + offsetX: externalOffsetX = 0, offsetY: externalOffsetY = 0, x, y, offsetYMode = 'fixed', + offsetXMode = 'fixed', + autoFlip = true, ...otherProps } = props; - const [cursorY, setCursorY] = useState(0); + const [cursor, setCursor] = useState({ x: 0, y: 0 }); const Wrapper = targetTagName as any; const visibleButtons = buttons.filter( (button) => isSeparator(button) || button?.visible !== false, ); - const offsetY = offsetYMode === 'fixed' ? externalOffsetY : cursorY; + const offsetY = offsetYMode === 'fixed' ? externalOffsetY : cursor.y; + const offsetX = offsetXMode === 'fixed' ? externalOffsetX : cursor.x; function handleMouseEnter(event) { - const { clientY, target } = event; - if (!target || offsetYMode !== 'cursor') return; - const targetElementRect = (target as HTMLElement)?.getBoundingClientRect(); - const y = clientY - targetElementRect.y; - setCursorY(y); + const { clientX, clientY, currentTarget } = event; + if (!(currentTarget instanceof Element)) return; + const rect = currentTarget.getBoundingClientRect(); + + setCursor((prev) => ({ + x: offsetXMode === 'cursor' ? clientX - rect.left : prev.x, + y: offsetYMode === 'cursor' ? clientY - rect.top : prev.y, + })); } + return (