import type { Position, BoxModel, Rect } from 'css-box-model'; import { patch } from '../position'; import type { Axis } from '../../types'; interface Args { axis: Axis; moveRelativeTo: BoxModel; isMoving: BoxModel; } const distanceFromStartToBorderBoxCenter = ( axis: Axis, box: BoxModel, ): number => box.margin[axis.start] + box.borderBox[axis.size] / 2; const distanceFromEndToBorderBoxCenter = (axis: Axis, box: BoxModel): number => box.margin[axis.end] + box.borderBox[axis.size] / 2; // We align the moving item against the cross axis start of the target // We used to align the moving item cross axis center with the cross axis center of the target. // However, this leads to a bad experience when reordering columns const getCrossAxisBorderBoxCenter = ( axis: Axis, target: Rect, isMoving: BoxModel, ): number => target[axis.crossAxisStart] + isMoving.margin[axis.crossAxisStart] + isMoving.borderBox[axis.crossAxisSize] / 2; export const goAfter = ({ axis, moveRelativeTo, isMoving }: Args): Position => patch( axis.line, // start measuring from the end of the target moveRelativeTo.marginBox[axis.end] + distanceFromStartToBorderBoxCenter(axis, isMoving), getCrossAxisBorderBoxCenter(axis, moveRelativeTo.marginBox, isMoving), ); export const goBefore = ({ axis, moveRelativeTo, isMoving }: Args): Position => patch( axis.line, // start measuring from the start of the target moveRelativeTo.marginBox[axis.start] - distanceFromEndToBorderBoxCenter(axis, isMoving), getCrossAxisBorderBoxCenter(axis, moveRelativeTo.marginBox, isMoving), ); interface GoIntoArgs { axis: Axis; moveInto: BoxModel; isMoving: BoxModel; } // moves into the content box export const goIntoStart = ({ axis, moveInto, isMoving, }: GoIntoArgs): Position => patch( axis.line, moveInto.contentBox[axis.start] + distanceFromStartToBorderBoxCenter(axis, isMoving), getCrossAxisBorderBoxCenter(axis, moveInto.contentBox, isMoving), );