Skip to content

Commit

Permalink
Lifecycle tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
clauderic committed Jun 22, 2024
1 parent 1554df0 commit 71f169a
Show file tree
Hide file tree
Showing 22 changed files with 118 additions and 71 deletions.
2 changes: 1 addition & 1 deletion packages/abstract/src/core/collision/notifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {CorePlugin} from '../plugins/index.ts';
import {defaultPreventable} from '../manager/events.ts';

export class CollisionNotifier extends CorePlugin {
constructor(manager: DragDropManager) {
constructor(manager: DragDropManager<any, any>) {
super(manager);

this.destroy = effect(() => {
Expand Down
7 changes: 5 additions & 2 deletions packages/abstract/src/core/entities/draggable/draggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ export interface Input<T extends Data = Data> extends EntityInput<T> {

export type DraggableStatus = 'idle' | 'dragging' | 'dropping';

export class Draggable<T extends Data = Data> extends Entity<T> {
export class Draggable<
T extends Data = Data,
U extends DragDropManager<any, any> = DragDropManager<any, any>,
> extends Entity<T> {
constructor(
{modifiers, type, sensors, ...input}: Input<T>,
manager: DragDropManager | undefined
manager: U | undefined
) {
super(input, manager);

Expand Down
7 changes: 5 additions & 2 deletions packages/abstract/src/core/entities/droppable/droppable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export interface Input<T extends Data = Data> extends EntityInput<T> {
type?: Type;
}

export class Droppable<T extends Data = Data> extends Entity<T> {
export class Droppable<
T extends Data = Data,
U extends DragDropManager<any, any> = DragDropManager<any, any>,
> extends Entity<T> {
constructor(
{
accept,
Expand All @@ -26,7 +29,7 @@ export class Droppable<T extends Data = Data> extends Entity<T> {
type,
...input
}: Input<T>,
manager: DragDropManager | undefined
manager: U | undefined
) {
super(input, manager);

Expand Down
27 changes: 23 additions & 4 deletions packages/abstract/src/core/entities/entity/entity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {reactive, type Effect} from '@dnd-kit/state';
import {CleanupFunction, reactive, type Effect} from '@dnd-kit/state';

import {DragDropManager} from '../../manager/index.ts';
import type {Data, UniqueIdentifier} from './types.ts';
Expand All @@ -16,14 +16,17 @@ export interface Input<T extends Data = Data> {
*
* @template T - The type of data associated with the entity.
*/
export class Entity<T extends Data = Data> {
export class Entity<
T extends Data = Data,
U extends DragDropManager<any, any> = DragDropManager<any, any>,
> {
/**
* Creates a new instance of the `Entity` class.
*
* @param input - An object containing the initial properties of the entity.
* @param manager - The manager that controls the drag and drop operations.
*/
constructor(input: Input<T>, manager: DragDropManager | undefined) {
constructor(input: Input<T>, manager: U | undefined) {
const {effects, id, data = {}, disabled = false} = input;

let previousId = id;
Expand Down Expand Up @@ -60,7 +63,7 @@ export class Entity<T extends Data = Data> {
* The manager that controls the drag and drop operations.
*/
@reactive
public accessor manager: DragDropManager | undefined;
public accessor manager: U | undefined;

/**
* The unique identifier of the entity.
Expand All @@ -85,6 +88,22 @@ export class Entity<T extends Data = Data> {
*/
public effects: () => Effect[];

/**
* A method that registers the entity with the manager.
* @returns CleanupFunction | void
*/
public register(): CleanupFunction | void {
return this.manager?.registry.register(this);
}

/**
* A method that unregisters the entity from the manager.
* @returns void
*/
public unregister(): void {
this.manager?.registry.unregister(this);
}

/**
* A method that cleans up the entity when it is no longer needed.
* @returns void
Expand Down
5 changes: 1 addition & 4 deletions packages/abstract/src/core/manager/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ export type DragDropManagerInput<T extends DragDropManager<any, any>> = {
renderer?: Renderer;
};

export class DragDropManager<
T extends Draggable = Draggable,
U extends Droppable = Droppable,
> {
export class DragDropManager<T extends Draggable, U extends Droppable> {
public actions: DragActions<T, U, DragDropManager<T, U>>;
public collisionObserver: CollisionObserver<T, U>;
public dragOperation: DragOperation<T, U>;
Expand Down
3 changes: 2 additions & 1 deletion packages/abstract/src/core/manager/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {DragDropManager} from './manager.ts';

export type InferDraggable<P> = P extends DragDropManager<infer T> ? T : never;
export type InferDraggable<P> =
P extends DragDropManager<infer T, any> ? T : never;

export type InferDroppable<P> =
P extends DragDropManager<any, infer T> ? T : never;
2 changes: 1 addition & 1 deletion packages/abstract/src/core/modifiers/modifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {DragDropManager} from '../manager/index.ts';
export type ModifierOptions = PluginOptions;

export class Modifier<
T extends DragDropManager<any, any> = DragDropManager,
T extends DragDropManager<any, any> = DragDropManager<any, any>,
U extends ModifierOptions = ModifierOptions,
> extends Plugin<T, U> {
constructor(
Expand Down
4 changes: 2 additions & 2 deletions packages/abstract/src/core/sensors/sensor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {CleanupFunction} from '@dnd-kit/state';

import type {DragDropManager} from '../manager/index.ts';
import type {Draggable} from '../entities/index.ts';
import type {Draggable, Droppable} from '../entities/index.ts';
import {
Plugin,
type PluginConstructor,
Expand All @@ -12,7 +12,7 @@ import {
export type SensorOptions = PluginOptions;

export abstract class Sensor<
T extends DragDropManager<any, any> = DragDropManager,
T extends DragDropManager<any, any> = DragDropManager<Draggable, Droppable>,
U extends SensorOptions = SensorOptions,
> extends Plugin<T, U> {
constructor(
Expand Down
11 changes: 8 additions & 3 deletions packages/abstract/src/modifiers/axis.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import {
DragOperation,
configurator,
Modifier,
DragDropManager,
type DragOperation,
type DragDropManager,
type Draggable,
type Droppable,
} from '@dnd-kit/abstract';

interface Options {
axis: 'x' | 'y';
value: number;
}

export class AxisModifier extends Modifier<DragDropManager, Options> {
export class AxisModifier extends Modifier<
DragDropManager<Draggable, Droppable>,
Options
> {
apply({transform}: DragOperation) {
if (!this.options) {
return transform;
Expand Down
11 changes: 8 additions & 3 deletions packages/abstract/src/modifiers/snap.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import {
DragOperation,
configurator,
Modifier,
DragDropManager,
type DragOperation,
type DragDropManager,
type Draggable,
type Droppable,
} from '@dnd-kit/abstract';

interface Options {
size: number | {x: number; y: number};
}

export class SnapModifier extends Modifier<DragDropManager, Options> {
export class SnapModifier extends Modifier<
DragDropManager<Draggable, Droppable>,
Options
> {
apply({transform}: DragOperation) {
const {size = 20} = this.options ?? {};
const x = typeof size === 'number' ? size : size.x;
Expand Down
9 changes: 2 additions & 7 deletions packages/dom/src/core/entities/draggable/draggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import {
Sensor,
descriptor,
} from '@dnd-kit/abstract';
import type {
Data,
DraggableInput,
DragDropManager as AbstractDragDropManager,
Modifiers,
} from '@dnd-kit/abstract';
import type {Data, DraggableInput, Modifiers} from '@dnd-kit/abstract';
import {reactive} from '@dnd-kit/state';

import type {DragDropManager} from '../../manager/index.ts';
Expand All @@ -33,7 +28,7 @@ export class Draggable<T extends Data = Data> extends AbstractDraggable<T> {
feedback = 'default',
...input
}: Input<T>,
manager: AbstractDragDropManager<any, any> | undefined
manager: DragDropManager | undefined
) {
super(
{
Expand Down
5 changes: 3 additions & 2 deletions packages/dom/src/core/entities/droppable/droppable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {Droppable as AbstractDroppable} from '@dnd-kit/abstract';
import type {
Data,
DroppableInput as AbstractDroppableInput,
DragDropManager as AbstractDragDropManager,
} from '@dnd-kit/abstract';
import {defaultCollisionDetection} from '@dnd-kit/collision';
import type {CollisionDetector} from '@dnd-kit/collision';
Expand All @@ -15,6 +14,8 @@ import {
getFirstScrollableAncestor,
} from '@dnd-kit/dom/utilities';

import type {DragDropManager} from '../../manager/manager.ts';

type OptionalInput = 'collisionDetector';

export interface Input<T extends Data = Data>
Expand All @@ -26,7 +27,7 @@ export interface Input<T extends Data = Data>
export class Droppable<T extends Data = Data> extends AbstractDroppable<T> {
constructor(
{element, effects = () => [], ...input}: Input<T>,
manager: AbstractDragDropManager<any, any> | undefined
manager: DragDropManager | undefined
) {
const {collisionDetector = defaultCollisionDetection} = input;

Expand Down
19 changes: 17 additions & 2 deletions packages/dom/src/sortable/sortable.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {batch, reactive, untracked} from '@dnd-kit/state';
import {CollisionPriority} from '@dnd-kit/abstract';
import {CollisionPriority, Entity} from '@dnd-kit/abstract';
import type {
Data,
PluginConstructor,
Expand Down Expand Up @@ -351,7 +351,22 @@ export class Sortable<T extends Data = Data> {
return this.droppable.accepts(draggable);
}

public destroy() {}
public register() {
this.manager?.registry.register(this.draggable);
this.manager?.registry.register(this.droppable);

return () => this.unregister();
}

public unregister() {
this.manager?.registry.unregister(this.draggable);
this.manager?.registry.unregister(this.droppable);
}

public destroy() {
this.draggable.destroy();
this.droppable.destroy();
}
}

export class SortableDraggable<T extends Data> extends Draggable<T> {
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/core/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import {createContext} from 'react';
import {DragDropManager} from '@dnd-kit/dom';

export const defaultManager = new DragDropManager();

export const DragDropContext = createContext<DragDropManager | null>(
new DragDropManager()
defaultManager
);
1 change: 0 additions & 1 deletion packages/react/src/core/context/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/react/src/core/draggable/index.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/react/src/core/draggable/useDraggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ export function useDraggable<T extends Data = Data>(
const handle = currentValue(input.handle);
const element = currentValue(input.element);
const draggable = useInstance(
() =>
(manager) =>
new Draggable(
{
...input,
handle,
element,
},
undefined
manager
)
);
const isDragSource = useComputed(() => draggable.isDragSource);
Expand Down
2 changes: 0 additions & 2 deletions packages/react/src/core/droppable/index.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/react/src/core/droppable/useDroppable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export function useDroppable<T extends Data = Data>(
const {collisionDetector, data, disabled, id, accept, type} = input;
const element = currentValue(input.element);
const droppable = useInstance(
() =>
(manager) =>
new Droppable(
{
...input,
element,
},
undefined
manager
)
);
const isDropTarget = useComputed(() => droppable.isDropTarget);
Expand Down
23 changes: 18 additions & 5 deletions packages/react/src/core/hooks/useInstance.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import {useEffect, useState} from 'react';
import type {DragDropManager, Entity} from '@dnd-kit/abstract';
import type {DragDropManager} from '@dnd-kit/abstract';
import type {CleanupFunction} from '@dnd-kit/state';

import {useDragDropManager} from './useDragDropManager.ts';
import {defaultManager} from '../context/context.ts';

export function useInstance<T extends Entity>(initializer: () => T): T {
export interface Instance<
T extends DragDropManager<any, any> = DragDropManager<any, any>,
> {
manager: T | undefined;
register(): CleanupFunction | void;
}

export function useInstance<T extends Instance>(
initializer: (manager: DragDropManager<any, any> | undefined) => T
): T {
const manager = useDragDropManager() ?? undefined;
const [instance] = useState<T>(() => initializer());
const [instance] = useState<T>(() =>
initializer(manager === defaultManager ? undefined : manager)
);

useEffect(() => {
instance.manager = manager as DragDropManager | undefined;
instance.manager = manager;

// Register returns an unregister callback
return manager?.registry.register(instance);
return instance.register();
}, [instance, manager]);

return instance;
Expand Down
14 changes: 11 additions & 3 deletions packages/react/src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
'use client';

export {DragDropProvider} from './context/index.ts';
export {DragDropProvider} from './context/DragDropProvider.tsx';

export {useDraggable} from './draggable/index.ts';
export {
useDraggable,
type UseDraggableInput,
} from './draggable/useDraggable.ts';

export {useDroppable} from './droppable/index.ts';
export {
useDroppable,
type UseDroppableInput,
} from './droppable/useDroppable.ts';

export {useDragDropManager} from './hooks/useDragDropManager.ts';

export {useDragOperation} from './hooks/useDragOperation.ts';

export {useInstance} from './hooks/useInstance.ts';
Loading

0 comments on commit 71f169a

Please sign in to comment.