@alekstar79/draggable-resizable-container
v1.0.9
Published
A modern TypeScript library for managing draggable and resizable containers
Maintainers
Readme
Draggable and Resizable Container
A modern, lightweight, and extensible TypeScript library for creating draggable and resizable containers (windows, dialogs) in your web applications. It features a reactive core, a powerful plugin system, and a clean API.
Features
- Draggable & Resizable: Smooth, performant dragging and resizing of containers with multiple handle directions.
- Reactive Core: Built with
@alekstar79/reactive-event-systemfor efficient state management and event handling. - Extensible Plugin System: Easily add new features like snapping, docking, or state persistence.
- Rich Event System: Subscribe to a wide range of events (
dragStart,drag,dragEnd,resize, etc.). - Boundary Constraints: Confine containers to the viewport or a parent element.
- Customizable: Control movement direction, resize handles, and more.
- Touch Device Support: Works on both desktop and mobile devices.
- Template Loading: A system for loading content from HTML templates.
- State Persistence: Save and restore container states using
localStorage. - TypeScript First: Written entirely in TypeScript for strong typing and better developer experience.
Installation
You can install the library using npm or yarn:
npm install @alekstar79/draggable-resizable-containeror
yarn add @alekstar79/draggable-resizable-containerYou also need to import the base styles for the library to work correctly.
import '@alekstar79/draggable-resizable-container/styles.css'Quick Start
Here's a simple example of how to create a draggable and resizable container.
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Draggable and Resizable Container</title>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"
rel="stylesheet"
>
<script src="src/index.ts" type="module"></script>
</head>
<body></body>
</html>TypeScript:
- See code from the example
ContainerManager API
The ContainerManager is the core class of the library.
new ContainerManager(element, config)
Creates a new ContainerManager instance.
element: TheHTMLElementto be managed.config(optional): AContainerConfigobject for customization.
ContainerConfig
| Property | Type | Description |
|-----------------------|-----------------|--------------------------------------------------------------------------------|
| mode | MovementMode | 'smooth' (default) or 'pinned'. |
| boundaries | Boundaries | An object with minWidth, minHeight, maxWidth, maxHeight. |
| draggingDirection | DirectionMode | 'all' (default), 'horizontal', or 'vertical'. |
| constrainToViewport | boolean | If true, constrains the container to the viewport. Default is false. |
| constrainToParent | boolean | If true, constrains the container to its parent element. Default is false. |
| resize | ResizeConfig | Configuration for resizing. |
Methods
getState(): ContainerState: Returns the current state (x,y,width,height) of the container.setState(state: Partial<ContainerState>): Sets the state of the container.getMode(): MovementMode: Returns the current movement mode.setMode(mode: MovementMode): Sets the movement mode.getDirection(): DirectionMode: Returns the current dragging direction.setDirection(direction: DirectionMode): Sets the dragging direction.on(event: string, callback: (data: ContainerEvent) => void): Subscribes to an event.off(event: string, callback: (data: ContainerEvent) => void): Unsubscribes from an event.destroy(): Cleans up theContainerManagerinstance and removes event listeners.
Events
You can subscribe to the following events using the on method:
dragStart,drag,dragEndresizeStart,resize,resizeEndmodeChangestateChangeviewportResize
Plugin System
The library has a powerful plugin system that allows you to extend its functionality.
Using a Plugin
To use a plugin, simply import it and pass it to the use method of your ContainerManager instance.
import { ContainerManager, SnappingPlugin } from '@alekstar79/draggable-resizable-container'
const manager = new ContainerManager(containerElement);
manager.use(new SnappingPlugin({
snapStep: 20,
enabled: true,
}));Included Plugins
SnappingPlugin
Adds snapping functionality to the container.
Options:
snapStep: The size of the grid to snap to (in pixels). Default is10.enabled: Whether snapping is enabled. Default istrue.
Methods added to ContainerManager:
setSnapStep(step: number)setSnappingEnabled(enabled: boolean)getSnappingConfig(): SnappingPluginOptions
EdgeDockingPlugin
Allows containers to be "docked" to the edges of the screen.
Options:
edgeThreshold: The distance from the edge (in pixels) at which docking is triggered. Default is30.visiblePeek: The amount of the container (in pixels) that remains visible when docked. Default is20.
Methods added to ContainerManager:
isContainerDocked(element: HTMLElement): booleangetContainerDockEdge(element: HTMLElement): Edge | null
StatePersistencePlugin
Saves the state of containers to localStorage and restores it on page load.
Options:
containerId: A unique ID for the container, required for persistence.isDemo: A flag to indicate if the container is part of the demo (for demo-specific logic).
Example:
import { StatePersistencePlugin } from '@alekstar79/draggable-resizable-container'
manager.use(new StatePersistencePlugin({
containerId: 'my-unique-container-id',
}))Utilities
The library also exports several utility classes that you can use.
ContainerInitializer
A simple utility for creating a container element.
import { ContainerInitializer } from '@alekstar79/draggable-resizable-container'
const newContainer = ContainerInitializer.createContainerElement(400, 250, 100, 100)
document.body.appendChild(newContainer)ContentCreator and TemplateLoader
These utilities help with managing the content of your containers, including loading HTML templates.
import { ContentCreator, getTemplateLoader, initializeTemplateSystem } from '@alekstar79/draggable-resizable-container'
// Initialize the template system once in your app
await initializeTemplateSystem()
const templateLoader = getTemplateLoader()
const contentCreator = new ContentCreator(templateLoader)
// Load content from a template
await contentCreator.createContent({ template: 'my-template-name' }, containerElement)Development
# Install dependencies
npm install
# Start development server
npm run dev
# Build library
npm run build:lib
# Build demo
npm run build
# Type checking
npm run type-checkBrowser Support
- Chrome 88+
- Firefox 78+
- Safari 14+
- Edge 88+
Contributing
Contributions are welcome! Please feel free to submit a pull request.
License
This project is licensed under the MIT License.
