FloatingWindow
Use DragHandle when controls inside the window need their own pointer interactions. Without it, the whole surface can be dragged.
Source
LLM docs
Package
Examples
9
Properties
47
Hooks
1
Basics
Drag the header to move the window. The corner grip resizes it.
Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened((value) => !value)}>
{opened ? 'Hide window' : 'Show window'}
</Button>
{opened && (
<FloatingWindow
dimensions={{ initialWidth: 260, initialHeight: 160 }}
initialPosition={{ top: 90, left: 40 }}
p="md"
>
<FloatingWindow.DragHandle>
<Text fw="600">Drag this header</Text>
</FloatingWindow.DragHandle>
<Text>Move or resize this window.</Text>
<FloatingWindow.ResizeHandle />
</FloatingWindow>
)}
</>
);
}Without Viewport Constraint
constrainToViewport={false} lets the window move beyond the viewport edge.Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened(!opened)}>Toggle window</Button>
{opened && (
<FloatingWindow w={240} p="md" constrainToViewport={false}>
<Text>Drag beyond the viewport.</Text>
</FloatingWindow>
)}
</>
);
}Drag Handle
The DragHandle confines movement to one region, leaving child buttons interactive.
Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened(true)}>Open window</Button>
{opened && (
<FloatingWindow w={260} p="md">
<FloatingWindow.DragHandle>
<Text fw="600">Drag here</Text>
</FloatingWindow.DragHandle>
<Button size="sm" onPress={() => setOpened(false)}>
Close
</Button>
</FloatingWindow>
)}
</>
);
}Disabled Dragging
enabled={false} keeps the window fixed in place.Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened(!opened)}>Toggle static window</Button>
{opened && (
<FloatingWindow enabled={false} w={220} p="md">
<Text>This window stays put.</Text>
</FloatingWindow>
)}
</>
);
}Constrain Offset
constrainOffset keeps space between the window and viewport edges.Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened(!opened)}>Toggle inset window</Button>
{opened && (
<FloatingWindow constrainOffset={30} w={220} p="md">
<Text>30 px from the edge.</Text>
</FloatingWindow>
)}
</>
);
}Lock Axis
axis="x" limits dragging to the horizontal axis.Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened(!opened)}>Toggle horizontal window</Button>
{opened && (
<FloatingWindow axis="x" w={220} p="md">
<Text>Drag horizontally.</Text>
</FloatingWindow>
)}
</>
);
}Set Position
setPositionRef can move the window to a new viewport inset.Loading demo…
import { useRef, useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
import type { FloatingWindowHandle } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
const windowRef = useRef<FloatingWindowHandle>(null);
return (
<>
<Button onPress={() => setOpened(true)}>Open window</Button>
{opened && (
<FloatingWindow
setPositionRef={windowRef}
initialPosition={{ top: 100, left: 40 }}
dimensions={{ initialWidth: 240, initialHeight: 140 }}
p="md"
>
<FloatingWindow.DragHandle>
<Text fw="600">Move me</Text>
</FloatingWindow.DragHandle>
<Button onPress={() => windowRef.current?.setPosition({ top: 60, right: 60 })}>
Move to top right
</Button>
</FloatingWindow>
)}
</>
);
}Resize Handle
FloatingWindow.ResizeHandle resizes within the limits in dimensions.Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
return (
<>
<Button onPress={() => setOpened(true)}>Open resizable window</Button>
{opened && (
<FloatingWindow
initialPosition={{ top: 110, left: 60 }}
dimensions={{
initialWidth: 230,
initialHeight: 130,
minWidth: 160,
minHeight: 90,
maxWidth: 360,
maxHeight: 280,
}}
p="md"
>
<FloatingWindow.DragHandle>
<Text fw="600">Resizable window</Text>
</FloatingWindow.DragHandle>
<FloatingWindow.ResizeHandle />
</FloatingWindow>
)}
</>
);
}Resize Callbacks
onSizeChange reports the final window dimensions after a resize.Loading demo…
import { useState } from 'react';
import { Button, FloatingWindow, Text } from '@plocks/ui';
export function Demo() {
const [opened, setOpened] = useState(false);
const [size, setSize] = useState({ width: 240, height: 140 });
return (
<>
<Button onPress={() => setOpened(true)}>Open window</Button>
{opened && (
<FloatingWindow
initialPosition={{ top: 110, left: 60 }}
dimensions={{ initialWidth: 240, initialHeight: 140 }}
onSizeChange={setSize}
p="md"
>
<FloatingWindow.DragHandle>
<Text fw="600">Resize me</Text>
</FloatingWindow.DragHandle>
<Text>
{Math.round(size.width)} × {Math.round(size.height)}
</Text>
<FloatingWindow.ResizeHandle />
</FloatingWindow>
)}
</>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources