Skip to content

Commit 7678e6e

Browse files
refactor: position 'move peaks' popup near cursor
refactor: improve actions popover positioning relative to cursor x/y close #3717
1 parent 76fdc89 commit 7678e6e

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

src/component/1d/peaks/PeakAnnotationsSpreadMode.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,12 @@ function PeakAnnotationsSpreadMode(props: PeakAnnotationsSpreadModeProps) {
116116
<ActionsButtonsPopover
117117
targetTagName="g"
118118
buttons={actionsButtons}
119-
positioningStrategy="fixed"
120-
position="top"
121119
direction="row"
122120
{...(isDragActive && { isOpen: true })}
123121
y={y}
122+
offsetY={-20}
123+
offsetXMode="cursor"
124+
autoFlip={false}
124125
>
125126
<g className="peaks">
126127
<g

src/component/elements/ActionsButtonsPopover.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ export interface ActionsButtonsPopoverProps
6363
offsetX?: number;
6464
offsetY?: number;
6565
offsetYMode?: 'fixed' | 'cursor';
66+
offsetXMode?: 'fixed' | 'cursor';
6667
x?: number;
6768
y?: number;
69+
autoFlip?: boolean;
6870
}
6971

7072
function ActionButton(props: ButtonProps) {
@@ -80,30 +82,37 @@ export function ActionsButtonsPopover(props: ActionsButtonsPopoverProps) {
8082
space,
8183
direction = 'column',
8284
contentStyle = {},
83-
offsetX = 0,
85+
offsetX: externalOffsetX = 0,
8486
offsetY: externalOffsetY = 0,
8587
x,
8688
y,
8789
offsetYMode = 'fixed',
90+
offsetXMode = 'fixed',
91+
autoFlip = true,
8892
...otherProps
8993
} = props;
9094

91-
const [cursorY, setCursorY] = useState(0);
95+
const [cursor, setCursor] = useState({ x: 0, y: 0 });
9296
const Wrapper = targetTagName as any;
9397

9498
const visibleButtons = buttons.filter(
9599
(button) => isSeparator(button) || button?.visible !== false,
96100
);
97101

98-
const offsetY = offsetYMode === 'fixed' ? externalOffsetY : cursorY;
102+
const offsetY = offsetYMode === 'fixed' ? externalOffsetY : cursor.y;
103+
const offsetX = offsetXMode === 'fixed' ? externalOffsetX : cursor.x;
99104

100105
function handleMouseEnter(event) {
101-
const { clientY, target } = event;
102-
if (!target || offsetYMode !== 'cursor') return;
103-
const targetElementRect = (target as HTMLElement)?.getBoundingClientRect();
104-
const y = clientY - targetElementRect.y;
105-
setCursorY(y);
106+
const { clientX, clientY, currentTarget } = event;
107+
if (!(currentTarget instanceof Element)) return;
108+
const rect = currentTarget.getBoundingClientRect();
109+
110+
setCursor((prev) => ({
111+
x: offsetXMode === 'cursor' ? clientX - rect.left : prev.x,
112+
y: offsetYMode === 'cursor' ? clientY - rect.top : prev.y,
113+
}));
106114
}
115+
107116
return (
108117
<Popover
109118
minimal
@@ -133,6 +142,8 @@ export function ActionsButtonsPopover(props: ActionsButtonsPopoverProps) {
133142
direction === 'column' ? [offsetY, offsetX] : [offsetX, offsetY],
134143
},
135144
},
145+
146+
flip: { enabled: autoFlip },
136147
}}
137148
content={
138149
<Container style={contentStyle} flexDirection={direction} gap={space}>

0 commit comments

Comments
 (0)