Third-party drag integration allows you to bridge existing drag-and-drop libraries (like Sortable.js, dragula, or custom implementations) with FullCalendar. This provides flexibility to use your preferred drag system while maintaining FullCalendar's drop handling.
Bridges third-party drag-and-drop systems with FullCalendar by detecting drag operations and translating them into FullCalendar-compatible events.
/**
* Bridges third-party drag-n-drop systems with FullCalendar
* Must be instantiated and destroyed by caller
* @param containerOrSettings - Event target container or settings object
* @param settings - Configuration options when first param is container
*/
export class ThirdPartyDraggable {
constructor(
containerOrSettings?: EventTarget | ThirdPartyDraggableSettings,
settings?: ThirdPartyDraggableSettings
);
/** Destroys the third-party draggable instance and removes listeners */
destroy(): void;
/** Internal dragging implementation (read-only) */
readonly dragging: InferredElementDragging;
}Usage Examples:
import { ThirdPartyDraggable } from '@fullcalendar/interaction';
// Global drag detection (detects drags anywhere in document)
const globalDraggable = new ThirdPartyDraggable({
itemSelector: '[data-event]',
eventData: (el) => ({
title: el.dataset.title,
duration: el.dataset.duration
})
});
// Container-specific drag detection
const containerEl = document.getElementById('external-container');
const containerDraggable = new ThirdPartyDraggable(containerEl, {
itemSelector: '.draggable-event',
mirrorSelector: '.drag-mirror',
eventData: {
title: 'Third-party Event',
backgroundColor: '#ff9f43'
}
});
// Cleanup
globalDraggable.destroy();
containerDraggable.destroy();Configuration interface for third-party drag integration.
interface ThirdPartyDraggableSettings {
/** Event data or function to generate event data when dropped */
eventData?: DragMetaGenerator;
/** CSS selector for draggable items */
itemSelector?: string;
/** CSS selector for drag mirror element */
mirrorSelector?: string;
}Property Details:
[data-event] for document container)The ThirdPartyDraggable constructor supports multiple patterns:
// Pattern 1: Settings only (uses document as container)
new ThirdPartyDraggable(settings);
// Pattern 2: Container and settings
new ThirdPartyDraggable(container, settings);
// Pattern 3: Document container explicitly
new ThirdPartyDraggable(document, settings);Pattern Examples:
// Document-wide detection with default selector
const docDraggable = new ThirdPartyDraggable({
eventData: { title: 'Document Event' }
}); // Uses [data-event] selector by default
// Specific container
const listContainer = document.getElementById('sortable-list');
const listDraggable = new ThirdPartyDraggable(listContainer, {
itemSelector: '.list-item',
eventData: (el) => ({ title: el.textContent })
});
// Document with custom selector
const customDraggable = new ThirdPartyDraggable(document, {
itemSelector: '.custom-draggable',
eventData: { title: 'Custom Event' }
});Sortable.js Integration:
import Sortable from 'sortablejs';
import { ThirdPartyDraggable } from '@fullcalendar/interaction';
// Set up Sortable.js
const listEl = document.getElementById('sortable-list');
const sortable = Sortable.create(listEl, {
group: {
name: 'shared',
pull: 'clone',
put: false
},
sort: false,
ghostClass: 'sortable-ghost'
});
// Bridge with FullCalendar
const thirdPartyDraggable = new ThirdPartyDraggable(listEl, {
itemSelector: '.sortable-item',
mirrorSelector: '.sortable-ghost',
eventData: (el) => ({
title: el.textContent,
backgroundColor: el.dataset.color,
duration: el.dataset.duration || '01:00'
})
});Custom Drag Library Integration:
// Assuming a custom drag library that adds 'dragging' class
const customDraggable = new ThirdPartyDraggable({
itemSelector: '.my-draggable',
mirrorSelector: '.dragging', // Element with dragging class
eventData: (el) => {
const config = JSON.parse(el.dataset.eventConfig || '{}');
return {
title: config.title || el.textContent,
backgroundColor: config.color || '#007bff',
extendedProps: config.props || {}
};
}
});Multiple Third-Party Sources:
// Different drag sources with different configurations
const sidebarDraggable = new ThirdPartyDraggable(
document.getElementById('sidebar'),
{
itemSelector: '.sidebar-item',
eventData: (el) => ({
title: el.dataset.title,
backgroundColor: '#28a745',
extendedProps: { source: 'sidebar' }
})
}
);
const toolboxDraggable = new ThirdPartyDraggable(
document.getElementById('toolbox'),
{
itemSelector: '.tool-item',
eventData: (el) => ({
title: el.dataset.name,
backgroundColor: '#dc3545',
extendedProps: {
source: 'toolbox',
toolType: el.dataset.type
}
})
}
);Dynamic Event Data with Complex Logic:
const complexDraggable = new ThirdPartyDraggable({
itemSelector: '.complex-item',
eventData: (el) => {
// Complex logic based on element state
const isUrgent = el.classList.contains('urgent');
const category = el.dataset.category;
const baseColor = el.style.backgroundColor;
return {
title: el.querySelector('.item-title').textContent,
backgroundColor: isUrgent ? '#ff0000' : baseColor,
borderColor: isUrgent ? '#cc0000' : 'transparent',
duration: isUrgent ? '00:30' : '01:00',
extendedProps: {
category,
urgent: isUrgent,
originalId: el.id,
metadata: JSON.parse(el.dataset.metadata || '{}')
}
};
}
});Third-party dragging integrates with the same FullCalendar event system:
const calendar = new Calendar(calendarEl, {
plugins: [interactionPlugin],
drop: (info) => {
console.log('Third-party element dropped:', info.draggedEl);
// info.draggedEl is the original dragged element
// info.jsEvent is the drop event
// info.date, info.dateStr, info.allDay provide drop location info
},
eventReceive: (info) => {
console.log('Event created from third-party drag:', info.event.title);
// info.event is the newly created event
// info.relatedEvents are any related events
// info.revert() can undo the operation
}
});Pointer Events: The third-party drag system automatically disables pointer event checking for drag mirrors, since third-party libraries may not follow FullCalendar's pointer event conventions.
Mirror Detection: If your third-party library creates drag mirrors/ghosts, specify the mirrorSelector to help FullCalendar identify the visual feedback element.
Performance: For document-wide detection, consider using specific containers when possible to reduce event listener overhead.
Cleanup: Always call destroy() when removing third-party draggable instances to prevent memory leaks.