Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/dev-os/llms.txt
Use this file to discover all available pages before exploring further.
Window is the visual shell that surrounds every application in DevOS. It handles all the behaviour you would expect from a desktop window — dragging, resizing, focusing, minimising, maximising, and closing — entirely within a single self-contained React component backed by Framer Motion for fluid animations. App components are dropped inside the content area as black-box children; Window itself is agnostic about what it is hosting.
Props
| Prop | Type | Description |
|---|---|---|
windowData | WindowData | The full window object from useWindowManager().windows |
windowData carries everything Window needs: the id used to dispatch mutations, the title and icon shown in the title bar, the component rendered in the body, and the boolean flags isMinimized, isMaximized that drive visual state.
Minimized behaviour
WhenwindowData.isMinimized is true, Window returns null immediately — the DOM node is removed and the Framer Motion exit animation fires. Because the window object itself stays in the WindowManager state, the app component’s local state is preserved for the lifetime of the session.
Minimised windows are not unmounted from the context — only from the DOM. Any state held inside the app component (scroll position, form input, loaded data) survives a minimise/restore cycle without needing to be persisted externally.
Title bar
The title bar is a40px-tall header flex row that displays the window icon and title on the left, and the three control buttons on the right.
- Focused windows:
bg-os-teal text-whitewith atext-os-cyanicon tint - Unfocused windows:
bg-os-teal/80 text-white/80with no icon tint - Pointer down on the title bar calls both
focusWindow(id)anddragControls.start(event), so a single gesture both focuses and begins a drag - Double-click on the title bar calls
maximizeWindow(id)to toggle maximised state
Control buttons
Three icon buttons sit at the right edge of the title bar:| Button | Icon | Action |
|---|---|---|
| Minimize | Minus (lucide) | minimizeWindow(id) — hides the window, keeps taskbar button |
| Maximize / Restore | Square (lucide) | maximizeWindow(id) — toggles full-viewport size |
| Close | X (lucide) | closeWindow(id) — removes the window entirely |
event.stopPropagation() to prevent the click from bubbling to the title bar’s drag handler.
Drag behaviour
Dragging uses Framer Motion’sdragControls API to restrict the drag initiation point to the title bar only:
onDragEnd callback updates a local position state with the new { x, y } offset so the window stays where it was dropped when other state updates re-render it.
Drag is automatically disabled (drag={false}) when isMaximized is true to prevent dragging a full-screen window.
Resize handle
A16×16 px div sits in the absolute bottom-right corner (cursor-se-resize). It uses raw pointer events rather than a drag library for fine-grained control:
Math.max guards enforce minimum dimensions: 300 px wide and 200 px tall. The resize handle is hidden when isMaximized is true.
Initial position
On first mount, auseEffect (with an empty dependency array) computes a centred-with-jitter starting position:
±20 px random offset means that when multiple windows are opened quickly they do not stack perfectly on top of each other.
Animations
The Framer Motiondiv carries these animation props:
| State | Effect |
|---|---|
| Open | Scales from 80 % → 100 % and fades in |
| Close | Scales back to 80 % and slides down off-screen (y: 100vh) |
| Maximize | Width and height animate to viewport size; position snaps to 0, 0 |
| Restore | Width, height, and position animate back to saved values |
spring transition with bounce: 0.1 gives a subtle elastic feel without being distracting.
Content area
The inner contentdiv uses flex-1 overflow-auto and renders windowData.component with no props: