UNPKG

resig.js

Version:

Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.

328 lines (323 loc) 25.7 kB
/** * Drag-n-Drop Reorder System * Uses Block.plug() with operad patterns for compositional drag-drop */ import { signal } from '../core/signal'; import { block } from '../blocks'; // Drag container using operad composition export class DragContainer { constructor(container, initialItems = [], config) { this.config = config; this.items = signal(initialItems); this.dragState = signal({ isDragging: false, draggedItem: null, draggedIndex: -1, targetIndex: -1, offset: { x: 0, y: 0 }, }); this.operations = signal([]); this.containerElement = container; this.blocks = new Map(); this.setupContainer(); this.bindEvents(); this.render(); } // Operad composition: plug draggable behavior into blocks createDraggableBlock(item, index) { const itemBlock = block('item', 0, (parent, _props, _children) => { const element = document.createElement('div'); element.innerHTML = this.config.itemRenderer(item, index); parent.appendChild(element); return element; }); // Plug drag behavior into item block using operad composition const draggableBlock = this.plugDragBehavior(itemBlock, item, index); return draggableBlock; } // Block.plug() implementation for drag behavior plugDragBehavior(itemBlock, _item, index) { return block('draggable-item', 0, (parent, _props, _children) => { const wrapper = document.createElement('div'); wrapper.className = 'draggable-item'; wrapper.setAttribute('data-index', index.toString()); wrapper.setAttribute('draggable', 'true'); const isDragging = this.dragState.value().draggedIndex === index; wrapper.style.cssText = ` cursor: grab; transition: transform 0.2s ease; ${isDragging ? 'opacity: 0.5; transform: scale(0.95);' : ''} `; const content = itemBlock.render(wrapper); wrapper.appendChild(content); parent.appendChild(wrapper); return wrapper; }); } // Setup container with drag-drop styling setupContainer() { this.containerElement.style.position = 'relative'; this.containerElement.style.minHeight = '50px'; this.containerElement.classList.add('drag-container'); // Add CSS for drag states const style = document.createElement('style'); style.textContent = ` .drag-container { user-select: none; } .draggable-item { position: relative; z-index: 1; } .draggable-item:hover { cursor: grab; } .draggable-item.dragging { cursor: grabbing; z-index: 1000; pointer-events: none; } .drag-placeholder { background: rgba(0, 123, 255, 0.1); border: 2px dashed rgba(0, 123, 255, 0.3); border-radius: 4px; margin: 2px 0; min-height: 40px; transition: all 0.2s ease; } .drag-ghost { position: fixed; pointer-events: none; z-index: 10000; opacity: 0.8; transform: rotate(5deg); box-shadow: 0 5px 15px rgba(0,0,0,0.3); } `; document.head.appendChild(style); } // Bind drag events using operad composition bindEvents() { // Dragstart event this.containerElement.addEventListener('dragstart', (e) => { const target = e.target; const draggableItem = target.closest('.draggable-item'); if (!draggableItem) return; const index = parseInt(draggableItem.dataset.index || '0'); const item = this.items.value()[index]; // Create drag ghost this.createDragGhost(draggableItem, e); // Update drag state const newState = { isDragging: true, draggedItem: item, draggedIndex: index, targetIndex: index, offset: { x: e.clientX - draggableItem.getBoundingClientRect().left, y: e.clientY - draggableItem.getBoundingClientRect().top, }, }; draggableItem.classList.add('dragging'); this.dragState._set(newState); }); // Dragover event for drop zones this.containerElement.addEventListener('dragover', (e) => { e.preventDefault(); const currentState = this.dragState.value(); if (!currentState.isDragging) return currentState; const targetIndex = this.getDropIndex(e.clientY); return { ...currentState, targetIndex, }; }); // Drop event this.containerElement.addEventListener('drop', (e) => { e.preventDefault(); const currentState = this.dragState.value(); if (!currentState.isDragging || !currentState.draggedItem) { this.resetDragState(); return; } // Create drag operation const operation = { source: currentState.draggedIndex, target: currentState.targetIndex, item: currentState.draggedItem, timestamp: Date.now(), }; // Apply reorder using operad composition this.applyReorder(operation); // Clean up this.removeDragGhost(); document.querySelectorAll('.draggable-item').forEach((el) => { el.classList.remove('dragging'); }); this.resetDragState(); }); // Dragend event this.containerElement.addEventListener('dragend', () => { this.removeDragGhost(); document.querySelectorAll('.draggable-item').forEach((el) => { el.classList.remove('dragging'); }); this.resetDragState(); }); } // Create visual drag ghost createDragGhost(element, e) { const ghost = element.cloneNode(true); ghost.classList.add('drag-ghost'); ghost.style.width = element.offsetWidth + 'px'; ghost.style.left = e.clientX - this.dragState.value().offset.x + 'px'; ghost.style.top = e.clientY - this.dragState.value().offset.y + 'px'; document.body.appendChild(ghost); // Update ghost position on mouse move const updateGhost = (e) => { ghost.style.left = e.clientX - this.dragState.value().offset.x + 'px'; ghost.style.top = e.clientY - this.dragState.value().offset.y + 'px'; }; document.addEventListener('dragover', updateGhost); // Store cleanup function ghost._cleanup = () => { document.removeEventListener('dragover', updateGhost); }; } // Remove drag ghost removeDragGhost() { const ghost = document.querySelector('.drag-ghost'); if (ghost) { ghost._cleanup?.(); ghost.remove(); } } // Calculate drop index based on mouse position getDropIndex(clientY) { const items = this.containerElement.querySelectorAll('.draggable-item'); const tolerance = this.config.tolerance || 5; for (let i = 0; i < items.length; i++) { const item = items[i]; const rect = item.getBoundingClientRect(); const midpoint = rect.top + rect.height / 2; if (clientY < midpoint + tolerance) { return i; } } return items.length; } // Apply reorder using operad composition applyReorder(operation) { const currentItems = this.items.value(); const newItems = [...currentItems]; // Remove item from source position const [movedItem] = newItems.splice(operation.source, 1); // Insert at target position const insertIndex = operation.target > operation.source ? operation.target - 1 : operation.target; newItems.splice(insertIndex, 0, movedItem); // Update items signal this.items._set(newItems); // Record operation this.operations._set([...this.operations.value(), operation]); // Notify callback this.config.onReorder?.(newItems, operation); // Re-render this.render(); } // Reset drag state resetDragState() { return { isDragging: false, draggedItem: null, draggedIndex: -1, targetIndex: -1, offset: { x: 0, y: 0 }, }; } // Render items using block composition render() { const items = this.items.value(); this.blocks.clear(); // Create blocks for each item using operad composition const itemBlocks = items.map((item, index) => { const block = this.createDraggableBlock(item, index); this.blocks.set(index, block); return block.render(document.createElement('div')); }); // Render placeholder if dragging const dragState = this.dragState.value(); if (dragState.isDragging && dragState.targetIndex !== dragState.draggedIndex) { const placeholder = document.createElement('div'); placeholder.className = 'drag-placeholder'; placeholder.innerHTML = '<div class="drag-placeholder"></div>'; itemBlocks.splice(dragState.targetIndex, 0, placeholder); } // Clear container and append all blocks this.containerElement.innerHTML = ''; itemBlocks.forEach((block) => { if (typeof block === 'string') { this.containerElement.innerHTML += block; } else { this.containerElement.appendChild(block); } }); } // Public API getItems() { return this.items.value(); } setItems(items) { this.items._set(items); this.render(); } addItem(item, index) { const currentItems = this.items.value(); const newItems = [...currentItems]; if (index !== undefined) { newItems.splice(index, 0, item); } else { newItems.push(item); } this.items._set(newItems); this.render(); } removeItem(index) { const currentItems = this.items.value(); const newItems = currentItems.filter((_, i) => i !== index); this.items._set(newItems); this.render(); } getOperations() { return this.operations.value(); } clearOperations() { this.operations._set([]); } } // Factory function for creating drag containers export const createDragContainer = (container, items, config) => { return new DragContainer(container, items, config); }; // Operad composition utilities export const composeDragBehaviors = (behaviors) => { return (item, index) => { return behaviors.reduce((acc, behavior) => { const behaviorBlock = behavior(item, index); return block('composed', 0, (parent, _props, _children) => { const accElement = acc.render(parent); const behaviorElement = behaviorBlock.render(parent); parent.appendChild(accElement); parent.appendChild(behaviorElement); return parent; }); }, block('empty', 0, (parent, _props, _children) => parent)); }; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZy1kcm9wLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2V4dGVuc2lvbnMvZHJhZy1kcm9wLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBVSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNoRCxPQUFPLEVBQVMsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBZ0N6QywwQ0FBMEM7QUFDMUMsTUFBTSxPQUFPLGFBQWE7SUFPeEIsWUFDRSxTQUFzQixFQUN0QixlQUFvQixFQUFFLEVBQ2QsTUFLUDtRQUxPLFdBQU0sR0FBTixNQUFNLENBS2I7UUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztZQUN0QixVQUFVLEVBQUUsS0FBSztZQUNqQixXQUFXLEVBQUUsSUFBSTtZQUNqQixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDZixNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7U0FDdkIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7UUFFeEIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVELDBEQUEwRDtJQUNsRCxvQkFBb0IsQ0FBQyxJQUFPLEVBQUUsS0FBYTtRQUNqRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxF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