Shopify/draggable
62.2
Adequate · 1 October 2026
7k
lines of production code
JavaScript
with TypeScript
2
measurements over time
What this system is
This system is a modular drag-and-drop library for JavaScript that provides core components for dragging, dropping, sorting, and swapping elements. It features a plugin and sensor architecture to handle various input methods, including mouse, touch, and native HTML5 drag events, while offering built-in accessibility support for screen readers. The library also includes specialized plugins for visual feedback, such as animations, collision detection, and element snapping, and is distributed with full TypeScript type definitions.
How it got here
2017 — TypeScript migration and modular architecture
37 changes.
The project underwent a comprehensive rewrite, migrating the build system from Webpack to Rollup and converting the entire codebase to TypeScript. This period involved restructuring the library into a modular architecture with shared base classes, removing legacy drag-and-drop implementations, and introducing a new plugin and sensor system for Draggable, Droppable, Sortable, and Swappable components.
2018 — Examples site and accessibility plugins
21 changes.
This period focused on establishing a comprehensive documentation and examples site to demonstrate the library's capabilities, including sortable, swappable, and droppable interactions. Concurrently, the core library expanded with new plugins for accessibility, such as screen reader announcements and keyboard focus management, alongside a dynamic resize mirror feature.
2020–2023 — TypeScript migration and SortAnimation plugin
6 changes.
This period focused on migrating core modules like the Emitter to TypeScript and adding comprehensive type definitions and tests for DragEvent and ResizeMirror components. It also introduced the SortAnimation plugin, which provides configurable CSS-based visual feedback for item reordering in sortable lists.
Features
Add Collidable, Snappable, and SwapAnimation plugin examples
The examples site now includes interactive demonstrations for the Collidable, Snappable, and SwapAnimation plugins. The Collidable example shows how to configure dropzones with obstacles and walls that visually react to collisions. The Snappable example demonstrates grid-based snapping with logic to prevent dragging specific item types. The SwapAnimation example illustrates sortable lists with configurable swap animations. These examples provide reference implementations for integrating these specific plugin capabilities into applications.
examples/src/content/Plugins/Collidable · high confidence
Add SimpleList and Transformed sortable list examples
The examples site now includes two new sortable list demos: a SimpleList using the StackedList component with mixed draggable and non-draggable items, and a Transformed list using the PaperStack component. Both examples initialize the @shopify/draggable Sortable library with mirror options that append the drag mirror to the container and constrain dimensions, providing users with ready-to-use patterns for implementing draggable lists in their applications.
examples/src/content/Sortable/SimpleList · high confidence
Add SortAnimation plugin example
An example demonstrating the SortAnimation plugin has been added to the Plugins section. This includes the HTML structure for draggable blocks, SCSS styles for layout and responsiveness, and a JavaScript entry point that initializes a Sortable instance with the SortAnimation plugin enabled, configuring a 200ms ease-in-out swap animation.
examples/src/content/Plugins/SortAnimation · high confidence
Add Swappable layout examples for Flexbox, Floated, and Grid
The examples site now includes three new interactive demos under the Swappable section: Flexbox, Floated, and Grid. Each demo showcases how the @shopify/draggable library handles item swapping within different CSS layout contexts, utilizing the ResizeMirror plugin to adjust the mirror element's dimensions during drag operations. The Flexbox and Floated examples demonstrate responsive behavior using specific block classes and media queries, while the Grid example illustrates complex area placement and resizing within a CSS Grid container.
examples/src/content/Swappable · high confidence
Add UniqueDropzone example demonstrating dropzone-restricted dragging
A new UniqueDropzone example has been added to the Droppable examples, featuring a grid and flex layout where draggable items are restricted to their original dropzone containers. The implementation uses the Droppable API to track the origin dropzone on drag start and cancels the drop event if the item is released into a different dropzone, providing a concrete pattern for enforcing dropzone-specific constraints in user interfaces.
examples/src/content/Droppable · high confidence
Add initial examples site components and layout
The examples site now includes a full set of UI components and layout structures, including a responsive navigation with a mobile hamburger menu, a brand logo with animated interactions, and draggable demonstration components like Block and PaperStack. The site also features a visual GridOverlay for layout debugging, standard UI elements such as Buttons and Links, and document-level configurations for SEO, favicons, and Google Analytics integration.
examples/src/components · high confidence
Add interactive draggable plate example to the Home page
The Home page content area now includes a new interactive demo featuring three draggable 'Plate' components (labeled One, Two, and Three) arranged in a wrapper. This change introduces the necessary HTML structure, styling, and JavaScript logic to enable drag-and-drop functionality using the @shopify/draggable library, allowing users to reposition the plates within the Home section.
examples/src/content/Home · high confidence
Add multiple-container sortable example with item capacity limits
The examples site now includes a new 'MultipleContainers' demo that showcases sorting items across three distinct containers. This example demonstrates how to enforce a specific item capacity (limiting the middle container to three items) using the Sortable library's event system, and utilizes the new ResizeMirror plugin to improve the visual feedback during drag operations.
examples/src/content/Sortable/MultipleContainers · high confidence
Added ForceTouchSensor for Mac force trackpads
A new ForceTouchSensor has been introduced to support drag interactions on devices with force-sensitive trackpads (specifically MacBooks). This sensor listens for native WebKit force touch events (such as \webkitmouseforcewillbegin\ and \webkitmouseforcedown\) to initiate drag operations, allowing users to start dragging by pressing down on the trackpad. It respects existing configuration options like \handle\ and \draggable\ selectors to determine valid drag targets and integrates with the standard drag lifecycle events (\drag:start\, \drag:move\, \drag:stop\, \drag:pressure\).
src/Draggable/Sensors/ForceTouchSensor · high confidence
Added TypeScript event classes for Snappable plugin
This change introduces the TypeScript definitions for the Snappable plugin's event system, including the base SnapEvent, SnapInEvent, and SnapOutEvent classes. Users can now interact with these events to detect when an element is about to snap in or out, with SnapInEvent and SnapOutEvent being cancelable to prevent the snapping action if needed. The events provide access to the triggering drag event and the snappable element itself.
src/Plugins/Snappable/SnappableEvent · high confidence
Added native browser DragSensor for HTML5 drag-and-drop integration
A new DragSensor has been introduced to the Draggable library, allowing users to leverage the browser's native HTML5 Drag and Drop API instead of the default mouse/touch sensors. This sensor listens for native drag events (drag:start, drag:move, drag:stop) on specified containers, enabling drag operations without creating a custom mirror element. Users can now instantiate this sensor via \Sensors.DragSensor\ and remove the default mouse sensor to switch to native behavior, though they should note that the \distance\ option is not supported and control over the drag mirror is limited compared to the default implementation.
src/Draggable/Sensors/DragSensor · high confidence
Droppable component now supports screen reader announcements
The Droppable module has been updated to include accessibility features for screen readers. It now automatically announces when a draggable element is dropped into a dropzone or returned to its original position, using customizable announcement functions that can be overridden via the \announcements\ option. This change introduces new default announcement logic and event-driven hooks (\droppable:dropped\, \droppable:returned\) to improve the experience for users relying on assistive technologies.
src/Droppable · high confidence
Focusable plugin added to make draggable elements keyboard-accessible
A new Focusable plugin has been introduced to automatically manage tabindex attributes on draggable containers and elements. When enabled, the plugin sets tabindex to 0 on elements that lack it, making them focusable via keyboard navigation, and restores their original state (tabindex -1) upon destruction. The plugin respects existing tabindex attributes and natively focusable elements, ensuring that user-defined focusability is not overridden.
src/Draggable/Plugins/Focusable · high confidence
Initial Examples site structure and documentation pages
The examples site now includes a foundational layout template and a set of documentation pages covering core Draggable features (Draggable, Droppable, Sortable, Swappable) and plugins (Collidable, Snappable, SortAnimation, SwapAnimation). This provides users with structured, navigable examples for these capabilities.
examples/src/views · high confidence
Initial Examples site styling and theme system
The Examples site now includes a complete SCSS styling foundation, introducing a dedicated 'Examples' theme that overrides the underlying 'Threads' design system with specific values for colors, typography, spacing, breakpoints, and z-indexes. This change adds a CSS reset, global utility mixins for layout and typography, and component-level styles for the site's navigation, sidebar, and example content areas, establishing the visual structure for the interactive demos.
examples/src/styles · high confidence
Initial release of the Examples site for Draggable
The Examples site has been added to aid developers interested in building web apps with Draggable and/or contributing back to the library. The site includes a local development setup with a Browsersync server, ESLint and Stylelint configurations, and a co-located component structure. It provides solutions to common drag and drop problems, such as resolving touch events and maintaining layout while dragging. The site also includes a mobile navigation component and Google Analytics integration.
examples · high confidence
Introduce Swappable component for element swapping
A new Swappable component is now available, extending Draggable to allow users to swap draggable elements by dragging them over one another without maintaining a specific order. This feature includes specific events (swappable:start, swappable:swap, swappable:swapped, swappable:stop) that can be listened to, with the swappable:swap event being cancelable to prevent the swap action. The implementation also includes accessibility support by announcing swaps to screen readers and provides documentation on usage via NPM, browser modules, and standalone scripts.
src/Swappable · high confidence
Introduce build tooling for the examples site
The examples/tools directory now provides a complete build system for the examples site, replacing any previous ad-hoc setup. It uses Gulp to orchestrate tasks for compiling JavaScript via Webpack (with code splitting and source maps), processing SCSS styles with PostCSS and sourcemaps, and rendering Nunjucks templates with HTML minification. A development watch mode is included that triggers live-reload via BrowserSync when source files change, and a production build configuration adds a bundle analyzer plugin to generate a static report of the output assets.
examples/tools · high confidence
Introduces SwapAnimation plugin for Sortable lists
Adds a new SwapAnimation plugin that provides animated transitions when items are reordered within a Sortable list. The plugin listens for the \sortable:sorted\ event and animates both the source and target elements using \translate3d\ transforms. Users can configure the animation duration, easing function, and direction (horizontal or vertical) via the \swapAnimation\ options object. The plugin is not included by default and must be explicitly imported and registered with the Sortable instance.
src/Plugins/SwapAnimation · high confidence
Introduction of AbstractEvent base class for draggable events
A new AbstractEvent base class has been added to the shared event system, serving as the foundation for all events emitted by the draggable library. This class provides a standardized way to handle event data, check cancellation status via the canceled() method, and clone events with modified data. The implementation includes TypeScript definitions, unit tests covering initialization and cancellation behavior, and documentation outlining the API for creating custom event types.
src/shared/AbstractEvent · high confidence
Introduction of AbstractPlugin base class for draggable plugins
A new AbstractPlugin class has been added to the shared module to serve as the base class for all draggable plugins. This class provides a standard constructor accepting a draggable instance and defines abstract attach and detach methods that derived plugins must implement to manage their event listeners.
src/shared/AbstractPlugin · high confidence
Introduction of Draggable event types
The Draggable module now exposes a structured event system with TypeScript definitions. Users can now interact with specific lifecycle events: \draggable:initialize\ when the component is set up, and \draggable:destroy\ when it is removed. These events extend a base \DraggableEvent\ that provides read-only access to the draggable instance via the \draggable\ property, allowing consumers to react to these state changes with type-safe data.
src/Draggable/DraggableEvent · high confidence
Introduction of base Sensor class with configurable delay and distance options
A new base Sensor class has been added to the Draggable library, providing the foundational API for detecting drag interactions. This class introduces configurable options for \delay\ (to postpone drag start) and \distance\ (to require a specific pointer movement before dragging begins), alongside support for \handle\ selectors to restrict drag initiation to specific child elements. The implementation includes methods to attach/detach DOM listeners and dynamically manage container elements, serving as the inheritance base for specific sensor types like MouseSensor or TouchSensor.
src/Draggable/Sensors/Sensor · high confidence
Introduction of default draggable plugins
The library now includes a set of default plugins that are bundled and exported for immediate use. Users can now leverage built-in capabilities such as screen reader announcements via the Announcement plugin, keyboard focus management with the Focusable plugin, visual drag feedback using the Mirror plugin, and automatic scrolling during drag operations with the Scrollable plugin. These plugins are now accessible through the main entry point, simplifying integration for common drag-and-drop behaviors.
src/Draggable/Plugins · high confidence
Introduction of new animation and interaction plugins
The Plugins directory now exposes a new set of capabilities including SwapAnimation, SortAnimation, ResizeMirror, Collidable, and Snappable. Users can import these specific plugins and their default options directly from the main index to enhance their applications with sorting, swapping, resizing, collision detection, and snapping behaviors.
src/Plugins · high confidence
Introduction of shared type definitions and documentation
A new shared module has been established in the src/shared directory, providing a central location for common type definitions. This includes the introduction of FixMeAny and FixMeUnknown types to assist with type conversions, alongside a README file documenting the shared folder's purpose.
src/shared · high confidence
Introduction of the Draggable core library with plugin and sensor architecture
This change introduces the core Draggable component, providing a configurable drag-and-drop system that supports mouse and touch interactions via a modular plugin and sensor architecture. Users can now initialize draggable containers with options to customize selectors, delays, distances, and CSS classes, while also having the ability to exclude default plugins (such as Announcement, Focusable, Mirror, and Scrollable) or sensors. The library exposes a comprehensive event system (including drag:start, drag:move, drag:stop, and drag:pressure) and a public API for managing containers, plugins, and sensors, along with a \cancel()\ method to immediately halt dragging.
src/Draggable · high confidence
New Announcement plugin for screen reader accessibility
Added a new Announcement plugin that injects a hidden ARIA live region into the DOM to announce draggable events (such as drag start, stop, and sorting) to screen readers. Users can configure static or dynamic announcement messages via plugin options, with a default expiration time of 7000ms for each announcement.
src/Draggable/Plugins/Announcement · high confidence
New Collidable plugin to freeze dragging on specific elements
The Collidable plugin is now available to prevent dragging over specified elements. By setting the \collidables\ option (accepting a selector, array, or function), the mirror movement freezes when the cursor enters a collidable area. The plugin triggers \collidable:in\ and \collidable:out\ events to notify users of these interactions, and is designed to work with Sortable, Swappable, and Droppable components.
src/Plugins/Collidable · high confidence
New ResizeMirror plugin for dynamic mirror resizing
A new ResizeMirror plugin has been added to the library, allowing the drag mirror element to dynamically resize to match the dimensions of the draggable element it is currently hovering over. This plugin is not included in the default bundle and must be imported separately; it automatically appends the mirror to the container being hovered and supports CSS transitions for animation. The implementation is provided in TypeScript and exposes a simple API with no additional configuration options.
src/Plugins/ResizeMirror · high confidence
New Sensors module for handling drag events
A new Sensors module has been added to the Draggable package, providing a set of components (MouseSensor, TouchSensor, DragSensor, ForceTouchSensor) that abstract native browser events into standardized drag:start, drag:move, and drag:stop events. This module is now exported from src/Draggable/Sensors, making these sensor implementations available for use in drag-and-drop operations.
src/Draggable/Sensors · high confidence
New Snappable plugin for automatic element snapping
A new Snappable plugin is now available to automatically snap draggable elements into place. When a draggable element is dragged over a target, the plugin hides the mirror element, removes the 'source:dragging' class from the source, and adds a 'source:placed' class to allow for drop animations. It exposes 'snap:in' and 'snap:out' events, which are cancelable, allowing users to prevent the snapping behavior if needed. This plugin is not included by default and must be explicitly imported and added to the Draggable instance's plugins array.
src/Plugins/Snappable · high confidence
New SortAnimation plugin for sortable lists
Added a new SortAnimation plugin that provides visual feedback when items are reordered in a Sortable list. The plugin animates affected elements using CSS transforms (translate3d) to smoothly move them to their new positions, supporting both horizontal and vertical layouts within a grid. Users can configure the animation duration (default 150ms) and easing function (default 'ease-in-out') via the sortAnimation options. This plugin is not included by default and must be explicitly imported and added to the plugins array. It is designed to work exclusively with the Sortable component and should not be used simultaneously with the SwapAnimation plugin to avoid conflicts.
src/Plugins/SortAnimation · high confidence
New shared utility functions and decorators
The shared utilities module now includes several new capabilities: a \closest\ function to find the nearest parent element matching a selector or callback, an \AutoBind\ decorator for automatic method binding in classes, a \distance\ calculator for Euclidean distance between points, a \requestNextAnimationFrame\ helper for double-wrapped animation frames, and a \touchCoords\ helper to extract the first touch point from touch events.
src/shared/utils · high confidence
Removals
Removal of legacy drag-and-drop implementation
The core drag-and-drop functionality, including the Accessibility module, Mirror visual feedback, and all input sensors (Mouse, Touch, Force Touch, and Drag), has been removed from the library. This deletion eliminates the previous implementation that relied on native browser drag events and ARIA attributes, indicating a shift away from this specific architecture.
src/core, src/sensors · high confidence
Removal of legacy event class hierarchy
The \src/events\ directory has been completely removed, deleting the entire legacy event class hierarchy including \AbstractEvent\ and all specific event types (such as \DragEvent\, \SensorEvent\, \CollidableEvent\, etc.). This change eliminates the previous object-oriented event structure, which will break any code relying on these specific classes and their inheritance chains.
src/events · high confidence
Behavioural changes
Added TypeScript type definitions for rollup-plugin-includepaths
A TypeScript declaration file has been added for the rollup-plugin-includepaths package, providing type definitions for its options interface (including include, paths, and extensions) and export function. This enables type checking and IntelliSense support for users and developers configuring this Rollup plugin within the project's TypeScript environment.
config · high confidence
Collidable events converted to TypeScript
The Collidable event classes (CollidableEvent, CollidableInEvent, CollidableOutEvent) have been rewritten in TypeScript, introducing strict typing for event data such as drag events and colliding elements, and are now exported via a dedicated index module.
src/Plugins/Collidable/CollidableEvent · high confidence
Draggable example now supports canceling drag with ESC key
The Draggable example in the examples site has been updated to allow users to cancel an active drag operation by pressing the Escape key. This is implemented by listening for the 'keyup' event during the 'drag:start' phase and calling the Draggable instance's cancel method when the Escape key is detected. The example also includes logic to toggle a 'PillSwitch' component's state based on drag position relative to a threshold, providing a visual demonstration of drag events and cancellation.
examples/src/content/Draggable · high confidence
Emitter module converted to TypeScript
The Emitter module in src/Draggable/Emitter has been rewritten in TypeScript, introducing static typing for event callbacks and event objects. This change provides better type safety for the on, off, and trigger methods while maintaining the existing event-driven behavior, including error handling during event triggering.
src/Draggable/Emitter · high confidence
Introduction of TypeScript-based SensorEvent classes
The SensorEvent module has been rewritten in TypeScript, introducing a base \SensorEvent\ class and specific event types (\DragStartSensorEvent\, \DragMoveSensorEvent\, \DragStopSensorEvent\, \DragPressureSensorEvent\) that extend it. This change provides a structured, type-safe API for sensor events, exposing properties such as \clientX\, \clientY\, \target\, \container\, \originalSource\, and \pressure\ to consumers, alongside updated documentation.
src/Draggable/Sensors/SensorEvent · high confidence
Introduction of TypeScript-based Swappable event classes
The Swappable module now exposes a set of TypeScript event classes (SwappableEvent, SwappableStartEvent, SwappableSwapEvent, SwappableSwappedEvent, and SwappableStopEvent) that replace the previous implementation. These classes define the specific event types emitted during drag-and-drop interactions, such as 'swappable:start', 'swappable:swap', and 'swappable:stop', and provide typed access to event data like the original drag event, the element being hovered over, and the element swapped with. This change improves type safety and developer experience for consumers of the Swappable library.
src/Swappable/SwappableEvent · high confidence
Library restructured into modular components with shared base classes
The library has been refactored from a monolithic structure into a modular architecture. Core classes like Draggable, Droppable, Sortable, and Swappable have been moved into their own directories, and the legacy behavior modules (Collidable, Snappable) have been removed. The public API now exports these components alongside namespaced Sensors and Plugins, and base classes AbstractEvent and AbstractPlugin are imported from a shared location and re-exported as BaseEvent and BasePlugin.
src · high confidence
Migrates build system from Webpack to Rollup and adds TypeScript support
The project's build pipeline has been replaced with Rollup, removing the previous Webpack configuration. This change introduces full TypeScript support, including new \tsconfig.json\ and \index.d.ts\ type definitions, and updates the output structure to generate CommonJS (\.cjs\), ES Modules (\.mjs\), and UMD bundles. Additionally, the Node.js engine requirement has been updated to v20.17.0, and development tooling has been standardized with new ESLint, Prettier, and Jest configurations.
(repo-wide) · high confidence
Mirror event types now expose threshold crossing data
The Mirror plugin's event system has been updated to include \passedThreshX\ and \passedThreshY\ boolean properties on the \MirrorMoveEvent\ and \MirrorMovedEvent\. This allows users to detect when the drag sensor has exceeded the configured mirror thresholds along the X and Y axes, enabling more precise control over mirror movement behavior.
src/Draggable/Plugins/Mirror/MirrorEvent · high confidence
Mirror plugin now supports axis constraints, cursor offsets, and scroll handling
The Mirror plugin has been refactored to offer finer control over the drag mirror's behavior. Users can now constrain the mirror's movement to a specific axis using the \xAxis\ and \yAxis\ options, or lock its dimensions to the source element with \constrainDimensions\. For better visual alignment, \cursorOffsetX\ and \cursorOffsetY\ allow manual adjustment of the mirror's position relative to the cursor. Additionally, the plugin now includes logic to handle scroll offsets for touch devices, ensuring the mirror remains correctly positioned during scrolling.
src/Draggable/Plugins/Mirror · high confidence
Mouse sensor now supports configurable delay and distance thresholds
The MouseSensor implementation has been updated to allow users to configure drag-start behavior using \delay\ and \distance\ options. Drag operations will now only initiate if the mouse is held down for at least the specified \delay\ duration AND the pointer has moved at least the specified \distance\ (in pixels) from the initial click position. This prevents accidental drags from minor movements or quick clicks, providing a more deliberate interaction model.
src/Draggable/Sensors/MouseSensor · high confidence
New TypeScript-based Droppable event system
The Droppable module now uses a new TypeScript event hierarchy (DroppableEvent, DroppableStartEvent, DroppableDroppedEvent, DroppableReturnedEvent, and DroppableStopEvent) that exposes specific properties like dragEvent and dropzone, replacing the previous implementation to improve type safety and consistency.
src/Droppable/DroppableEvent · high confidence
Restructured and documented drag event types
The drag event system has been restructured into a dedicated module, consolidating event definitions (DragEvent, DragStartEvent, DragMoveEvent, DragOverEvent, DragOutEvent) and their associated data interfaces into a single TypeScript file. This change includes comprehensive documentation in a new README that details the properties, cancelability, and specific behaviors of each event type, such as how DragStartEvent and DragOverEvent can be canceled to prevent drag initiation or default sortable actions. The module also exports helper functions like isDragOverEvent for type narrowing, providing a clearer and more robust API for consumers interacting with drag interactions.
src/Draggable/DragEvent · high confidence
Sortable component with accessibility announcements and public API methods
The Sortable module, which extends Draggable to reorder elements within containers, now includes built-in accessibility support by announcing sort actions (e.g., 'Placed X after Y') to screen readers via the \sortable:sorted\ event. It exposes a public \getSortableElementsForContainer\ method to retrieve sortable items while excluding the drag mirror and original source, and ensures that sorting logic correctly ignores these temporary elements when calculating indices.
src/Sortable · high confidence
Sortable event types restructured and documented
The Sortable module's event system has been restructured into a unified TypeScript module (\src/Sortable/SortableEvent\). This change introduces a base \SortableEvent\ class and specific event classes (\SortableStartEvent\, \SortableSortEvent\, \SortableSortedEvent\, \SortableStopEvent\) that extend it, providing consistent interfaces for drag-and-drop lifecycle events. The module also includes a comprehensive README documenting the API for each event, including properties like \startIndex\, \currentIndex\, \over\, \oldIndex\, and \newIndex\, ensuring developers have clear access to context during sorting operations.
src/Sortable/SortableEvent · high confidence
Touch sensor now supports configurable delay and distance thresholds
The TouchSensor component now exposes \delay\ and \distance\ options to control when a drag interaction begins. Users can specify a \delay\ (in milliseconds) to require a long press before dragging starts, and a \distance\ (in pixels) to require the pointer to move a specific amount before the drag initiates. When a distance threshold is set, scrolling is automatically prevented during the pre-drag phase to avoid accidental page scrolls.
src/Draggable/Sensors/TouchSensor · high confidence
Fixes
Fix scrollable plugin mouse position and touch handling
The Scrollable plugin now correctly handles mouse coordinates during drag operations, fixing a bug where the scroll position would not update accurately when dragging elements. This is achieved by adjusting the clientX and clientY values based on the current page offset, ensuring consistent scrolling behavior across different scroll contexts. Additionally, the plugin now properly supports touch events, allowing for smooth scrolling on touch-enabled devices by accounting for the touch sensor's position relative to the viewport.
src/Draggable/Plugins/Scrollable · high confidence
Test coverage
Added TypeScript tests for DragEvent classes; Added TypeScript tests for ResizeMirror plugin; Added test suite for Sortable component; Added tests for Droppable event triggers and drop behavior; Added tests for Swappable component behavior; Added tests for the Mirror plugin; Added unit tests for TouchSensor behavior; Added unit tests for the Sensor class; Initial test suite for Draggable core functionality; Migrate test suite to TypeScript.
Dependencies
Major dependency upgrade and build system migration
The project has undergone a significant dependency overhaul, upgrading core tooling from Babel 6 and Webpack 2 to Babel 7, Jest 29, and ESLint 8, while migrating the build pipeline from Webpack to Rollup. This change also updates the library's version to 1.2.1, introduces TypeScript support with new type definitions, and adds multi-format build outputs (CJS, ESM, UMD) to improve compatibility and developer experience.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 57 → 62 (+5.4)
- Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 83 → 83 (+0.0)
- Architecture 99 → 89 (-9.9)
- Maturity 59 → 59 (+0.0)
- Readiness 68 → 69 (+1.0)
- Security 44 → 56 (+12.1)
Resolved (5)
- Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (no pnpm-resolved versions to grade)
- Documentation: no architecture or design documentation (README.md)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Documentation: written for insiders (src/shared/utils/requestNextAnimationFrame/README.md)
New (4)
- Documentation: no project overview (src/shared/utils/README.md)
- End-of-life runtime: Node.js 20
- Outdated (npm): core-js
- Projects may be oversized for their cohesion
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Shopify/draggable was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 8a1eed57f3ab2dff9371e8ce60fb39ac85871e8d — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.