Get StartedComponentsStylingThemingMath & Science
MCP

Overlays & Feedback

Floating Panel

A draggable, resizable panel that floats above the page. It ships with the Indoku theme applied.

Always give CloseTrigger and StageTrigger children (icons or text); they render only what you pass.

Markdown

Import

tsx
import { FloatingPanel, useFloatingPanel } from "@indoku/ui"

Anatomy

FloatingPanel.Root (or RootProvider)├─ FloatingPanel.Trigger└─ Portal   └─ FloatingPanel.Positioner      └─ FloatingPanel.Content         ├─ FloatingPanel.Header         │  ├─ FloatingPanel.DragTrigger › FloatingPanel.Title         │  └─ FloatingPanel.Control › StageTrigger / CloseTrigger         ├─ FloatingPanel.Body         └─ FloatingPanel.ResizeTriggers

Examples

Basic

Root, Positioner, Content, Header, Body and ResizeTriggers.

Controlled open

Drive open and onOpenChange yourself.

Stage triggers

minimized, maximized and default.

Store provider

Create the store with useFloatingPanel and pass it to RootProvider.

open: false

Boundary constraints

Keep the panel inside an element with getBoundaryEl.

The panel cannot leave this box.

Anchor positioning

Compute the starting position with getAnchorPosition.

Props

FloatingPanel.Root

PropTypeDefaultDescription
openboolean–Controlled open state.
defaultOpenbooleanfalseInitial open state.
onOpenChange(details: { open: boolean }) => void–Called when the panel opens or closes.
onStageChange(details: { stage: 'minimized' | 'maximized' | 'default' }) => void–Called when the stage changes.
defaultSize / size{ width: number; height: number }–Initial or controlled size.
minSize / maxSize{ width: number; height: number }–Resize limits.
defaultPosition / position{ x: number; y: number }–Initial or controlled position.
getBoundaryEl() => HTMLElement | null–Element the panel is constrained to. Defaults to the viewport.
getAnchorPosition(details: { triggerRect, boundaryRect }) => { x: number; y: number }–Computes the position when the panel opens.
draggable / resizablebooleantrueTurn dragging or resizing off.
lockAspectRatiobooleanfalseKeep the aspect ratio while resizing.
persistRectbooleanfalseRemember size and position between opens.

FloatingPanel.StageTrigger

PropTypeDefaultDescription
stage*'minimized' | 'maximized' | 'default'–Stage this trigger switches to.

useFloatingPanel (store)

PropTypeDefaultDescription
open / setOpen(open)boolean / fn–Read or set the open state.
minimize() / maximize() / restore()() => void–Change the stage.
setPosition(pos) / setSize(size)fn–Move or resize programmatically.

* required. Style props and HTML attributes are accepted as well.

Accessibility

  • The title is wired to the content with aria-labelledby.
  • Give icon-only triggers an aria-label.

Notes

  • Render Positioner inside a Portal so the panel is not clipped by overflow containers.
  • With getBoundaryEl, the boundary should be position: relative.

Created by @indokudev