- Drag handle résout les blocs conteneurs (columns, toggle, callout) au lieu du paragraphe intérieur - Delete agit sur tout le bloc conteneur, pas juste le paragraphe - Menu popup (block action menu) clampé dans le viewport (Math.min + overflow auto) - Drag handle clamped dans le viewport via MutationObserver + scroll/resize
41 lines
1.6 KiB
TypeScript
41 lines
1.6 KiB
TypeScript
import type { Editor } from '@tiptap/core'
|
|
import type { Node as PMNode } from '@tiptap/pm/model'
|
|
|
|
export const BLOCK_DRAG_HANDLE_ID = 'notion-block-drag-handle'
|
|
export const BLOCK_DRAG_HANDLE_WIDTH = 20
|
|
|
|
/** Même logique de résolution de bloc que tiptap-extension-global-drag-handle */
|
|
export function resolveBlockAtDragHandle(editor: Editor): { node: PMNode; pos: number } | null {
|
|
const handle = document.getElementById(BLOCK_DRAG_HANDLE_ID)
|
|
if (!handle || editor.isDestroyed) return null
|
|
|
|
const rect = handle.getBoundingClientRect()
|
|
const coords = editor.view.posAtCoords({
|
|
left: rect.right + 50 + BLOCK_DRAG_HANDLE_WIDTH,
|
|
top: rect.top + rect.height / 2,
|
|
})
|
|
if (coords?.pos == null) return null
|
|
|
|
const $pos = editor.state.doc.resolve(coords.pos)
|
|
const blockPos = $pos.depth > 0 ? $pos.before($pos.depth) : coords.pos
|
|
const node = editor.state.doc.nodeAt(blockPos)
|
|
if (!node) return null
|
|
|
|
// Climb up to container blocks (columns, toggleBlock, calloutBlock)
|
|
// so the drag handle operates on the whole container, not inner paragraphs
|
|
const CONTAINER_TYPES = ['columns', 'toggleBlock', 'calloutBlock']
|
|
const $blockPos = editor.state.doc.resolve(blockPos)
|
|
for (let depth = $blockPos.depth; depth > 0; depth--) {
|
|
const ancestor = $blockPos.node(depth)
|
|
if (CONTAINER_TYPES.includes(ancestor.type.name)) {
|
|
const containerPos = $blockPos.before(depth)
|
|
const containerNode = editor.state.doc.nodeAt(containerPos)
|
|
if (containerNode) {
|
|
return { node: containerNode, pos: containerPos }
|
|
}
|
|
}
|
|
}
|
|
|
|
return { node, pos: blockPos }
|
|
}
|