import type { Modifier } from '@dnd-kit/core' import { getEventCoordinates } from '@dnd-kit/utilities' import { spacing } from '@planview/pv-utilities' import type { UseGridReturn } from '../../hooks' import { rubberBandIfOutOfBounds } from './column/utils' export const modifiersFactory = (grid: UseGridReturn) => { /* Adapted from @dnd-kit/modifiers */ const snapCenterToCursor: Modifier = ({ activatorEvent, draggingNodeRect, transform, }) => { const rowHeight = grid.selectors.selectRowHeight(grid.getState()) if (draggingNodeRect && activatorEvent) { const activatorCoordinates = getEventCoordinates(activatorEvent) if (!activatorCoordinates) { return transform } const offsetX = activatorCoordinates.x - draggingNodeRect.left const offsetY = activatorCoordinates.y - draggingNodeRect.top const halfRowHeight = rowHeight / 2 return { ...transform, x: transform.x + offsetX - spacing.xsmall, y: transform.y + offsetY - halfRowHeight, } } return transform } const restrictToHorizontalAxis: Modifier = ({ active, transform }) => ({ ...transform, y: -(active?.data.current?.offsetY ?? 0), }) const rubberBand = (minLeft: number, maxLeft: number): Modifier => ({ transform }) => { const modifiedX = rubberBandIfOutOfBounds( transform.x, minLeft, maxLeft ) return { ...transform, x: modifiedX, } } return { snapCenterToCursor, restrictToHorizontalAxis, rubberBand } }