Vue3 Component for resizable and draggable elements
npx @tessl/cli install tessl/npm-vue-draggable-resizable@3.0.0Vue Draggable Resizable is a Vue 3 component that provides draggable and resizable functionality for DOM elements. It offers comprehensive customization options for styling, behavior, constraints, and event handling, making it ideal for building interactive dashboards, layout builders, and any application requiring movable and resizable UI elements.
npm install vue-draggable-resizableimport VueDraggableResizable from "vue-draggable-resizable";
import "vue-draggable-resizable/style.css";For plugin installation:
import { install } from "vue-draggable-resizable";
app.use({ install });<template>
<div style="height: 500px; width: 500px; position: relative; border: 1px solid #ccc;">
<vue-draggable-resizable
:w="200"
:h="150"
:x="50"
:y="50"
:parent="true"
@dragging="onDrag"
@resizing="onResize"
>
<p>I can be dragged and resized!</p>
</vue-draggable-resizable>
</div>
</template>
<script>
import VueDraggableResizable from "vue-draggable-resizable";
import "vue-draggable-resizable/style.css";
export default {
components: {
VueDraggableResizable
},
methods: {
onDrag(left, top) {
console.log('Dragging to:', left, top);
},
onResize(left, top, width, height) {
console.log('Resizing to:', width, height, 'at:', left, top);
}
}
}
</script>Vue Draggable Resizable is built around several key concepts:
Core configuration options for behavior, styling, positioning, sizing, and constraints. The component accepts over 30 props covering all aspects of draggable and resizable behavior.
// Positioning & Sizing Props
interface PositioningProps {
x: number; // Initial X position (default: 0)
y: number; // Initial Y position (default: 0)
w: number | string; // Initial width (default: 200, supports 'auto')
h: number | string; // Initial height (default: 200, supports 'auto')
z: number | string; // Z-index (default: 'auto')
}
// Constraint Props
interface ConstraintProps {
minWidth: number; // Minimum width (default: 0)
minHeight: number; // Minimum height (default: 0)
maxWidth: number; // Maximum width (default: null)
maxHeight: number; // Maximum height (default: null)
parent: boolean; // Constrain to parent bounds (default: false)
grid: [number, number]; // Grid snapping [x, y] (default: [1, 1])
axis: 'x' | 'y' | 'both'; // Drag axis constraint (default: 'both')
}Event system providing real-time feedback for drag and resize operations, plus lifecycle events for component activation state.
// Event Signatures
interface ComponentEvents {
// Lifecycle Events
activated(): void; // Component becomes active
deactivated(): void; // Component becomes inactive
'update:active'(active: boolean): void; // V-model support for active prop
// Drag Events
dragging(left: number, top: number): void; // During drag
dragStop(left: number, top: number): void; // Drag complete
// Resize Events
resizing(left: number, top: number, width: number, height: number): void; // During resize
resizeStop(left: number, top: number, width: number, height: number): void; // Resize complete
}Advanced functionality including aspect ratio locking, handle customization, custom CSS classes, and programmatic control methods.
// Advanced Configuration
interface AdvancedFeatures {
lockAspectRatio: boolean; // Maintain aspect ratio (default: false)
handles: HandleType[]; // Enabled resize handles
scale: number | [number, number]; // Parent element scale factor
dragHandle: string; // CSS selector for drag handle
dragCancel: string; // CSS selector to prevent dragging
}
// Programmatic Methods
interface ComponentMethods {
moveHorizontally(val: number): void; // Set horizontal position
moveVertically(val: number): void; // Set vertical position
changeWidth(val: number): void; // Set width
changeHeight(val: number): void; // Set height
}
// Handle Types
type HandleType = 'tl' | 'tm' | 'tr' | 'mr' | 'br' | 'bm' | 'bl' | 'ml';// Main Component Type
interface VueDraggableResizable {
// Component instance with all props, methods, and reactive state
}
// Handle Types
type HandleType = 'tl' | 'tm' | 'tr' | 'mr' | 'br' | 'bm' | 'bl' | 'ml';
// Callback Function Types
type DragStartCallback = (event: MouseEvent | TouchEvent) => boolean | void;
type DragCallback = (x: number, y: number) => boolean | void;
type ResizeStartCallback = (handle: HandleType, event: MouseEvent | TouchEvent) => boolean | void;
type ResizeCallback = (handle: HandleType, x: number, y: number, width: number, height: number) => boolean | void;
// Configuration Types
interface GridConfig {
0: number; // X grid size
1: number; // Y grid size
}
interface ScaleConfig {
0: number; // X scale factor
1: number; // Y scale factor
}
// Slot Types
interface Slot {
// Vue slot content
}
// Axis Constraint Type
type AxisType = 'x' | 'y' | 'both';
// Size Value Type
type SizeValue = number | 'auto';
// Z-Index Value Type
type ZIndexValue = number | 'auto';
// Event Types
interface MouseEvent extends Event {
clientX: number;
clientY: number;
// Standard MouseEvent properties
}
interface TouchEvent extends Event {
touches: TouchList;
// Standard TouchEvent properties
}