File size: 1,832 Bytes
fc414a2 32849cc 759cc6f 71ff5df fc414a2 71ff5df fc414a2 71ff5df fc414a2 71ff5df fc414a2 71ff5df fc414a2 71ff5df fc414a2 71ff5df fc414a2 71ff5df fc414a2 32849cc 71ff5df 32849cc 71ff5df 32849cc 71ff5df 32849cc 71ff5df 32849cc fc414a2 32849cc 71ff5df 32849cc fc414a2 71ff5df fc414a2 71ff5df fc414a2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 'use client'
import { useState } from 'react'
import type React from 'react'
import { isTextNode } from '@/hooks/useCurrentPage'
import type { PointerToDocumentFn } from '@/hooks/usePointerToDocument'
import type { Page } from '@/lib/api/schemas'
type BlockContextMenuOptions = {
page: Page | null
pointerToDocument: PointerToDocumentFn
onSelect: (nodeId: string | null) => void
onRemove: (nodeId: string) => void
}
/**
* Right-click on a text node pops the context menu. `onSelect(null)` / clear
* on empty-space right-click. `onRemove(id)` triggered by menu's delete item.
*/
export function useBlockContextMenu({
page,
pointerToDocument,
onSelect,
onRemove,
}: BlockContextMenuOptions) {
const [contextMenuNodeId, setContextMenuNodeId] = useState<string | null>(null)
const handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
if (!page) return
const point = pointerToDocument(event)
if (!point) {
event.preventDefault()
setContextMenuNodeId(null)
onSelect(null)
return
}
const hitId = Object.entries(page.nodes).find(([, n]) => {
if (!isTextNode(n)) return false
const t = n.transform
if (!t) return false
return (
point.x >= t.x && point.x <= t.x + t.width && point.y >= t.y && point.y <= t.y + t.height
)
})?.[0]
if (hitId) {
onSelect(hitId)
setContextMenuNodeId(hitId)
} else {
event.preventDefault()
setContextMenuNodeId(null)
onSelect(null)
}
}
const handleDeleteBlock = () => {
if (!contextMenuNodeId) return
onRemove(contextMenuNodeId)
setContextMenuNodeId(null)
}
const clearContextMenu = () => setContextMenuNodeId(null)
return {
contextMenuNodeId,
handleContextMenu,
handleDeleteBlock,
clearContextMenu,
}
}
|