desktop-window
v0.4.7
Published
A lightweight Web Components-based custom element that replicates the look and feel of native desktop application windows — resizable, movable, and styled like a traditional OS window.
Readme
desktop-window
A lightweight Web Components-based custom element that replicates the look and feel of native desktop application windows — resizable, movable, and styled like a traditional OS window. No frameworks required.

NOT READY FOR PRODUCTION
This package is in active development, and not yet reached the point where I can recommend using in production environment:
- Its tested to some degree, but not well tested or battle proven.
- Documentation is still in the making (and will probably arrive in a month).
- The API may still change. It's getting more stable, but changes are still possible.
Roadmap
- comprehensive documentation
- accessibility
- test cases / unit tests?
Usage
import { register, DesktopWindow } from 'desktop-window';
register(); // this guards against multiple accidental registration
// OR you could just do this instead:
customElements.define('desktop-window', DesktopWindow);Or without a build tool:
Manually copy the desktop-window.autoload.js to your site, then:
<script src="desktop-window.autoload.js"></script>Use the <desktop-window> tag in HTML code.
<style>
desktop-window[fullscreen] #enter-fullscreen { display: none; }
desktop-window:not([fullscreen]) #exit-fullscreen { display: none; }
</style>
<div style="position: relative; width: 100vw; height: 100vh;">
<desktop-window name="Hello world!" movable resizable minimizable maximizable closable centered>
The contents of the window are placed here.
<button id="enter-fullscreen">⛶ Enter fullscreen</button>
<button id="exit-fullscreen">⛶ Exit fullscreen</button>
</desktop-window>
</div>
<script>
document.getElementById('enter-fullscreen').addEventListener('click', function (event) {
this.dispatchEvent(new Event('request-fullscreen', { bubbles: true }));
});
document.getElementById('exit-fullscreen').addEventListener('click', function (event) {
this.dispatchEvent(new Event('exit-fullscreen', { bubbles: true }));
});
</script>Examples
For examples see the Github project examples folder.
- Clone repository or download zip.
- Open
examples/index.htmlin your browser.
Documentation
Contents
Attributes
All boolean attributes on <desktop-window> follow this rule:
- If the attribute is present, its value is considered
true, regardless of whether the value is empty,"true", or equals the attribute name. - If the attribute is not present, the value is
false.
Truthy examples (evaluated as true):
<desktop-window centered>
<desktop-window centered="true">
<desktop-window centered="centered">
<desktop-window centered="1">
<desktop-window centered="">Falsy example (evaluated as false):
<desktop-window>There is no way to explicitly pass false via the attribute. Omitting the attribute entirely is the only way to make it false.
If dynamic control of booleans is needed, use JavaScript to set/remove attributes:
element.removeAttribute('centered'); // false
element.setAttribute('centered', ''); // truename
Type: string
Specifies the title displayed in the window's title bar.
Example:
<desktop-window name="My Window">movable
Type: boolean
If present, the window can be dragged. If omitted, the window is fixed in place.
Example:
<desktop-window movable>x
Type: number
Initial horizontal coordinate of the window (in pixels, omit the px unit). Ignored if centered is set.
Example:
<desktop-window x="100">y
Type: number
Initial vertical coordinate of the window (in pixels, omit px unit). Ignored if centered is set.
Example:
<desktop-window y="100">centered
Type: boolean
If present, the window is centered. Overrides x and y.
Example:
<desktop-window centered>resizable
Type: boolean
If present, the window can be resized.
Omitting it disables resizing.
Example:
<desktop-window resizable>width
Type: number
Default: 350.
Initial width in pixels.
Example:
<desktop-window width="800">height
Type: number
Default: 350.
Initial height in pixels.
Example:
<desktop-window height="600">minwidth
Type: number
Default: 150.
Minimum width allowed during resizing.
Example:
<desktop-window minwidth="200">maxwidth
Type: number
Maximum width allowed during resizing.
Example:
<desktop-window maxwidth="1000">minheight
Type: number
Default: 150.
Minimum height allowed during resizing.
Example:
<desktop-window minheight="200">maxheigh
Type: number
Maximum height allowed during resizing.
Example:
<desktop-window maxheigh="700">minimizable
Type: boolean
If present, the window shows a minimize button and allows minimizing.
Example:
<desktop-window minimizable>minimized
Type: boolean
If present, the window is minimized.
Example:
<desktop-window minimized>maximizable
Type: boolean
If present, the window shows a maximize button and allows maximizing.
Example:
<desktop-window maximizable>maximized
Type: boolean
If present, the window is maximized.
Example:
<desktop-window maximized>closable
Type: boolean
If present, the window can be closed via an UI button. Omit to disable closing from the UI.
Closing via JS API is still possible when this is disabled.
Example:
<desktop-window closable>fullscreen
Type: boolean
If present, the window is displayed in fullscreen mode.
In fullscreen mode there is no borders around the window, but the titlebar is still visible with the minimize, restore, close controls.
Example:
<desktop-window fullscreen>hidden
Type: boolean
If present, the window is not visible. Remove this attribute to show the window.
Example:
<desktop-window hidden>autofocus
Type: boolean
If present, the window receives focus on creation.
Example:
<desktop-window autofocus>frameless
Type: boolean
If present, the window is rendered without borders or title bar.
Example:
<desktop-window frameless>modal
Type: boolean
If present, the window becomes modal (blocks interaction with other sibling windows or the background).
Example:
<desktop-window modal>aspectratio
Type: number
Enforces a fixed aspect ratio (width / height) when resizing.
Example:
<desktop-window aspectratio="1.777">aspectratioextrawidth
Type: number
Extra width in pixels added to the actual content width when maintaining the aspect ratio.
Example:
<desktop-window aspectratioextrawidth="50">aspectratioextraheight
Type: number
Extra height in pixels added to the content height for aspect ratio calculation.
Example:
<desktop-window aspectratioextraheight="50">Events emitted
'closing''closed''minimizing''minimized''maximizing''maximized''restoring''restored''requesting-fullscreen''exiting-fullscreen'
Events listening for
'close''minimize''maximize''restore''request-fullscreen''exit-fullscreen''move''resize-n''resize-e''resize-s''resize-w''resize-ne''resize-nw''resize-se''resize-sw'
Properties
namemovablexycenteredwidthheightminWidthminHeightmaxWidthmaxHeightresizableminimizableminimizedmaximizablemaximizedclosablefullscreenhiddenautofocusframelessmodalaspectRatioaspectRatioExtraWidthaspectRatioExtraHeight
Methods
flash()isFocused()focus()blur()close()destroy()getPosition()setPosition(x, y)getSize()setSize(width, height)getNormalBounds()getBounds()setBounds({ x, y, width, height })getContentSize()setContentSize(width, height)getContentBounds()setContentBounds({ x, y, width, height })setAspectRatio(ratio, { width, height })
Slots
titlebar-starttitlebar-centertitlebar-end
Parts
windowtitlebartitlebar-starttitlebar-centertitlebar-endtitlebar-textminimize-buttonrestore-buttonmaximize-buttonclose-buttonclient-area
CSS Variables
--desktop-window-background-color--desktop-window-border-width--desktop-window-border-color--desktop-window-minimize-duration--desktop-window-maximize-duration--desktop-window-titlebar-height--desktop-window-titlebar-text-color--desktop-window-titlebar-background-color--desktop-window-titlebar-font-family--desktop-window-titlebar-font-size--desktop-window-minimize-button-mask-image--desktop-window-maximize-button-mask-image--desktop-window-restore-button-mask-image--desktop-window-close-button-mask-image--desktop-window-buttons-width--desktop-window-buttons-height--desktop-window-buttons-margin--desktop-window-buttons-text-color--desktop-window-buttons-background-color--desktop-window-buttons-hover-text-color--desktop-window-buttons-hover-background-color--desktop-window-minimize-text-color--desktop-window-minimize-background-color--desktop-window-minimize-hover-text-color--desktop-window-minimize-hover-background-color--desktop-window-maximize-text-color--desktop-window-maximize-background-color--desktop-window-maximize-hover-text-color--desktop-window-maximize-hover-background-color--desktop-window-restore-text-color--desktop-window-restore-background-color--desktop-window-restore-hover-text-color--desktop-window-restore-hover-background-color--desktop-window-close-text-color--desktop-window-close-background-color--desktop-window-close-hover-text-color--desktop-window-close-hover-background-color--desktop-window-focused-background-color--desktop-window-focused-border-color--desktop-window-focused-titlebar-text-color--desktop-window-focused-titlebar-background-color--desktop-window-focused-buttons-text-color--desktop-window-focused-buttons-background-color--desktop-window-focused-buttons-hover-text-color--desktop-window-focused-buttons-hover-background-color--desktop-window-focused-minimize-text-color--desktop-window-focused-minimize-background-color--desktop-window-focused-minimize-hover-text-color--desktop-window-focused-minimize-hover-background-color--desktop-window-focused-maximize-text-color--desktop-window-focused-maximize-background-color--desktop-window-focused-maximize-hover-text-color--desktop-window-focused-maximize-hover-background-color--desktop-window-focused-restore-text-color--desktop-window-focused-restore-background-color--desktop-window-focused-restore-hover-text-color--desktop-window-focused-restore-hover-background-color--desktop-window-focused-close-text-color--desktop-window-focused-close-background-color--desktop-window-focused-close-hover-text-color--desktop-window-focused-close-hover-background-color
Notes
Always set
position: relativeorposition: absoluteon the immediate parent container, or the window may behave unexpectedly. Only exception is when the parent isdocument.body.Setting
overflow: hiddenon the container element is recommended to hide windows moved partially outside of the area and prevent an appearing scrollbar.The window works only when there is a valid
parentElement, so appending eg. to a shadow root directly will not work.Appending to the
document.bodyworks, but don't forget to set the body height or have content that stretches the area!When the script is asynchronously loaded and the HTML has windows, I recommend you this CSS to prevent jumping content:
desktop-window:not(:defined) { display: none; }
Missing a feature?
Create an issue describing your needs! If it fits the scope of the project I will implement it.
