Introducing Vue DnD Kit: A New Library for Creating Drag and Drop Interfaces in Vue 3 ๐
Hello, DEV Community! Today I want to introduce my new project โ Vue DnD Kit, a lightweight and performant library for creating drag and drop interfaces for Vue 3.
Why did I create another drag and drop library? ๐ค
There are already several solutions for implementing drag and drop in the Vue ecosystem, but most of them are either outdated or have limitations in performance and flexibility. Inspired by the popular dnd-kit library for React, I decided to create a similar solution for Vue 3 that would be:
- Lightweight โ๏ธ โ minimal impact on bundle size
- Performant โก โ optimized to work even with large lists
- Flexible ๐ โ allows implementing virtually any drag and drop scenario
- Accessible โฟ โ full support for keyboard navigation and screen readers
Key Features of Vue DnD Kit โจ
1. Simple API based on composable functions ๐
The library provides an intuitive API based on Vue 3 composable functions:
import { useDraggable, useDroppable } from '@vue-dnd-kit/core';
// For draggable element
const { elementRef, handleDragStart, isDragging } = useDraggable();
// For droppable area
const { elementRef: dropRef, isOvered } = useDroppable({
events: {
onDrop: () => console.log('Element dropped!')
}
});
2. Full keyboard navigation support โจ๏ธ
One of the unique features of the library is full keyboard control support:
- W A S D for moving elements
- Space/Enter for selecting and dropping
- Escape to cancel drag operation
- Tab for navigating between elements
This makes your interfaces accessible to all users, including those who cannot use a mouse.
3. High performance ๐๏ธ
Vue DnD Kit is optimized to work even with large lists and complex interfaces:
- Minimal component re-renders
- Efficient DOM operations
- Prevention of memory leaks
4. Full customization ๐จ
- Ability to change the container appearance
- Ability to change the appearance of the dragged element(s)
- Group support
- Ability to completely write your own element detection sensor where automatic element priority detection and its availability works under the hood (a zone may have groups into which the element(s) cannot enter)
- Throttle support with custom sensor
- Support for animations with both CSS and JS animation libraries like GSAP, Anime.js, etc.
- Ability to completely write your own drop logic
Usage Examples ๐ป
<script setup>
import { ref } from 'vue';
import Draggable from './components/Draggable.vue';
import Droppable from './components/Droppable.vue';
const elementInDropZone = ref(false);
const handleDrop = () => (elementInDropZone.value = true);
const handleEnd = () => (elementInDropZone.value = false);
</script>
<template>
<div class="container">
<Draggable v-if="!elementInDropZone"> Drag me! </Draggable>
<Droppable @drop="handleDrop">
<Draggable
v-if="elementInDropZone"
@end="handleEnd"
>
I'm in the drop zone!
</Draggable>
</Droppable>
</div>
</template>
SortableList ๐
Drag.vue
<script setup lang="ts">
import { useDraggable } from '@vue-dnd-kit/core';
import { computed } from 'vue';
const props = defineProps<{
source?: any[];
index?: number;
}>();
const { elementRef, handleDragStart, isOvered } = useDraggable({
data: computed(() => ({
source: props.source,
index: props.index,
})),
});
</script>
<template>
<div
ref="elementRef"
@pointerdown="handleDragStart"
>
<slot />
<hr v-if="isOvered" />
</div>
</template>
List
<script setup lang="ts">
import { DnDOperations, useDroppable } from '@vue-dnd-kit/core';
import Drag from 'src/components/Drag.vue';
import { ref } from 'vue';
const items = ref([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
]);
const { elementRef } = useDroppable({
events: {
onDrop: (store) => {
DnDOperations.applyTransfer(store);
},
},
});
</script>
<template>
<div ref="elementRef">
<TransitionGroup name="sortable-list">
<Drag
v-for="(item, index) in items"
:key="item.id"
:source="items"
:index="index"
>
{{ item.name }}
</Drag>
</TransitionGroup>
</div>
</template>
<style>
.sortable-list-move,
.sortable-list-enter-active,
.sortable-list-leave-active {
transition: all 0.5s ease;
}
.sortable-list-enter-from,
.sortable-list-leave-to {
opacity: 0;
transform: translateX(30px);
}
</style>
How to start using ๐
Installation ๐ฆ
#npm
npm install @vue-dnd-kit/core @vueuse/core
#yarn
yarn add @vue-dnd-kit/core @vueuse/core
#pnpm
pnpm add @vue-dnd-kit/core @vueuse/core
Adding as a plugin ๐
import { createApp } from 'vue';
import App from './App.vue';
import VueDnDKitPlugin from '@vue-dnd-kit/core';
const app = createApp(App);
app.use(VueDnDKitPlugin);
app.mount('#app');
Vue DnD Kit Ecosystem ๐
It's important to note that @vue-dnd-kit/core is just the main package of the library, which provides basic functionality for drag and drop. Additional packages are in development:
- @vue-dnd-kit/utils ๐ ๏ธ โ a set of utilities to simplify typical scenarios
- @vue-dnd-kit/components ๐งฉ โ ready-made components for quick integration (sortable lists, kanban boards, etc.)
- @vue-dnd-kit/devtools ๐ โ a plugin for Vue DevTools that will allow debugging the state of drag and drop in the application
These additional packages will significantly simplify the development of complex drag and drop interfaces and will be released in the near future.
Future Plans ๐ฎ
This is just the beginning! Plans include:
- Creating additional packages with ready-made components for typical scenarios
- Improving documentation and examples
- Expanding capabilities for working with nested lists
- Optimizing for even higher performance
Conclusion ๐
Vue DnD Kit is my contribution to the Vue ecosystem, which I hope will help developers create more interactive and accessible interfaces. It currently has a stable API and will be improved in the future. Documentation has already been added but will be improved. The library is open source, and I welcome any contributions from the community!
Repository: github.com/zizigy/vue-dnd-kit
Documentation: zizigy.github.io/vue-dnd-kit
I look forward to your feedback and suggestions in the comments!
Top comments (0)