From e9be5051b5c99e522fb6efd028d425220b171890 Mon Sep 17 00:00:00 2001 From: Clauderic Demers Date: Thu, 11 Jul 2024 08:28:37 -0400 Subject: [PATCH] Fix local modifiers --- .changeset/fix-local-modifiers.md | 5 +++ .../src/core/entities/draggable/draggable.ts | 28 ++-------------- .../src/core/manager/dragOperation.ts | 32 +++++++++++++++++-- 3 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 .changeset/fix-local-modifiers.md diff --git a/.changeset/fix-local-modifiers.md b/.changeset/fix-local-modifiers.md new file mode 100644 index 00000000..0c4a16a9 --- /dev/null +++ b/.changeset/fix-local-modifiers.md @@ -0,0 +1,5 @@ +--- +'@dnd-kit/abstract': patch +--- + +Fix lifecycle of local modifiers now that it's possible to initialize a Draggable instance without a manager instance. diff --git a/packages/abstract/src/core/entities/draggable/draggable.ts b/packages/abstract/src/core/entities/draggable/draggable.ts index fd159ed4..01b83e2c 100644 --- a/packages/abstract/src/core/entities/draggable/draggable.ts +++ b/packages/abstract/src/core/entities/draggable/draggable.ts @@ -2,10 +2,8 @@ import {derived, reactive} from '@dnd-kit/state'; import {Entity} from '../entity/index.ts'; import type {EntityInput, Data, Type} from '../entity/index.ts'; -import {Modifier} from '../../modifiers/index.ts'; import type {Modifiers} from '../../modifiers/index.ts'; import type {DragDropManager} from '../../manager/index.ts'; -import {descriptor} from '../../plugins/index.ts'; import type {Sensors} from '../../sensors/sensor.ts'; export interface Input extends EntityInput { @@ -33,24 +31,8 @@ export class Draggable< public sensors: Sensors | undefined; - #modifiers: Modifier[] | undefined; - - public set modifiers(modifiers: Modifiers | undefined) { - const {manager} = this; - - this.#modifiers?.forEach((modifier) => modifier.destroy()); - - if (!manager) return; - this.#modifiers = modifiers?.map((modifier) => { - const {plugin, options} = descriptor(modifier); - - return new plugin(manager, options); - }); - } - - public get modifiers(): Modifier[] | undefined { - return this.#modifiers; - } + @reactive + public accessor modifiers: Modifiers | undefined; @reactive public accessor type: Type | undefined; @@ -65,10 +47,4 @@ export class Draggable< public get isDragSource() { return this.manager?.dragOperation.source?.id === this.id; } - - public destroy() { - super.destroy(); - - this.modifiers?.forEach((modifier) => modifier.destroy()); - } } diff --git a/packages/abstract/src/core/manager/dragOperation.ts b/packages/abstract/src/core/manager/dragOperation.ts index 9f03fb29..f6bf7326 100644 --- a/packages/abstract/src/core/manager/dragOperation.ts +++ b/packages/abstract/src/core/manager/dragOperation.ts @@ -1,12 +1,14 @@ import {Position, type Shape} from '@dnd-kit/geometry'; import type {Coordinates} from '@dnd-kit/geometry'; -import {batch, computed, signal} from '@dnd-kit/state'; +import {batch, computed, effect, signal} from '@dnd-kit/state'; import type { Draggable, Droppable, UniqueIdentifier, } from '../entities/index.ts'; +import type {Modifier} from '../modifiers/index.ts'; +import {descriptor} from '../plugins/index.ts'; import type {DragDropManager} from './manager.ts'; import {defaultPreventable} from './events.ts'; @@ -100,9 +102,24 @@ export function DragOperationManager< return identifier != null ? droppables.get(identifier) ?? null : null; }); + const modifiers = signal([]); + + effect(() => { + const currentModifiers = modifiers.peek(); + + if (currentModifiers !== manager.modifiers) { + currentModifiers.forEach((modifier) => modifier.destroy()); + } + + modifiers.value = + source.value?.modifiers?.map((modifier) => { + const {plugin, options} = descriptor(modifier); + return new plugin(manager, options); + }) ?? manager.modifiers; + }); + const transform = computed(() => { const {x, y} = position.delta; - const modifiers = source?.value?.modifiers ?? manager.modifiers; let transform = {x, y}; const initialShape = shape.initial.peek(); @@ -128,7 +145,7 @@ export function DragOperationManager< position, }; - for (const modifier of modifiers) { + for (const modifier of modifiers.value) { transform = modifier.apply({...operation, transform}); } @@ -204,6 +221,7 @@ export function DragOperationManager< shape.current.value = null; shape.initial.value = null; position.reset({x: 0, y: 0}); + modifiers.value = []; }); }; @@ -236,6 +254,14 @@ export function DragOperationManager< return manager.renderer.rendering; }, start({event, coordinates}: {event: Event; coordinates: Coordinates}) { + const sourceInstance = source.peek(); + + if (!sourceInstance) { + throw new Error( + 'Cannot start a drag operation without a drag source' + ); + } + batch(() => { dragended.value = false; canceled.value = false;