fix: drag handle resolve container blocks + menu popup clamp viewport
- 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
This commit is contained in:
@@ -322,8 +322,10 @@ export function BlockActionMenu({
|
||||
const menuStyle: React.CSSProperties = {
|
||||
position: 'fixed',
|
||||
left: menuLeft > window.innerWidth - 230 ? anchorRect.left - 215 : menuLeft,
|
||||
top: menuTop + 320 > window.innerHeight ? window.innerHeight - 330 : menuTop,
|
||||
top: Math.max(10, Math.min(menuTop, window.innerHeight - 620)),
|
||||
zIndex: 9999,
|
||||
maxHeight: window.innerHeight - 20,
|
||||
overflowY: 'auto',
|
||||
}
|
||||
|
||||
return createPortal(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* Poignée drag globale (Novel / tiptap-extension-global-drag-handle).
|
||||
* L’extension TipTap positionne cet élément ; le clic ouvre le menu bloc.
|
||||
* L'extension TipTap positionne cet élément ; le clic ouvre le menu bloc.
|
||||
*/
|
||||
import { memo, useEffect, useRef } from 'react'
|
||||
import type { Editor } from '@tiptap/core'
|
||||
@@ -46,14 +46,37 @@ export const EditorBlockDragHandle = memo(function EditorBlockDragHandle({
|
||||
onOpenMenuRef.current(el.getBoundingClientRect())
|
||||
}
|
||||
|
||||
const clampPosition = () => {
|
||||
if (el.classList.contains('hide') || el.style.display === 'none') return
|
||||
const rect = el.getBoundingClientRect()
|
||||
if (rect.height === 0) return
|
||||
const overshootBottom = rect.bottom - window.innerHeight + 10
|
||||
const overshootTop = 10 - rect.top
|
||||
if (overshootBottom > 0) {
|
||||
const currentTop = parseFloat(el.style.top) || 0
|
||||
el.style.top = `${currentTop - overshootBottom}px`
|
||||
} else if (overshootTop > 0) {
|
||||
const currentTop = parseFloat(el.style.top) || 0
|
||||
el.style.top = `${currentTop + overshootTop}px`
|
||||
}
|
||||
}
|
||||
|
||||
el.addEventListener('pointerdown', onPointerDown)
|
||||
el.addEventListener('dragstart', onDragStart)
|
||||
el.addEventListener('click', onClick)
|
||||
|
||||
const observer = new MutationObserver(clampPosition)
|
||||
observer.observe(el, { attributes: true, attributeFilter: ['style'] })
|
||||
window.addEventListener('scroll', clampPosition, { passive: true })
|
||||
window.addEventListener('resize', clampPosition)
|
||||
|
||||
return () => {
|
||||
el.removeEventListener('pointerdown', onPointerDown)
|
||||
el.removeEventListener('dragstart', onDragStart)
|
||||
el.removeEventListener('click', onClick)
|
||||
observer.disconnect()
|
||||
window.removeEventListener('scroll', clampPosition)
|
||||
window.removeEventListener('resize', clampPosition)
|
||||
}
|
||||
}, [editor])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user