npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

drag-kit

v1.1.0

Published

Lightweight cross-platform drag library supporting mobile, tablet, PC with Vue2/Vue3/React compatibility and full TypeScript support

Downloads

65

Readme

drag-kit - A Lightweight Draggable Element Library

drag-kit is a lightweight JavaScript library designed to implement drag-and-drop functionality for elements. It offers various configuration options, including initial positioning, position saving, drag area constraints, grid alignment, and auto-snapping. The library handles drag-and-drop issues within iframes and is compatible with major front-end frameworks such as Vue 2, Vue 3, and React.

npm version

简体中文 | English

Features

  • Basic Dragging: Drag specified elements.
  • Cross-Device Support: Auto-detect device type, supports mobile phones, tablets (iPad), and PC with unified API.
  • Axis Locking: Lock dragging to a specific direction (horizontal or vertical).
  • Grid Alignment: Align dragging to a specified grid.
  • Auto-Snapping: Automatically snap elements to viewport edges.
  • Edge Buffering: Set a buffer distance between the element and the edges.
  • Boundary Limiting: Prevent elements from being dragged outside a specified area.
  • Position Saving and Restoring: Save drag positions to local storage and restore them on page reload.
  • Iframe Compatibility: Handle drag issues within iframes to ensure compatibility.
  • Framework Support: Works with Vue 2, Vue 3, React, and other major front-end frameworks.
  • TypeScript Support: Complete type definitions with type inference and IntelliSense.

img gif

Installation

npm install drag-kit

Usage

Quick Start

In Vue, using the onMounted hook:

<template>
  <div id="draggableElement" style="display: none;">Drag me!</div>
</template>

<script lang="ts">
import { onMounted } from 'vue';
import { createDraggable } from 'drag-kit';

export default {
  setup() {
    onMounted(() => {
      createDraggable('draggableElement', {
        initialPosition: { x: '100px', y: '200px' }
      });
    });
  }
};
</script>

In React, using the useEffect hook:

import React, { useEffect } from 'react';
import { createDraggable } from 'drag-kit';

const DraggableComponent: React.FC = () => {
  useEffect(() => {
    createDraggable('draggableElement', {
      initialPosition: { x: '100px', y: '200px' }
    });
  }, []);

  return <div id="draggableElement" style={{ display: 'none' }}>Drag me!</div>;
};

export default DraggableComponent;

It's recommended to set the element's display to none before initialization to enhance the user experience.

Parameter Details

createDraggable(elementId: string, options?: DraggableOptions): Draggable | MobileDraggable;

Auto Device Detection: createDraggable automatically detects the current device type:

  • Touch Devices: Returns MobileDraggable instance (touch events)
  • Desktop Devices: Returns Draggable instance (mouse events)

Parameters

  • elementId: The ID of the element to make draggable. (Required)
  • options: Configuration object with the following optional fields:
    • mode ('screen' | 'page' | 'container'): Drag mode (screen, page, or container). Default is screen. See details below.
    • initialPosition: Initial position of the element, default x = 0, y = 0.
    • dragArea (HTMLElement): Drag area (default is null, meaning full screen). Required if mode is container.
    • lockAxis ('x' | 'y' | 'none'): Lock dragging to a specific axis (x-axis, y-axis, or none).
    • edgeBuffer (number): Edge buffer distance.
    • gridSize (number): Grid size for alignment (default is undefined, meaning no grid alignment).
    • snapMode ('none' | 'auto' | 'right' | 'left' | 'top' | 'bottom'): Auto-snapping mode, default is none.
    • shouldSave: Whether to save the drag position to local storage.
    • onDragStart: Callback function when dragging starts.
    • onDrag: Callback function during dragging.
    • onDragEnd: Callback function when dragging ends.

Detailed Explanation of mode Parameter

The mode parameter defines the drag area and determines where the element can be moved:

  1. screen Mode
    The element can only be dragged within the current viewport, restricted to the screen boundaries. This mode is suitable for UI elements that need to remain within the screen, such as dialogs or toolbars.

  2. page Mode
    The element can be dragged anywhere within the page boundaries, regardless of viewport limits. The element can be moved to any part of the page, and overflow can be scrolled to view.

  3. container Mode
    The element can only be dragged within a specified container. The drag area is constrained by the container's boundaries. Set the dragArea parameter to specify the container element. This mode is suitable for dragging within specific areas like panels or dialogs.

Cross-Platform Support & TypeScript

drag-kit supports mobile phones, tablets (iPad), and PC with complete cross-platform support and TypeScript type definitions:

Auto Device Detection

The system automatically detects device type and selects appropriate drag implementation without additional configuration:

import { createDraggable, DraggableOptions } from 'drag-kit';

// Complete TypeScript type support
const options: DraggableOptions = {
  mode: 'screen',
  initialPosition: { x: '100px', y: '200px' },
  lockAxis: 'y',
  gridSize: 50,
  snapMode: 'auto',
  onDragStart: (element: HTMLElement) => {
    console.log('Drag started', element);
  },
  onDrag: (element: HTMLElement) => {
    console.log('Dragging', element);
  },
  onDragEnd: (element: HTMLElement) => {
    console.log('Drag ended', element);
  }
};

// Auto type inference: Draggable | MobileDraggable | null
const draggable = createDraggable('elementId', options);

Touch Device Features (Mobile/Tablet)

  • Touch Dragging: Support single-finger touch dragging
  • Prevent Scrolling: Automatically prevent page scrolling during dragging
  • Multi-touch Handling: Only respond to the first touch point
  • Full Compatibility: Support all PC features (grid, snapping, axis locking, etc.)

Manual Control

import { Draggable, MobileDraggable } from 'drag-kit';

// Force PC implementation
const desktopDraggable: Draggable = new Draggable(element, options);

// Force touch device implementation  
const mobileDraggable: MobileDraggable = new MobileDraggable(element, options);

// Detect if it's a touch device (mobile/tablet)
const isMobile: boolean = MobileDraggable.isMobileDevice();

Performance Optimization

To avoid performance overhead, it's recommended to destroy the draggable instance when the element is removed or the view is destroyed, especially when dragging is no longer needed.

Destroying the instance in Vue

<template>
  <div id="draggableElement" style="display: none;">Drag me!</div>
</template>

<script lang="ts">
import { onMounted, onBeforeUnmount } from 'vue';
import { createDraggable } from 'drag-kit';

export default {
  setup() {
    let draggable;

    onMounted(() => {
      draggable = createDraggable('draggableElement', {
        initialPosition: { x: '100px', y: '200px' }
      });
    });
    
    onBeforeUnmount(() => {
      draggable?.destroy();
    });
  }
};
</script>

Destroying the instance in React

import React, { useEffect } from 'react';
import { createDraggable } from 'drag-kit';

const DraggableComponent: React.FC = () => {
  useEffect(() => {
    const draggable = createDraggable('draggableElement', {
      initialPosition: { x: '100px', y: '200px' }
    });
    
    return () => {
      draggable?.destroy();
    };
  }, []);

  return <div id="draggableElement" style={{ display: 'none' }}>Drag me!</div>;
};

export default DraggableComponent;

Example Collection (Vue 3)

效果动态图

代码

<template>
    <div class="example-container">
        <h1 style="padding-top: 80px;">Draggable Examples</h1>
    
        <!-- Basic Dragging (screen mode) -->
        <div id="draggable-screen" class="draggable" ref="basic">
            Basic Draggable
        </div>
    
        <!-- Page Mode Dragging -->
        <div id="draggable-page" class="draggable" ref="page">
            Draggable in Page Mode
        </div>
    
        <!-- Container Boundaries -->
        <div id="drag-container">
            <div id="draggable-bounds" class="draggable" ref="bounds">
                Draggable with Container Area
            </div>
        </div>
    
        <!-- Lock x-axis Dragging -->
        <div id="draggable-x-axis" class="draggable" ref="yAxis">
            Draggable on Y Axis
        </div>
    
        <!-- Grid Mode Dragging -->
        <div id="draggable-grid" class="draggable" ref="grid">
            Draggable with Grid
        </div>

        <!-- Snap Mode (screen mode) -->
        <div id="draggable-snap" class="draggable" ref="snap">
            Draggable with Snap
        </div>
    </div>
</template>
  
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { createDraggable } from 'drag-kit';

const basic = ref<HTMLElement | null>(null);
const page = ref<HTMLElement | null>(null);
const bounds = ref<HTMLElement | null>(null);
const yAxis = ref<HTMLElement | null>(null);
const grid = ref<HTMLElement | null>(null);
const snap = ref<HTMLElement | null>(null); // New snap example
  
onMounted(() => {
    // Basic Dragging
    createDraggable(basic.value!.id);
  
    // Page Mode Dragging
    createDraggable(page.value!.id, {
        mode: 'page',
        initialPosition: { x: '0px', y: '200px' },
    });
  
    // Container Boundaries
    createDraggable(bounds.value!.id, {
        mode: 'container',
        dragArea: document.getElementById('drag-container')!, // Drag area is specified element
        edgeBuffer: 20,          // Set buffer distance to prevent exceeding boundaries
    });

    // Lock x-axis Dragging
    createDraggable(yAxis.value!.id, { 
        lockAxis: 'y', 
        initialPosition: { x: '0px', y: '400px' } 
    });
  
    // Grid Mode Dragging
    createDraggable(grid.value!.id, {
        gridSize: 50,  
        // snapMode: 'auto', // Snap every 50px while dragging
        initialPosition: { x: '0px', y: '600px' },
    });

    // Snap Mode Dragging (screen mode)
    createDraggable(snap.value!.id, {
      mode: 'screen', // Use screen mode
      snapMode: 'auto',
      initialPosition: { x: 'calc(100vw - 230px)', y: '0' },
    });
});
</script>
<style scoped>
.example-container {
    height: 1000px;
}
.draggable {
    width: 230px;
    height: 100px;
    line-height: 40px;
    background-color: lightcoral;
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    cursor: pointer;
    z-index: 111;
}
#drag-container {
    width: 500px;
    height: 300px;
    background: yellow;
    position: fixed;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
</style>

Conclusion

drag-kit is a streamlined and efficient cross-platform drag-and-drop solution for mobile phones, tablets, and PC. If you have any suggestions or issues, please feel free to provide feedback on our GitHub Issues page.