fix: Refactor hover previews to reduce false positives (#6091)
This commit is contained in:
64
shared/editor/extensions/HoverPreviews.ts
Normal file
64
shared/editor/extensions/HoverPreviews.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Plugin } from "prosemirror-state";
|
||||
import { EditorView } from "prosemirror-view";
|
||||
import Extension from "../lib/Extension";
|
||||
|
||||
interface HoverPreviewsOptions {
|
||||
/** Callback when a hover target is found or lost. */
|
||||
onHoverLink?: (target: Element | null) => void;
|
||||
|
||||
/** Delay before the target is considered "hovered" and callback is triggered. */
|
||||
delay: number;
|
||||
}
|
||||
|
||||
export default class HoverPreviews extends Extension {
|
||||
get defaultOptions(): HoverPreviewsOptions {
|
||||
return {
|
||||
delay: 500,
|
||||
};
|
||||
}
|
||||
|
||||
get name() {
|
||||
return "hover-previews";
|
||||
}
|
||||
|
||||
get plugins() {
|
||||
const isHoverTarget = (target: Element | null, view: EditorView) =>
|
||||
target instanceof HTMLElement &&
|
||||
this.editor.elementRef.current?.contains(target) &&
|
||||
(!view.editable || (view.editable && !view.hasFocus()));
|
||||
|
||||
let hoveringTimeout: ReturnType<typeof setTimeout>;
|
||||
|
||||
return [
|
||||
new Plugin({
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
mouseover: (view: EditorView, event: MouseEvent) => {
|
||||
const target = (event.target as HTMLElement)?.closest(
|
||||
".use-hover-preview"
|
||||
);
|
||||
if (isHoverTarget(target, view)) {
|
||||
if (this.options.onHoverLink) {
|
||||
hoveringTimeout = setTimeout(() => {
|
||||
this.options.onHoverLink?.(target);
|
||||
}, this.options.delay);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
mouseout: (view: EditorView, event: MouseEvent) => {
|
||||
const target = (event.target as HTMLElement)?.closest(
|
||||
".use-hover-preview"
|
||||
);
|
||||
if (isHoverTarget(target, view)) {
|
||||
clearTimeout(hoveringTimeout);
|
||||
this.options.onHoverLink?.(null);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user