diff --git a/apps/stories/stories/react/Draggable/Modifiers/Modifiers.stories.tsx b/apps/stories/stories/react/Draggable/Modifiers/Modifiers.stories.tsx index 78c53502f..995e510bd 100644 --- a/apps/stories/stories/react/Draggable/Modifiers/Modifiers.stories.tsx +++ b/apps/stories/stories/react/Draggable/Modifiers/Modifiers.stories.tsx @@ -1,13 +1,13 @@ -import type {Meta, StoryObj} from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { RestrictToHorizontalAxis, RestrictToVerticalAxis, } from '@dnd-kit/abstract/modifiers'; -import {RestrictToElement, RestrictToWindow} from '@dnd-kit/dom/modifiers'; +import { RestrictToElement, RestrictToWindow, SnapCenterToCursor } from '@dnd-kit/dom/modifiers'; import docs from './docs/ModifierDocs.mdx'; -import {DraggableExample} from '../DraggableExample'; -import {SnapToGridExample} from './SnapToGridExample'; +import { DraggableExample } from '../DraggableExample'; +import { SnapToGridExample } from './SnapToGridExample'; import styles from './styles.module.css'; const meta: Meta = { @@ -48,7 +48,7 @@ export const WindowModifier: Story = { export const ContainerModifier: Story = { name: 'Restrict to container', args: { - container({children}) { + container({ children }) { return (
{children} @@ -69,3 +69,10 @@ export const SnapModifierExample: Story = { name: 'Snap to grid', render: SnapToGridExample, }; + +export const SnapToCursor: Story = { + name: 'Snap to cursor', + args: { + modifiers: [SnapCenterToCursor], + }, +}; \ No newline at end of file diff --git a/packages/abstract/src/modifiers/index.ts b/packages/abstract/src/modifiers/index.ts index d07c36c96..62306aaf4 100644 --- a/packages/abstract/src/modifiers/index.ts +++ b/packages/abstract/src/modifiers/index.ts @@ -4,6 +4,6 @@ export { RestrictToVerticalAxis, } from './axis.ts'; -export {restrictShapeToBoundingRectangle} from './boundingRectangle.ts'; +export { restrictShapeToBoundingRectangle } from './boundingRectangle.ts'; -export {SnapModifier} from './snap.ts'; +export { SnapModifier, SnapCenterToCursor } from './snap.ts'; diff --git a/packages/abstract/src/modifiers/snap.ts b/packages/abstract/src/modifiers/snap.ts index fa5340793..3f5711b71 100644 --- a/packages/abstract/src/modifiers/snap.ts +++ b/packages/abstract/src/modifiers/snap.ts @@ -8,15 +8,15 @@ import { } from '@dnd-kit/abstract'; interface Options { - size: number | {x: number; y: number}; + size: number | { x: number; y: number }; } export class SnapModifier extends Modifier< DragDropManager, Options > { - apply({transform}: DragOperation) { - const {size = 20} = this.options ?? {}; + apply({ transform }: DragOperation) { + const { size = 20 } = this.options ?? {}; const x = typeof size === 'number' ? size : size.x; const y = typeof size === 'number' ? size : size.y; @@ -29,3 +29,26 @@ export class SnapModifier extends Modifier< static configure = configurator(SnapModifier); } + +export class SnapCenterToCursor extends Modifier< + DragDropManager +> { + apply({ shape, position, transform }: DragOperation) { + if (!position.initial || !shape) { + return transform; + } + + const { initial, current } = shape; + const { left, top } = initial.boundingRectangle; + const { height, width } = current.boundingRectangle; + + const offsetX = position.initial.x - left; + const offsetY = position.initial.y - top; + + return { + ...transform, + x: transform.x + offsetX - width / 2, + y: transform.y + offsetY - height / 2, + }; + } +} diff --git a/packages/dom/src/modifiers/index.ts b/packages/dom/src/modifiers/index.ts index aca5e8a13..53969e2d6 100644 --- a/packages/dom/src/modifiers/index.ts +++ b/packages/dom/src/modifiers/index.ts @@ -1,2 +1,2 @@ -export {RestrictToWindow} from './RestrictToWindow.ts'; -export {RestrictToElement} from './RestrictToElement.ts'; +export { RestrictToWindow } from './RestrictToWindow.ts'; +export { RestrictToElement } from './RestrictToElement.ts';