33 lines
1.0 KiB
TypeScript
33 lines
1.0 KiB
TypeScript
import type { Editor } from "@tiptap/react"
|
|
|
|
/** Focus editor at viewport coords; clamp to prose bounds when click is on padding. */
|
|
export function focusEditorAtPointer(
|
|
editor: Editor,
|
|
clientX: number,
|
|
clientY: number
|
|
): void {
|
|
if (editor.isDestroyed || !editor.isInitialized) return
|
|
|
|
const direct = editor.view.posAtCoords({ left: clientX, top: clientY })
|
|
if (direct) {
|
|
editor.chain().focus().setTextSelection(direct.pos).run()
|
|
return
|
|
}
|
|
|
|
const rect = editor.view.dom.getBoundingClientRect()
|
|
if (rect.width <= 0 || rect.height <= 0) {
|
|
editor.chain().focus("end").run()
|
|
return
|
|
}
|
|
|
|
const clampedLeft = Math.min(Math.max(clientX, rect.left + 1), rect.right - 1)
|
|
const clampedTop = Math.min(Math.max(clientY, rect.top + 1), rect.bottom - 1)
|
|
const clamped = editor.view.posAtCoords({ left: clampedLeft, top: clampedTop })
|
|
if (clamped) {
|
|
editor.chain().focus().setTextSelection(clamped.pos).run()
|
|
return
|
|
}
|
|
|
|
editor.chain().focus(clientY < rect.top + rect.height / 2 ? "start" : "end").run()
|
|
}
|