@gfazioli/mantine-window
A Mantine extension component that renders draggable, resizable floating windows with persistent state, customizable boundaries, collapsible content, z-index management, and flexible control over position, size, and interaction modes. Includes a WindowGroup compound component for coordinated multi-window management with layout presets.
Migrating from v1.x
Breaking changes:
v2.0 replaces the object-based
defaultPositionanddefaultSizeprops with a flat API.
defaultPosition={{ x, y }}→defaultXanddefaultYdefaultSize={{ width, height }}→defaultWidthanddefaultHeightBefore (v1.x):
After (v2.0):
New features:
- Controlled position and size — new
x,y,width,heightprops for full external control- Responsive values — all dimension props accept Mantine breakpoint objects (
{ base: 280, sm: 350, md: 450 })- Responsive
radiusandshadow— these props now accept breakpoint objects tooWindow.Group— new compound component for coordinated multi-window management with layout presets- Tools button — layout menu in the window header with snap, tile, columns, rows, and fill actions
withToolsButtonprop — control tools button visibility per window or per group (showToolsButton)groupRef— imperative API to apply layouts programmatically- Accessibility —
role="dialog",aria-label, and labeled buttons for close, collapse, and tools
Installation
After installation import package styles at the root of your application:
You can import styles within a layer @layer mantine-window by importing @gfazioli/mantine-window/styles.layer.css file.
Usage
The Window component allows you to create draggable and resizable windows within your application. It provides a familiar desktop-like experience for users. You can customize the appearance and behavior of the windows using various props.
Note:
Usually, you would want to use the
Windowcomponent within a portal to avoid layout issues. However, if you want the window to be constrained within a specific container, you can set thewithinPortalprop tofalseand the container should haveposition: relativestyle.For example, in the demos below, the
Windowcomponent is rendered relative to its parent container which hasposition: relativestyle.
Hello, World! Hello, Mantiners! Say Hello to the Window component
Controlled
You can control the open and close state of the Window component using the opened and onClose props. This allows you to manage the visibility of the window programmatically.
Position and Size
Set the initial position and size of the window using defaultX, defaultY, defaultWidth, and defaultHeight props. These values are used when the window is first rendered and can be modified by the user via drag and resize.
Custom Position & Size
Controlled Position and Size
For full external control, use the x, y, width, and height props. When these are set, the component does not manage that value internally — your state drives it. Combine with onPositionChange and onSizeChange to sync state after user interactions.
You can also mix controlled and uncontrolled: for example, control only x and y while letting width and height remain uncontrolled via defaultWidth and defaultHeight.
X: 50
Y: 50
Width: 300
Controlled
Within Portal vs Container
The withinPortal prop controls how the window is positioned. When withinPortal={true} (default), the window uses fixed positioning relative to the viewport. When withinPortal={false}, it uses absolute positioning relative to its parent container.
Fixed positioning (withinPortal=true):
- Window stays in place when scrolling
- Positioned relative to the browser viewport
- Best for modals and overlays
Absolute positioning (withinPortal=false):
- Window is constrained within parent container
- Parent must have
position: relative - Window cannot be dragged or resized outside container boundaries
- Best for embedded UI components
Container with position: relative
Unit Types
Position and size props support three unit types:
- Pixels (number): Fixed pixel values, e.g.
defaultX={100} - Viewport units (string):
vwfor viewport width,vhfor viewport height, e.g.defaultX="10vw" - Percentages (string): Relative to the reference container, e.g.
defaultX="20%"
Understanding Unit References:
vw/vh: Always relative to the browser viewport, regardless ofwithinPortalsetting%: WithwithinPortal={true}(default) relative to the viewport; withwithinPortal={false}relative to the parent container- Pixels: Always fixed, regardless of
withinPortalsetting
You can mix different unit types freely on the same component.
Pixels
Percentages
Mixed
Responsive
All dimension and position props support responsive values using Mantine breakpoints. Pass an object with breakpoint keys (base, xs, sm, md, lg, xl) to change values at different screen sizes.
This also applies to minWidth, maxWidth, minHeight, maxHeight, radius, and shadow.
Responsive Window
Min/Max Size Constraints
Control the minimum and maximum dimensions during resize operations using minWidth, minHeight, maxWidth, and maxHeight props. These support all unit types (pixels, viewport units, percentages) and responsive breakpoint objects.
Constrained Resize
You can mix different unit types for constraints — for example, a fixed pixel minimum with a viewport-based maximum:
Drag Boundaries
Restrict the draggable area of the window using the dragBounds prop. This ensures the window stays within specific boundaries. The dragBounds object accepts minX, maxX, minY, and maxY values, each supporting pixels, viewport units, and percentages.
Bounded Dragging
Combine different unit types (pixels, viewport units, percentages) for drag boundaries to create flexible constraints:
Centered Window
Create a centered, fixed window that cannot be moved or resized by combining position/size props with resizable="none" and draggable="none".
Centered Window
Disable Collapsing
Prevent the window from being collapsed by setting collapsable={false}. This removes the collapse functionality, including the double-click handler on the header.
No Collapsable
Full Size Resize Handles
By default, resize handles (top, bottom, left, right) are centered and have a limited size (40px). Setting fullSizeResizeHandles={true} makes these handles span the entire width or height of the window edge, providing a larger interaction area.
Full Size Resize Handles
Persistence
Enable state persistence to save the window's position and size in localStorage by setting persistState={true} (default is false). When enabled, the window will remember its position and size across page refreshes.
With Persistence
Callbacks
Use onPositionChange and onSizeChange callbacks to respond to window movements and resize operations. These callbacks receive the current position or size as pixel values.
With Callbacks
Multiple Windows
You can render multiple windows in the same container. Each window maintains its own z-index and can be brought to the front by clicking on it. Use unique id props to ensure proper state persistence.
Window 1
Window 2
Window.Group
Wrap multiple windows in a Window.Group to enable coordinated window management. The group provides:
- Coordinated z-index: Windows within a group share a stacking context
- Layout presets: Snap, tile, and fill layouts via the green tools button in each window header
- Global actions: Collapse all, expand all, close all
Each Window inside a Window.Group must have a unique id prop. The group defaults to withinPortal={false} (overridable via the withinPortal prop) and applies position: relative on its container.
Editor
Preview
Console
Tools Button
The green tools button in the window header provides layout options. It is controlled by the withToolsButton prop (default: true) and is available on every window, even outside a Window.Group.
Without a Group, the menu shows only single-window actions:
- Move & Resize: Snap left, snap right, snap top, snap bottom — positions the current window to fill half of the container or viewport
- Fill: Maximizes the current window to fill the entire available area
Inside a Group, the menu also shows group-wide actions:
- Arrange Columns / Rows: Distributes all visible windows in equal columns or rows
- Tile: Arranges all visible windows in an automatic grid
- Collapse all / Expand all: Collapses or expands all windows that have
collapsable={true}. Windows withcollapsable={false}are skipped. - Close all: Closes all windows in the group
The onLayoutChange callback on Window.Group notifies you when a group layout is applied.
Last layout applied:
Window 1
Window 2
Window 3
Window 4
Layout Presets
Use defaultLayout to apply an initial layout when the group mounts. To control the layout externally, use the groupRef prop to access the group API and call applyLayout programmatically.
Window 1
Window 2
Window 3
Styles API
Window supports Styles API, you can add styles to any inner element of the component with classNames prop. Follow Styles API documentation to learn more.
Styles API
Component Styles API
Hover over selectors to highlight corresponding elements