Skip to Content

Window

The Window suite is a set of composable primitives for Windows 98 application chrome. Window is the root: it owns window state (active, maximized, minimized) and shares it with the slots below.

Window renders no DOM of its own — it is a context provider, like a shadcn/ui root. That is deliberate: window managers need full control over layout, portalling, stacking, and drag/resize, so those concerns stay in your app while Window only coordinates state. Wire the useDraggable and useResizable hooks onto the frame yourself — see Build a complete window below.

Composition

Use the following composition to build a Window:

Window └── WindowFrame ├── WindowTitleBar │ ├── WindowTitle │ └── WindowButtons │ ├── WindowMinimizeButton │ ├── WindowMaximizeButton │ └── WindowCloseButton ├── WindowMenuBar │ └── WindowMenuBarMenu │ ├── WindowMenuBarTrigger │ └── WindowMenuBarContent │ ├── MenuItem │ ├── MenuCheckboxItem │ ├── MenuRadioGroup │ │ └── MenuRadioItem │ ├── MenuSeparator │ └── MenuSub │ ├── MenuSubTrigger │ └── MenuSubContent ├── WindowContent ├── WindowStatusBar │ └── WindowStatusBarField └── WindowResizeGrip

Props

Window

The root context provider. Renders no element of its own.

PropTypeDefaultDescription
activebooleantrueActive (focused) styling for descendant slots.
minimizedbooleanfalseHides the frame via CSS while preserving the DOM.
defaultMaximizedbooleanfalseInitial maximized state.
positioning'absolute' | 'fixed''fixed'Positioning mode inherited by the frame and overlay.
maximizablebooleantrueWhether the maximize control is enabled.

Slots

ExportKey propsDescription
WindowFramediv propsOuter raised frame.
WindowTitleBar, WindowTitle, WindowButtonsdiv propsTitle bar slots.
WindowMinimizeButton, WindowMaximizeButton, WindowCloseButton, WindowHelpButtonbutton propsTitle bar controls.
WindowMenuBar, WindowMenuBarMenu, WindowMenuBarTrigger, WindowMenuBarContent, WindowMenuBarItemvalue, defaultValue, onValueChange, menu/menuitem propsTop-level window menu bar with dropdown coordination.
WindowContentdiv propsScroll/content body.
WindowOverlaypositioning, div propsSemi-transparent backdrop (aria-hidden). Inherits positioning from context.
WindowPortalcontainerPortal that respects the scoped LayerProvider target. Falls back to document.body.
WindowResizeGripdiv propsBottom-right resize handle rendered with Marlett font glyphs. Hidden when maximized.
WindowStatusBar, WindowStatusBarFielddiv propsBottom status area.
useWindowContext-Read state / actions / meta inside custom chrome.

Examples

Primitives assembly

Example.exe

Window primitives compose into app chrome.

Ready
NUM

Menu bar dropdowns

Write.exe

A tiny document window with classic top menus.

Ready

Build a complete window

Because Window renders no DOM, a draggable, resizable window is assembled by wiring the interaction hooks onto the frame and title bar yourself:

import { MenuItem, useDraggable, useResizable, Window, WindowButtons, WindowCloseButton, WindowContent, WindowFrame, WindowMaximizeButton, WindowMenuBar, WindowMenuBarContent, WindowMenuBarMenu, WindowMenuBarTrigger, WindowMinimizeButton, WindowResizeGrip, WindowStatusBar, WindowStatusBarField, WindowTitle, WindowTitleBar, } from '@murasaki-io/react98' function MyWindow() { const { setTargetRef: setDragTarget, setDragRef } = useDraggable<HTMLDivElement, HTMLDivElement>() const { setTargetRef: setResizeTarget, setResizeRef } = useResizable<HTMLDivElement, HTMLDivElement>({ minWidth: 320, minHeight: 200, }) const setFrameRef = (el: HTMLDivElement | null) => { setDragTarget(el) setResizeTarget(el) } return ( <Window positioning="absolute"> <WindowFrame ref={setFrameRef} style={{ left: 80, top: 60, width: 480, height: 320 }}> <WindowTitleBar ref={setDragRef}> <WindowTitle>Notepad 98</WindowTitle> <WindowButtons> <WindowMinimizeButton /> <WindowMaximizeButton /> <WindowCloseButton /> </WindowButtons> </WindowTitleBar> <WindowMenuBar> <WindowMenuBarMenu value="file"> <WindowMenuBarTrigger>File</WindowMenuBarTrigger> <WindowMenuBarContent> <MenuItem reserveIconSpace>New</MenuItem> <MenuItem reserveIconSpace>Open…</MenuItem> </WindowMenuBarContent> </WindowMenuBarMenu> </WindowMenuBar> <WindowContent className="p-2">Your app content</WindowContent> <WindowStatusBar> <WindowStatusBarField>Ready</WindowStatusBarField> </WindowStatusBar> <WindowResizeGrip ref={setResizeRef} /> </WindowFrame> </Window> ) }

For a full desktop shell — multiple windows, z-index stacking, taskbar, and position persistence — see the Build a desktop guide.

Positioning model

  • left / top and width / height are static inline styles you set once for the initial layout.
  • Dragging adds a translate() transform on top of the base position; useDraggable re-clamps it to the container/viewport.
  • Resizing overwrites the inline width / height; useResizable clamps it to minWidth/minHeight/maxWidth/maxHeight and the container/viewport.
  • useDraggable ignores mousedowns on button / a / input / select / textarea / [role="button"], so the title-bar buttons keep working.

ARIA

Window primitives provide visual structure. Add dialog/window roles, labels, focus management, and close behavior at the app shell layer.

Keyboard

Window chrome primitives do not add global keyboard shortcuts. Title-bar buttons and menu-bar items keep their native button or menu keyboard behavior.

SSR

Window owns maximized state. Use defaultMaximized for initial layout and keep positioning classes stable across hydration.

Last updated on