Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
clauderic committed Aug 6, 2023
1 parent 0a805a4 commit 95fc4f8
Show file tree
Hide file tree
Showing 33 changed files with 390 additions and 261 deletions.
34 changes: 19 additions & 15 deletions apps/docs/stories/Droppable/DroppableExample.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useRef, useState} from 'react';
import React, {useEffect, useRef, useState} from 'react';
import type {PropsWithChildren} from 'react';
import type {UniqueIdentifier} from '@dnd-kit/types';
import {DndContext, useDraggable, useDroppable} from '@dnd-kit/react';
Expand Down Expand Up @@ -39,12 +39,16 @@ export function DroppableExample() {
onDragStart={() => {
snapshot.current = cloneDeep(items);
}}
onDragOver={(event) => {
onCollision={(event, manager) => {
const [firstCollision] = event.collisions;
manager.actions.setDropTarget(firstCollision?.id);
}}
onDragEnd={(event) => {
const {source, target} = event.operation;

// if (event.canceled) {
// return;
// }
if (event.canceled) {
return;
}

if (source && target) {
const targetRowId = target.id;
Expand All @@ -61,7 +65,9 @@ export function DroppableExample() {
][currentRowId].filter((child) => child.id !== source.id);

newItems[targetColumnId][targetRowId] = [
...newItems[targetColumnId][targetRowId],
...newItems[targetColumnId][targetRowId].filter(
(child) => child.id !== source.id
),
{id: source.id, type: source.type},
];

Expand All @@ -70,19 +76,17 @@ export function DroppableExample() {
}
}
}}
onDragEnd={(event) => {
if (event.canceled) {
setItems(snapshot.current);
}
}}
// onDragEnd={(event) => {
// if (event.canceled) {
// setItems(snapshot.current);
// }
// }}
>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: 20,
position: 'relative',
zIndex: 999999999,
}}
>
{Object.entries(items).map(([columnId, items]) => (
Expand Down Expand Up @@ -155,10 +159,10 @@ function Droppable({
collisionDetector,
children,
}: PropsWithChildren<DroppableProps>) {
const {ref, isOver} = useDroppable({id, accept, collisionDetector});
const {ref, isDropTarget} = useDroppable({id, accept, collisionDetector});

return (
<Dropzone ref={ref} highlight={isOver}>
<Dropzone ref={ref} highlight={isDropTarget}>
{children}
</Dropzone>
);
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/stories/Sortable/Sortable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function Droppable({
collisionDetector,
children,
}: PropsWithChildren<DroppableProps>) {
const {ref, isOver} = useDroppable({id, accept, collisionDetector});
const {ref, isDropTarget} = useDroppable({id, accept, collisionDetector});

return (
<div
Expand All @@ -100,7 +100,7 @@ function Droppable({
border: '1px solid #DEDEDE',
borderRadius: 10,
margin: 10,
backgroundColor: isOver ? 'green' : undefined,
backgroundColor: isDropTarget ? 'green' : undefined,
}}
>
<div>Container: {id}</div>
Expand Down
14 changes: 10 additions & 4 deletions apps/docs/stories/components/Button/Button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,29 @@
color: #f6f8ff;
cursor: pointer;
outline: none;
transition: background 0.4s ease, box-shadow 0.3s ease;
transition: background 0.4s ease, box-shadow 0.3s ease, transform 0.25s ease;
min-height: 62px;
box-shadow: var(--box-shadow);
}

.Button:hover, .Button:focus {
background-color: #1e202a;
}

.Button:focus-visible {
box-shadow: inset 0 0 0 3px #4c9ffe;
.Button:focus-visible:not(.shadow) {
--box-shadow: inset 0 0 0 3px #4c9ffe;
transition: background 0.4s ease;
}

.shadow {
box-shadow: -1px 0 15px 0 rgba(34, 33, 81, 0.01), 0px 15px 15px 0 rgba(34, 33, 81, 0.25);
transform: scale(1.03);
--box-shadow: -1px 0 15px 0 rgba(34, 33, 81, 0.01), 0px 15px 15px 0 rgba(34, 33, 81, 0.25);
}

.hasActions {
padding-right: 10px;
}

.Button:not(.hasActions) {
touch-action: none;
}
1 change: 1 addition & 0 deletions packages/abstract/src/collision/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export {CollisionObserver} from './observer';
export {CollisionNotifier} from './notifier';
export * from './types';
16 changes: 16 additions & 0 deletions packages/abstract/src/collision/notifier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {effect} from '@dnd-kit/state';
import {DragDropManager} from '../manager';
import {Plugin} from '../plugins';

export class CollisionNotifier extends Plugin {
constructor(manager: DragDropManager) {
super(manager);

this.destroy = effect(() => {
const {collisionObserver, monitor} = manager;
const {collisions} = collisionObserver;

monitor.dispatch('collision', {collisions});
});
}
}
4 changes: 3 additions & 1 deletion packages/abstract/src/collision/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export type Input<
registry: DragDropRegistry<T, U>;
};

const DEFAULT_VALUE: Collisions = [];

export class CollisionObserver<
T extends Draggable = Draggable,
U extends Droppable = Droppable,
Expand All @@ -23,7 +25,7 @@ export class CollisionObserver<
const {source, shape, initialized} = dragOperation;

if (!initialized || !shape) {
return null;
return DEFAULT_VALUE;
}

const type = source?.type;
Expand Down
6 changes: 3 additions & 3 deletions packages/abstract/src/collision/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ export interface Collision {
value: number;
}

export type Collisions = Collision[] | null;
export type Collisions = Collision[];

export interface CollisionDetectorInput<
T extends Draggable = Draggable,
U extends Droppable = Droppable
U extends Droppable = Droppable,
> {
droppable: U;
dragOperation: DragOperation<T, U>;
}

export type CollisionDetector = <
T extends Draggable = Draggable,
U extends Droppable = Droppable
U extends Droppable = Droppable,
>(
input: CollisionDetectorInput<T, U>
) => Collision | null;
21 changes: 11 additions & 10 deletions packages/abstract/src/manager/manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {Draggable, Droppable} from '../nodes';
import {CollisionObserver} from '../collision';
import {CollisionObserver, CollisionNotifier} from '../collision';

import {DragDropRegistry} from './registry';
import {
Expand All @@ -9,8 +9,8 @@ import {
} from './dragOperation';
import {DragDropMonitor} from './monitor';
import {PluginRegistry, descriptor, type Plugins} from '../plugins';
import type {Sensor, SensorConstructor, Sensors} from '../sensors';
import type {Modifier, ModifierConstructor} from '../modifiers';
import type {SensorConstructor, Sensors} from '../sensors';
import type {ModifierConstructor} from '../modifiers';

export interface DragDropConfiguration<T extends DragDropManager<any, any>> {
plugins: Plugins<T>;
Expand All @@ -34,25 +34,26 @@ export class DragDropManager<
public plugins: PluginRegistry<DragDropManager<T, U>>;
public sensors: PluginRegistry<
DragDropManager<T, U>,
Sensor<DragDropManager<T, U>>
SensorConstructor<DragDropManager<T, U>>
>;
public modifiers: PluginRegistry<
DragDropManager<T, U>,
Modifier<DragDropManager<T, U>>
ModifierConstructor<DragDropManager<T, U>>
>;

constructor(config?: DragDropManagerInput<DragDropManager<T, U>>) {
constructor(config?: DragDropManagerInput<any>) {
type V = DragDropManager<T, U>;

const {plugins = [], sensors = [], modifiers = []} = config ?? {};
const {sensors = [], modifiers = []} = config ?? {};
const plugins = [CollisionNotifier, ...(config?.plugins ?? [])];
const monitor = new DragDropMonitor<T, U, V>(this);
const registry = new DragDropRegistry<T, U>();

this.registry = registry;
this.monitor = monitor;
this.plugins = new PluginRegistry<V>(this);
this.sensors = new PluginRegistry<V, Sensor<V>>(this);
this.modifiers = new PluginRegistry<V, Modifier<V>>(this);
this.sensors = new PluginRegistry(this);
this.modifiers = new PluginRegistry(this);

const {actions, operation} = DragOperationManager<T, U, V>(this);
const collisionObserver = new CollisionObserver<T, U>({
Expand All @@ -75,7 +76,7 @@ export class DragDropManager<

for (const entry of sensors) {
const {plugin, options} = descriptor(entry);
this.sensors.register(plugin as SensorConstructor, options);
this.sensors.register(plugin, options);
}
}

Expand Down
8 changes: 5 additions & 3 deletions packages/abstract/src/manager/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {AnyFunction} from '@dnd-kit/types';
import type {DragDropManager} from './manager';
import type {DragOperation} from './dragOperation';
import type {Draggable, Droppable} from '../nodes';
import type {Collisions} from '../collision';

export type Events = Record<string, {} | undefined>;

Expand Down Expand Up @@ -30,7 +31,7 @@ class Monitor<T extends Events> {
registry.set(name, listeners);
}

public dispatch<U extends keyof T>(name: U, event?: T[U]) {
public dispatch<U extends keyof T>(name: U, event?: T[U], ...args: any[]) {
const {registry} = this;
const listeners = registry.get(name);

Expand All @@ -39,12 +40,13 @@ class Monitor<T extends Events> {
}

for (const listener of listeners) {
listener(event);
listener(event, ...args);
}
}
}

export type DragDropEvents<T extends Draggable, U extends Droppable> = {
collision: {collisions: Collisions};
dragstart: {};
dragmove: {};
dragover: {operation: DragOperation<T, U>};
Expand All @@ -64,6 +66,6 @@ export class DragDropMonitor<
type: Key,
event: DragDropEvents<T, U>[Key]
) {
super.dispatch(type, event);
super.dispatch(type, event, this.manager);
}
}
2 changes: 1 addition & 1 deletion packages/abstract/src/modifiers/modifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Plugin, type PluginConstructor} from '../plugins';
import type {DragDropManager, DragOperation} from '../manager';

export class Modifier<T extends DragDropManager<any, any>> extends Plugin<T> {
constructor(manager: T) {
constructor(protected manager: T) {
super(manager);
}

Expand Down
36 changes: 30 additions & 6 deletions packages/abstract/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,52 @@ import type {DragDropManager} from '../manager';

import type {PluginOptions} from './types';

/**
* An abstract plugin class that can be extended to implement custom
* functionality that augments the `DragDropManager`'s core capabilities.
*/
export class Plugin<
T extends DragDropManager<any, any> = DragDropManager<any, any>,
U extends PluginOptions = PluginOptions,
U extends PluginOptions | undefined = PluginOptions,
> {
constructor(
protected manager: T,
options?: U
) {
this.manager = manager;
}
public options?: U
) {}

/**
* Whether the plugin instance is disabled.
*/
public disabled: boolean = false;

/**
* Enable a disabled plugin instance.
*/
public enable() {
this.disabled = false;
}

/**
* Disable an enabled plugin instance.
*/
public disable() {
this.disabled = true;
}

/**
* Configure a plugin instance with new options.
*/
public configure(options?: U) {
this.options = options;
}

/**
* Destroy a plugin instance.
*/
public destroy() {
// no-op
/*
* Each plugin is responsible for implementing its own
* destroy method to clean up effects and listeners
*/
}
}
14 changes: 7 additions & 7 deletions packages/abstract/src/plugins/registry.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import {DragDropManager} from '../manager';

import type {Plugin} from './plugin';
import type {PluginConstructor, PluginOptions} from './types';
import type {InferPluginOptions, PluginConstructor} from './types';

export class PluginRegistry<
T extends DragDropManager<any, any>,
U extends Plugin<T> = Plugin<T>,
V extends PluginConstructor<T, U> = PluginConstructor<T, U>,
W extends PluginConstructor = PluginConstructor,
U extends Plugin = InstanceType<W>,
> {
private instances: Map<V, U> = new Map();
private instances: Map<W, U> = new Map();

constructor(private manager: T) {}

public [Symbol.iterator]() {
return this.instances.values();
}

public get(plugin: V): U | undefined {
public get(plugin: W): U | undefined {
const instance = this.instances.get(plugin);

return instance;
}

public register(plugin: V, options?: PluginOptions): U {
const instance = new plugin(this.manager, options);
public register(plugin: W, options?: InferPluginOptions<W>): U {
const instance = new plugin(this.manager, options) as U;

this.instances.set(plugin, instance);

Expand Down
Loading

0 comments on commit 95fc4f8

Please sign in to comment.