snap-dnd 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snap-dnd",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A zero-dependency, memory-optimized drag and drop library for vanilla JS and Web Components",
5
5
  "type": "module",
6
6
  "main": "./dist/snap.umd.js",
@@ -1,20 +0,0 @@
1
- /**
2
- * AutoScroll behavior - scrolls containers when dragging near edges
3
- */
4
- import type { Behavior, DragSession, AutoScrollOptions } from '../types/index.js';
5
- export declare class AutoScroll implements Behavior {
6
- name: string;
7
- private _options;
8
- private _scrollableAncestors;
9
- private _rafId;
10
- private _active;
11
- constructor(options?: AutoScrollOptions);
12
- onDragStart(session: DragSession): void;
13
- onDragMove(session: DragSession): void;
14
- onDragEnd(): void;
15
- destroy(): void;
16
- private _performScroll;
17
- private _calculateScrollSpeed;
18
- private _getSpeed;
19
- private _findScrollableAncestors;
20
- }
@@ -1,37 +0,0 @@
1
- /**
2
- * ConstraintAxis behavior - constrain movement to specific axis
3
- * Note: Basic axis constraint is handled in DragEngine via options.axis
4
- * This behavior adds additional constraint features like bounds
5
- */
6
- import type { Behavior, DragSession, Axis, Point } from '../types/index.js';
7
- export interface ConstraintOptions {
8
- axis?: Axis;
9
- /** Bounding rectangle to constrain within */
10
- bounds?: {
11
- minX?: number;
12
- maxX?: number;
13
- minY?: number;
14
- maxY?: number;
15
- };
16
- /** Constrain to parent element bounds */
17
- containWithinParent?: boolean;
18
- }
19
- export declare class ConstraintAxis implements Behavior {
20
- name: string;
21
- private _options;
22
- private _bounds;
23
- constructor(options?: ConstraintOptions);
24
- onDragStart(session: DragSession): void;
25
- onDragMove(_session: DragSession): void;
26
- onDragEnd(): void;
27
- destroy(): void;
28
- /**
29
- * Apply constraints to a point
30
- */
31
- constrain(point: Point, origin: Point): Point;
32
- /**
33
- * Get current bounds
34
- */
35
- getBounds(): typeof this._bounds;
36
- private _calculateParentBounds;
37
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * SnapGrid behavior - snaps drag position to a grid
3
- * Note: This is handled in DragEngine via options.grid
4
- * This behavior provides additional grid-related features
5
- */
6
- import type { Behavior, DragSession, GridOptions } from '../types/index.js';
7
- export interface SnapGridOptions extends GridOptions {
8
- /** Only snap when within threshold of grid line */
9
- threshold?: number;
10
- /** Show visual grid guides */
11
- showGuides?: boolean;
12
- }
13
- export declare class SnapGrid implements Behavior {
14
- name: string;
15
- private _options;
16
- private _guideContainer;
17
- constructor(options: SnapGridOptions);
18
- onDragStart(session: DragSession): void;
19
- onDragMove(_session: DragSession): void;
20
- onDragEnd(): void;
21
- destroy(): void;
22
- /**
23
- * Snap a point to the grid
24
- */
25
- snap(x: number, y: number): {
26
- x: number;
27
- y: number;
28
- };
29
- /**
30
- * Snap with threshold - only snap when close to grid line
31
- */
32
- snapWithThreshold(x: number, y: number, threshold?: number): {
33
- x: number;
34
- y: number;
35
- };
36
- private _createGuides;
37
- private _removeGuides;
38
- }
@@ -1,3 +0,0 @@
1
- export { AutoScroll } from './AutoScroll.js';
2
- export { SnapGrid, type SnapGridOptions } from './SnapGrid.js';
3
- export { ConstraintAxis, type ConstraintOptions } from './ConstraintAxis.js';
@@ -1,60 +0,0 @@
1
- /**
2
- * DragEngine orchestrates the drag operation
3
- * Coordinates between sensors, state, and drop zones
4
- */
5
- import type { SnapOptions, Axis } from '../types/index.js';
6
- import { DragState } from './DragState.js';
7
- export interface DragEngineOptions {
8
- container: HTMLElement | ShadowRoot;
9
- state: DragState;
10
- options: SnapOptions;
11
- getDropZones: () => HTMLElement[];
12
- getItemData: (element: HTMLElement) => Record<string, unknown> | undefined;
13
- getItemAxis: (element: HTMLElement) => Axis | undefined;
14
- }
15
- export declare class DragEngine {
16
- private _container;
17
- private _state;
18
- private _options;
19
- private _getDropZones;
20
- private _getItemData;
21
- private _getItemAxis;
22
- private _pointerSensor;
23
- private _enabled;
24
- private _ghost;
25
- private _ghostOffset;
26
- constructor(engineOptions: DragEngineOptions);
27
- /**
28
- * Enable drag engine
29
- */
30
- enable(): void;
31
- /**
32
- * Disable drag engine
33
- */
34
- disable(): void;
35
- /**
36
- * Check if enabled
37
- */
38
- get isEnabled(): boolean;
39
- /**
40
- * Update options
41
- */
42
- updateOptions(options: Partial<SnapOptions>): void;
43
- private _setupListeners;
44
- private _onPointerDown;
45
- private _onPointerMove;
46
- private _onPointerUp;
47
- private _onPointerCancel;
48
- private _applyAxisConstraint;
49
- private _applyGridSnap;
50
- private _updateDropZone;
51
- private _createGhost;
52
- private _updateGhost;
53
- private _removeGhost;
54
- private _cleanup;
55
- private _extractDataAttributes;
56
- /**
57
- * Cleanup
58
- */
59
- destroy(): void;
60
- }
@@ -1,67 +0,0 @@
1
- /**
2
- * Centralized drag state management
3
- * Single source of truth for the current drag session
4
- */
5
- import type { DragSession, Point, StateEvent, Unsubscribe } from '../types/index.js';
6
- import { EventEmitter } from '../utils/EventEmitter.js';
7
- interface StateEvents {
8
- dragstart: DragSession;
9
- dragmove: DragSession;
10
- dragend: DragSession;
11
- dropzoneenter: DragSession;
12
- dropzoneleave: DragSession;
13
- drop: DragSession;
14
- }
15
- export declare class DragState extends EventEmitter<StateEvents> {
16
- private _session;
17
- private _idCounter;
18
- /**
19
- * Get current drag session (null if not dragging)
20
- */
21
- get session(): DragSession | null;
22
- /**
23
- * Check if currently dragging
24
- */
25
- isDragging(): boolean;
26
- /**
27
- * Get the element being dragged
28
- */
29
- getActiveElement(): HTMLElement | null;
30
- /**
31
- * Get current drop zone
32
- */
33
- getCurrentDropZone(): HTMLElement | null;
34
- /**
35
- * Start a new drag session
36
- */
37
- startDrag(element: HTMLElement, origin: Point, initialData?: Record<string, unknown>): DragSession;
38
- /**
39
- * Update position during drag
40
- */
41
- updatePosition(point: Point): void;
42
- /**
43
- * Set or clear drop zone target
44
- */
45
- setDropTarget(zone: HTMLElement | null): void;
46
- /**
47
- * Complete the drag with a drop
48
- */
49
- endDrag(): DragSession | null;
50
- /**
51
- * Cancel the current drag
52
- */
53
- cancelDrag(): DragSession | null;
54
- /**
55
- * Subscribe to state changes
56
- */
57
- subscribe(event: StateEvent, callback: (session: DragSession) => void): Unsubscribe;
58
- /**
59
- * Reset state
60
- */
61
- reset(): void;
62
- /**
63
- * Cleanup
64
- */
65
- destroy(): void;
66
- }
67
- export {};
@@ -1,97 +0,0 @@
1
- /**
2
- * DropZone manages individual drop target areas
3
- * Handles hit testing and insertion index calculation
4
- */
5
- import type { DataTransfer, DropZoneOptions } from '../types/index.js';
6
- export declare class DropZone {
7
- private _element;
8
- private _options;
9
- private _isActive;
10
- constructor(element: HTMLElement, options?: DropZoneOptions);
11
- /**
12
- * The DOM element for this drop zone
13
- */
14
- get element(): HTMLElement;
15
- /**
16
- * Whether this zone is currently active (being hovered)
17
- */
18
- get isActive(): boolean;
19
- /**
20
- * Update options
21
- */
22
- setOptions(options: Partial<DropZoneOptions>): void;
23
- /**
24
- * Check if a point is inside this drop zone
25
- */
26
- containsPoint(x: number, y: number): boolean;
27
- /**
28
- * Check if this zone accepts the given data
29
- */
30
- accepts(data: DataTransfer): boolean;
31
- /**
32
- * Set active state and add/remove CSS class
33
- */
34
- setActive(active: boolean): void;
35
- /**
36
- * Calculate insertion index for sortable behavior
37
- * Returns the index where an item should be inserted based on position
38
- */
39
- getInsertionIndex(x: number, y: number, itemSelector: string, excludeElement?: HTMLElement): number;
40
- /**
41
- * Get closest item to a point (for visual feedback)
42
- */
43
- getClosestItem(x: number, y: number, itemSelector: string, excludeElement?: HTMLElement): {
44
- element: HTMLElement;
45
- position: 'before' | 'after';
46
- } | null;
47
- /**
48
- * Force update cached bounds
49
- */
50
- updateBounds(): void;
51
- /**
52
- * Cleanup
53
- */
54
- destroy(): void;
55
- }
56
- /**
57
- * DropZoneManager handles multiple drop zones
58
- */
59
- export declare class DropZoneManager {
60
- private _zones;
61
- /**
62
- * Register a drop zone
63
- */
64
- register(element: HTMLElement, options?: DropZoneOptions): DropZone;
65
- /**
66
- * Unregister a drop zone
67
- */
68
- unregister(element: HTMLElement): void;
69
- /**
70
- * Get drop zone for an element
71
- */
72
- get(element: HTMLElement): DropZone | undefined;
73
- /**
74
- * Get all drop zone elements
75
- */
76
- getElements(): HTMLElement[];
77
- /**
78
- * Get all drop zones
79
- */
80
- getAll(): DropZone[];
81
- /**
82
- * Find drop zone at point
83
- */
84
- findAtPoint(x: number, y: number): DropZone | null;
85
- /**
86
- * Clear all drop zones
87
- */
88
- clear(): void;
89
- /**
90
- * Update all bounds (e.g., after scroll/resize)
91
- */
92
- updateAllBounds(): void;
93
- /**
94
- * Cleanup
95
- */
96
- destroy(): void;
97
- }
@@ -1,85 +0,0 @@
1
- /**
2
- * Snap - Main entry point for the drag and drop library
3
- * Coordinates all subsystems and provides the public API
4
- */
5
- import type { SnapOptions, SnapInstance, ItemOptions, DropZoneOptions, Plugin, Behavior } from '../types/index.js';
6
- export declare class Snap implements SnapInstance {
7
- private _container;
8
- private _options;
9
- private _state;
10
- private _engine;
11
- private _dropZoneManager;
12
- private _imperativeDraggables;
13
- private _imperativeDropZones;
14
- private _plugins;
15
- private _behaviors;
16
- private _observer;
17
- private _refreshScheduled;
18
- private _scrollHandler;
19
- private _resizeHandler;
20
- constructor(container: HTMLElement | ShadowRoot, options?: SnapOptions);
21
- /**
22
- * Current options
23
- */
24
- get options(): SnapOptions;
25
- /**
26
- * Enable drag and drop
27
- */
28
- enable(): void;
29
- /**
30
- * Disable drag and drop
31
- */
32
- disable(): void;
33
- /**
34
- * Cleanup and destroy instance
35
- */
36
- destroy(): void;
37
- /**
38
- * Re-scan for declarative elements (call after DOM changes)
39
- */
40
- refresh(): void;
41
- /**
42
- * Register a draggable element imperatively
43
- */
44
- addDraggable(element: HTMLElement, options?: ItemOptions): void;
45
- /**
46
- * Unregister a draggable element
47
- */
48
- removeDraggable(element: HTMLElement): void;
49
- /**
50
- * Register a drop zone imperatively
51
- */
52
- addDropZone(element: HTMLElement, options?: DropZoneOptions): void;
53
- /**
54
- * Unregister a drop zone
55
- */
56
- removeDropZone(element: HTMLElement): void;
57
- /**
58
- * Check if currently dragging
59
- */
60
- isDragging(): boolean;
61
- /**
62
- * Get the element currently being dragged
63
- */
64
- getActiveElement(): HTMLElement | null;
65
- /**
66
- * Register a plugin
67
- */
68
- use(plugin: Plugin): this;
69
- /**
70
- * Add a behavior
71
- */
72
- addBehavior(behavior: Behavior): this;
73
- /**
74
- * Update options dynamically
75
- */
76
- setOptions(options: Partial<SnapOptions>): void;
77
- private _getDropZones;
78
- private _getItemData;
79
- private _getItemAxis;
80
- private _scanDeclarativeElements;
81
- private _setupStateListeners;
82
- private _setupAutoRefresh;
83
- private _setupScrollResize;
84
- }
85
- export default Snap;
@@ -1,4 +0,0 @@
1
- export { Snap, default } from './Snap.js';
2
- export { DragState } from './DragState.js';
3
- export { DragEngine, type DragEngineOptions } from './DragEngine.js';
4
- export { DropZone, DropZoneManager } from './DropZone.js';
package/dist/index.d.ts DELETED
@@ -1,62 +0,0 @@
1
- /**
2
- * Snap - A zero-dependency, memory-optimized drag and drop library
3
- *
4
- * @example Basic usage with data attributes
5
- * ```html
6
- * <div id="container">
7
- * <div data-draggable>Drag me</div>
8
- * <div data-droppable>Drop here</div>
9
- * </div>
10
- *
11
- * <script>
12
- * const snap = new Snap(document.getElementById('container'));
13
- * </script>
14
- * ```
15
- *
16
- * @example Imperative usage
17
- * ```javascript
18
- * const snap = new Snap(container, {
19
- * onDrop: (e) => console.log('Dropped!', e.element, e.dropZone)
20
- * });
21
- *
22
- * snap.addDraggable(myElement, { data: { id: 1 } });
23
- * snap.addDropZone(myZone, { accepts: ['item'] });
24
- * ```
25
- *
26
- * @example With Lit Element
27
- * ```javascript
28
- * class MyComponent extends LitElement {
29
- * snap;
30
- *
31
- * firstUpdated() {
32
- * this.snap = new Snap(this.shadowRoot, {
33
- * autoRefresh: true,
34
- * onDrop: this.handleDrop.bind(this)
35
- * });
36
- * }
37
- *
38
- * disconnectedCallback() {
39
- * super.disconnectedCallback();
40
- * this.snap?.destroy();
41
- * }
42
- * }
43
- * ```
44
- */
45
- export { Snap, default } from './core/Snap.js';
46
- export { DragState } from './core/DragState.js';
47
- export { DragEngine } from './core/DragEngine.js';
48
- export { DropZone, DropZoneManager } from './core/DropZone.js';
49
- export { Sortable } from './plugins/Sortable.js';
50
- export { Kanban } from './plugins/Kanban.js';
51
- export { FileDrop, createFileDropZone } from './plugins/FileDrop.js';
52
- export { AutoScroll } from './behaviors/AutoScroll.js';
53
- export { SnapGrid } from './behaviors/SnapGrid.js';
54
- export { ConstraintAxis } from './behaviors/ConstraintAxis.js';
55
- export { EventEmitter } from './utils/EventEmitter.js';
56
- export { ObjectPool, pointPool, rectPool } from './utils/ObjectPool.js';
57
- export { BoundsCache, boundsCache } from './utils/BoundsCache.js';
58
- export { RAFThrottle, rafThrottle } from './utils/RAFThrottle.js';
59
- export { SnapDataTransfer } from './utils/DataTransfer.js';
60
- export { PointerSensor } from './sensors/PointerSensor.js';
61
- export { FileSensor } from './sensors/FileSensor.js';
62
- export type { Point, Rect, Axis, Unsubscribe, DragSession, DragPhase, DataTransfer, DragStartEvent, DragMoveEvent, DragEndEvent, DropEvent, DropZoneEnterEvent, DropZoneLeaveEvent, FileDropEvent, SnapOptions, SnapInstance, ItemOptions, DropZoneOptions, AutoScrollOptions, GridOptions, SortableOptions, KanbanOptions, FileDropOptions, Plugin, Behavior, Sensor, } from './types/index.js';
@@ -1,33 +0,0 @@
1
- /**
2
- * FileDrop plugin - enables file drop zones for external files
3
- */
4
- import type { Plugin, SnapInstance, FileDropOptions, FileDropEvent } from '../types/index.js';
5
- export declare class FileDrop implements Plugin {
6
- name: string;
7
- private _snap;
8
- private _options;
9
- private _sensor;
10
- private _onFileDrop;
11
- constructor(options?: FileDropOptions);
12
- init(snap: SnapInstance): void;
13
- destroy(): void;
14
- /**
15
- * Set callback for file drop events
16
- */
17
- onFileDrop(callback: (event: FileDropEvent) => void): this;
18
- /**
19
- * Update file drop options
20
- */
21
- setOptions(options: Partial<FileDropOptions>): void;
22
- private _getContainer;
23
- private _setupEventHandlers;
24
- }
25
- /**
26
- * Simple file drop zone creation helper
27
- * For basic use cases without full Snap instance
28
- */
29
- export declare function createFileDropZone(element: HTMLElement, options: FileDropOptions & {
30
- onDrop: (files: File[]) => void;
31
- onDragEnter?: () => void;
32
- onDragLeave?: () => void;
33
- }): () => void;
@@ -1,40 +0,0 @@
1
- /**
2
- * Kanban plugin - enables moving items between multiple containers
3
- */
4
- import type { Plugin, SnapInstance, KanbanOptions } from '../types/index.js';
5
- export declare class Kanban implements Plugin {
6
- name: string;
7
- private _snap;
8
- private _options;
9
- private _sourceContainer;
10
- private _targetContainer;
11
- private _placeholder;
12
- private _originalIndex;
13
- private _currentIndex;
14
- constructor(options?: KanbanOptions);
15
- init(snap: SnapInstance): void;
16
- destroy(): void;
17
- private _onDragStart;
18
- private _onDragMove;
19
- private _onDropZoneEnter;
20
- private _onDropZoneLeave;
21
- private _onDragEnd;
22
- private _createPlaceholder;
23
- private _movePlaceholder;
24
- private _calculateInsertionIndex;
25
- private _getItemCount;
26
- private _animateItems;
27
- private _cleanup;
28
- /**
29
- * Get source container during drag
30
- */
31
- getSourceContainer(): HTMLElement | null;
32
- /**
33
- * Get target container during drag
34
- */
35
- getTargetContainer(): HTMLElement | null;
36
- /**
37
- * Get current insertion index
38
- */
39
- getCurrentIndex(): number;
40
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * Sortable plugin - enables reordering items within a container
3
- */
4
- import type { Plugin, SnapInstance, SortableOptions } from '../types/index.js';
5
- export declare class Sortable implements Plugin {
6
- name: string;
7
- private _snap;
8
- private _options;
9
- private _placeholder;
10
- private _originalIndex;
11
- private _currentIndex;
12
- private _container;
13
- private _items;
14
- private _unsubscribers;
15
- constructor(options?: SortableOptions);
16
- init(snap: SnapInstance): void;
17
- destroy(): void;
18
- private _onDragStart;
19
- private _onDragMove;
20
- private _onDragEnd;
21
- private _createPlaceholder;
22
- private _movePlaceholder;
23
- private _animateItems;
24
- private _cleanup;
25
- /**
26
- * Get the current insertion index during drag
27
- */
28
- getCurrentIndex(): number;
29
- /**
30
- * Get the original index of the dragged item
31
- */
32
- getOriginalIndex(): number;
33
- }
@@ -1,3 +0,0 @@
1
- export { Sortable } from './Sortable.js';
2
- export { Kanban } from './Kanban.js';
3
- export { FileDrop, createFileDropZone } from './FileDrop.js';
@@ -1,51 +0,0 @@
1
- /**
2
- * File drop sensor for handling external file drags
3
- * Uses native HTML5 drag and drop API since pointer events
4
- * don't work for external drags
5
- */
6
- import type { Point, Sensor } from '../types/index.js';
7
- import { EventEmitter } from '../utils/EventEmitter.js';
8
- export interface FileSensorEvents {
9
- dragenter: FileDragEvent;
10
- dragover: FileDragEvent;
11
- dragleave: FileDragEvent;
12
- drop: FileDropEvent;
13
- }
14
- export interface FileDragEvent {
15
- position: Point;
16
- dropZone: HTMLElement;
17
- originalEvent: DragEvent;
18
- }
19
- export interface FileDropEvent {
20
- files: File[];
21
- position: Point;
22
- dropZone: HTMLElement;
23
- originalEvent: DragEvent;
24
- }
25
- export interface FileSensorOptions {
26
- container: HTMLElement | ShadowRoot;
27
- dropZoneSelector: string;
28
- accept?: string[];
29
- multiple?: boolean;
30
- maxSize?: number;
31
- }
32
- export declare class FileSensor extends EventEmitter<FileSensorEvents> implements Sensor {
33
- private _container;
34
- private _options;
35
- private _attached;
36
- private _dragCount;
37
- private _currentDropZone;
38
- constructor(options: FileSensorOptions);
39
- attach(): void;
40
- detach(): void;
41
- private _getEventTarget;
42
- private _onDragEnter;
43
- private _onDragOver;
44
- private _onDragLeave;
45
- private _onDrop;
46
- private _findDropZone;
47
- private _hasFiles;
48
- private _getFiles;
49
- private _matchesAccept;
50
- destroy(): void;
51
- }