vue-draggable-next

repository·master·Indexed 20 days ago

https://github.com/anish2690/vue-draggable-next

A lightweight, touch-friendly, and TypeScript-ready Vue 3 drag-and-drop component based on Sortable.js. It supports list reordering, dragging between multiple lists using groups, custom drag handles, item cloning, and conditional movement control via the move prop. Version 2.3.0.

Tokens
13.9K
Snippets
34
Records
39
Agent score
69%

What's inside vue-draggable-next

  1. Style ghost, chosen, and drag elements

    master

    You can customize the visual appearance of elements during the drag process by using the ghost-class, chosen-class, and drag-class props. These props allow you to apply specific CSS classes to the placeholder (ghost), the element currently selected (chosen), and the element being actively dragged (drag).

    <!-- Component configuration -->
    <draggable 
      v-model="list"
      :animation="300"
      easing="cubic-bezier(0.4, 0, 0.2, 1)"
      ghost-class="ghost"
      chosen-class="chosen"
      drag-class="drag"
    >
      <!-- items -->
    </draggable>
    
    /* Corresponding CSS */
    .ghost {
      opacity: 0.5;
      background: #c8ebfb;
      border: 2px dashed #2196f3;
    }
    
    .chosen {
      transform: rotate(5deg);
    }
    
    .drag {
      transform: rotate(0deg;
    }
  2. Migrate from vuedraggable (Vue 2) to vue-draggable-next (Vue 3)

    master

    To migrate from the Vue 2 version (vuedraggable) to the Vue 3 version (vue-draggable-next), follow these steps:

    1. Uninstall the old package: npm uninstall vuedraggable.
    2. Install the new package: npm install vue-draggable-next.
    3. Update Imports: Change import draggable from 'vuedraggable' to import { VueDraggableNext } from 'vue-draggable-next' (or use an alias import { VueDraggableNext as draggable } from 'vue-draggable-next').
    4. Update Component Registration: Register VueDraggableNext instead of the old draggable component.
    5. Update Props: Change value to modelValue for v-model support, and move configuration from the options prop to individual props (e.g., :animation instead of :options="{ animation: 150 }").
    6. Update Template Syntax: For optimal performance in Vue 3, use the item-key prop and the #item slot instead of direct children.
    7. Update TypeScript: Use the built-in types like DragChangeEvent and SortableEvent for full type safety.
    npm uninstall vuedraggable
    npm install vue-draggable-next
  3. Run tests for vue-draggable-next

    master

    You can execute the test suite using the following commands via npm or npx:

    • Run all tests: npm run test
    • Run with coverage: npm run test:unit
    • Run a specific test file: npx jest <path_to_file>
    • Run in watch mode: npx jest --watch
    • Full CI/CD suite (types, unit, and build): npm test
    # Run all tests
    npm run test
    
    # Run with coverage
    npm run test:unit
    
    # Run specific test file
    npx jest __tests__/basic-examples.test.ts
    
    # Run in watch mode
    npx jest --watch
  4. Migrate from Vue 2 to Vue 3

    master

    When migrating from the Vue 2 version of vue-draggable-next to the Vue 3 version, note that this package is strictly for Vue 3.

    The recommended way to implement the component in Vue 3 is using the item-key prop combined with the #item slot. This provides better performance and follows the Vue 3 pattern for list rendering. While the traditional v-for approach still works, using the slot pattern is preferred.

    <!-- Recommended Vue 3 approach using item-key and #item slot -->
    <draggable v-model="list" item-key="id" @end="onEnd">
      <template #item="{ element }">
        <div>{{ element.name }}</div>
      </template>
    </draggable>
  5. Optimize for mobile support

    master

    While vue-draggable-next works out of the box on mobile, you can improve the user experience by applying specific CSS to your draggable items. Recommended practices include preventing text selection during drags and ensuring touch targets are large enough.

    .drag-item {
      /* Prevent text selection during drag */
      user-select: none;
      -webkit-user-select: none;
      
      /* Better touch targets */
      min-height: 44px;
      
      /* Smooth feedback */
      transition: transform 0.2s ease;
    }
    
    .drag-item:active {
      transform: scale(1.02);
    }
  6. Register VueDraggableNext globally or locally

    master

    Global Registration (Vue 3)

    Use app.component on your Vue application instance.

    import { createApp } from 'vue'
    import { VueDraggableNext } from 'vue-draggable-next'
    
    const app = createApp({})
    app.component('draggable', VueDraggableNext)

    Local Registration

    Register the component within your component's components option.

    import { VueDraggableNext } from 'vue-draggable-next'
    
    export default {
      components: {
        draggable: VueDraggableNext
      }
    }
  7. Configure Dragging Groups

    master

    The group prop allows you to define how different draggable lists interact. You can pass a simple string (the group name) or a GroupSpec object for advanced control.

    GroupSpec options:

    • name: The unique identifier for the group.
    • pull: Controls how items are pulled from this list. Can be boolean, 'clone', a list of allowed group names, or a callback function (to, from, dragEl, evt) => boolean | string.
    • put: Controls whether items from other lists can be dropped into this list. Can be boolean, a list of allowed group names, or a callback function (to, from, dragEl, evt) => boolean.
    • revertClone: Boolean to determine if clones should revert to their original position.
    // Simple grouping
    // List A
    // <VueDraggable group="my-group" ... />
    // List B
    // <VueDraggable group="my-group" ... />
    
    // Advanced grouping with GroupSpec
    const groupConfig: GroupSpec = {
      name: 'restricted-group',
      pull: 'other-group-name',
      put: (to, from) => {
        // Only allow items from a specific element
        return from.classList.contains('allowed-source')
      }
    }
  8. How the `move` prop works

    master

    The move prop allows you to intercept and potentially cancel a drag operation before it happens. It is a function that receives an event object and the original Sortable event.

    When move is called, the event object is augmented with:

    • relatedContext: Information about the target list/component being hovered over.
    • draggedContext: Information about the item currently being dragged.

    Return true to allow the move, or false to cancel it.

  9. Troubleshoot common drag issues

    master

    If you encounter issues with vue-draggable-next, check the following:

    1. Items not dragging: Verify that the disabled prop is set to false and that every item in your list has a unique key.
    2. Performance issues: Ensure you are using the item-key prop to allow the library to track items efficiently.
    3. Touch not working: Check your CSS for touch-action properties that might be preventing touch events from reaching the component.
    4. Transitions glitching: If using transitions, try setting tag="transition-group" and ensure you are using the correct transition classes.
  10. Use the recommended Vue 3 template syntax with item-key

    master

    While basic usage works, for better performance in Vue 3, you should use the item-key prop and the #item slot pattern. This allows the library to track items more efficiently.

    <template>
      <draggable v-model="list" item-key="id" @change="onChange">
        <template #item="{ element }">
          <div>{{ element.name }}</div>
        </template>
      </draggable>
    </template>
  11. Quick Start with Options API

    master

    To use vue-draggable-next with the Options API, register VueDraggableNext as a component. You can use the :list prop to pass your data array and the v-for directive inside the <draggable> component to render items.

    <template>
      <draggable 
        :list="list"
        class="drag-area"
        @change="handleChange"
      >
        <div 
          v-for="element in list"
          :key="element.id"
          class="drag-item"
        >
          {{ element.name }}
        </div>
      </draggable>
    </template>
    
    <script lang="ts">
    import { defineComponent } from 'vue'
    import { VueDraggableNext } from 'vue-draggable-next'
    
    export default defineComponent({
      components: {
        draggable: VueDraggableNext
      },
      data() {
        return {
          list: [
            { id: 1, name: 'Item 1' },
            { id: 2, name: 'Item 2' },
            { id: 3, name: 'Item 3' }
          ]
        }
      },
      methods: {
        handleChange(event: any) {
          console.log('Changed:', event)
        }
      }
    })
    </script>