Files
payloadcms/packages/richtext-lexical/src/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.ts
Elliot DeNolf 9816787fbf chore: remove all unused imports (#7999)
Removes all unused imports.

Temporarily swapped in
https://github.com/sweepline/eslint-plugin-unused-imports to
differentiate between unused imports and unused vars. The default rule
does not differentiate.
2024-08-30 16:52:08 -04:00

147 lines
4.2 KiB
TypeScript

'use client'
import { getCollapsedMargins } from '../utils/getCollapsedMargins.js'
const TARGET_LINE_HALF_HEIGHT = 0
const TEXT_BOX_HORIZONTAL_PADDING = -24
const DEBUG = false
let animationTimer = 0
export function setTargetLine(
offsetWidth: string,
offsetLeft: number,
targetLineElem: HTMLElement,
targetBlockElem: HTMLElement,
lastTargetBlock: {
boundingBox?: DOMRect
elem: HTMLElement | null
isBelow: boolean
},
mouseY: number,
anchorElem: HTMLElement,
event: DragEvent,
debugHighlightRef: React.RefObject<HTMLDivElement | null>,
isFoundNodeEmptyParagraph: boolean = false,
) {
const { height: targetBlockElemHeight, top: targetBlockElemTop } =
targetBlockElem.getBoundingClientRect() // used to be getBoundingClientRectWithoutTransform. Not sure what's better, but the normal getBoundingClientRect seems to work fine
const { top: anchorTop, width: anchorWidth } = anchorElem.getBoundingClientRect()
const { marginBottom, marginTop } = getCollapsedMargins(targetBlockElem)
let lineTop = targetBlockElemTop
const isBelow = mouseY >= targetBlockElemTop + targetBlockElemHeight / 2 + window.scrollY
let willStayInSamePosition = false
/**
* Do not run any transform or changes if the actual new line position would be the same (even if it's now inserted BEFORE rather than AFTER - position would still be the same)
* This prevents unnecessary flickering.
*
* We still need to let it run even if the position (IGNORING the transform) would not change, as the transform animation is not finished yet. This is what animationTimer does. Otherwise, the positioning will be inaccurate
*/
if (lastTargetBlock?.elem) {
if (targetBlockElem !== lastTargetBlock?.elem) {
if (
isBelow &&
lastTargetBlock?.elem &&
lastTargetBlock?.elem === targetBlockElem.nextElementSibling
) {
animationTimer++
if (animationTimer < 200) {
willStayInSamePosition = true
}
} else if (
!isBelow &&
lastTargetBlock?.elem &&
lastTargetBlock?.elem === targetBlockElem.previousElementSibling
) {
animationTimer++
if (animationTimer < 200) {
willStayInSamePosition = true
}
}
} else {
animationTimer++
const lastBoundingBoxPosition = lastTargetBlock?.boundingBox?.y
const currentBoundingBoxPosition = targetBlockElem.getBoundingClientRect().y
if (
(isBelow === lastTargetBlock?.isBelow &&
lastBoundingBoxPosition === currentBoundingBoxPosition) ||
animationTimer < 200
) {
willStayInSamePosition = false
}
}
}
if (willStayInSamePosition) {
return {
isBelow,
willStayInSamePosition,
}
}
/**
* Paragraphs need no isBelow/above handling,
*/
if (!isFoundNodeEmptyParagraph) {
//if (!isFoundNodeEmptyParagraph) {
if (isBelow) {
// below targetBlockElem
lineTop += targetBlockElemHeight + marginBottom / 2
} else {
// above targetBlockElem
lineTop -= marginTop / 2
}
} else {
lineTop += targetBlockElemHeight / 2
}
let targetElemTranslate2 = 0
if (!isFoundNodeEmptyParagraph) {
if (isBelow) {
targetElemTranslate2 = -TARGET_LINE_HALF_HEIGHT
} else {
targetElemTranslate2 = TARGET_LINE_HALF_HEIGHT
}
}
const top = lineTop - anchorTop + targetElemTranslate2
const left = TEXT_BOX_HORIZONTAL_PADDING - offsetLeft
targetLineElem.style.width = `calc(${anchorWidth}px - ${offsetWidth})`
targetLineElem.style.opacity = '.8'
// if (DEBUG) {
// //targetBlockElem.style.border = '3px solid red'
// highlightElemOriginalPosition(debugHighlightRef, targetBlockElem, anchorElem)
// }
targetLineElem.style.transform = `translate(${left}px, calc(${top}px - ${'2px'}))`
/**
* Properly reset previous targetBlockElem styles
*/
lastTargetBlock.elem.style.opacity = ''
if (lastTargetBlock?.elem === targetBlockElem) {
if (isBelow) {
lastTargetBlock.elem.style.marginTop = ''
} else {
lastTargetBlock.elem.style.marginBottom = ''
}
} else {
lastTargetBlock.elem.style.marginBottom = ''
lastTargetBlock.elem.style.marginTop = ''
}
animationTimer = 0
return {
isBelow,
willStayInSamePosition,
}
}