A lightweight and flexible window management library for organizing draggable and resizable windows in a web application.
- β₯ Drag & Resize β Easily move and resize windows.
- π Sticky Mode β Suggest predefined sizes when snapping to corners.
- πΎ Save & Restore Configuration β Save window states and restore them later.
- β‘ Optimized for Performance β Minimal overhead.
Simple Example Demo
A basic demonstration of the library's functionality.
Demo with iframe widgets
A more advanced demo showcasing iframe-based widgets.
npm install window-manager
# or
yarn add window-managerCreate root element:
<div id="wm"></div>Import and initialize the WindowManager:
import { WindowManager } from 'window-manager';
import 'window-manager/style.css';
const root = document.querySelector('#wm') as HTMLElement;
const schema = [
{
title: 'My window',
name: 'myWindow',
width: 50,
height: 50,
position: [20, 20],
isClosable: true,
ctor: (window, container, schema) => {
const element = document.createElement('div');
container.appendChild(element);
},
},
];
const wm = new WindowManager(root, schema);
wm.init();Create root element:
<div id="wm"></div>Import and initialize the WindowManager:
import { WindowManager } from 'window-manager';
import 'window-manager/style.css';
const root = document.querySelector('#wm') as HTMLElement;
const schema = [
{
title: 'My window',
name: 'myWindow',
width: 50,
height: 50,
position: [20, 20],
isClosable: true,
props: {
myProp: 'My first window',
},
},
];
const wm = new WindowManager(root, schema);
wm.registerConstructor('myWindow', (window, container, schema) => {
const element = document.createElement('div');
if (typeof schema.props?.myProp === 'string') {
element.innerText = schema.props.myProp;
}
container.appendChild(element);
});
wm.init();You can customize WindowManager behavior by passing an options object when initializing it.
{
snapThreshold?: number;
minWindowWidth?: number;
minWindowHeight?: number;
}| Option | Type | Default | Description |
|---|---|---|---|
snapThreshold |
number |
20 |
Defines the distance (in pixels) within which a window will snap to predefined positions when dragged. |
minWindowWidth |
number |
10 |
The minimum allowed width for a window (in percent). |
minWindowHeight |
number |
10 |
The minimum allowed height for a window (in percent). |
Each window is represented as an object following this schema:
{
title: string;
name: string;
width: number;
height: number;
position: [number, number];
isClosable?: boolean;
isExpandable?: boolean;
ctor?: ContentCtor;
props?: Record<string, unknown>;
}| Property | Type | Default | Description |
|---|---|---|---|
title |
string |
The display title of the window. | |
name |
string |
A unique identifier for the window. | |
width |
number |
The initial width of the window (in percent). | |
height |
number |
The initial height of the window (in percent). | |
position |
[number, number] |
The [x, y] coordinates for the window's initial position (in percent). |
|
isClosable |
boolean (optional) |
true |
If true, the window can be closed by the user. |
isExpandable |
boolean (optional) |
true |
If true, the window can be maximized. |
ctor |
ContentCtor (optional) |
A constructor for the window content component. | |
props |
Record<string, unknown> (optional) |
Custom properties passed to the content component. |
You can subscribe to the following events for WindowManager and WmWindow to handle user interactions dynamically.
window:closeβ Triggered when a window is closed.window:selectβ Fired when a window is selected.window:expandβ Emitted when a window is expanded.
drag:startβ Fires when dragging starts.dragβ Continuously emitted while dragging.drag:endβ Fires when dragging ends.
resize:startβ Fires when resizing starts.resizeβ Continuously emitted while resizing.resize:endβ Fires when resizing ends.
To listen for an event, use:
wm.on(Events.DragStart, (event) => {
console.log('Dragging started:', event);
});
// OR
wm.registerConstructor('myWindow', (window, container, schema) => {
const element = document.createElement('div');
window.on(Events.DragStart, (event) => {
console.log('Dragging started:', event);
});
container.appendChild(element);
});