diff --git a/app/editor/components/SuggestionsMenu.tsx b/app/editor/components/SuggestionsMenu.tsx index 5e1a7d5cc..7eef5d1c4 100644 --- a/app/editor/components/SuggestionsMenu.tsx +++ b/app/editor/components/SuggestionsMenu.tsx @@ -78,6 +78,10 @@ function SuggestionsMenu(props: Props) { const { view, commands } = useEditor(); const dictionary = useDictionary(); const hasActivated = React.useRef(false); + const pointerRef = React.useRef<{ clientX: number; clientY: number }>({ + clientX: 0, + clientY: 0, + }); const menuRef = React.useRef(null); const inputRef = React.useRef(null); const [position, setPosition] = React.useState(defaultPosition); @@ -576,7 +580,23 @@ function SuggestionsMenu(props: Props) { return null; } - const handlePointer = () => { + const handlePointerMove = (ev: React.PointerEvent) => { + if ( + selectedIndex !== index && + // Safari triggers pointermove with identical coordinates when the pointer has not moved. + // This causes the menu selection to flicker when the pointer is over the menu but not moving. + (pointerRef.current.clientX !== ev.clientX || + pointerRef.current.clientY !== ev.clientY) + ) { + setSelectedIndex(index); + } + pointerRef.current = { + clientX: ev.clientX, + clientY: ev.clientY, + }; + }; + + const handlePointerDown = () => { if (selectedIndex !== index) { setSelectedIndex(index); } @@ -585,8 +605,8 @@ function SuggestionsMenu(props: Props) { return ( {props.renderMenuItem(item as any, index, { selected: index === selectedIndex,