CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue-draggable-resizable

Vue3 Component for resizable and draggable elements

Pending
Overview
Eval results
Files

component-events.mddocs/

Component Events

Event system providing real-time feedback for drag and resize operations, plus lifecycle events for component activation state.

Capabilities

Lifecycle Events

Events related to component activation state and user interaction.

/**
 * Component lifecycle events
 */
interface LifecycleEvents {
  /** Emitted when component becomes active (gains focus/selection) */
  activated(): void;
  
  /** Emitted when component becomes inactive (loses focus/selection) */
  deactivated(): void;
  
  /** Emitted for v-model support when active state changes */
  'update:active'(active: boolean): void;
}

Usage Examples:

<template>
  <vue-draggable-resizable
    @activated="onActivated"
    @deactivated="onDeactivated"
    :prevent-deactivation="preventDeactivate"
  >
    Click me to activate
  </vue-draggable-resizable>
</template>

<script>
export default {
  data() {
    return {
      isActive: false,
      preventDeactivate: false
    };
  },
  methods: {
    onActivated() {
      console.log('Component activated');
      this.isActive = true;
      // Show selection UI, enable keyboard shortcuts, etc.
    },
    
    onDeactivated() {
      console.log('Component deactivated');
      this.isActive = false;
      // Hide selection UI, disable keyboard shortcuts, etc.
    }
  }
}
</script>

V-Model Support:

<template>
  <!-- Two-way binding with active state -->
  <vue-draggable-resizable
    v-model:active="isElementActive"
  >
    Element with v-model binding
  </vue-draggable-resizable>
  
  <p>Element is {{ isElementActive ? 'active' : 'inactive' }}</p>
</template>

<script>
export default {
  data() {
    return {
      isElementActive: false
    };
  }
}
</script>

Drag Events

Events fired during drag operations providing position feedback.

/**
 * Drag operation events with position coordinates
 */
interface DragEvents {
  /** 
   * Emitted continuously during drag operation
   * @param left - Current X position (left coordinate)
   * @param top - Current Y position (top coordinate)
   */
  dragging(left: number, top: number): void;
  
  /** 
   * Emitted when drag operation completes
   * @param left - Final X position (left coordinate)
   * @param top - Final Y position (top coordinate)
   */
  dragStop(left: number, top: number): void;
}

Usage Examples:

<template>
  <vue-draggable-resizable
    @dragging="onDragging"
    @dragStop="onDragStop"
    :x="elementX"
    :y="elementY"
  >
    Drag me around
  </vue-draggable-resizable>
  
  <div>Position: {{ elementX }}, {{ elementY }}</div>
</template>

<script>
export default {
  data() {
    return {
      elementX: 100,
      elementY: 50,
      dragHistory: []
    };
  },
  methods: {
    onDragging(left, top) {
      // Update position display in real-time
      this.elementX = left;
      this.elementY = top;
      
      // Track drag path
      this.dragHistory.push({ x: left, y: top, timestamp: Date.now() });
      
      // Send position updates to server
      this.throttledPositionUpdate(left, top);
    },
    
    onDragStop(left, top) {
      console.log(`Drag completed at: ${left}, ${top}`);
      
      // Save final position
      this.savePosition(left, top);
      
      // Clear drag history
      this.dragHistory = [];
    },
    
    throttledPositionUpdate: _.throttle(function(x, y) {
      // Update server every 100ms during drag
      this.$emit('position-changed', { x, y });
    }, 100)
  }
}
</script>

Resize Events

Events fired during resize operations providing size and position feedback.

/**
 * Resize operation events with dimension and position data
 */
interface ResizeEvents {
  /** 
   * Emitted continuously during resize operation
   * @param left - Current X position (left coordinate)
   * @param top - Current Y position (top coordinate)
   * @param width - Current width
   * @param height - Current height
   */
  resizing(left: number, top: number, width: number, height: number): void;
  
  /** 
   * Emitted when resize operation completes
   * @param left - Final X position (left coordinate)
   * @param top - Final Y position (top coordinate)
   * @param width - Final width
   * @param height - Final height
   */
  resizeStop(left: number, top: number, width: number, height: number): void;
}

Usage Examples:

<template>
  <vue-draggable-resizable
    @resizing="onResizing"
    @resizeStop="onResizeStop"
    :w="elementWidth"
    :h="elementHeight"
  >
    <div>Size: {{ elementWidth }}x{{ elementHeight }}</div>
  </vue-draggable-resizable>
</template>

<script>
export default {
  data() {
    return {
      elementWidth: 200,
      elementHeight: 150,
      minArea: 5000,
      maxArea: 50000
    };
  },
  methods: {
    onResizing(left, top, width, height) {
      // Update size display in real-time
      this.elementWidth = width;
      this.elementHeight = height;
      
      // Validate size constraints
      const area = width * height;
      if (area < this.minArea) {
        console.warn('Element too small!');
      } else if (area > this.maxArea) {
        console.warn('Element too large!');
      }
      
      // Update layout of other elements
      this.updateLayout({ left, top, width, height });
    },
    
    onResizeStop(left, top, width, height) {
      console.log(`Resize completed: ${width}x${height} at ${left},${top}`);
      
      // Save dimensions
      this.saveDimensions(width, height);
      
      // Trigger layout recalculation
      this.$nextTick(() => {
        this.recalculateLayout();
      });
    },
    
    updateLayout(bounds) {
      // Update other components based on new size
      this.$emit('element-resized', bounds);
    }
  }
}
</script>

Event Usage Patterns

Common patterns for handling component events effectively.

/**
 * Common event handling patterns and utilities
 */
interface EventPatterns {
  /** Debounced event handler to reduce update frequency */
  debouncedHandler: (delay: number, callback: Function) => Function;
  
  /** Event handler with validation and constraints */
  constrainedHandler: (validator: Function, callback: Function) => Function;
  
  /** Event handler with state synchronization */
  syncedHandler: (stateProperty: string, callback: Function) => Function;
}

Usage Examples:

<template>
  <vue-draggable-resizable
    @dragging="debouncedDragHandler"
    @resizing="constrainedResizeHandler"
    @activated="syncActivationState"
  >
    Advanced event handling
  </vue-draggable-resizable>
</template>

<script>
import { debounce } from 'lodash';

export default {
  data() {
    return {
      position: { x: 0, y: 0 },
      size: { width: 200, height: 150 },
      isActive: false
    };
  },
  
  methods: {
    // Debounced drag handler to reduce server calls
    debouncedDragHandler: debounce(function(left, top) {
      this.position = { x: left, y: top };
      this.saveToServer();
    }, 300),
    
    constrainedResizeHandler(left, top, width, height) {
      // Apply business logic constraints
      const aspectRatio = this.originalWidth / this.originalHeight;
      const constrainedHeight = width / aspectRatio;
      
      if (Math.abs(height - constrainedHeight) > 10) {
        // Emit correction event if aspect ratio is wrong
        this.$emit('aspect-ratio-corrected', {
          original: { width, height },
          corrected: { width, height: constrainedHeight }
        });
      }
      
      this.size = { width, height };
    },
    
    syncActivationState() {
      this.isActive = true;
      // Sync with global state management
      this.$store.commit('setActiveElement', this.$el);
    }
  }
}
</script>

Install with Tessl CLI

npx tessl i tessl/npm-vue-draggable-resizable

docs

advanced-features.md

component-events.md

component-props.md

index.md

tile.json