A window manager for React
npm install @jonce/react-window-managerA powerful, type-safe React library for building desktop-style window management interfaces. Built with TypeScript and reactive state management for smooth, performant window interactions.
- š„ļø Full Window Management: Create, close, focus, move, resize, minimize, maximize, and fullscreen windows
- šÆ Type-Safe: Built with TypeScript generics for complete type safety across window types
- ā” Reactive State: Powered by @legendapp/state for optimal performance and reactivity
- šØ Customizable: Fully customizable window components with flexible styling options and custom headers
- š±ļø Interactive: Built-in dragging, resizing, and focus management
- š± Responsive: Automatic container size management and window constraints
- š§ Extensible: Plugin-style window type registration system
``bash`
npm install @jx/react-window-manager
`bash`
npm install react react-dom
`tsx
import React from "react";
import {
createWindowManager,
WindowManagerProvider,
WindowRenderer,
Window,
useWindowActions,
} from "@jx/react-window-manager";
// Define your window types
type AppWindowTypes = "text-editor" | "file-browser" | "calculator";
// Create a window manager instance
const windowManager = createWindowManager
// Create window components
const TextEditor = ({ window, onClose }) => (
Text Editor
);
const Calculator = ({ window, onClose }) => (
Calculator
Calculator UI goes here...
);
// Register window types
const windowTypes = {
"text-editor": TextEditor,
calculator: Calculator,
};
// App component
function App() {
return (
windowTypes={windowTypes}
>
);
}
// Component that can open windows
function AppContent() {
const actions = useWindowActions
return (
Core Concepts
$3
The window manager is the central state container that manages all windows:
`tsx
import { createWindowManager } from "@jx/react-window-manager";const windowManager = createWindowManager<"myWindowType">();
`$3
Define your application's window types using TypeScript string literals:
`tsx
type MyWindowTypes = "dashboard" | "settings" | "chat" | "notifications";
`$3
Windows can be in different states:
-
normal: Standard windowed state
- maximized: Fills the entire container
- minimized: Hidden but still in memory
- fullscreen: Covers the entire viewportAPI Reference
$3
####
useWindowActions()Access window management actions:
`tsx
const actions = useWindowActions();// Open a new window
actions.open(
"myWindowType",
{ title: "Hello" },
{
position: { x: 100, y: 100 },
size: { width: 400, height: 300 },
}
);
// Close a window
actions.close("window-id");
// Focus a window
actions.focus("window-id");
// Move a window
actions.move("window-id", { x: 200, y: 150 });
// Resize a window
actions.resize("window-id", { width: 500, height: 400 });
`####
useWindows()Get all currently open windows:
`tsx
const windows = useWindows();
`####
useFocusedWindow()Get the currently focused window:
`tsx
const focusedWindow = useFocusedWindow();
`####
useWindowCount()Get the total number of open windows:
`tsx
const windowCount = useWindowCount();
`####
useWindowManager()Get the full window manager instance:
`tsx
const windowManager = useWindowManager();
`####
useWindowTypes()Get window type registration functions:
`tsx
const { windowTypes, registerWindowType, unregisterWindowType } =
useWindowTypes();
`$3
####
Context provider for the window manager:
`tsx
{children}
`####
Renders all open windows:
`tsx
`####
Container component for individual windows with built-in dragging and resizing:
`tsx
window={window}
onClose={onClose}
draggable={true}
resizable={true}
headerHeight={30}
customHeader={customHeaderComponent}
>
{windowContent}
$3
The
Window component supports fully customizable headers through the customHeader prop:#### No Header
`tsx
{/ Window content without header /}
`#### Custom React Node Header
`tsx
window={window}
customHeader={
My Custom Header
}
>
{windowContent}
`#### Function-based Header with Window Data
`tsx
window={window}
customHeader={({ window, onClose, onMaximize, onMinimize, onFocus }) => (
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "10px",
background: window.isFocused ? "#007acc" : "#f0f0f0",
color: window.isFocused ? "white" : "black",
}}
>
{window.type}
#### Header Component Using Hooks
You can also create header components that use the window manager hooks:
`tsx
const CustomHeaderComponent = () => {
const actions = useWindowActions();
const focusedWindow = useFocusedWindow(); return (
Active: {focusedWindow?.type}
);
}; }>
{windowContent}
;
`$3
All window actions are available through the
useWindowActions hook:-
open(type, props, options) - Create a new window
- close(id) - Close a window
- focus(id) - Bring a window to front
- move(id, position) - Move a window
- resize(id, size) - Resize a window
- minimize(id) - Minimize a window
- maximize(id) - Maximize a window
- fullscreen(id) - Make a window fullscreen
- unfullscreen(id) - Exit fullscreen mode
- closeAll() - Close all windows
- closeByType(type) - Close all windows of a specific typeAdvanced Usage
$3
Create sophisticated window components with custom behavior:
`tsx
const CustomWindow = ({ window, onClose, onMinimize, onMaximize }) => (
window={window}
onClose={onClose}
className="custom-window"
headerHeight={40}
customHeader={({ window, onClose, onMinimize, onMaximize }) => (
{window.props.title}
)}
>
{/ Your window content /}
);
`$3
Register window types dynamically:
`tsx
const { registerWindowType, unregisterWindowType } = useWindowTypes();// Register a new window type
registerWindowType("new-type", NewWindowComponent);
// Unregister a window type
unregisterWindowType("old-type");
`$3
Use hooks to access window manager state in any component within the provider:
`tsx
const WindowStatusBar = () => {
const windows = useWindows();
const focusedWindow = useFocusedWindow();
const windowCount = useWindowCount(); return (
Windows: {windowCount}
Focused: {focusedWindow?.type || "None"}
);
};
`Styling
The library provides minimal default styling. You can customize the appearance using CSS:
`css
.window-container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}.window {
position: absolute;
border: 1px solid #ccc;
border-radius: 8px;
background: white;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.window-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 12px;
height: 30px;
background: #f5f5f5;
border-bottom: 1px solid #e0e0e0;
cursor: move;
}
.custom-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 12px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
``- React 17.0.0 or higher
- TypeScript 4.5+ (for full type safety)