$ show formkit/drag-and-drop
This repository is a framework-agnostic drag-and-drop library developed by FormKit. It provides a data-first approach where consumers manage a reactive array as the source of truth, and the library handles DOM reordering internally. The core is written in TypeScript and is small (~4KB gzip), with first-class adapters for React, Vue, Solid, and Marko. The architecture consists of a central state machine using WeakMap stores to associate DOM elements with drag state, an event emitter pattern for global and parent-level events, and a plugin system for extensibility (animations, drop-or-swap, insert). Key entry points include the `dragAndDrop` function and framework-specific hooks/composables (e.g., `useDragAndDrop` for React). The library supports native HTML drag-and-drop and synthetic pointer-based dragging for touch devices, with features like multi-drag, drag handles, shadow DOM, and configurable animations. External dependencies are minimalβonly peer dependencies for framework adapters and optional Marko runtime. The repository also includes a comprehensive Playwright test suite covering sorting, transfer, animations, and edge cases, plus a Nuxt-based documentation site with live examples for all supported frameworks.
The LLM identified 3 files worth highlighting for reuse:
Provides foundational utilities: `createEmitter` for a simple event emitter pattern used throughout the library, `eq` for deep equality checks, `rect` for normalized bounding rectangles, and `eventCoordinates` for extracting pointer coordinates. These are self-contained, reusable functions that could be extracted into any project needing lightweight event handling or geometry helpers.
Implements the animations plugin as a factory function that hooks into the core's plugin lifecycle (`setup`, `teardown`, `setupNode`, `teardownNode`). It applies configurable CSS transitions (duration, easing, scale) to dragged and dropped elements. The plugin pattern is cleanly separated from the core, demonstrating how to extend drag-and-drop behavior without modifying the core logic. This module could serve as a template for building other plugins.
Implements the drop-or-swap plugin, which toggles between drop (insert) and swap behavior based on a configuration flag. It uses the same plugin lifecycle hooks as the animations plugin and manages internal state via a WeakMap. This module is a clear example of a stateful plugin that modifies core behavior without tight coupling, making it a reusable pattern for similar toggleable features.