Migrating from WinBox
@surdeddd/wmkit/winbox speaks the WinBox.js 0.2 API, so an app moves over by changing one import. Under it runs the wmkit manager, which brings snapping, keyboard control, screen-reader announcements, undo and persistence along.
Three steps
- Install:
npm i @surdeddd/wmkit. - Swap the import:js
// before import WinBox from 'winbox/src/js/winbox.js' import 'winbox/dist/css/winbox.min.css' // after import WinBox from '@surdeddd/wmkit/winbox' - Delete the WinBox stylesheet import. A WinBox-like look is injected once (
<style data-wmkit-winbox>); callWinBox.configure({ styles: false })before the first window to bring your own.
Every way of opening a window keeps working: new WinBox(title, options), new WinBox(options), WinBox.new(...) and WinBox(...) without new.
In CommonJS, require('@surdeddd/wmkit/winbox') returns the constructor itself, as WinBox's own bundle does; .default, .WinBox, .winboxMessages and .winboxMessagesRu hang off it. The CommonJS types use export =, so import WinBox = require('@surdeddd/wmkit/winbox') type-checks in TypeScript.
What maps to what
| WinBox | wmkit |
|---|---|
id, title, width, height, x, y (px, %, "center", "right", "bottom") | the same, resolved against the window area |
minwidth, minheight, maxwidth, maxheight | minSize / maxSize of the window |
modal | layer: 'modal' plus a backdrop; the windows below take no input |
max, min, hidden | start maximized, minimized or hidden |
mount, html, url | node moved in (and back on close), innerHTML, an iframe |
top, right, bottom, left | the area the windows live in; snapping and maximize respect it |
overflow | windows may leave the area |
background, border, icon, class | the same; control classes no-min, no-max, no-full, no-close, no-resize, no-move, no-header, no-shadow, no-animation |
autosize | size to the content once it is in |
oncreate, onclose(force) (a truthy return vetoes), onfocus, onblur, onmove(x, y), onresize(w, h), onminimize, onmaximize, onrestore, onfullscreen, onhide, onshow | the same, with the instance as this |
mount, unmount, setUrl, setTitle, setIcon, setBackground, move, resize, close(force), focus, blur, hide, show, minimize, maximize, fullscreen, restore, addClass, removeClass, hasClass, toggleClass, addControl, removeControl | the same, chainable |
x, y, width, height, minwidth … (writable), min, max, full, hidden, focused | the same |
WinBox.stack() | open windows in focus order, the focused one last |
The markup keeps WinBox's class names — .winbox with the focus, min, max, full, hide and modal state classes, .wb-header, .wb-control (.wb-min, .wb-max, .wb-full, .wb-close), .wb-drag, .wb-icon, .wb-title, .wb-body — so CSS written for WinBox keeps applying.
The state classes and the callbacks follow the manager rather than the call that caused a change, so they stay right after undo, redo, a restored layout and a viewport change. onresize and onmove also fire when maximizing, restoring or snapping changes the geometry, in the order WinBox uses: resize, then move, then the stage callback.
What is different
- Snapping and keyboard control are on. Drag a window to an edge to snap it, use the arrow keys on a focused window. Turn either off with
WinBox.configure({ snap: false, keyboard: false }). Grouping windows into tabs is off by default and comes back withgrouping: true. - The control buttons work from the keyboard. They take focus and answer Enter and Space, those added with
addControltoo. A hidden window cannot take the focus, so F6 skips it, and passing the focus on from a window you hide records no undo step, during undo and redo too. - Closing is final. A closed window never comes back through undo, redo or a restored layout; open a new one instead. Undoing the close of a box therefore shows nothing — the box is gone and its window closes again at once — and the next undo goes on to the step before. An undo whose only effect would be to put the focus back on a hidden box shows nothing either.
- The last window takes its desktop along. When the last window of a desktop closes, the desktop, its controller and their listeners on the page are removed, and the next
new WinBox()builds a fresh one. A desktop whose manager you took withWinBox.manager()stays, sopersist(WinBox.manager(), …)keeps working. - Minimized windows wait in a strip of title buttons along the bottom edge; a click restores them.
top/right/bottom/leftbelong to a desktop, not a window. Windows created with the same set share one desktop; another set gets its own. Positions are measured inside that area.indexis ignored: stacking is the manager's job.htmlwritesinnerHTML, as in WinBox. Pages that enforce Trusted Types or a strict CSP should passmountinstead.- Size. The compat entry is about 22 kB brotli with the manager inside it;
winbox.bundle.min.js0.2.82 is 5.4 kB. The difference pays for snapping, undo, persistence, keyboard control, focus management and the screen-reader layer — if you need none of those, WinBox stays the lighter choice.
Going further
WinBox.manager(root?) returns the underlying WindowManager, so the rest of wmkit is one call away:
import WinBox from '@surdeddd/wmkit/winbox'
import { persist } from '@surdeddd/wmkit/persist'
persist(WinBox.manager(), { key: 'my-desktop' })
new WinBox('Notes', { width: 400, height: 300 })